diff options
author | jomui <jongmun.woo@samsung.com> | 2015-06-17 21:03:29 +0900 |
---|---|---|
committer | jomui <jongmun.woo@samsung.com> | 2015-07-03 09:56:20 +0900 |
commit | 97d897a3b193be6ed51acece01a12e2b626d8c20 (patch) | |
tree | 5a77e62d1d27f224e2fb09998a68e64d35348e02 | |
parent | d96f4dca6cda95ddc27da94f662a1a6641f34566 (diff) | |
download | geofence-server-97d897a3b193be6ed51acece01a12e2b626d8c20.tar.gz geofence-server-97d897a3b193be6ed51acece01a12e2b626d8c20.tar.bz2 geofence-server-97d897a3b193be6ed51acece01a12e2b626d8c20.zip |
code sync with tizen 2.4submit/tizen_mobile/20150708.024411submit/tizen/20150703.074815accepted/tizen/mobile/20150708.070148
Signed-off-by: jomui <jongmun.woo@samsung.com>
Change-Id: Id3cedfbba98766a47de00d2ef0995941f599edb6
37 files changed, 7970 insertions, 0 deletions
@@ -0,0 +1,5 @@ +Jongmun Woo <jongmun.woo@samsung.com> +Young-Ae Kang <youngae.kang@samsung.com> +Kyoungjun Sung <kj7.sung@samsung.com> +Karthik Paulraj <p.karthik@samsung.com> +VENKATAKOTIVIJAYALAKSHMINARAYA <lnarayana.k@samsung.com> diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..39189a4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,43 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(geofence-server) + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(BIN_DIR "${PREFIX}/bin") + +#Dependencies + +SET(common_dp "glib-2.0 geofence-dbus dlog gio-2.0 capi-appfw-app-manager") +SET(server_dp "${common_dp} network vconf vconf-internal-keys gthread-2.0 gio-unix-2.0 sqlite3 db-util alarm-service deviced capi-location-manager capi-network-bluetooth capi-network-wifi libcore-context-manager") +SET(module_dp "${common_dp} gmodule-2.0") + +# Set required packages +INCLUDE(FindPkgConfig) + +## SERVER +pkg_check_modules(server_pkgs REQUIRED ${server_dp}) +FOREACH(flag ${server_pkgs_CFLAGS}) + SET(SERVER_EXTRA_CFLAGS "${SERVER_EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +## MODULE +pkg_check_modules(module_pkgs REQUIRED ${module_dp}) +FOREACH(flag ${module_pkgs_CFLAGS}) + SET(MODULE_EXTRA_CFLAGS "${MODULE_EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs -fvisibility=hidden ") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -fPIC") +#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter -Wno-missing-field-initializers -Wno-missing-declarations -Wall -Wcast-align -Wno-sign-compare") + +SET(SERVER_SRCS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/geofence-server") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS(" -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" ") + +MESSAGE(${CMAKE_C_FLAGS}) +MESSAGE(${CMAKE_EXE_LINKER_FLAGS}) + +ADD_SUBDIRECTORY(module) +ADD_SUBDIRECTORY(geofence-server) @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/geofence-server.manifest b/geofence-server.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/geofence-server.manifest @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_" /> + </request> +</manifest> diff --git a/geofence-server/CMakeLists.txt b/geofence-server/CMakeLists.txt new file mode 100644 index 0000000..8d06754 --- /dev/null +++ b/geofence-server/CMakeLists.txt @@ -0,0 +1,20 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.0) +PROJECT(geofence-server) + +SET(server_pkgs_LDFLAGS "${server_pkgs_LDFLAGS} -ldl") +SET(SERVER_EXTRA_CFLAGS "${SERVER_EXTRA_CFLAGS} -D_GNU_SOURCE") + +AUX_SOURCE_DIRECTORY(src SERVER_SRCS) + +INCLUDE_DIRECTORIES(src include) + +CONFIGURE_FILE(org.tizen.lbs.Providers.GeofenceServer.service.in org.tizen.lbs.Providers.GeofenceServer.service @ONLY) +INSTALL(FILES org.tizen.lbs.Providers.GeofenceServer.service DESTINATION /usr/share/dbus-1/system-services) +INSTALL(FILES config/geofence-server.conf DESTINATION ${SYSCONF_DIR}/dbus-1/system.d) + +ADD_EXECUTABLE(${PROJECT_NAME} ${SERVER_SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${server_pkgs_LDFLAGS} -lm) +SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS ${SERVER_EXTRA_CFLAGS}) +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BIN_DIR}) diff --git a/geofence-server/config/geofence-server.conf b/geofence-server/config/geofence-server.conf new file mode 100644 index 0000000..2b49ee6 --- /dev/null +++ b/geofence-server/config/geofence-server.conf @@ -0,0 +1,25 @@ +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + + <!-- root can own the service --> + <policy user="root"> + <allow own="org.tizen.lbs.Providers.GeofenceServer"/> + + <!-- Allow all methods on interfaces --> + <allow send_destination="org.tizen.lbs.Providers.GeofenceServer"/> + <allow receive_sender="org.tizen.lbs.Providers.GeofenceServer"/> + </policy> + + <policy user="system"> + <allow own="org.tizen.lbs.Providers.GeofenceServer"/> + <allow send_destination="org.tizen.lbs.Providers.GeofenceServer"/> + <allow receive_sender="org.tizen.lbs.Providers.GeofenceServer"/> + </policy> + + <policy context="default"> + <allow own="org.tizen.lbs.Providers.GeofenceServer"/> + <allow send_destination="org.tizen.lbs.Providers.GeofenceServer"/> + <allow receive_sender="org.tizen.lbs.Providers.GeofenceServer"/> + </policy> +</busconfig> diff --git a/geofence-server/include/geofence-module.h b/geofence-server/include/geofence-module.h new file mode 100644 index 0000000..67361b4 --- /dev/null +++ b/geofence-server/include/geofence-module.h @@ -0,0 +1,86 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __GEOFENCE_MODULE_H__ +#define __GEOFENCE_MODULE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file geofence-module.h + * @brief This file contains the structure and enumeration for geofence plug-in development. + */ + + +/** + * @brief This represents geofence parameter. + */ +typedef enum { + GEOFENCE_TYPE_GEOPOINT = 1, /**< Geofence is specified by geo position */ + GEOFENCE_TYPE_WIFI, /**< Geofence is specified by WiFi hotspot */ + GEOFENCE_TYPE_BT, /**< Geofence is specified BT */ +} geofence_type_e; + +typedef enum { + ACCESS_TYPE_PRIVATE = 1, + ACCESS_TYPE_PUBLIC, + ACCESS_TYPE_UNKNOWN, +} access_type_e; + +/** + * @brief The geofence manager handle. + */ +typedef struct place_params_s *place_params_h; +/** + * @brief The geofence params handle. + */ +typedef struct geofence_params_s *geofence_params_h; + +/** + * @brief This represents a geofence callback function for geofence plug-in. + */ +typedef void (*GeofenceModCB) (int fence_id, int state, gpointer userdata); + +typedef void (*GeofenceModEventCB) (int place_id, int fence_id, int error, int state, gpointer userdata); + +/** + * @brief This represents APIs declared in a Geofence plug-in for Geofence modules. + */ +typedef struct { + int (*create) (void *handle, GeofenceModCB geofence_cb, GeofenceModEventCB geofence_event_cb, void *userdata); + int (*destroy) (void *handle); + int (*enable_service) (void *handle, int fence_id, bool enable); + int (*add_geopoint) (void *handle, int place_id, double latitude, double longitude, int radius, const char *address, int *fence_id); + int (*add_bssid) (void *handle, int place_id, const char *bssid, const char *ssid, geofence_type_e type, int *fence_id); + int (*add_place) (void *handle, const char *place_name, int *place_id); + int (*update_place) (void *handle, int place_id, const char *place_name); + int (*remove_geofence) (void *handle, int fence_id); + int (*remove_place) (void *handle, int place_id); + int (*start_geofence) (void *handle, int fence_id); + int (*stop_geofence) (void *handle, int fence_id); + int (*get_place_name) (void *handle, int place_id, char **place_name); + int (*get_list) (void *handle, int place_id, int *fence_amount, int **fence_ids, struct geofence_params_s **params); + int (*get_place_list) (void *handle, int *place_amount, int **place_ids, struct place_params_s **params); +} GeofenceModOps; + +/** + * @} @} + */ +#ifdef __cplusplus +} +#endif +#endif diff --git a/geofence-server/include/geofence_server_data_types.h b/geofence-server/include/geofence_server_data_types.h new file mode 100644 index 0000000..36353d5 --- /dev/null +++ b/geofence-server/include/geofence_server_data_types.h @@ -0,0 +1,134 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 _GEOFENCE_MANAGER_DATA_TYPES_H_ +#define _GEOFENCE_MANAGER_DATA_TYPES_H_ + +#include <stdint.h> +#include <time.h> +#include <tizen_type.h> +#include <tizen_error.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Tizen Geofence Server Error */ +#if !defined(TIZEN_ERROR_GEOFENCE_SERVER) +#define TIZEN_ERROR_GEOFENCE_SERVER -0x02C10000 +#endif + +/** + * This enumeration has geofence service status. + */ +typedef enum { + GEOFENCE_STATUS_UNABAILABLE = 0, + GEOFENCE_STATUS_ABAILABLE = 1, +} geofence_status_t; + +/** + * This enumeration descript the geofence fence state. + */ +typedef enum { + GEOFENCE_EMIT_STATE_UNCERTAIN = 0, + GEOFENCE_EMIT_STATE_IN = 1, + GEOFENCE_EMIT_STATE_OUT = 2, +} geofence_emit_state_e; + +/** + * This enumeration descript the geofence fence state. + */ +typedef enum { + GEOFENCE_FENCE_STATE_UNCERTAIN = -1, + GEOFENCE_FENCE_STATE_OUT = 0, + GEOFENCE_FENCE_STATE_IN = 1, +} geofence_fence_state_e; + +/** + * This enumeration descript the geofence state. + */ +typedef enum { + GEOFENCE_DIRECTION_BOTH = 0, + GEOFENCE_DIRECTION_ENTER, + GEOFENCE_DIRECTION_EXIT, +} geofence_direction_e; + +/** + * This enumeration has geofence service error type. + */ + +typedef enum { + FENCE_ERR_NONE = 0, /** No error */ + FENCE_ERR_SQLITE_FAIL = -100, + FENCE_ERR_INVALID_PARAMETER = -101, + FENCE_ERR_INTERNAL = -102, + FENCE_ERR_FENCE_ID = -103, + FENCE_ERR_PREPARE = -104, + FENCE_ERR_FENCE_TYPE = -105, /* geofence type ERROR */ + FENCE_ERR_STRING_TRUNCATED = -106, /* String truncated */ + FENCE_ERR_COUNT = -107, /* count <= 0 */ + FENCE_ERR_UNKNOWN = -108 +} fence_err_e; + +/** + * @brief Enumerations of error code for Geofence manager. + * @since_tizen 2.4 + */ +typedef enum { + GEOFENCE_SERVER_ERROR_NONE = TIZEN_ERROR_NONE, /**< Success */ + GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + GEOFENCE_SERVER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + GEOFENCE_SERVER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + GEOFENCE_SERVER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ + GEOFENCE_SERVER_ERROR_NOT_INITIALIZED = TIZEN_ERROR_GEOFENCE_SERVER | 0x01, /**< Geofence Manager is not initialized */ + GEOFENCE_SERVER_ERROR_ID_NOT_EXIST = TIZEN_ERROR_GEOFENCE_SERVER | 0x02, /**< Geofence ID is not exist */ + GEOFENCE_SERVER_ERROR_EXCEPTION = TIZEN_ERROR_GEOFENCE_SERVER | 0x03, /**< exception is occured */ + GEOFENCE_SERVER_ERROR_ALREADY_STARTED = TIZEN_ERROR_GEOFENCE_SERVER | 0x04, /**< Geofence is already started */ + GEOFENCE_SERVER_ERROR_TOO_MANY_GEOFENCE = TIZEN_ERROR_GEOFENCE_SERVER | 0x05, /**< Too many Geofence */ + GEOFENCE_SERVER_ERROR_IPC = TIZEN_ERROR_GEOFENCE_SERVER | 0x06, /**< Error occured in GPS/WIFI/BT */ + GEOFENCE_SERVER_ERROR_DATABASE = TIZEN_ERROR_GEOFENCE_SERVER | 0x07, /**< DB error occured in the server side */ + GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED = TIZEN_ERROR_GEOFENCE_SERVER | 0x08, /**< Access to specified place is denied */ + GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED = TIZEN_ERROR_GEOFENCE_SERVER | 0x09, /**< Access to specified geofence is denied */ +} geofence_server_error_e; + +/** +* This enumeration describes the geofence param state +*/ +typedef enum { + GEOFENCE_MANAGE_FENCE_ADDED = 0x00, + GEOFENCE_MANAGE_FENCE_REMOVED, + GEOFENCE_MANAGE_FENCE_STARTED, + GEOFENCE_MANAGE_FENCE_STOPPED, + + GEOFENCE_MANAGE_PLACE_ADDED = 0x10, + GEOFENCE_MANAGE_PLACE_REMOVED, + GEOFENCE_MANAGE_PLACE_UPDATED, + + GEOFENCE_MANAGE_SETTING_ENABLED = 0x20, + GEOFENCE_MANAGE_SETTING_DISABLED +} geofence_manage_e; + +/** + * This enumeration descript the Smart Assistant State + */ +typedef enum { + GEOFENCE_SMART_ASSIST_STOP = 0, + GEOFENCE_SMART_ASSIST_START +} geofence_smart_assist_state_e; + +#ifdef __cplusplus +} +#endif +#endif /* _GEOFENCE_MANAGER_DATA_TYPES_H_ */ diff --git a/geofence-server/include/geofence_server_extra_data_types.h b/geofence-server/include/geofence_server_extra_data_types.h new file mode 100644 index 0000000..6effb67 --- /dev/null +++ b/geofence-server/include/geofence_server_extra_data_types.h @@ -0,0 +1,32 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 _GEOFENCE_MANAGER_EXTRA_DATA_TYPES_H_ +#define _GEOFENCE_MANAGER_EXTRA_DATA_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + GEOFENCE_ZONE_IN = 0x00, + GEOFENCE_ZONE_OUT = 0x01, + GEOFENCE_ZONE_UNCERTAIN = 0x02, +} geofence_zone_state_t; + +#ifdef __cplusplus +} +#endif +#endif /* _GEOFENCE_MANAGER_EXTRA_DATA_TYPES_H_ */ diff --git a/geofence-server/org.tizen.lbs.Providers.GeofenceServer.service.in b/geofence-server/org.tizen.lbs.Providers.GeofenceServer.service.in new file mode 100644 index 0000000..c45ba2f --- /dev/null +++ b/geofence-server/org.tizen.lbs.Providers.GeofenceServer.service.in @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.tizen.lbs.Providers.GeofenceServer +Exec=@BIN_DIR@/geofence-server +User=system +Group=system diff --git a/geofence-server/script/geofence-server b/geofence-server/script/geofence-server new file mode 100644 index 0000000..541a6cb --- /dev/null +++ b/geofence-server/script/geofence-server @@ -0,0 +1,11 @@ +#!/bin/sh +##/etc/init.d/geofence-manager Lv : S90 + +## This file is boot script of /usr/bin/geofence-server + +if [ -x /usr/bin/geofence-server ]; then + if [ ! -z "`pgrep geofence-server`" ]; then + killall geofence-server + fi + /usr/bin/geofence-server & +fi diff --git a/geofence-server/src/debug_util.h b/geofence-server/src/debug_util.h new file mode 100644 index 0000000..56a4347 --- /dev/null +++ b/geofence-server/src/debug_util.h @@ -0,0 +1,43 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 _GEOFENCE_MANAGER_DEBUG_UTIL_H_ +#define _GEOFENCE_MANAGER_DEBUG_UTIL_H_ + +#include <glib.h> +#include <libgen.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define GEOFENCE_SERVER_DLOG +#define LBS_DLOG_DEBUG + +#include <dlog.h> +#define TAG_GEOFENCE_SERVER "GEOFENCE_SERVER" + +/*#define __LOCAL_TEST__*/ + +#define LOGD_GEOFENCE(fmt, args...) SLOG(LOG_DEBUG, TAG_GEOFENCE_SERVER, fmt, ##args) +#define LOGI_GEOFENCE(fmt, args...) SLOG(LOG_INFO, TAG_GEOFENCE_SERVER, fmt, ##args) +#define LOGW_GEOFENCE(fmt, args...) SLOG(LOG_WARN, TAG_GEOFENCE_SERVER, fmt, ##args) +#define LOGE_GEOFENCE(fmt, args...) SLOG(LOG_ERROR, TAG_GEOFENCE_SERVER, fmt, ##args) +#define FUNC_ENTRANCE_SERVER LOGD_GEOFENCE("[%s] Entered!!\n", __func__); + +#ifdef __cplusplus +} +#endif +#endif /* _GEOFENCE_MANAGER_DEBUG_UTIL_H_ */ diff --git a/geofence-server/src/geofence_server.c b/geofence-server/src/geofence_server.c new file mode 100644 index 0000000..848ef5b --- /dev/null +++ b/geofence-server/src/geofence_server.c @@ -0,0 +1,2176 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 <stdio.h> +#include <string.h> +#include <time.h> +#include <stdlib.h> +#include <glib.h> +#include <glib-object.h> +#include <geofence_client.h> +#include <dd-display.h> +#include <vconf.h> +#include <vconf-internal-wifi-keys.h> +#include "geofence_server_data_types.h" +#include "geofence_server.h" +#include "server.h" +#include "debug_util.h" +#include "geofence_server_db.h" +#include "geofence_server_private.h" +#include "geofence_server_wifi.h" +#include "geofence_server_alarm.h" +#include "geofence_server_internal.h" +#include "geofence_server_bluetooth.h" +#include <wifi.h> + +#define TIZEN_ENGINEER_MODE +#ifdef TIZEN_ENGINEER_MODE +#include "geofence_server_log.h" +#endif + +#define GEOFENCE_SERVER_SERVICE_NAME "org.tizen.lbs.Providers.GeofenceServer" +#define GEOFENCE_SERVER_SERVICE_PATH "/org/tizen/lbs/Providers/GeofenceServer" +#define TIME_INTERVAL 5 + +#define SMART_ASSIST_HOME 1 + +#define SMART_ASSIST_TIMEOUT 60 /* Refer to LPP */ +#define GEOFENCE_DEFAULT_RADIUS 200 /* Default 200 m */ + +#define NPS_TIMEOUT 180 + +#define MYPLACES_APPID "org.tizen.myplace" +#define DEFAULT_PLACE_HOME 1 +#define DEFAULT_PLACE_OFFICE 2 +#define DEFAULT_PLACE_CAR 3 + +static int __nps_alarm_cb(alarm_id_t alarm_id, void *user_data); +static int __nps_timeout_cb(alarm_id_t alarm_id, void *user_data); +static void __add_left_fences(gpointer user_data); +static void __stop_geofence_service(gint fence_id, const gchar *app_id, gpointer userdata); +static void __start_activity_service(GeofenceServer *geofence_server); +static void __stop_activity_service(GeofenceServer *geofence_server); +static void __activity_cb(activity_type_e type, const activity_data_h data, double timestamp, activity_error_e error, void *user_data); + +static const char *__convert_wifi_error_to_string(wifi_error_e err_type) +{ + switch (err_type) { + case WIFI_ERROR_NONE: + return "NONE"; + case WIFI_ERROR_INVALID_PARAMETER: + return "INVALID_PARAMETER"; + case WIFI_ERROR_OUT_OF_MEMORY: + return "OUT_OF_MEMORY"; + case WIFI_ERROR_INVALID_OPERATION: + return "INVALID_OPERATION"; + case WIFI_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED: + return "ADDRESS_FAMILY_NOT_SUPPORTED"; + case WIFI_ERROR_OPERATION_FAILED: + return "OPERATION_FAILED"; + case WIFI_ERROR_NO_CONNECTION: + return "NO_CONNECTION"; + case WIFI_ERROR_NOW_IN_PROGRESS: + return "NOW_IN_PROGRESS"; + case WIFI_ERROR_ALREADY_EXISTS: + return "ALREADY_EXISTS"; + case WIFI_ERROR_OPERATION_ABORTED: + return "OPERATION_ABORTED"; + case WIFI_ERROR_DHCP_FAILED: + return "DHCP_FAILED"; + case WIFI_ERROR_INVALID_KEY: + return "INVALID_KEY"; + case WIFI_ERROR_NO_REPLY: + return "NO_REPLY"; + case WIFI_ERROR_SECURITY_RESTRICTED: + return "SECURITY_RESTRICTED"; + case WIFI_ERROR_PERMISSION_DENIED: + return "PERMISSION_DENIED"; + default: + return "NOT Defined"; + } +} + +#if 0 /* Not used */ +static const char *__bt_get_error_message(bt_error_e err) +{ + switch (err) { + case BT_ERROR_NONE: + return "BT_ERROR_NONE"; + case BT_ERROR_CANCELLED: + return "BT_ERROR_CANCELLED"; + case BT_ERROR_INVALID_PARAMETER: + return "BT_ERROR_INVALID_PARAMETER"; + case BT_ERROR_OUT_OF_MEMORY: + return "BT_ERROR_OUT_OF_MEMORY"; + case BT_ERROR_RESOURCE_BUSY: + return "BT_ERROR_RESOURCE_BUSY"; + case BT_ERROR_TIMED_OUT: + return "BT_ERROR_TIMED_OUT"; + case BT_ERROR_NOW_IN_PROGRESS: + return "BT_ERROR_NOW_IN_PROGRESS"; + case BT_ERROR_NOT_INITIALIZED: + return "BT_ERROR_NOT_INITIALIZED"; + case BT_ERROR_NOT_ENABLED: + return "BT_ERROR_NOT_ENABLED"; + case BT_ERROR_ALREADY_DONE: + return "BT_ERROR_ALREADY_DONE"; + case BT_ERROR_OPERATION_FAILED: + return "BT_ERROR_OPERATION_FAILED"; + case BT_ERROR_NOT_IN_PROGRESS: + return "BT_ERROR_NOT_IN_PROGRESS"; + case BT_ERROR_REMOTE_DEVICE_NOT_BONDED: + return "BT_ERROR_REMOTE_DEVICE_NOT_BONDED"; + case BT_ERROR_AUTH_REJECTED: + return "BT_ERROR_AUTH_REJECTED"; + case BT_ERROR_AUTH_FAILED: + return "BT_ERROR_AUTH_FAILED"; + case BT_ERROR_REMOTE_DEVICE_NOT_FOUND: + return "BT_ERROR_REMOTE_DEVICE_NOT_FOUND"; + case BT_ERROR_SERVICE_SEARCH_FAILED: + return "BT_ERROR_SERVICE_SEARCH_FAILED"; + case BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED: + return "BT_ERROR_REMOTE_DEVICE_NOT_CONNECTED"; +#ifndef TIZEN_TV + case BT_ERROR_PERMISSION_DENIED: + return "BT_ERROR_PERMISSION_DENIED"; + case BT_ERROR_SERVICE_NOT_FOUND: + return "BT_ERROR_SERVICE_NOT_FOUND"; +#endif + default: + return "NOT Defined"; + } +} +#endif + +static int __emit_fence_event(GeofenceServer *geofence_server, int place_id, int fence_id, access_type_e access_type, const gchar *app_id, geofence_server_error_e error, geofence_manage_e state) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(geofence_server, -1); + + geofence_dbus_server_send_geofence_event_changed(geofence_server->geofence_dbus_server, place_id, fence_id, access_type, app_id, error, state); + return 0; +} + +static int __emit_fence_inout(GeofenceServer *geofence_server, int fence_id, geofence_fence_state_e state) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(geofence_server, -1); + int ret = 0; + + LOGD_GEOFENCE("FenceId[%d], state[%d]", fence_id, state); + GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server); + if (item_data == NULL) { + LOGD_GEOFENCE("Invalid item_data"); + return -1; + } + + if (state == GEOFENCE_FENCE_STATE_IN) { + LOGD_GEOFENCE("FENCE_IN to be set, current state: %d", + item_data->common_info.status); + if (item_data->common_info.status != GEOFENCE_FENCE_STATE_IN) { + geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, item_data->common_info.appid, fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_IN); + if (item_data->client_status == GEOFENCE_CLIENT_STATUS_START) { + item_data->client_status = GEOFENCE_CLIENT_STATUS_RUNNING; + } +#ifdef TIZEN_ENGINEER_MODE + GEOFENCE_PRINT_LOG("FENCE_IN") +#endif + } + + item_data->common_info.status = GEOFENCE_FENCE_STATE_IN; + + } else if (state == GEOFENCE_FENCE_STATE_OUT) { + LOGD_GEOFENCE("FENCE_OUT to be set, current state: %d", + item_data->common_info.status); + if (item_data->common_info.status != GEOFENCE_FENCE_STATE_OUT) { + geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, item_data->common_info.appid, fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_OUT); + if (item_data->client_status == GEOFENCE_CLIENT_STATUS_START) { + item_data->client_status = GEOFENCE_CLIENT_STATUS_RUNNING; + } +#ifdef TIZEN_ENGINEER_MODE + GEOFENCE_PRINT_LOG("FENCE_OUT") +#endif + } else { + LOGD_GEOFENCE("Fence status [%d]", item_data->common_info.status); + } + item_data->common_info.status = GEOFENCE_FENCE_STATE_OUT; + } else { + LOGD_GEOFENCE("Not emit, Prev[%d], Curr[%d]", item_data->common_info.status, state); + } + + return ret; +} + +static void __check_inout_by_gps(double latitude, double longitude, int fence_id, void *user_data) +{ + FUNC_ENTRANCE_SERVER; + double distance = 0.0; + LOGD_GEOFENCE("fence_id [%d]", fence_id); + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server); + if (!item_data || item_data->client_status == GEOFENCE_CLIENT_STATUS_NONE) + return; + + location_accuracy_level_e level = 0; + double horizontal = 0.0; + double vertical = 0.0; + geofence_fence_state_e status = GEOFENCE_FENCE_STATE_OUT; + + geocoordinate_info_s *geocoordinate_info = (geocoordinate_info_s *)item_data->priv; + + /* get_current_position/ check_fence_in/out for geoPoint */ + location_manager_get_accuracy(geofence_server->loc_manager, &level, &horizontal, &vertical); + location_manager_get_distance(latitude, longitude, geocoordinate_info->latitude, geocoordinate_info->longitude, &distance); + + if (distance >= geocoordinate_info->radius) { + LOGD_GEOFENCE("FENCE_OUT : based on distance. Distance[%f]", distance); + status = GEOFENCE_FENCE_STATE_OUT; + } else { + LOGD_GEOFENCE("FENCE_IN : based on distance. Distance[%f]", distance); + status = GEOFENCE_FENCE_STATE_IN; + } + + if (__emit_fence_inout(geofence_server, item_data->common_info.fence_id, status) == 0 && status == GEOFENCE_FENCE_STATE_IN) { + LOGD_GEOFENCE("Disable timer"); + } +} + +static void __check_current_location_cb(double latitude, double longitude, double altitude, time_t timestamp, void *user_data) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + location_accuracy_level_e level; + double hor_acc = 0.0; + double ver_acc = 0.0; + int ret = 0; + int fence_id = 0; + GList *tracking_list = NULL; + GeofenceItemData *item_data = NULL; + + ret = location_manager_get_accuracy(geofence_server->loc_manager, &level, &hor_acc, &ver_acc); + if (ret == LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("hor_acc:%f, ver_acc:%f", hor_acc, ver_acc); + } + if (hor_acc > 500) { + return; + } + + LOGD_GEOFENCE("Traversing the tracking list"); + tracking_list = g_list_first(geofence_server->tracking_list); + LOGD_GEOFENCE("Got the first element in tracking list"); + + while (tracking_list) { + fence_id = GPOINTER_TO_INT(tracking_list->data); + item_data = __get_item_by_fence_id(fence_id, geofence_server); + + if (item_data != NULL) { + if (item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) { + LOGD_GEOFENCE("TRACKING FENCE ID :: %d", fence_id); + __check_inout_by_gps(latitude, longitude, fence_id, geofence_server); + } + } + tracking_list = g_list_next(tracking_list); + } + LOGD_GEOFENCE("Unsetting the position_updated_cb"); + location_manager_unset_position_updated_cb(geofence_server->loc_manager); + location_manager_stop(geofence_server->loc_manager); + geofence_server->loc_started = FALSE; +} + +static void __geofence_position_changed_cb(double latitude, double longitude, double altitude, time_t timestamp, void *user_data) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + double distance = 0; + int interval = 0; + /*Remove the timeout callback that might be running when requesting for fix.*/ + if (geofence_server->nps_timeout_alarm_id != -1) { + LOGI_GEOFENCE("Removing the timeout alarm from restart gps"); + geofence_server->nps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->nps_timeout_alarm_id); + } + geofence_server->last_loc_time = timestamp; + __check_current_location_cb(latitude, longitude, altitude, timestamp, user_data); + + /* Distance based alarm */ + distance = _get_min_distance(latitude, longitude, geofence_server); + + if (distance < 200) { + LOGD_GEOFENCE("interval: 1 secs"); + interval = 1; + } else if (distance < 500) { + LOGD_GEOFENCE("interval: 3 secs"); + interval = 3; + } else if (distance < 1000) { + LOGD_GEOFENCE("interval: 6 secs"); + interval = 6; + } else if (distance < 2000) { + LOGD_GEOFENCE("interval: 20 secs"); + interval = 20; + } else if (distance < 3000) { + LOGD_GEOFENCE("interval : 1 min"); + interval = 1 * 60; + } else if (distance < 5000) { + LOGD_GEOFENCE("interval: 2 mins"); + interval = 2 * 60; + } else if (distance < 10000) { + LOGD_GEOFENCE("interval: 5 mins"); + interval = 5 * 60; + } else if (distance < 20000) { + LOGD_GEOFENCE("interval : 10 mins"); + interval = 10 * 60; + } else if (distance < 100000) { + LOGD_GEOFENCE("interval : 20 mins"); + interval = 20 * 60; + } else { + LOGD_GEOFENCE("interval : 60 mins"); + interval = 60 * 60; + } + + /* remove the activity value when 10 hours later */ + if (geofence_server->last_loc_time - geofence_server->activity_timestamp > 10 * 60 * 60) + geofence_server->activity_type = ACTIVITY_IN_VEHICLE; + + if (geofence_server->activity_type == ACTIVITY_STATIONARY) + interval = interval * 10; + else if (geofence_server->activity_type == ACTIVITY_WALK) + interval = interval * 5; + else if (geofence_server->activity_type == ACTIVITY_RUN) + interval = interval * 3; + + LOGI_GEOFENCE("Setting the interval of alrm %d s", interval); + + if (geofence_server->nps_alarm_id == -1) { + LOGI_GEOFENCE("Setting the nps alarm from the callback"); + geofence_server->nps_alarm_id = _geofence_add_alarm(interval, __nps_alarm_cb, geofence_server); + } + return; +} + +static void __check_tracking_list(const char *bssid, void *user_data, + geofence_type_e type) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + g_return_if_fail(geofence_server); + int tracking_fence_id = 0; + GeofenceItemData *item_data = NULL; + GList *tracking_fences = g_list_first(geofence_server->tracking_list); + + while (tracking_fences) { + tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data); + tracking_fences = g_list_next(tracking_fences); + item_data = __get_item_by_fence_id(tracking_fence_id, geofence_server); + if (item_data != NULL) { + if (item_data->common_info.type == type) { + if (type == GEOFENCE_TYPE_WIFI) { + bssid_info_s *wifi_info = (bssid_info_s *)item_data->priv; + + if ((!g_ascii_strcasecmp(wifi_info->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(wifi_info->bssid, "-", ':'), bssid)) && item_data->is_wifi_status_in == false) { + LOGI_GEOFENCE("Matched wifi fence: fence_id = %d, bssid = %s", item_data->common_info.fence_id, wifi_info->bssid); + item_data->is_wifi_status_in = true; + } + } else if (type == GEOFENCE_TYPE_BT) { + bssid_info_s *bt_info = (bssid_info_s *)item_data->priv; + + if ((!g_ascii_strcasecmp(bt_info->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(bt_info->bssid, "-", ':'), bssid)) && item_data->is_bt_status_in == false) { + LOGI_GEOFENCE("Matched bt fence: fence_id = %d, bssid received = %s, bssid = %s", item_data->common_info.fence_id, bt_info->bssid, bssid); + item_data->is_bt_status_in = true; + } + } + } + } else { + LOGI_GEOFENCE("No data present for the fence: %d", tracking_fence_id); + } + } +} + +void bt_adapter_device_discovery_state_cb(int result, bt_adapter_device_discovery_state_e discovery_state, bt_adapter_device_discovery_info_s *discovery_info, void *user_data) +{ + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + GeofenceItemData *item_data = NULL; + int i; + int tracking_fence_id = 0; + GList *tracking_fences = g_list_first(geofence_server->tracking_list); + + if (discovery_state != BT_ADAPTER_DEVICE_DISCOVERY_FOUND) { + LOGI_GEOFENCE("BREDR discovery %s", discovery_state == BT_ADAPTER_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished"); + /* Check only if some BT fence is running */ + if (discovery_state == BT_ADAPTER_DEVICE_DISCOVERY_FINISHED && geofence_server->running_bt_cnt > 0) { + LOGI_GEOFENCE("Comparison for BT is done. Now emit the status..."); + while (tracking_fences) { + tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data); + tracking_fences = g_list_next(tracking_fences); + item_data = __get_item_by_fence_id(tracking_fence_id, geofence_server); + if (item_data && item_data->common_info.type == GEOFENCE_TYPE_BT) { + if (item_data->is_bt_status_in == true) { + __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_IN); + } else { + __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_OUT); + } + item_data->is_bt_status_in = false; + } + } + } + } else { + LOGI_GEOFENCE("%s %s", discovery_info->remote_address, discovery_info->remote_name); + LOGI_GEOFENCE("rssi: %d is_bonded: %d", discovery_info->rssi, discovery_info->is_bonded); + + if (geofence_server->running_bt_cnt > 0) { + for (i = 0; i < discovery_info->service_count; i++) { + LOGI_GEOFENCE("uuid: %s", discovery_info->service_uuid[i]); + } + LOGI_GEOFENCE("Tracking list is being checked for the BT geofence"); + __check_tracking_list(discovery_info->remote_address, geofence_server, GEOFENCE_TYPE_BT); + } + } +} + +static void geofence_network_evt_cb(net_event_info_t *event_cb, void *user_data) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + g_return_if_fail(geofence_server); + GList *tracking_fences = g_list_first(geofence_server->tracking_list); + GeofenceItemData *item_data = NULL; + int tracking_fence_id = 0; + + switch (event_cb->Event) { + case NET_EVENT_WIFI_SCAN_IND: + + LOGD_GEOFENCE("Got WIFI scan Ind : %d\n", event_cb->Error); + + net_profile_info_t *profiles = NULL; + int num_of_profile = 0; + + if (geofence_server->running_wifi_cnt > 0) { /*Check only if some wifi fence is running*/ + if (NET_ERR_NONE != net_get_profile_list(NET_DEVICE_WIFI, &profiles, &num_of_profile)) { + LOGD_GEOFENCE("Failed to get the scanned list"); + } else { + LOGD_GEOFENCE("Scan results retrieved successfully. No.of profiles: %d", num_of_profile); + if (num_of_profile > 0 && profiles != NULL) { + int cnt; + for (cnt = 0; cnt < num_of_profile; cnt++) { + net_wifi_profile_info_t *ap_info = &profiles[cnt].ProfileInfo.Wlan; + LOGD_GEOFENCE("BSSID %s", ap_info->bssid); + __check_tracking_list(ap_info->bssid, geofence_server, GEOFENCE_TYPE_WIFI); + } + LOGD_GEOFENCE("Comparing fences with scan results is done.Now emit the status to the application"); + while (tracking_fences) { + tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data); + tracking_fences = g_list_next(tracking_fences); + item_data = __get_item_by_fence_id(tracking_fence_id, geofence_server); + if (item_data && item_data->common_info.type == GEOFENCE_TYPE_WIFI) { + if (item_data->is_wifi_status_in == true) { + __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_IN); + } else { + __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_OUT); + } + item_data->is_wifi_status_in = false; + } + } + } + } + } + + break; + default: + break; + } +} + +static int __start_gps_positioning(GeofenceServer *geofence_server, location_position_updated_cb callback) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(geofence_server, -1); + int ret = FENCE_ERR_NONE; + + if (geofence_server->loc_manager == NULL) { + ret = location_manager_create(LOCATIONS_METHOD_GPS, &geofence_server->loc_manager); + if (ret != LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("Fail to create location_manager_h: %d", ret); + return FENCE_ERR_UNKNOWN; + } + } + + if (geofence_server->loc_started == FALSE) { + ret = location_manager_set_position_updated_cb(geofence_server->loc_manager, callback, 1, (void *) geofence_server); + if (ret != LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("Fail to set callback. %d", ret); + return FENCE_ERR_UNKNOWN; + } + + ret = location_manager_start(geofence_server->loc_manager); + if (ret != LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("Fail to start. %d", ret); + return FENCE_ERR_UNKNOWN; + } + if (geofence_server->nps_timeout_alarm_id == -1) + geofence_server->nps_timeout_alarm_id = _geofence_add_alarm(NPS_TIMEOUT, __nps_timeout_cb, geofence_server); + + geofence_server->loc_started = TRUE; + } else { + LOGD_GEOFENCE("loc_started TRUE"); + } + + return ret; +} + +static void __stop_gps_positioning(gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + g_return_if_fail(userdata); + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + int ret = 0; + if (geofence_server->loc_started == TRUE) { + ret = location_manager_stop(geofence_server->loc_manager); + if (ret != LOCATIONS_ERROR_NONE) { + return; + } + geofence_server->loc_started = FALSE; + ret = location_manager_unset_position_updated_cb + (geofence_server->loc_manager); + if (ret != LOCATIONS_ERROR_NONE) { + return; + } + } + + if (geofence_server->loc_manager != NULL) { + ret = location_manager_destroy(geofence_server->loc_manager); + if (ret != LOCATIONS_ERROR_NONE) { + return; + } + geofence_server->loc_manager = NULL; + } +} + +static int __nps_timeout_cb(alarm_id_t alarm_id, void *user_data) +{ + LOGI_GEOFENCE("__nps_timeout_cb"); + g_return_val_if_fail(user_data, -1); + LOGD_GEOFENCE("alarm_id : %d", alarm_id); + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + geofence_server->nps_timeout_alarm_id = -1; /*resetting the alarm id*/ + /*Stop the gps for sometime when there is no fix*/ + __stop_gps_positioning(geofence_server); + geofence_server->nps_alarm_id = _geofence_add_alarm(1 * 60, __nps_alarm_cb, geofence_server); + display_unlock_state(LCD_OFF, PM_RESET_TIMER); + return 0; +} + +static int __nps_alarm_cb(alarm_id_t alarm_id, void *user_data) +{ + LOGI_GEOFENCE("__nps_alarm_cb"); + g_return_val_if_fail(user_data, -1); + LOGD_GEOFENCE("alarm_id : %d", alarm_id); + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + __start_gps_positioning(geofence_server, __geofence_position_changed_cb); + geofence_server->nps_alarm_id = -1; + return 0; +} + +static void gps_setting_changed_cb(location_method_e method, bool enable, + void *user_data) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + g_return_if_fail(geofence_server); + GList *tracking_fences = g_list_first(geofence_server->tracking_list); + GeofenceItemData *item_data = NULL; + int tracking_fence_id = 0; + int ret = FENCE_ERR_NONE; + if (enable == false && geofence_server->running_geopoint_cnt > 0) { + LOGI_GEOFENCE("Stopping the GPS from settings callback"); + __stop_gps_positioning(geofence_server); + + /*Stop the interval alarm if it is running...*/ + if (geofence_server->nps_alarm_id != -1) { + LOGI_GEOFENCE("Interval timer removed. ID[%d]", geofence_server->nps_alarm_id); + geofence_server->nps_alarm_id = _geofence_remove_alarm(geofence_server->nps_alarm_id); + } + /*stop the timeout alarm if it is running...*/ + if (geofence_server->nps_timeout_alarm_id != -1) { + LOGI_GEOFENCE("Timeout timer removed. ID[%d]", + geofence_server->nps_timeout_alarm_id); + geofence_server->nps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->nps_timeout_alarm_id); + } + while (tracking_fences) { + tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data); + tracking_fences = g_list_next(tracking_fences); + item_data = __get_item_by_fence_id(tracking_fence_id, geofence_server); + if (item_data && item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) { + __emit_fence_inout(geofence_server, item_data->common_info.fence_id, GEOFENCE_FENCE_STATE_OUT); + } + } + } else if (enable == true && geofence_server->running_geopoint_cnt > 0) { + ret = __start_gps_positioning(geofence_server, __geofence_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start gps positioning. Error[%d]", ret); + return; + } + } +} + +#if 0 /* Not used */ +static int __check_fence_interval(alarm_id_t alarm_id, void *data) +{ + return TRUE; +} + +static void __pause_geofence_service(void *userdata) +{ + FUNC_ENTRANCE_SERVER; + g_return_if_fail(userdata); +} + +static void __resume_geofence_service(void *userdata) +{ + FUNC_ENTRANCE_SERVER; + g_return_if_fail(userdata); +} +#endif + +/*********************************THIS HAS TO BE USED ONLY FOR TESTING*********************************************/ +#ifdef __LOCAL_TEST__ +static void __free_geofence_list(gpointer userdata) +{ + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + + GList *tmp_fence_list = g_list_first(geofence_server->geofence_list); + while (tmp_fence_list) { + GeofenceItemData *tmp_data = (GeofenceItemData *)tmp_fence_list->data; + if (tmp_data) { + g_free(tmp_data); + } + tmp_fence_list = g_list_next(tmp_fence_list); + } + geofence_server->geofence_list = NULL; +} +#endif + +static int __check_fence_permission(int fence_id, const char *app_id) +{ + access_type_e access_type = ACCESS_TYPE_PUBLIC; + char *appid; + int ret = FENCE_ERR_NONE; + ret = geofence_manager_get_access_type(fence_id, -1, &access_type); + if (ret != FENCE_ERR_NONE) { + LOGE("Error getting the access_type"); + return -1; + } + if (access_type == ACCESS_TYPE_PRIVATE) { + ret = geofence_manager_get_appid_from_geofence(fence_id, &appid); + if (ret != FENCE_ERR_NONE) { + LOGE("Error getting the app_id for fence_id[%d]", fence_id); + return -1; + } + if (g_strcmp0(appid, app_id)) { + LOGE("Not authorized to access this private fence[%d]", fence_id); + return 0; + } + } + return 1; +} + +static int __check_place_permission(int place_id, const char *app_id) +{ + access_type_e access_type = ACCESS_TYPE_PUBLIC; + char *appid; + int ret = FENCE_ERR_NONE; + ret = geofence_manager_get_access_type(-1, place_id, &access_type); + if (ret != FENCE_ERR_NONE) { + LOGE("Error getting the access_type"); + return -1; + } + if (access_type == ACCESS_TYPE_PRIVATE) { + ret = geofence_manager_get_appid_from_places(place_id, &appid); + if (ret != FENCE_ERR_NONE) { + LOGE("Error getting the place_id for place_id[%d]", place_id); + return -1; + } + if (g_strcmp0(appid, app_id)) { + LOGE("Not authorized to access this private place[%d]", place_id); + return 0; + } + } + return 1; +} + +static int __add_fence(const gchar *app_id, + gint place_id, + gint geofence_type, + gdouble latitude, + gdouble longitude, + gint radius, + const gchar *address, + const gchar *bssid, const gchar *ssid, gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + + /* create fence id*/ + int fence_id = -1; + int ret = FENCE_ERR_NONE; + void *next_item_ptr = NULL; + time_t cur_time; + time(&cur_time); + access_type_e access_type; + + ret = geofence_manager_get_access_type(-1, place_id, &access_type); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the access type from the DB for place: %d or place-id does not exist.", place_id); + __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_FENCE_ADDED); + return -1; + } + + ret = __check_place_permission(place_id, app_id); + if (ret != 1) { + LOGE("Unable to add the fence. Permission denied or DB error occured while accessing the place[%d]", place_id); + if (ret == 0) { + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_ADDED); + } else { + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_ADDED); + } + return -1; + } + /* create GeofenceItemData item, and append it into geofence_list*/ + GeofenceItemData *item_data = (GeofenceItemData *)g_malloc0(sizeof(GeofenceItemData)); + if (item_data == NULL) { + LOGI_GEOFENCE("Unable to add the fence because of malloc fail"); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_FENCE_ADDED); + return -1; + } + + item_data->distance = -1; + item_data->client_status = GEOFENCE_CLIENT_STATUS_NONE; + item_data->common_info.type = geofence_type; + /*fences added by myplaces application are public fences by default*/ + if (!g_strcmp0(app_id, MYPLACES_APPID)) { + item_data->common_info.access_type = ACCESS_TYPE_PUBLIC; + } else { + item_data->common_info.access_type = ACCESS_TYPE_PRIVATE; + } + item_data->common_info.enable = 1; + item_data->common_info.status = GEOFENCE_FENCE_STATE_UNCERTAIN; + item_data->is_wifi_status_in = false; + item_data->is_bt_status_in = false; + g_strlcpy(item_data->common_info.appid, app_id, APP_ID_LEN); + item_data->common_info.running_status = 0; + item_data->common_info.place_id = place_id; + + /*DB is called and fence-id is retrieved from there(by auto increment mechanism)*/ + geofence_manager_set_common_info(&(item_data->common_info), &fence_id); + item_data->common_info.fence_id = fence_id; + LOGD_GEOFENCE("fence id : %d", item_data->common_info.fence_id); + + if (geofence_type == GEOFENCE_TYPE_GEOPOINT) { + LOGD_GEOFENCE("Add geofence with GeoPoint"); + geocoordinate_info_s *geocoordinate_info = (geocoordinate_info_s *)g_malloc0(sizeof(geocoordinate_info_s)); + if (geocoordinate_info == NULL) { + LOGI_GEOFENCE("Fail to set geocoordinate_info for GPS because of malloc fail"); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_FENCE_ADDED); + return -1; + } + geocoordinate_info->latitude = latitude; + geocoordinate_info->longitude = longitude; + if (radius < GEOFENCE_DEFAULT_RADIUS) { + geocoordinate_info->radius = GEOFENCE_DEFAULT_RADIUS; + } else { + geocoordinate_info->radius = radius; + } + g_strlcpy(geocoordinate_info->address, address, ADDRESS_LEN); + + /*Geopoint information is saved in the DB*/ + ret = geofence_manager_set_geocoordinate_info(fence_id, geocoordinate_info); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Fail to set geocoordinate_info"); + ret = geofence_manager_delete_fence_info(fence_id); + if (ret != FENCE_ERR_NONE) + LOGI_GEOFENCE("Fail to delete fence_id[%d] from common table", fence_id); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_ADDED); + return -1; + } + item_data->priv = (void *) geocoordinate_info; + + } else if (geofence_type == GEOFENCE_TYPE_WIFI) { /* Specific AP */ + LOGD_GEOFENCE("Add geofence with specific AP"); + + bssid_info_s *wifi_info = NULL; + wifi_info = (bssid_info_s *) g_malloc0(sizeof(bssid_info_s)); + if (wifi_info == NULL) { + LOGI_GEOFENCE("Fail to set bssid_info for wifi because of malloc fail"); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_FENCE_ADDED); + return -1; + } + g_strlcpy(wifi_info->bssid, bssid, WLAN_BSSID_LEN); + g_strlcpy(wifi_info->ssid, ssid, WLAN_BSSID_LEN); + + /*Wifi information is saved in the DB(both wifi and BT share the same bssid table here)*/ + ret = geofence_manager_set_bssid_info(fence_id, wifi_info); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Fail to set bssid_info for wifi"); + ret = geofence_manager_delete_fence_info(fence_id); + if (ret != FENCE_ERR_NONE) + LOGI_GEOFENCE("Fail to delete fence_id[%d] from common table", fence_id); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_ADDED); + return -1; + } + item_data->priv = (void *) wifi_info; + } else if (geofence_type == GEOFENCE_TYPE_BT) { + LOGD_GEOFENCE("Add geofence with bluetooth bssid"); + + bssid_info_s *bt_info = NULL; + bt_info = (bssid_info_s *) g_malloc0(sizeof(bssid_info_s)); + if (bt_info == NULL) { + LOGI_GEOFENCE("Fail to set bssid_info for BT because of malloc fail"); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_FENCE_ADDED); + return -1; + } + bt_info->enabled = TRUE; + g_strlcpy(bt_info->bssid, bssid, WLAN_BSSID_LEN); + g_strlcpy(bt_info->ssid, ssid, WLAN_BSSID_LEN); + + /*BT info is saved in the DB(both wifi and BT share the same bssid table here)*/ + ret = geofence_manager_set_bssid_info(fence_id, bt_info); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Fail to set bssid_info for BT"); + ret = geofence_manager_delete_fence_info(fence_id); + if (ret != FENCE_ERR_NONE) + LOGI_GEOFENCE("Fail to delete fence_id[%d] from common table", fence_id); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_ADDED); + return -1; + } + item_data->priv = (void *) bt_info; + } + /*Adding the data to the geofence_list which contains the added geofences list information*/ + if (geofence_server->geofence_list == NULL) { + geofence_server->geofence_list = g_list_append(geofence_server->geofence_list, item_data); + } else { + geofence_server->geofence_list = g_list_insert_before(geofence_server->geofence_list, next_item_ptr, item_data); + } + /*This code is just for testing purpose. It will be removed after the development phase - Karthik*/ + int temp_cnt = 0; + GList *temp_list = g_list_first(geofence_server->geofence_list); + temp_list = g_list_first(geofence_server->geofence_list); + while (temp_list) { + temp_cnt++; + temp_list = g_list_next(temp_list); + } + LOGI_GEOFENCE("Fences in local list: %d", temp_cnt); + geofence_manager_get_count_of_fences(&temp_cnt); + LOGI_GEOFENCE("Fence count in DB: %d", temp_cnt); + + /*Emit the error code*/ + __emit_fence_event(geofence_server, place_id, fence_id, item_data->common_info.access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_ADDED); + return fence_id; +} + +static int __add_place(const gchar *app_id, + const gchar *place_name, gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + int place_id = -1; + int ret = FENCE_ERR_NONE; + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + place_info_s *place_info = (place_info_s *)g_malloc0(sizeof(place_info_s)); + + if (place_info == NULL) { + LOGI_GEOFENCE("Unable to add the place due to malloc fail"); + __emit_fence_event(geofence_server, -1, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_PLACE_ADDED); + return -1; + } + /*fences added by myplaces application are public fences by default*/ + if (!g_strcmp0(app_id, MYPLACES_APPID)) + place_info->access_type = ACCESS_TYPE_PUBLIC; + else + place_info->access_type = ACCESS_TYPE_PRIVATE; + + g_strlcpy(place_info->place_name, place_name, PLACE_NAME_LEN); + g_strlcpy(place_info->appid, app_id, APP_ID_LEN); + /*Add the place details to db*/ + ret = geofence_manager_set_place_info(place_info, &place_id); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Unable to add the place due to DB error"); + __emit_fence_event(geofence_server, -1, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_ADDED); + return -1; + } + __emit_fence_event(geofence_server, place_id, -1, place_info->access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_PLACE_ADDED); + + return place_id; +} + +static void __enable_service(gint fence_id, const gchar *app_id, gboolean enable, gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + g_return_if_fail(userdata); + + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + int ret = FENCE_ERR_NONE; + access_type_e access_type = ACCESS_TYPE_UNKNOWN; + int place_id = -1; + int enable_status = 0; + geofence_manage_e manage_enum = GEOFENCE_MANAGE_SETTING_ENABLED; + + if (enable == 0) + manage_enum = GEOFENCE_MANAGE_SETTING_DISABLED; + + ret = geofence_manager_get_access_type(fence_id, -1, &access_type); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the access type from the DB for fence: %d or fence-id does not exist.", fence_id); + __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, manage_enum); + return; + } + ret = geofence_manager_get_place_id(fence_id, &place_id); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the place_id from the DB for fence: %d", fence_id); + __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, manage_enum); + return; + } + if (access_type == ACCESS_TYPE_PUBLIC) { + if (g_strcmp0(app_id, MYPLACES_APPID) != 0) { + LOGI_GEOFENCE("Received: %s", app_id); + LOGI_GEOFENCE("Not authorized to enable/disable this fence[%d] service.", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, manage_enum); + return; + } + if (enable == true) + enable_status = 1; + ret = geofence_manager_set_enable_status(fence_id, enable_status); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("DB error in enabling/disabling the fence[%d].", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, manage_enum); + return; + } + } else { + LOGI_GEOFENCE("Currently, only public fences can be enabled/disabled. It can be done by MyPlaces app only."); + } + /*Emit the error code*/ + __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, manage_enum); +} + +static void __update_place(gint place_id, const gchar *app_id, const gchar *place_name, gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + int ret = FENCE_ERR_NONE; + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + + if (place_id == DEFAULT_PLACE_HOME || place_id == DEFAULT_PLACE_OFFICE || place_id == DEFAULT_PLACE_CAR) { + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED, GEOFENCE_MANAGE_PLACE_UPDATED); + return; + } + + place_info_s *place_info = (place_info_s *) g_malloc0(sizeof(place_info_s)); + if (place_info == NULL) { + LOGI_GEOFENCE("malloc fail for place id[%d]", place_id); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_OUT_OF_MEMORY, GEOFENCE_MANAGE_PLACE_UPDATED); + return; + } + ret = geofence_manager_get_place_info(place_id, &place_info); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Place_id does not exist or DB error in getting the place info for place_id[%d].", place_id); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_PLACE_UPDATED); + g_free(place_info); + return; + } + if (g_strcmp0(app_id, place_info->appid) != 0) { + LOGI_GEOFENCE("Not authorized to update the place"); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED, GEOFENCE_MANAGE_PLACE_UPDATED); + g_free(place_info); + return; + } + + /*Update the place details to db*/ + ret = geofence_manager_update_place_info(place_id, place_name); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Unable to update the place"); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_UPDATED); + g_free(place_info); + return; + } + __emit_fence_event(geofence_server, place_id, -1, place_info->access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_PLACE_UPDATED); + g_free(place_info); +} + +static void __remove_fence(gint fence_id, const gchar *app_id, gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + g_return_if_fail(geofence_server); + int ret = FENCE_ERR_NONE; + int place_id = -1; + char *app_id_db; + access_type_e access_type = ACCESS_TYPE_UNKNOWN; + + /*//////////Required to be sent in the event callback////////////////--*/ + ret = geofence_manager_get_place_id(fence_id, &place_id); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the place_id from the DB for fence: %d or fence-id does not exist", fence_id); + __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_FENCE_REMOVED); + return; + } + /*//////////////////////////////////////////////////////////////////--*/ + ret = geofence_manager_get_appid_from_geofence(fence_id, &app_id_db); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Failed to get the appid, Error - %d", ret); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED); + return; + } + if (g_strcmp0(app_id_db, app_id) != 0) { + LOGI_GEOFENCE("Not authorized to remove the fence"); + g_free(app_id_db); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_REMOVED); + return; + } + g_free(app_id_db); + /*/////////required to be sent in the event callback///////////////--*/ + ret = geofence_manager_get_access_type(fence_id, -1, &access_type); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the access type from the DB for fence: %d", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED); + return; + } + /*///////////////////////////////////////////////////////////////////////--*/ + GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server); + if (item_data == NULL) { + LOGI_GEOFENCE("Invalid fence_id[%d]", fence_id); + return; + } + + /*Stop the geofence service for the fence first if it is running*/ + int tracking_status = -1; + ret = geofence_manager_get_running_status(fence_id, &tracking_status); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the running status from the DB for fence: %d or fence-id does not exist", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED); + return; + } + if (tracking_status == 1) { + __stop_geofence_service(fence_id, app_id, userdata); + } else if (tracking_status > 1) {/*its a public fence*/ + tracking_status = 1; /*resetting the running status to 1 for forcefull stop from MYPlacesApp*/ + ret = geofence_manager_set_running_status(fence_id, tracking_status); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error resetting the running status in the DB for fence: %d or fence-id does not exist", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED); + return; + } + __stop_geofence_service(fence_id, app_id, userdata); + } + /*Removing the fence id from the DB*/ + ret = geofence_manager_delete_fence_info(fence_id); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Fail to delete fence_id[%d]", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_REMOVED); + return; + } + + /*Removing the fence id from the geofence_list which contains the added fence list details*/ + geofence_server->geofence_list = g_list_remove(geofence_server->geofence_list, item_data); + LOGI_GEOFENCE("Removed fence_id[%d]", fence_id); + g_free(item_data); /*freeing the memory*/ + + /*Check if the length of the geofence_list is 0 then free and make it null*/ + if (g_list_length(geofence_server->geofence_list) == 0) { + g_list_free(geofence_server->geofence_list); + geofence_server->geofence_list = NULL; + } + /*Emit the error code*/ + __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_REMOVED); +} + +static void __get_place_name(gint place_id, const gchar *app_id, char **place_name, int *error_code, gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + access_type_e access_type = ACCESS_TYPE_UNKNOWN; + + int ret = geofence_manager_get_access_type(-1, place_id, &access_type); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the access type from the DB for place: %d or place-id does not exist.", place_id); + *error_code = GEOFENCE_SERVER_ERROR_ID_NOT_EXIST; + return; + } + + ret = __check_place_permission(place_id, app_id); + if (ret != 1) { + LOGE("Unable to get the place name. Permission denied or DB error occured while accessing the place[%d]", place_id); + if (ret == 0) { + *error_code = GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED; + } else { + *error_code = GEOFENCE_SERVER_ERROR_DATABASE; + } + return; + } + ret = geofence_manager_get_place_name(place_id, place_name); + if (ret != FENCE_ERR_NONE) { + *error_code = GEOFENCE_SERVER_ERROR_DATABASE; + return; + } + *error_code = GEOFENCE_SERVER_ERROR_NONE; +} + +static void __remove_place(gint place_id, const gchar *app_id, + gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + g_return_if_fail(userdata); + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + GList *fence_list = NULL, *list = NULL; + int fence_cnt = 0; + int tracking_status = 0; + int ret = FENCE_ERR_NONE; + GeofenceItemData *item_data = NULL; + access_type_e access_type = ACCESS_TYPE_UNKNOWN; + + /* Default places */ + if (place_id == DEFAULT_PLACE_HOME || place_id == DEFAULT_PLACE_OFFICE || place_id == DEFAULT_PLACE_CAR) { + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED, GEOFENCE_MANAGE_PLACE_REMOVED); + return; + } + ret = geofence_manager_get_access_type(-1, place_id, &access_type); + if (ret != FENCE_ERR_NONE) { + LOGE("Unable to fetch the access type for place_id[%d]", place_id); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_PLACE_REMOVED); + return; + } + + place_info_s *place_info = + (place_info_s *) g_malloc0(sizeof(place_info_s)); + ret = geofence_manager_get_place_info(place_id, &place_info); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Place_id does not exist or DB error in getting the place info for place_id[%d].", place_id); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_PLACE_REMOVED); + g_free(place_info); + return; + } + if (g_strcmp0(app_id, place_info->appid) != 0) { + LOGI_GEOFENCE("Not authorized to remove the place"); + g_free(place_info); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED, GEOFENCE_MANAGE_PLACE_REMOVED); + return; + } + g_free(place_info); + + ret = geofence_manager_get_fenceid_list_from_db(&fence_cnt, &fence_list, place_id); + if (ret != FENCE_ERR_NONE) { + LOGE("Unable to fetch the fence list from the DB"); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_REMOVED); + return; + } + int fence_id = 0; + list = g_list_first(fence_list); + while (list) { + fence_id = GPOINTER_TO_INT(list->data); + item_data = __get_item_by_fence_id(fence_id, geofence_server); + ret = geofence_manager_get_running_status(fence_id, &tracking_status); + if (ret != FENCE_ERR_NONE) { + LOGE("Unable to fetch the running status before removing the fence while removing a place"); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_REMOVED); + return; + } + if (tracking_status == 1) { + __stop_geofence_service(fence_id, app_id, userdata); + } else if (tracking_status > 1) { + tracking_status = 1; /*resetting the running status as it is a forcefull stop from MYPlacesApp*/ + ret = geofence_manager_set_running_status(fence_id, tracking_status); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error setting the running status from the DB for fence: %d or fence-id does not exist", fence_id); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_REMOVED); + return; + } + __stop_geofence_service(fence_id, app_id, userdata); + } + + /*Removing the fence id from the geofence_list which contains the added fence list details*/ + geofence_server->geofence_list = g_list_remove(geofence_server->geofence_list, item_data); + LOGI_GEOFENCE("Removed fence_id[%d]", fence_id); + g_free(item_data); + /*Check if the length of the geofence_list is 0 then free and make it null*/ + if (g_list_length(geofence_server->geofence_list) == 0) { + g_list_free(geofence_server->geofence_list); + geofence_server->geofence_list = NULL; + } + list = g_list_next(list); + } + ret = geofence_manager_delete_place_info(place_id); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("DB error occured while removing the place from DB"); + __emit_fence_event(geofence_server, place_id, -1, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_PLACE_REMOVED); + return; + } + __emit_fence_event(geofence_server, place_id, -1, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_PLACE_REMOVED); +} + +static void __start_geofence_service(gint fence_id, const gchar *app_id, gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + g_return_if_fail(userdata); + + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + int tracking_fence_id = -1; + void *next_item_ptr = NULL; + GList *track_list = g_list_first(geofence_server->tracking_list); + GeofenceItemData *item_data = NULL; + + int ret = FENCE_ERR_NONE; + int tracking_status = -1; + int place_id = -1; + access_type_e access_type = ACCESS_TYPE_UNKNOWN; + char *app_id_db = NULL; + geofence_fence_state_e status_to_be_emitted = GEOFENCE_FENCE_STATE_UNCERTAIN; + + item_data = __get_item_by_fence_id(fence_id, geofence_server); /*Fetch the fence details from add_list*/ + if (item_data == NULL) { + LOGI_GEOFENCE("Invalid fence id - no fence exists with this fence id"); + __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_FENCE_STARTED); + return; /*Invalid fence id - no fence exists with this fence id*/ + } + if (!g_strcmp0(app_id, MYPLACES_APPID)) { + LOGI_GEOFENCE("My Places cannot start a fence"); + __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + ret = geofence_manager_get_place_id(fence_id, &place_id); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the place_id from the DB for fence: %d", fence_id); + __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + + ret = geofence_manager_get_running_status(fence_id, &tracking_status); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the running status from the DB for fence: %d or fence-id does not exist.", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + + ret = geofence_manager_get_access_type(fence_id, -1, &access_type); + if (ret != FENCE_ERR_NONE) { + LOGE("Error getting the access_type"); + return; + } + if (access_type == ACCESS_TYPE_PRIVATE) { + ret = geofence_manager_get_appid_from_geofence(fence_id, &app_id_db); + if (ret != FENCE_ERR_NONE) { + LOGE("Error getting the app_id for fence_id[%d]", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + if (g_strcmp0(app_id_db, app_id)) { + LOGE("Not authorized to access this private fence[%d]", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_STARTED); + g_free(app_id_db); + return; + } + g_free(app_id_db); + if (tracking_status == 1) { + LOGI_GEOFENCE("Private fence ID: %d, already exists in the tracking list", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_ALREADY_STARTED, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } else { + ret = geofence_manager_set_running_status(fence_id, 1); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error setting the fence status"); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + tracking_status = 1; + } + } else if (access_type == ACCESS_TYPE_PUBLIC) { + int enable = -1; + ret = geofence_manager_get_enable_status(fence_id, &enable); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the enable status from the DB for fence: %d or fence-id does not exist.", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + if (enable == 0) { + LOGI_GEOFENCE("Error - Fence[%d] is not enabled", + fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + if (tracking_status > 0) { + LOGI_GEOFENCE("Public fence ID: %d, already exists in the tracking list, incrementing the counter for fence", fence_id); + ret = geofence_manager_set_running_status(fence_id, (tracking_status + 1)); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error setting the fence status"); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } else { + ret = geofence_manager_set_running_status(fence_id, (tracking_status + 1)); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error setting the fence status"); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + tracking_status++; + } + } + + item_data->client_status = GEOFENCE_CLIENT_STATUS_START; + + if (item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) { + ret = __start_gps_positioning(geofence_server, __geofence_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start gps positioning. Error[%d]", ret); + geofence_manager_set_running_status(fence_id, (tracking_status - 1)); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_IPC, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + geofence_server->running_geopoint_cnt++; + + __start_activity_service(geofence_server); + } else if (item_data->common_info.type == GEOFENCE_TYPE_BT) { + LOGI_GEOFENCE("fence_type [GEOFENCE_TYPE_BT]"); + + bssid_info_s *bt_info = NULL; + if (item_data->priv != NULL) { + bt_info = (bssid_info_s *) item_data->priv; + if (!bt_info->enabled) + bt_info->enabled = TRUE; + } + bt_adapter_state_e adapter_state = BT_ADAPTER_DISABLED; + bt_error_e error = BT_ERROR_NONE; + error = bt_adapter_get_state(&adapter_state); + if (error == BT_ERROR_NONE) { + geofence_server->running_bt_cnt++; + if (adapter_state == BT_ADAPTER_DISABLED) { + LOGE_GEOFENCE("BT Adapter is DISABLED"); + status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT; + } else if (adapter_state == BT_ADAPTER_ENABLED) { + bt_device_info_s *bt_device_info = NULL; + if (bt_info != NULL) { + ret = bt_adapter_get_bonded_device_info(bt_info->bssid, &bt_device_info); + if (ret != BT_ERROR_NONE) { + LOGE_GEOFENCE("Fail to get the bonded device info/ Not bonded with any device. Error[%d]", ret); + /*NEED TO BE DECIDED WHETHER TO REQUEST FOR A SCAN HERE OR JUST EMIT OUT AS STATUS*/ + if (ret == BT_ERROR_REMOTE_DEVICE_NOT_BONDED) + status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT; + } else { + if (bt_device_info == NULL) { + LOGI_GEOFENCE("bt_adapter_get_bonded_device_info [%s] failed.", bt_info->bssid); + status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT; + } else { + if (bt_device_info->is_bonded == TRUE && bt_device_info->is_connected == TRUE) { + LOGI_GEOFENCE("[%s] bonded TRUE, connected TRUE", bt_info->bssid); + status_to_be_emitted = GEOFENCE_FENCE_STATE_IN; + } else { + status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT; + } + } + } + } + } + } else { + if (error != BT_ERROR_NONE) { + LOGI_GEOFENCE("Unable to get the BT adapter state. Not added to track list: %d", error); + geofence_manager_set_running_status(fence_id, (tracking_status - 1)); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_IPC, GEOFENCE_MANAGE_FENCE_STARTED); + return; + } + } + } else if (item_data->common_info.type == GEOFENCE_TYPE_WIFI) { + LOGI_GEOFENCE("fence_type [GEOFENCE_TYPE_WIFI]"); + wifi_error_e rv = WIFI_ERROR_NONE; + int nWifiState; + wifi_ap_h ap_h; + char *ap_bssid = NULL; + int bssidlen; + bssid_info_s *wifi_info = NULL; + vconf_get_int(VCONFKEY_WIFI_STATE, &nWifiState); + + if (nWifiState != 0) { + LOGI_GEOFENCE("Wifi is on..."); + geofence_server->running_wifi_cnt++; /*Incrementing the counter for wifi fence*/ + + if (item_data->priv != NULL) { + wifi_info = (bssid_info_s *) item_data->priv; + } + rv = wifi_get_connected_ap(&ap_h); + if (rv != WIFI_ERROR_NONE) { + LOGI_GEOFENCE("Fail/not connected to get the connected AP: [%s] , geofence will be added to the fence list", __convert_wifi_error_to_string(rv)); + if (rv == WIFI_ERROR_NO_CONNECTION) { + LOGI_GEOFENCE("Not connected to any AP"); + status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT; + } + } else { + rv = wifi_ap_get_bssid(ap_h, &ap_bssid); + if (rv != WIFI_ERROR_NONE) { + LOGI_GEOFENCE("Fail to get the bssid: [%d]\n", __convert_wifi_error_to_string(rv)); + } else { + bssidlen = strlen(ap_bssid); + LOGI_GEOFENCE("Connected AP: %s, %d\n", ap_bssid, bssidlen); + if (g_strcmp0(wifi_info->bssid, ap_bssid) == 0) { + status_to_be_emitted = GEOFENCE_FENCE_STATE_IN; + } else { + status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT; + } + + } + } + } else { + LOGI_GEOFENCE("Wifi is not switched on..."); + geofence_server->running_wifi_cnt++; /*Incrementing the counter for wifi fence*/ + /*Emit the fence status as out as wifi is not switched on here*/ + status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT; + } + } else { + LOGI_GEOFENCE("Invalid fence_type[%d]", + item_data->common_info.type); + return; + } + /*Adding the fence to the tracking list*/ + LOGI_GEOFENCE("Add to tracklist: Fence id: %d", fence_id); + if (geofence_server->tracking_list == NULL) { + geofence_server->tracking_list = g_list_append(geofence_server->tracking_list, GINT_TO_POINTER(fence_id)); + } else { + geofence_server->tracking_list = g_list_insert_before(geofence_server->tracking_list, next_item_ptr, GINT_TO_POINTER(fence_id)); + } + LOGI_GEOFENCE("Added fence id: Fence id: %d", fence_id); + + __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_STARTED); + + __emit_fence_inout(geofence_server, item_data->common_info.fence_id, status_to_be_emitted); + + track_list = g_list_first(geofence_server->tracking_list); + while (track_list) { + tracking_fence_id = GPOINTER_TO_INT(track_list->data); + LOGI_GEOFENCE("%d", tracking_fence_id); + track_list = g_list_next(track_list); + } +} + +static void __stop_geofence_service(gint fence_id, const gchar *app_id, gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + g_return_if_fail(userdata); + + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + GeofenceItemData *item_data = NULL; + int tracking_status = -1; + int ret = FENCE_ERR_NONE; + int place_id = -1; + access_type_e access_type = ACCESS_TYPE_UNKNOWN; + + item_data = __get_item_by_fence_id(fence_id, geofence_server); /*Fetch the fence details from add_list*/ + if (item_data == NULL) { + LOGI_GEOFENCE("Invalid fence id - no fence exists with this fence id"); + __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_ID_NOT_EXIST, GEOFENCE_MANAGE_FENCE_STOPPED); + return; /*Invalid fence id - no fence exists with this fence id*/ + } + ret = geofence_manager_get_place_id(fence_id, &place_id); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the place_id from the DB for fence: %d", fence_id); + __emit_fence_event(geofence_server, -1, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED); + return; + } + ret = geofence_manager_get_access_type(fence_id, -1, &access_type); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the access type from the DB for fence: %d", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED); + return; + } + ret = __check_fence_permission(fence_id, app_id); + if (ret != 1) { + LOGE("Permission denied or DB error occured while accessing the fence[%d]", fence_id); + if (ret == 0) { + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_GEOFENCE_ACCESS_DENIED, GEOFENCE_MANAGE_FENCE_STOPPED); + } else { + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED); + } + return; + } + ret = geofence_manager_get_running_status(fence_id, &tracking_status); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error fetching the running status from the DB for fence: %d", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED); + return; + } + + if (tracking_status == 0) { + /*This fence is not in the tracking mode currently - nothing to do, just return saying the error*/ + LOGI_GEOFENCE("Fence ID: %d, is not in the tracking mode", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_STOPPED); + return; + } + + if (tracking_status > 0) { + LOGI_GEOFENCE("Remove from tracklist: Fence id: %d", fence_id); + item_data = __get_item_by_fence_id(fence_id, geofence_server); + + /*Item needs to be removed from the fence list*/ + if (item_data != NULL) { + /*Main DB table should be updated here with the unsetting of running status flag*/ + tracking_status = tracking_status - 1; + ret = geofence_manager_set_running_status(fence_id, tracking_status); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error resetting the running status in DB for fence: %d", fence_id); + __emit_fence_event(geofence_server, place_id, fence_id, ACCESS_TYPE_UNKNOWN, app_id, GEOFENCE_SERVER_ERROR_DATABASE, GEOFENCE_MANAGE_FENCE_STOPPED); + return; + } + /*Update the geofence count according to the type of geofence*/ + if (item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) { + geofence_server->running_geopoint_cnt--; + LOGI_GEOFENCE("Removed geopoint fence: %d from tracking list", fence_id); + + if (geofence_server->running_geopoint_cnt <= 0) { + /*Stopping GPS...*/ + __stop_gps_positioning(geofence_server); + + /*Stop the interval alarm if it is running...*/ + if (geofence_server->nps_alarm_id != -1) { + LOGI_GEOFENCE("Interval timer removed. ID[%d]", geofence_server->nps_alarm_id); + geofence_server->nps_alarm_id = _geofence_remove_alarm(geofence_server->nps_alarm_id); + } + /*Stop the timeout alarm if it is running...*/ + if (geofence_server->nps_timeout_alarm_id != -1) { + LOGI_GEOFENCE("Timeout timer removed. ID[%d]", geofence_server->nps_timeout_alarm_id); + geofence_server->nps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->nps_timeout_alarm_id); + } + + __stop_activity_service(geofence_server); + } + } else if (item_data->common_info.type == GEOFENCE_TYPE_BT) { + geofence_server->running_bt_cnt--; + LOGI_GEOFENCE("Removed bt fence: %d from tracking list", fence_id); + + if (geofence_server->running_bt_cnt <= 0) { + /*May be unsetting the cb for bt discovery can be done here*/ + } + } else if (item_data->common_info.type == GEOFENCE_TYPE_WIFI) { + /*NOTHING NEED TO BE DONE HERE EXCEPT DECREMENTING THE COUNT*/ + geofence_server->running_wifi_cnt--; + } + + if (tracking_status == 0) { + /*Remove the fence from the tracklist*/ + LOGD_GEOFENCE("Setting the fence status as uncertain here..."); + item_data->common_info.status = GEOFENCE_FENCE_STATE_UNCERTAIN; + geofence_server->tracking_list = g_list_remove(geofence_server->tracking_list, GINT_TO_POINTER(fence_id)); + if (g_list_length(geofence_server->tracking_list) == 0) { + g_list_free(geofence_server->tracking_list); + geofence_server->tracking_list = NULL; + } + } + } else { + LOGI_GEOFENCE("Geofence service is not running for this fence"); + } + + } + /* Emit the error code */ + __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_STOPPED); +} + +static void __start_activity_service(GeofenceServer *geofence_server) +{ + FUNC_ENTRANCE_SERVER; + bool activity_supported = TRUE; + int ret = ACTIVITY_ERROR_NONE; + + if (geofence_server->activity_stationary_h == NULL) { + activity_is_supported(ACTIVITY_STATIONARY, &activity_supported); + if (activity_supported == TRUE) { + ret = activity_create(&(geofence_server->activity_stationary_h)); + if (ret != ACTIVITY_ERROR_NONE) { + LOGD_GEOFENCE("Fail to create stationary activity %d", ret); + } else { + ret = activity_start_recognition(geofence_server->activity_stationary_h, ACTIVITY_STATIONARY, __activity_cb, geofence_server); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to start stationary activity %d", ret); + else + LOGD_GEOFENCE("Success to start stationary activity"); + } + } else + LOGD_GEOFENCE("Not support stationary activity"); + } + + if (geofence_server->activity_walk_h == NULL) { + activity_is_supported(ACTIVITY_WALK, &activity_supported); + if (activity_supported == TRUE) { + ret = activity_create(&(geofence_server->activity_walk_h)); + if (ret != ACTIVITY_ERROR_NONE) { + LOGD_GEOFENCE("Fail to create walk activity %d", ret); + } else { + ret = activity_start_recognition(geofence_server->activity_walk_h, ACTIVITY_WALK, __activity_cb, geofence_server); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to start walk activity %d", ret); + else + LOGD_GEOFENCE("Success to start walk activity"); + } + } else + LOGD_GEOFENCE("Not support walk activity"); + } + + if (geofence_server->activity_run_h == NULL) { + activity_is_supported(ACTIVITY_RUN, &activity_supported); + if (activity_supported == TRUE) { + ret = activity_create(&(geofence_server->activity_run_h)); + if (ret != ACTIVITY_ERROR_NONE) { + LOGD_GEOFENCE("Fail to create run activity %d", ret); + } else { + ret = activity_start_recognition(geofence_server->activity_run_h, ACTIVITY_RUN, __activity_cb, geofence_server); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to start run activity %d", ret); + else + LOGD_GEOFENCE("Success to start run activity"); + } + } else + LOGD_GEOFENCE("Not support run activity"); + } + + if (geofence_server->activity_in_vehicle_h == NULL) { + activity_is_supported(ACTIVITY_IN_VEHICLE, &activity_supported); + if (activity_supported == TRUE) { + ret = activity_create(&(geofence_server->activity_in_vehicle_h)); + if (ret != ACTIVITY_ERROR_NONE) { + LOGD_GEOFENCE("Fail to create in_vehicle activity %d", ret); + } else { + ret = activity_start_recognition(geofence_server->activity_in_vehicle_h, ACTIVITY_IN_VEHICLE, __activity_cb, geofence_server); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to start in_vehicle activity %d", ret); + else + LOGD_GEOFENCE("Success to start in_vehicle activity"); + } + } else + LOGD_GEOFENCE("Not support in_vehicle activity"); + } +} + +static void __stop_activity_service(GeofenceServer *geofence_server) +{ + FUNC_ENTRANCE_SERVER; + int ret = ACTIVITY_ERROR_NONE; + + if (geofence_server->activity_stationary_h != NULL) { + ret = activity_stop_recognition(geofence_server->activity_stationary_h); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to stop stationary activity %d", ret); + else + LOGD_GEOFENCE("Success to stop stationary activity"); + + ret = activity_release(geofence_server->activity_stationary_h); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to release stationary activity %d", ret); + else + geofence_server->activity_stationary_h = NULL; + } + + if (geofence_server->activity_walk_h != NULL) { + ret = activity_stop_recognition(geofence_server->activity_walk_h); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to stop walk activity %d", ret); + else + LOGD_GEOFENCE("Success to stop walk activity"); + + ret = activity_release(geofence_server->activity_walk_h); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to release walk activity %d", ret); + else + geofence_server->activity_walk_h = NULL; + } + + if (geofence_server->activity_run_h != NULL) { + ret = activity_stop_recognition(geofence_server->activity_run_h); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to stop run activity %d", ret); + else + LOGD_GEOFENCE("Success to stop run activity"); + + ret = activity_release(geofence_server->activity_run_h); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to release run activity %d", ret); + else + geofence_server->activity_run_h = NULL; + } + + if (geofence_server->activity_in_vehicle_h != NULL) { + ret = activity_stop_recognition(geofence_server->activity_in_vehicle_h); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to stop in_vehicle activity %d", ret); + else + LOGD_GEOFENCE("Success to stop in_vehicle activity"); + + ret = activity_release(geofence_server->activity_in_vehicle_h); + if (ret != ACTIVITY_ERROR_NONE) + LOGD_GEOFENCE("Fail to release in_vehicle activity %d", ret); + else + geofence_server->activity_in_vehicle_h = NULL; + } +} + +static void __activity_cb(activity_type_e type, const activity_data_h data, double timestamp, activity_error_e error, void *user_data) +{ + FUNC_ENTRANCE_SERVER + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + activity_accuracy_e accuracy; + int result = ACTIVITY_ERROR_NONE; + + if (error != ACTIVITY_ERROR_NONE) { + LOGD_GEOFENCE("Error in activity callback %d", error); + return; + } + + result = activity_get_accuracy(data, &accuracy); + if (result != ACTIVITY_ERROR_NONE) { + LOGD_GEOFENCE("Fail to get accuracy of activity %d", error); + return; + } + + if (accuracy >= ACTIVITY_ACCURACY_MID) { + geofence_server->activity_type = type; + geofence_server->activity_timestamp = timestamp; + + LOGD_GEOFENCE("Activity type = %d, timestamp = %lf", type, timestamp); + } +} + +static GVariant *__get_list(int place_id, const gchar *app_id, int *fenceCnt, int *errorCode, gpointer userdata) +{ + geofence_info_s *item; + GVariantBuilder b; + GList *fence_list = NULL, *list = NULL; + place_info_s *place_info = NULL; + int count = 0, fence_cnt = 0; + int ret = 0; + + LOGI_GEOFENCE(">>> Enter"); + /*As same API is used to get the fence list, whenever complete fence list is requested, place_id is passed as -1 from the module.*/ + /*Whenever fence_list in a particular place is requested place_id will not be -1. This is jusr maintained internally*/ + if (place_id == -1) { + ret = geofence_manager_get_fence_list_from_db(&count, &fence_list, -1); + } else { + ret = geofence_manager_get_place_info(place_id, &place_info); + if (ret != FENCE_ERR_NONE) { + LOGE("Error getting the place info for place_id[%d]", place_id); + /* Send ZERO data gvariant*/ + *errorCode = GEOFENCE_SERVER_ERROR_DATABASE; + *fenceCnt = fence_cnt; + g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}")); + return g_variant_builder_end(&b); + } + if ((place_info != NULL) && (place_info->access_type == ACCESS_TYPE_PRIVATE)) { + if (g_strcmp0(app_id, place_info->appid) != 0) { + LOGI_GEOFENCE("Not authorized to access this private place[%d]", place_id); + if (place_info) + g_free(place_info); + /* Send ZERO data gvariant*/ + *errorCode = GEOFENCE_SERVER_ERROR_PLACE_ACCESS_DENIED; + *fenceCnt = fence_cnt; + g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}")); + return g_variant_builder_end(&b); + } + if (place_info) + g_free(place_info); + } + ret = geofence_manager_get_fence_list_from_db(&count, &fence_list, place_id); + } + LOGI_GEOFENCE("count = %d", count); + + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("get list failed"); + /* Send ZERO data gvariant*/ + *errorCode = GEOFENCE_SERVER_ERROR_DATABASE; + *fenceCnt = fence_cnt; + g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}")); + return g_variant_builder_end(&b); + } else if (count == 0) { + LOGI_GEOFENCE("List is empty"); + /* Send ZERO data gvariant*/ + *errorCode = GEOFENCE_SERVER_ERROR_NONE; + *fenceCnt = fence_cnt; + g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}")); + return g_variant_builder_end(&b); + } + + /* Initialize for the container*/ + g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}")); + + list = g_list_first(fence_list); + while (list) { + item = (geofence_info_s *) list->data; + + if (item && ((item->access_type == ACCESS_TYPE_PUBLIC) || !(g_strcmp0(app_id, item->app_id)))) { + /* Open container*/ + g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}")); + + /* Add parameters to dictionary*/ + g_variant_builder_add(&b, "{sv}", "fence_id", g_variant_new_int32(item->fence_id)); + + LOGI_GEOFENCE("fence_id: %d, place_id: %d, latitude: %f, longitude: %f, radius: %d", item->fence_id, item->param.place_id, item->param.latitude, item->param.longitude, item->param.radius); + + switch (item->param.type) { + case GEOFENCE_TYPE_GEOPOINT:{ + g_variant_builder_add(&b, "{sv}", "place_id", g_variant_new_int32(item->param.place_id)); + g_variant_builder_add(&b, "{sv}", "geofence_type", g_variant_new_int32(item->param.type)); + g_variant_builder_add(&b, "{sv}", "latitude", g_variant_new_double(item->param.latitude)); + g_variant_builder_add(&b, "{sv}", "longitude", g_variant_new_double(item->param.longitude)); + g_variant_builder_add(&b, "{sv}", "radius", g_variant_new_int32(item->param.radius)); + g_variant_builder_add(&b, "{sv}", "address", g_variant_new_string(item->param.address)); + g_variant_builder_add(&b, "{sv}", "bssid", g_variant_new_string("NA")); + g_variant_builder_add(&b, "{sv}", "ssid", g_variant_new_string("NA")); + } + break; + case GEOFENCE_TYPE_WIFI: + case GEOFENCE_TYPE_BT:{ + g_variant_builder_add(&b, "{sv}", "place_id", g_variant_new_int32(item->param.place_id)); + g_variant_builder_add(&b, "{sv}", "geofence_type", g_variant_new_int32(item->param.type)); + g_variant_builder_add(&b, "{sv}", "latitude", g_variant_new_double(0.0)); + g_variant_builder_add(&b, "{sv}", "longitude", g_variant_new_double(0.0)); + g_variant_builder_add(&b, "{sv}", "radius", g_variant_new_int32(0.0)); + g_variant_builder_add(&b, "{sv}", "address", g_variant_new_string("NA")); + g_variant_builder_add(&b, "{sv}", "bssid", g_variant_new_string(item->param.bssid)); + g_variant_builder_add(&b, "{sv}", "ssid", g_variant_new_string(item->param.ssid)); + } + break; + default: + LOGI_GEOFENCE("Unsupported type: [%d]", item->param.type); + break; + } + + /* Close container*/ + g_variant_builder_close(&b); + fence_cnt++; + } else { + if (item != NULL) + LOGI_GEOFENCE("This fence id: %d is private. Not authorized to access by this app", item->fence_id); + } + + /* Move to next node*/ + list = g_list_next(list); + } + *errorCode = GEOFENCE_SERVER_ERROR_NONE; + *fenceCnt = fence_cnt; + return g_variant_builder_end(&b); +} + +static GVariant *__get_place_list(const gchar *app_id, int *placeCnt, int *errorCode, gpointer userdata) +{ + place_info_s *item; + GVariantBuilder b; + GList *place_list = NULL, *list = NULL; + int count = 0, place_cnt = 0; + int ret = 0; + + LOGI_GEOFENCE(">>> Enter"); + + ret = geofence_manager_get_place_list_from_db(&count, &place_list); + + LOGI_GEOFENCE("count = %d", count); + + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("get list failed"); + /* Send ZERO data gvariant*/ + *errorCode = GEOFENCE_SERVER_ERROR_DATABASE; + *placeCnt = place_cnt; + g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}")); + return g_variant_builder_end(&b); + } else if (count == 0) { + LOGI_GEOFENCE("List is empty"); + /* Send ZERO data gvariant*/ + *errorCode = GEOFENCE_SERVER_ERROR_NONE; + *placeCnt = place_cnt; + g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}")); + return g_variant_builder_end(&b); + } + + /* Initialize for the container*/ + g_variant_builder_init(&b, G_VARIANT_TYPE("aa{sv}")); + + list = g_list_first(place_list); + while (list) { + item = (place_info_s *) list->data; + + if (item && ((item->access_type == ACCESS_TYPE_PUBLIC) || !(g_strcmp0(app_id, item->appid)))) { + /* Open container*/ + g_variant_builder_open(&b, G_VARIANT_TYPE("a{sv}")); + + LOGI_GEOFENCE("place_id: %d, access_type: %d, place_name: %s, app_id: %s", item->place_id, item->access_type, item->place_name, item->appid); + /* Add data to dictionary*/ + g_variant_builder_add(&b, "{sv}", "place_id", g_variant_new_int32(item->place_id)); + g_variant_builder_add(&b, "{sv}", "place_name", g_variant_new_string(item->place_name)); + /* Close container*/ + g_variant_builder_close(&b); + place_cnt++; + } else { + if (item != NULL) + LOGI_GEOFENCE("This place id: %d is private. Not authorized to access by this app", item->place_id); + } + list = g_list_next(list); + } + *errorCode = GEOFENCE_SERVER_ERROR_NONE; + *placeCnt = place_cnt; + return g_variant_builder_end(&b); +} + +static void __add_default_place(char *place_name) +{ + int place_id; + place_info_s *place_info = (place_info_s *) g_malloc0(sizeof(place_info_s)); + g_return_if_fail(place_info); + + place_info->access_type = ACCESS_TYPE_PUBLIC; + g_strlcpy(place_info->place_name, place_name, PLACE_NAME_LEN); + g_strlcpy(place_info->appid, "dummy_app_id", APP_ID_LEN); + /*Add the place details to db*/ + int ret = geofence_manager_set_place_info(place_info, &place_id); + if (ret != FENCE_ERR_NONE) + LOGI_GEOFENCE("Unable to add the default places due to DB error"); +} + +static void __init_geofencemanager(GeofenceServer *geofence_server) +{ + FUNC_ENTRANCE_SERVER; + + geofence_server->loc_started = FALSE; + + geofence_server->timer_id = -1; + geofence_server->nps_alarm_id = -1; + geofence_server->nps_timeout_alarm_id = -1; + geofence_server->geofence_list = NULL; + geofence_server->tracking_list = NULL; + geofence_server->running_geopoint_cnt = 0; + geofence_server->running_bt_cnt = 0; + geofence_server->running_wifi_cnt = 0; + geofence_server->activity_type = ACTIVITY_IN_VEHICLE; + geofence_server->activity_timestamp = 0; + + geofence_server->activity_stationary_h = NULL; + geofence_server->activity_walk_h = NULL; + geofence_server->activity_run_h = NULL; + geofence_server->activity_in_vehicle_h = NULL; + + /*Initializing the DB to store the fence informations*/ + if (geofence_manager_db_init() != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Error initalizing the DB"); + } + /*Adding default places in the DB*/ + int place_id = DEFAULT_PLACE_HOME; + int count = -1; + + while (place_id <= DEFAULT_PLACE_CAR) { + if (geofence_manager_get_place_count_by_placeid(place_id, &count) == FENCE_ERR_NONE) { + if (count == 0) { + if (place_id == DEFAULT_PLACE_HOME) { + __add_default_place("Home"); + } else if (place_id == DEFAULT_PLACE_OFFICE) { + __add_default_place("Office"); + } else if (place_id == DEFAULT_PLACE_CAR) { + __add_default_place("Car"); + } + } + } else { + LOGI_GEOFENCE("Error adding the default place: %d", place_id); + } + place_id++; + count = -1; + } + + /*delete all fences at rebooting for a test. TODO: will be replaced by updating previous fences*/ + /*geofence_manager_db_reset();*/ +} + + +#if USE_HW_GEOFENCE +static void __start_gps_geofence_client(void *handle, GeofenceModCB geofence_cb, void *userdata) +{ + FUNC_ENTRANCE_SERVER; + /*Previously code to start the HW geofence client was there. It has been removed now*/ + return; +} + +static void __stop_gps_geofence_client(void *handle) +{ + FUNC_ENTRANCE_SERVER; + /*Stop tracking the geofences*/ + return; +} +#endif + +int __copy_geofence_to_item_data(int fence_id, GeofenceItemData *item_data) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(item_data, FENCE_ERR_INVALID_PARAMETER); + char *app_id = NULL; + + item_data->common_info.fence_id = fence_id; + item_data->common_info.status = GEOFENCE_FENCE_STATE_UNCERTAIN; + if (FENCE_ERR_NONE != geofence_manager_get_geofence_type(fence_id, &item_data->common_info.type)) + return FENCE_ERR_SQLITE_FAIL; + + if (FENCE_ERR_NONE != geofence_manager_get_access_type(fence_id, -1, &item_data->common_info.access_type)) + return FENCE_ERR_SQLITE_FAIL; + + if (FENCE_ERR_NONE != geofence_manager_get_enable_status(fence_id, &item_data->common_info.enable)) + return FENCE_ERR_SQLITE_FAIL; + + if (FENCE_ERR_NONE != geofence_manager_get_appid_from_geofence(fence_id, &app_id)) { + g_free(app_id); + return FENCE_ERR_SQLITE_FAIL; + } else { + g_strlcpy(item_data->common_info.appid, app_id, APP_ID_LEN); + g_free(app_id); + } + if (FENCE_ERR_NONE != geofence_manager_get_placeid_from_geofence(fence_id, &item_data->common_info.place_id)) + return FENCE_ERR_SQLITE_FAIL; + + if (FENCE_ERR_NONE != geofence_manager_get_running_status(fence_id, &item_data->common_info.running_status)) + return FENCE_ERR_SQLITE_FAIL; + + if (item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) { + geocoordinate_info_s *geocoordinate_info = NULL; + int ret = FENCE_ERR_NONE; + + ret = geofence_manager_get_geocoordinate_info(fence_id, &geocoordinate_info); + if (ret != FENCE_ERR_NONE || geocoordinate_info == NULL) { + LOGI_GEOFENCE("can not get geocoordinate_info"); + return FENCE_ERR_SQLITE_FAIL; + } + item_data->priv = (void *) geocoordinate_info; + } else { + bssid_info_s *bssid_info = NULL; + int ret = FENCE_ERR_NONE; + + ret = geofence_manager_get_bssid_info(fence_id, &bssid_info); + if (ret != FENCE_ERR_NONE || bssid_info == NULL) { + LOGI_GEOFENCE("can not get bssid_info"); + return FENCE_ERR_SQLITE_FAIL; + } + item_data->priv = (void *) bssid_info; + } + return FENCE_ERR_NONE; +} + +static void __add_left_fences(gpointer user_data) +{ + g_return_if_fail(user_data); + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + if (geofence_server->geofence_list != NULL) + return; + GList *fence_list = NULL; + int fence_id = 0; + int count = 0; + + /*Get the number of fences count*/ + geofence_manager_get_count_of_fences(&count); + if (count <= 0) + return; + /*Fetch the fences from the DB and populate it in the list*/ + geofence_manager_get_fences(NULL, 0, &fence_list); + fence_list = g_list_first(fence_list); + while (fence_list) { + fence_id = GPOINTER_TO_INT(fence_list->data); + + /*if(geofence_server is not restarted by dbus auto activation method[It means phone is rebooted so app should start the fences again. If we start the service by ourself it is waste of power. So we should not do that]) + * { + * geofence_manager_set_running_status(fence_id, 0); // resetting the running-status flag since it is a device reboot + * } */ + + GeofenceItemData *item_data = (GeofenceItemData *)g_malloc0(sizeof(GeofenceItemData)); + if (FENCE_ERR_NONE != __copy_geofence_to_item_data(fence_id, item_data)) { + g_free(item_data); + return; + } + LOGI_GEOFENCE("adding fence_id = %d to fence_list", item_data->common_info.fence_id); + + /*Here fences from DB will be added to the list but tracking list is not populated here*/ + geofence_server->geofence_list = g_list_append(geofence_server->geofence_list, item_data); + + fence_list = g_list_next(fence_list); + } +} + +static void _glib_log(const gchar *log_domain, GLogLevelFlags log_level, const gchar *msg, gpointer user_data) +{ + LOGI_GEOFENCE("GLIB[%d] : %s", log_level, msg); +} + +int main(int argc, char **argv) +{ + GeofenceServer *geofenceserver = NULL; + + /*Callback registrations*/ + geofence_callbacks cb; + cb.bt_conn_state_changed_cb = bt_conn_state_changed; + cb.bt_apater_disable_cb = bt_adp_disable; + cb.wifi_conn_state_changed_cb = wifi_conn_state_changed; + cb.wifi_device_state_changed_cb = wifi_device_state_changed; + cb.network_evt_cb = geofence_network_evt_cb; + cb.bt_discovery_cb = bt_adapter_device_discovery_state_cb; + cb.gps_setting_changed_cb = gps_setting_changed_cb; + +#if !GLIB_CHECK_VERSION(2, 35, 0) + g_type_init(); +#endif + + geofenceserver = g_new0(GeofenceServer, 1); + if (!geofenceserver) { + LOGI_GEOFENCE("GeofenceServer create fail"); + return 1; + } + + if (alarmmgr_init(PACKAGE_NAME) != ALARMMGR_RESULT_SUCCESS) { + LOGI_GEOFENCE("alarmmgr_init fail"); + return 1; + } + + g_log_set_default_handler(_glib_log, geofenceserver); + + /*Initialize the geofence manager where DB related activities exists*/ + __init_geofencemanager(geofenceserver); + + /*This will read the DB and populate the list*/ + __add_left_fences(geofenceserver); + + /*This call goes and registers the cb with Server.c where all the wifi,bt event callbacks are triggered*/ + _geofence_register_update_callbacks(&cb, geofenceserver); + + /*This call goes and make initializations of bt and wifi stacks and then register the callbacks with them*/ + _geofence_initialize_geofence_server(geofenceserver); + +#ifdef TIZEN_ENGINEER_MODE + _init_log(); +#endif + + /* This call goes to Geofence_dbus_server.c and creates the actual server dbus connection who will interact with the client*/ + geofence_dbus_server_create(GEOFENCE_SERVER_SERVICE_NAME, GEOFENCE_SERVER_SERVICE_PATH, "geofence_manager", "geofence manager provider", &(geofenceserver->geofence_dbus_server), __add_fence, __add_place, __enable_service, __update_place, __remove_fence, __remove_place, __get_place_name, __get_list, __get_place_list, __start_geofence_service, __stop_geofence_service, (void *) geofenceserver); + + LOGD_GEOFENCE("lbs_geofence_server_creation done"); + + geofenceserver->loop = g_main_loop_new(NULL, TRUE); + g_main_loop_run(geofenceserver->loop); + + LOGD_GEOFENCE("GEOFENCE_manager deamon Stop...."); + + /*This call goes to server.c and deregisters all the callbacks w.r.t bt and wifi*/ + _geofence_deinitialize_geofence_server(); + +#ifdef TIZEN_ENGINEER_MODE + _deinit_log(); +#endif + /*This call goes to Geofence_dbus_server.c and deletes the memory allocated to the server, hence destroys it*/ + geofence_dbus_server_destroy(geofenceserver->geofence_dbus_server); + LOGD_GEOFENCE("lbs_server_destroy called"); + + g_main_loop_unref(geofenceserver->loop); + + /*Closing the DB and the handle is aquired again when geofence server comes up.*/ + geofence_manager_close_db(); + + g_free(geofenceserver); + + return 0; +} diff --git a/geofence-server/src/geofence_server.h b/geofence-server/src/geofence_server.h new file mode 100644 index 0000000..cdd42a0 --- /dev/null +++ b/geofence-server/src/geofence_server.h @@ -0,0 +1,155 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file geofence_server.h + * @brief Geofence server related APIs + * + */ + +#ifndef _GEOFENCE_MANAGER_H_ +#define _GEOFENCE_MANAGER_H_ + +#include <glib.h> +#include <bluetooth.h> +#include <wifi.h> +#include <locations.h> +#include <network-wifi-intf.h> +#include "geofence_server_data_types.h" + +#define PACKAGE_NAME "geofence-server" + +/** + * @brief Bluetooth connection status change callback + * @remarks This callback will be called when the bluetooth connection status changes. + * @Param[in] connected The bool value indicating the connection, 0 indicates not connected and 1 indicates connected. + * @Param[in] conn_info The connection information of the bluetooth + * @Param[in] user_data The user data to be returned + * @see None. + */ +typedef void (*geofence_bt_conn_state_changed_cb) (gboolean connected, bt_device_connection_info_s *conn_info, void *user_data); + +/** + * @brief Bluetooth adapter disabled callback + * @remarks This callback will be called when the bluetooth adapter is disabled. + * @Param[in] connected The bool value indicating the connection, 0 indicates not connected and 1 indicates connected. + * @Param[in] user_data The user data to be returned + * @see None. + */ +typedef void (*geofence_bt_adapter_disable_cb) (gboolean connected, void *user_data); + +/** + * @brief Wifi connection status change callback + * @remarks This callback will be called when the wifi connection status changes. + * @Param[in] state The status of the wifi connection + * @Param[in] ap The wifi ap + * @Param[in] user_data The user data to be returned + * @see None. + */ +typedef void (*geofence_wifi_conn_state_changed_cb) (wifi_connection_state_e state, wifi_ap_h ap, void *user_data); + +/** + * @brief Wifi device status change callback + * @remarks This callback will be called when the wifi device status changes. + * @Param[in] state The status of the wifi device + * @Param[in] user_data The user data to be returned + * @see None. + */ +typedef void (*geofence_wifi_device_state_changed_cb) (wifi_device_state_e state, void *user_data); + +/** + * @brief Network scan status change callback + * @remarks This callback will be called when the wifi scanning happen in the background. + * @Param[in] event_cb The callback of the event happened + * @Param[in] user_data The user data to be returned + * @see None. + */ +typedef void (*geofence_network_event_cb) (net_event_info_t *event_cb, void *user_data); + +/** + * @brief BT Discovery status change callback + * @remarks This callback will be called when the BT scanning happen as soon as BT is switched on. + * @Param[in] event_cb The callback of the event happened + * @Param[in] user_data The user data to be returned + * @see None. + */ +typedef void (*geofence_bt_adapter_device_discovery_state_changed_cb) (int result, bt_adapter_device_discovery_state_e discovery_state, bt_adapter_device_discovery_info_s *discovery_info, void *user_data); + +/** + * @brief Called when the state of location method is changed. + * @since_tizen 2.3 + * @param[in] method The method changed on setting + * @param[in] enable The setting value changed + * @param[in] user_data The user data passed from the callback registration function + * @pre location_setting_changed_cb() will invoke this callback if you register this callback using location_manager_set_setting_changed_cb() + * @see location_manager_set_setting_changed_cb() + * @see location_manager_unset_setting_changed_cb() + */ +typedef void (*geofence_gps_setting_changed_cb) (location_method_e method, bool enable, void *user_data); + +/** + * Geofence callback structure. + */ +struct geofence_callbacks_s { + geofence_bt_conn_state_changed_cb bt_conn_state_changed_cb; + geofence_bt_adapter_disable_cb bt_apater_disable_cb; + geofence_wifi_conn_state_changed_cb wifi_conn_state_changed_cb; + geofence_wifi_device_state_changed_cb wifi_device_state_changed_cb; + geofence_network_event_cb network_evt_cb; + geofence_bt_adapter_device_discovery_state_changed_cb bt_discovery_cb; + geofence_gps_setting_changed_cb gps_setting_changed_cb; +}; + +typedef struct geofence_callbacks_s geofence_callbacks; + +/** + * This enumeration describe the smart assistant status. + */ +typedef enum { + GEOFENCE_SMART_ASSIST_NONE, + GEOFENCE_SMART_ASSIST_ENABLED, + GEOFENCE_SMART_ASSIST_DISABLED, + GEOFENCE_SMART_ASSIST_COLLECTING, +} smart_assist_status_e; + +/** + * This enumeration describe the cell geofence in and out status. + */ +typedef enum { + CELL_UNKNOWN = -1, + CELL_OUT = 0, + CELL_IN = 1 +} cell_status_e; + +/** + * This enumeration describe the wifi geofence in and out status. + */ +typedef enum { + WIFI_DIRECTION_UNKNOWN = -1, + WIFI_DIRECTION_OUT = 0, + WIFI_DIRECTION_IN = 1 +} wifi_status_e; + +/** + * This enumeration describe the geofence client status. + */ +typedef enum { + GEOFENCE_CLIENT_STATUS_NONE, + GEOFENCE_CLIENT_STATUS_FIRST_LOCATION, + GEOFENCE_CLIENT_STATUS_START, + GEOFENCE_CLIENT_STATUS_RUNNING +} geofence_client_status_e; + +#endif diff --git a/geofence-server/src/geofence_server_alarm.c b/geofence-server/src/geofence_server_alarm.c new file mode 100644 index 0000000..9fb86c9 --- /dev/null +++ b/geofence-server/src/geofence_server_alarm.c @@ -0,0 +1,48 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "geofence_server.h" +#include "geofence_server_private.h" +#include "geofence_server_log.h" +#include "debug_util.h" + +int _geofence_add_alarm(int interval, alarm_cb_t alarm_cb, void *userdata) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + + int ret = 0; + alarm_id_t alarm_id = -1; + + ret = alarmmgr_add_alarm_withcb(ALARM_TYPE_DEFAULT, interval, 0, alarm_cb, geofence_server, &alarm_id); + if (ret != ALARMMGR_RESULT_SUCCESS) { + LOGE_GEOFENCE("Fail to alarmmgr_add_alarm_withcb : %d", ret); + } + LOGD_GEOFENCE("alarm_id : %d", alarm_id); + + return alarm_id; +} + +int _geofence_remove_alarm(alarm_id_t alarm_id) +{ + FUNC_ENTRANCE_SERVER; + int ret = 0; + ret = alarmmgr_remove_alarm(alarm_id); + if (ret != ALARMMGR_RESULT_SUCCESS) { + LOGE_GEOFENCE("Fail to alarmmgr_remove_alarm : %d", ret); + } + + return -1; +} diff --git a/geofence-server/src/geofence_server_alarm.h b/geofence-server/src/geofence_server_alarm.h new file mode 100644 index 0000000..8db24d9 --- /dev/null +++ b/geofence-server/src/geofence_server_alarm.h @@ -0,0 +1,45 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file geofence_server_alarm.h + * @brief Geofence server alarm related APIs + * + */ + +#ifndef GEOFENCE_MANAGER_ALARM_H_ +#define GEOFENCE_MANAGER_ALARM_H_ + +/** +* @brief Adds the geofence alarm +* @param[in] interval Interval value in int. +* @param[in] alarm_cb The alarm callback function +* @return int +* @retval alarmid if success + -1 if addition of alarm fails +* @see _geofence_remove_alarm +*/ +int _geofence_add_alarm(int interval, alarm_cb_t alarm_cb, void *userdata); + +/** +* @brief Removes the geofence alarm +* @param[in] alarm_id The alarm id. +* @return int +* @retval -1 +* @see _geofence_add_alarm +*/ +int _geofence_remove_alarm(alarm_id_t alarm_id); + +#endif /* GEOFENCE_MANAGER_ALARM_H_ */ diff --git a/geofence-server/src/geofence_server_bluetooth.c b/geofence-server/src/geofence_server_bluetooth.c new file mode 100644 index 0000000..51f78b7 --- /dev/null +++ b/geofence-server/src/geofence_server_bluetooth.c @@ -0,0 +1,182 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 <stdlib.h> +#include <glib.h> + +#include "geofence_server.h" +#include "server.h" +#include "debug_util.h" +#include "geofence_server_log.h" +#include "geofence_server_private.h" +#include "geofence_server_internal.h" +#include "geofence_server_db.h" + +static gboolean __geofence_check_fence_status(int fence_status, GeofenceItemData *item_data) +{ + FUNC_ENTRANCE_SERVER + gboolean ret = FALSE; + + if (fence_status != item_data->common_info.status) { + LOGD_GEOFENCE("Fence status changed. %d -> %d", item_data->common_info.status, fence_status); + ret = TRUE; + item_data->common_info.status = fence_status; /*update status*/ + } + return ret; +} + +static void emit_bt_geofence_inout_changed(GeofenceServer *geofence_server, GeofenceItemData *item_data, int fence_status) +{ + FUNC_ENTRANCE_SERVER + char *app_id = (char *)g_malloc0(sizeof(char)*APP_ID_LEN); + g_strlcpy(app_id, item_data->common_info.appid, APP_ID_LEN); + if (app_id == NULL) { + LOGD_GEOFENCE("get app_id failed. fence_id [%d]", item_data->common_info.fence_id); + return; + } + + if (fence_status == GEOFENCE_FENCE_STATE_IN) { + geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, app_id, item_data->common_info.fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_IN); + } else if (fence_status == GEOFENCE_FENCE_STATE_OUT) { + geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, app_id, item_data->common_info.fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_OUT); + } + + if (item_data->client_status == GEOFENCE_CLIENT_STATUS_START) { + item_data->client_status = GEOFENCE_CLIENT_STATUS_RUNNING; + } + if (app_id) + free(app_id); +} + +static void __geofence_check_bt_fence_type(gboolean connected, const char *bssid, void *data) +{ + FUNC_ENTRANCE_SERVER + GeofenceServer *geofence_server = (GeofenceServer *)data; + g_return_if_fail(geofence_server); + g_return_if_fail(bssid); + + int fence_id = 0; + geofence_type_e fence_type; + GeofenceItemData *item_data = NULL; + bssid_info_s *bt_info_from_db = NULL; + bssid_info_s *bt_info_from_list = NULL; + + GList *fence_list = g_list_first(geofence_server->tracking_list); + + for (; fence_list != NULL; fence_list = g_list_next(fence_list)) { + int ret = FENCE_ERR_NONE; + item_data = NULL; + fence_id = GPOINTER_TO_INT(fence_list->data); + item_data = __get_item_by_fence_id(fence_id, geofence_server); + + if (item_data == NULL) + continue; + + fence_type = item_data->common_info.type; + + if (fence_type != GEOFENCE_TYPE_BT) + continue; + + bt_info_from_list = (bssid_info_s *) item_data->priv; + + if (bt_info_from_list == NULL || bt_info_from_list->enabled == FALSE) + continue; + + ret = geofence_manager_get_bssid_info(fence_id, &bt_info_from_db); + + if (bt_info_from_db == NULL) { + LOGD_GEOFENCE("Failed to get bt_info. Fence Id[%d], Error[%d]", fence_id, ret); + continue; + } + LOGD_GEOFENCE("bt_info->bssid [%s]", bt_info_from_db->bssid); + + if (g_ascii_strcasecmp(bt_info_from_db->bssid, bssid) == 0) { + if (connected) { /* connected => FENCE_IN*/ + if (__geofence_check_fence_status(GEOFENCE_FENCE_STATE_IN, item_data) == TRUE) { + LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_IN", fence_id); + emit_bt_geofence_inout_changed(geofence_server, item_data, GEOFENCE_FENCE_STATE_IN); + } + } else { /* disconnected => FENCE_OUT*/ + if (__geofence_check_fence_status(GEOFENCE_FENCE_STATE_OUT, item_data) == TRUE) { + LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_OUT", fence_id); + emit_bt_geofence_inout_changed(geofence_server, item_data, GEOFENCE_FENCE_STATE_OUT); + } + } + } + g_slice_free(bssid_info_s, bt_info_from_db); + bt_info_from_db = NULL; + bt_info_from_list = NULL; + } + + LOGD_GEOFENCE("exit"); +} + +void bt_conn_state_changed(gboolean connected, bt_device_connection_info_s *conn_info, void *user_data) +{ + FUNC_ENTRANCE_SERVER + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + g_return_if_fail(geofence_server); + g_return_if_fail(conn_info); + + if (connected == true) { + if (conn_info->remote_address == NULL) { + LOGD_GEOFENCE("Bluetooth device connected, but remote_address not exist."); + } else { + LOGD_GEOFENCE("Bluetooth device connected [%s].", conn_info->remote_address); + __geofence_check_bt_fence_type(connected, conn_info->remote_address, user_data); + } + } else { + LOGD_GEOFENCE("Bluetooth device disconnected [%s]. reason [%d]", conn_info->remote_address, conn_info->disconn_reason); + __geofence_check_bt_fence_type(connected, conn_info->remote_address, user_data); + } + LOGD_GEOFENCE("exit"); +} + +void bt_adp_disable(gboolean connected, void *user_data) +{ + FUNC_ENTRANCE_SERVER + GeofenceServer * geofence_server = (GeofenceServer *) user_data; + g_return_if_fail(geofence_server); + + int fence_id = 0; + + geofence_type_e fence_type; + GeofenceItemData *item_data = NULL; + + GList *fence_list = g_list_first(geofence_server->tracking_list); + + for (; fence_list != NULL; fence_list = g_list_next(fence_list)) { + fence_id = GPOINTER_TO_INT(fence_list->data); + item_data = NULL; + item_data = __get_item_by_fence_id(fence_id, geofence_server); + + if (item_data == NULL) + continue; + + fence_type = item_data->common_info.type; + + if (fence_type != GEOFENCE_TYPE_BT) /* check only bluetooth type*/ + continue; + + if (connected == FALSE) { + if (__geofence_check_fence_status(GEOFENCE_FENCE_STATE_OUT, item_data) == TRUE) { + LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_OUT", fence_id); + emit_bt_geofence_inout_changed(geofence_server, item_data, GEOFENCE_FENCE_STATE_OUT); + } + } + } + + LOGD_GEOFENCE("exit"); +} diff --git a/geofence-server/src/geofence_server_bluetooth.h b/geofence-server/src/geofence_server_bluetooth.h new file mode 100644 index 0000000..414cc7f --- /dev/null +++ b/geofence-server/src/geofence_server_bluetooth.h @@ -0,0 +1,43 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file geofence_server_bluetooth.h + * @brief Geofence server bluetooth related APIs + * + */ + +#ifndef GEOFENCE_MANAGER_BLUETOOTH_H_ +#define GEOFENCE_MANAGER_BLUETOOTH_H_ + +/** +* @brief Bluetooth connection status change callback +* @Param[in] connected The bool value indicating the connection, 0 indicates not connected and 1 indicates connected. +* @Param[in] conn_info The connection information of the bluetooth +* @Param[in] user_data The user data to be returned +* @return int +* @see none +*/ +void bt_conn_state_changed(gboolean connected, bt_device_connection_info_s *conn_info, void *user_data); + +/** + * @brief Bluetooth adapter disabled callback + * @Param[in] connected The bool value indicating the connection, 0 indicates not connected and 1 indicates connected. + * @Param[in] user_data The user data to be returned + * @see None. + */ +void bt_adp_disable(gboolean connected, void *user_data); + +#endif /* GEOFENCE_MANAGER_BLUETOOTH_H_ */ diff --git a/geofence-server/src/geofence_server_db.c b/geofence-server/src/geofence_server_db.c new file mode 100644 index 0000000..13cf92c --- /dev/null +++ b/geofence-server/src/geofence_server_db.c @@ -0,0 +1,2605 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 <sqlite3.h> +#include <sys/time.h> +#include <db-util.h> +#include <gio/gio.h> +#include <sys/stat.h> +#include <ss_manager.h> +#include <string.h> +#include <bluetooth.h> +#include <wifi.h> + +#include "debug_util.h" +#include "geofence_server.h" +#include "geofence_server_db.h" +#include "geofence_server_private.h" + +#define GEOFENCE_SERVER_DB_FILE ".geofence-server.db" +#define GEOFENCE_SERVER_DB_PATH "/opt/dbspace/"GEOFENCE_SERVER_DB_FILE + +#define FENCE_SQL_LEN_MAX 256 +#define MAX_DATA_NAME 20 +#define DATA_LEN 20 + +#define GEOFENCE_INVALID 0 + +char *menu_table[4] = { "GeoFence", "FenceGeocoordinate", "FenceGeopointWifi", "FenceBssid" }; + +const char *group_id = NULL; +static char *password = "k1s2c3w4k5a6"; +const char *col_latitude = "la"; +const char *col_longitude = "lo"; +const char *col_radius = "r"; + +typedef enum { + FENCE_MAIN_TABLE = 0, /*GeoFence */ + FENCE_GEOCOORDINATE_TAB, /*FenceGeocoordinate */ + FENCE_GEOPOINT_WIFI_TABLE, /*FenceCurrentLocation */ + FENCE_BSSID_TABLE /*FenceBluetoothBssid */ +} fence_table_type_e; + +static struct { + sqlite3 *handle; +} db_info_s = { + .handle = NULL, +}; + +#define SQLITE3_RETURN(ret, msg, state) \ + if (ret != SQLITE_OK) { \ + LOGI_GEOFENCE("sqlite3 Error[%d] : %s", ret, msg); \ + sqlite3_reset(state); \ + sqlite3_clear_bindings(state); \ + sqlite3_finalize(state); \ + return FENCE_ERR_SQLITE_FAIL; \ + } + +/* + * \note + * DB Table schema + * + * GeoFence + * +----------+-------+-------+------------+-------+-------+-----------+---------+ + * | fence_id | name | app_id | geofence_type |direction |enable |smart_assist_id|time_stamp + * +-------+-------+-------+-------+ + * | - | - | - | - | + * +-------+-------+-------+-------+ + * CREATE TABLE GeoFence ( fence_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, app_id TEXT NOT NULL, geofence_type INTEGER," \ + "direction INTEGER, enable INTEGER, smart_assist_id INTEGER, time_stamp INTEGER)"; + * + * + * FenceGeocoordinate + * +----------+---------+--------+------+ + * | fence_id | latitude | longitude | radius + * +-------+---------+-----+---------+ + * | - | - | - | - | - | - | + * +-------+---------+-----+---------+ + * CREATE TABLE FenceGeocoordinate ( fence_id INTEGER , latitude DOUBLE, longitude DOUBLE, radius DOUBLE, FOREIGN KEY(fence_id) REFERENCES GeoFence(fence_id) ON DELETE CASCADE)"; + * + * + * FenceCurrentLocation + * +-----+-------+------ + * |bssid 1|fence_id1 |... + * +-----+-------+------ + * |bssid 2|fence_id1|... + * +-----+-------+------ + * |bssid 3|fence_id1|... + * +-----+-------+------ + * |bssid 1|fence_id2|... + * +-----+-------+------ + * |bssid 2|fence_id2|... + * +-------+---------+-----+---------+ + * | - | - | - | - | - | - | + * +-------+---------+-----+---------+ +*CREATE TABLE FenceCurrentLocation ( fence_id INTEGER, bssid TEXT, FOREIGN KEY(fence_id) REFERENCES GeoFence(fence_id) ON DELETE CASCADE)"; +*/ + +static inline int begin_transaction(void) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *stmt; + int ret; + + ret = sqlite3_prepare_v2(db_info_s.handle, "BEGIN TRANSACTION", -1, &stmt, NULL); + + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + return FENCE_ERR_SQLITE_FAIL; + } + + if (sqlite3_step(stmt) != SQLITE_DONE) { + LOGI_GEOFENCE("Failed to do update (%s)", sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(stmt); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(stmt); + return FENCE_ERR_NONE; +} + +static inline int rollback_transaction(void) +{ + FUNC_ENTRANCE_SERVER; + int ret; + sqlite3_stmt *stmt; + + ret = sqlite3_prepare_v2(db_info_s.handle, "ROLLBACK TRANSACTION", -1, &stmt, NULL); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + return FENCE_ERR_SQLITE_FAIL; + } + + if (sqlite3_step(stmt) != SQLITE_DONE) { + LOGI_GEOFENCE("Failed to do update (%s)", sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(stmt); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(stmt); + return FENCE_ERR_NONE; +} + +static inline int commit_transaction(void) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *stmt; + int ret; + + ret = sqlite3_prepare_v2(db_info_s.handle, "COMMIT TRANSACTION", -1, &stmt, NULL); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + return FENCE_ERR_SQLITE_FAIL; + } + + if (sqlite3_step(stmt) != SQLITE_DONE) { + LOGI_GEOFENCE("Failed to do update (%s)", sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(stmt); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(stmt); + return FENCE_ERR_NONE; +} + +static inline int __geofence_manager_db_create_places_table(void) +{ + FUNC_ENTRANCE_SERVER; + char *err = NULL; + char *ddl; + + ddl = sqlite3_mprintf("CREATE TABLE Places ( place_id INTEGER PRIMARY KEY AUTOINCREMENT, access_type INTEGER, place_name TEXT NOT NULL, app_id TEXT NOT NULL)"); + if (sqlite3_exec(db_info_s.handle, ddl, NULL, NULL, &err) != SQLITE_OK) { + LOGI_GEOFENCE("Failed to execute the DDL (%s)", err); + sqlite3_free(ddl); + return FENCE_ERR_SQLITE_FAIL; + } + + if (sqlite3_changes(db_info_s.handle) == 0) { + LOGI_GEOFENCE("No changes to DB"); + } + sqlite3_free(ddl); + return FENCE_ERR_NONE; +} + +static inline int __geofence_manager_db_create_geofence_table(void) +{ + FUNC_ENTRANCE_SERVER; + char *err = NULL; + char *ddl; + + ddl = sqlite3_mprintf("CREATE TABLE GeoFence ( fence_id INTEGER PRIMARY KEY AUTOINCREMENT, place_id INTEGER, enable INTEGER, app_id TEXT NOT NULL, geofence_type INTEGER, access_type INTEGER, running_status INTEGER, FOREIGN KEY(place_id) REFERENCES Places(place_id) ON DELETE CASCADE)"); + + if (sqlite3_exec(db_info_s.handle, ddl, NULL, NULL, &err) != SQLITE_OK) { + LOGI_GEOFENCE("Failed to execute the DDL (%s)", err); + sqlite3_free(ddl); + return FENCE_ERR_SQLITE_FAIL; + } + + if (sqlite3_changes(db_info_s.handle) == 0) { + LOGI_GEOFENCE("No changes to DB"); + } + sqlite3_free(ddl); + return FENCE_ERR_NONE; +} + +static inline int __geofence_manager_db_create_geocoordinate_table(void) +{ + FUNC_ENTRANCE_SERVER; + char *err = NULL; + char *ddl; + + ddl = sqlite3_mprintf("CREATE TABLE FenceGeocoordinate ( fence_id INTEGER PRIMARY KEY, latitude TEXT NOT NULL, longitude TEXT NOT NULL, radius TEXT NOT NULL, address TEXT, FOREIGN KEY(fence_id) REFERENCES GeoFence(fence_id) ON DELETE CASCADE ON UPDATE CASCADE)"); + + if (sqlite3_exec(db_info_s.handle, ddl, NULL, NULL, &err) != SQLITE_OK) { + LOGI_GEOFENCE("Failed to execute the DDL (%s)", err); + sqlite3_free(ddl); + return FENCE_ERR_SQLITE_FAIL; + } + + if (sqlite3_changes(db_info_s.handle) == 0) { + LOGI_GEOFENCE("No changes to DB"); + } + sqlite3_free(ddl); + return FENCE_ERR_NONE; +} + +static inline int __geofence_manager_db_create_wifi_data_table(void) +{ + FUNC_ENTRANCE_SERVER; + char *err = NULL; + char *ddl; + + ddl = sqlite3_mprintf("CREATE TABLE FenceGeopointWifi (fence_id INTEGER, bssid TEXT, FOREIGN KEY(fence_id) REFERENCES GeoFence(fence_id) ON DELETE CASCADE ON UPDATE CASCADE)"); + + if (sqlite3_exec(db_info_s.handle, ddl, NULL, NULL, &err) != SQLITE_OK) { + LOGI_GEOFENCE("Failed to execute the DDL (%s)", err); + sqlite3_free(ddl); + return FENCE_ERR_SQLITE_FAIL; + } + + if (sqlite3_changes(db_info_s.handle) == 0) { + LOGI_GEOFENCE("No changes to DB"); + } + sqlite3_free(ddl); + return FENCE_ERR_NONE; +} + +/* DB table for save the pair of fence id and bluetooth bssid */ +static inline int __geofence_manager_db_create_bssid_table(void) +{ + FUNC_ENTRANCE_SERVER + char *err = NULL; + char *ddl; + + ddl = sqlite3_mprintf("CREATE TABLE FenceBssid (fence_id INTEGER PRIMARY KEY, bssid TEXT, ssid TEXT, FOREIGN KEY(fence_id) REFERENCES GeoFence(fence_id) ON DELETE CASCADE ON UPDATE CASCADE)"); + + if (sqlite3_exec(db_info_s.handle, ddl, NULL, NULL, &err) != SQLITE_OK) { + LOGI_GEOFENCE("Failed to execute the DDL (%s)", err); + sqlite3_free(ddl); + return FENCE_ERR_SQLITE_FAIL; + } + + if (sqlite3_changes(db_info_s.handle) == 0) + LOGI_GEOFENCE("No changes to DB"); + sqlite3_free(ddl); + return FENCE_ERR_NONE; +} + +static int __geofence_manager_open_db_handle(void) +{ + LOGI_GEOFENCE("enter"); + int ret = SQLITE_OK; + + ret = db_util_open_with_options(GEOFENCE_SERVER_DB_PATH, &db_info_s.handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_FULLMUTEX, NULL); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("sqlite3_open_v2 Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + return FENCE_ERR_SQLITE_FAIL; + } + + return FENCE_ERR_NONE; +} + +static int __geofence_manager_db_get_count_by_fence_id_and_bssid(int fence_id, char *bssid, fence_table_type_e table_type, int *count) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(bssid, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + + char *query = sqlite3_mprintf("SELECT COUNT(fence_id) FROM %Q where fence_id = %d AND bssid = %Q;", menu_table[table_type], fence_id, bssid); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + *count = sqlite3_column_int(state, 0); + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +static int __geofence_manager_db_insert_bssid_info(const int fence_id, const char *bssid_info, const char *ssid) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(fence_id, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(bssid_info, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + int index = 0; + int count = -1; + const char *tail; + char *bssid = NULL; + + char *query = sqlite3_mprintf("INSERT INTO %Q(fence_id, bssid, ssid) VALUES (?, ?, ?)", menu_table[FENCE_BSSID_TABLE]); + bssid = (char *)g_malloc0(sizeof(char)*WLAN_BSSID_LEN); + g_strlcpy(bssid, bssid_info, WLAN_BSSID_LEN); + LOGI_GEOFENCE("fence_id[%d], bssid[%s], ssid[%s]", fence_id, bssid, ssid); + + ret = __geofence_manager_db_get_count_by_fence_id_and_bssid(fence_id, bssid, FENCE_BSSID_TABLE, &count); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("__geofence_manager_db_get_count_by_fence_id_and_bssid() failed. ERROR(%d)", ret); + sqlite3_free(query); + return ret; + } + if (count > 0) { + LOGI_GEOFENCE("count = %d", count); + return FENCE_ERR_NONE; + } + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_bind_int(state, ++index, fence_id); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_text(state, ++index, bssid, -1, SQLITE_STATIC); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_text(state, ++index, ssid, -1, SQLITE_STATIC); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + g_free(bssid); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_reset(state); + sqlite3_clear_bindings(state); + sqlite3_finalize(state); + g_free(bssid); + sqlite3_free(query); + LOGI_GEOFENCE("fence_id[%d], bssid[%s], ssid[%s] inserted db table [%s] successfully.", fence_id, bssid_info, ssid, menu_table[FENCE_BSSID_TABLE]); + + return FENCE_ERR_NONE; +} + +static int __geofence_manager_db_insert_wifi_data_info(gpointer data, gpointer user_data) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(data, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(user_data, FENCE_ERR_INVALID_PARAMETER); + int *fence_id = (int *) user_data; + sqlite3_stmt *state = NULL; + wifi_info_s *wifi_info = NULL; + int ret = SQLITE_OK; + int index = 0; + int count = -1; + const char *tail; + char *bssid = NULL; + wifi_info = (wifi_info_s *) data; + bssid = (char *)g_malloc0(sizeof(char)*WLAN_BSSID_LEN); + g_strlcpy(bssid, wifi_info->bssid, WLAN_BSSID_LEN); + LOGI_GEOFENCE("fence_id[%d] bssid[%s]", *fence_id, wifi_info->bssid); + + char *query = sqlite3_mprintf("INSERT INTO FenceGeopointWifi(fence_id, bssid) VALUES (?, ?)"); + + ret = __geofence_manager_db_get_count_by_fence_id_and_bssid(*fence_id, bssid, FENCE_GEOPOINT_WIFI_TABLE, &count); + if (count > 0) { + LOGI_GEOFENCE("count = %d", count); + sqlite3_free(query); + return ret; + } + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_bind_int(state, ++index, *fence_id); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_text(state, ++index, bssid, -1, SQLITE_STATIC); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + g_free(bssid); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_reset(state); + sqlite3_clear_bindings(state); + sqlite3_finalize(state); + g_free(bssid); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +static int __geofence_manager_delete_table(int fence_id, fence_table_type_e table_type) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + + char *query = sqlite3_mprintf("DELETE from %Q where fence_id = %d;", menu_table[table_type], fence_id); + LOGI_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, NULL); + if (SQLITE_OK != ret) { + LOGI_GEOFENCE("Fail to connect to table. Error[%s]", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + ret = sqlite3_step(state); + if (SQLITE_DONE != ret) { + LOGI_GEOFENCE("Fail to step. Error[%d]", ret); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + sqlite3_finalize(state); + LOGI_GEOFENCE("fence_id[%d], deleted from db table [%s] successfully.", fence_id, menu_table[table_type]); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +static int __geofence_manager_delete_place_table(int place_id) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + + char *query = sqlite3_mprintf("DELETE from Places where place_id = %d;", place_id); + + LOGI_GEOFENCE("current place id is [%d]", place_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, NULL); + if (SQLITE_OK != ret) { + LOGI_GEOFENCE("Fail to connect to table. Error[%s]", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + ret = sqlite3_step(state); + if (SQLITE_DONE != ret) { + LOGI_GEOFENCE("Fail to step. Error[%d]", ret); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + sqlite3_finalize(state); + LOGI_GEOFENCE("place_id[%d], deleted place from db table Places successfully.", place_id); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +static inline void __geofence_manager_db_create_table(void) +{ + FUNC_ENTRANCE_SERVER; + int ret; + begin_transaction(); + + ret = __geofence_manager_db_create_geofence_table(); + if (ret < 0) { + rollback_transaction(); + return; + } + + ret = __geofence_manager_db_create_geocoordinate_table(); + if (ret < 0) { + rollback_transaction(); + return; + } + + ret = __geofence_manager_db_create_wifi_data_table(); + if (ret < 0) { + rollback_transaction(); + return; + } + + ret = __geofence_manager_db_create_bssid_table(); + if (ret < 0) { + rollback_transaction(); + return; + } + + commit_transaction(); +} + +/* Get fence id count in certain table, such as GeoFence/FenceGeocoordinate/FenceCurrentLocation */ +static int __geofence_manager_db_get_count_of_fence_id(int fence_id, fence_table_type_e table_type, int *count) +{ + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + + char *query = sqlite3_mprintf("SELECT COUNT(fence_id) FROM %Q where fence_id = %d;", menu_table[table_type], fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + *count = sqlite3_column_int(state, 0); + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +static int __geofence_manager_db_enable_foreign_keys(void) +{ + sqlite3_stmt *state = NULL; + int ret = FENCE_ERR_NONE; + char *query = sqlite3_mprintf("PRAGMA foreign_keys = ON;"); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, NULL); + if (SQLITE_OK != ret) { + LOGI_GEOFENCE("Fail to connect to table. Error[%s]", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + ret = sqlite3_step(state); + if (SQLITE_DONE != ret) { + LOGI_GEOFENCE("Fail to step. Error[%d]", ret); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +void replaceChar(char *src, char oldChar, char newChar) +{ + while (*src) { + if (*src == oldChar) + *src = newChar; + src++; + } +} + +void __geofence_manager_genarate_password(char *password) +{ + char *bt_address = NULL; + char *wifi_address = NULL; + char *token = NULL; + int bt_temp[6] = {0}, wifi_temp[6] = {0}; + int i = 0, fkey[6], lkey[6]; + char s1[100], s2[100], result[200]; + char keyword[6] = { 'b', 'w', 'd', 's', 'j', 'f' }; + + bt_adapter_get_address(&bt_address); + wifi_get_mac_address(&wifi_address); + + token = strtok(bt_address, ":"); + i = 0; + while (token) { + bt_temp[i++] = atoi(token); + token = strtok(NULL, ":"); + if (i >= 6) + break; + } + token = strtok(wifi_address, ":"); + i = 0; + while (token) { + wifi_temp[i++] = atoi(token); + token = strtok(NULL, ":"); + if (i >= 6) + break; + } + + memset((void *) s1, 0, sizeof(s1)); + memset((void *) s2, 0, sizeof(s2)); + memset((void *) result, 0, sizeof(result)); + + for (i = 0; i < 6; i++) { + fkey[i] = bt_temp[i] * wifi_temp[i]; + lkey[i] = bt_temp[i] + wifi_temp[i]; + } + + for (i = 0; i < 6; i++) { + sprintf(s1, "%s%x", s1, fkey[i]); + sprintf(s2, "%s%x", s2, lkey[i]); + replaceChar(s1, 0x30 + ((i * 2) % 10), keyword[i]); + replaceChar(s2, 0x30 + ((i * 2 + 1) % 10), keyword[i]); + LOGD_GEOFENCE("s1 %s", s1); + LOGD_GEOFENCE("s2 %s", s2); + } + + sprintf(result, "%s%s", s1, s2); + + password = result; + LOGD_GEOFENCE("result : %s", result); +} + +/** + * This function in DB and create GeoFence/FenceGeocoordinate /FenceCurrentLocation four table on DB if necessary. + * + * @param[in] struct of fence_point_info_s + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_db_init(void) +{ + FUNC_ENTRANCE_SERVER; + struct stat stat; + + if (__geofence_manager_open_db_handle() != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Fail to location_geofence_open_db_handle"); + return FENCE_ERR_SQLITE_FAIL; + } + + if (lstat(GEOFENCE_SERVER_DB_PATH, &stat) < 0) { + LOGI_GEOFENCE("lstat is ERROR!!!"); + db_util_close(db_info_s.handle); + db_info_s.handle = NULL; + return FENCE_ERR_SQLITE_FAIL; + } + + if (!S_ISREG(stat.st_mode)) { + LOGI_GEOFENCE("Invalid file"); + db_util_close(db_info_s.handle); + db_info_s.handle = NULL; + return FENCE_ERR_SQLITE_FAIL; + } + + if (!stat.st_size) + __geofence_manager_db_create_table(); + + return FENCE_ERR_NONE; +} + +int geofence_manager_db_reset(void) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int idx = 0; + int ret = SQLITE_OK; + char *query = NULL; + + for (idx = 0; idx < 4; idx++) { + query = sqlite3_mprintf("DELETE from %Q;", menu_table[idx]); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, NULL); + if (SQLITE_OK != ret) { + LOGI_GEOFENCE("Fail to connect to table. Error[%s]", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + ret = sqlite3_step(state); + if (SQLITE_DONE != ret) { + LOGI_GEOFENCE("Fail to step. Error[%d]", ret); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + sqlite3_finalize(state); + sqlite3_free(query); + } + return FENCE_ERR_NONE; +} + +int geofence_manager_set_place_info(place_info_s *place_info, int *place_id) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(place_info, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(place_id, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + int index = 0; + const char *tail; + char *appid = NULL; + char *place_name = NULL; + char *query = sqlite3_mprintf("INSERT INTO Places (access_type, place_name, app_id) VALUES (?, ?, ?)"); + + place_name = (char *)g_malloc0(sizeof(char)*PLACE_NAME_LEN); + g_strlcpy(place_name, place_info->place_name, PLACE_NAME_LEN); + appid = (char *)g_malloc0(sizeof(char)*APP_ID_LEN); + g_strlcpy(appid, place_info->appid, APP_ID_LEN); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + LOGD_GEOFENCE("appid[%s] access_type[%d] place_name[%s]", appid, place_info->access_type, place_info->place_name); + + ret = sqlite3_bind_int(state, ++index, place_info->access_type); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_text(state, ++index, place_name, -1, SQLITE_STATIC); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_text(state, ++index, appid, -1, SQLITE_STATIC); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + g_free(place_name); + g_free(appid); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + *place_id = sqlite3_last_insert_rowid(db_info_s.handle); + LOGI_GEOFENCE(" auto-genarated place_id[%d]", *place_id); + sqlite3_reset(state); + sqlite3_clear_bindings(state); + sqlite3_finalize(state); + g_free(place_name); + g_free(appid); + sqlite3_free(query); + + if (*place_id < 1) { + LOGI_GEOFENCE("TMP Invalid fence_id"); + *place_id = 0; + } + + return FENCE_ERR_NONE; +} + +int geofence_manager_set_common_info(fence_common_info_s *fence_info, int *fence_id) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(fence_info, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(fence_id, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + int index = 0; + const char *tail; + char *appid = NULL; + char *query = sqlite3_mprintf("INSERT INTO GeoFence (place_id, enable, app_id, geofence_type, access_type, running_status) VALUES (?, ?, ?, ?, ?, ?)"); + appid = (char *)g_malloc0(sizeof(char)*APP_ID_LEN); + g_strlcpy(appid, fence_info->appid, APP_ID_LEN); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + LOGD_GEOFENCE("place_id[%d], enable[%d], appid[%s] geofence_type[%d] access_type[%d] running_status[%d]", fence_info->place_id, fence_info->enable, appid, fence_info->running_status, fence_info->type, fence_info->access_type, fence_info->place_id); + + ret = sqlite3_bind_int(state, ++index, fence_info->place_id); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_int(state, ++index, fence_info->enable); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_text(state, ++index, appid, -1, SQLITE_STATIC); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_int(state, ++index, fence_info->type); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_int(state, ++index, fence_info->access_type); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_int(state, ++index, fence_info->running_status); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + g_free(appid); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + *fence_id = sqlite3_last_insert_rowid(db_info_s.handle); + LOGI_GEOFENCE(" auto-genarated fence_id[%d]", *fence_id); + sqlite3_reset(state); + sqlite3_clear_bindings(state); + sqlite3_finalize(state); + g_free(appid); + sqlite3_free(query); + + if (*fence_id < 1) { + LOGI_GEOFENCE("TMP Invalid fence_id"); + *fence_id = 0; + } + + return FENCE_ERR_NONE; +} + +int geofence_manager_get_place_list_from_db(int *number_of_places, GList **places) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *query = NULL; + int count = 0; + + query = sqlite3_mprintf("SELECT place_id, place_name, access_type, app_id FROM Places"); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + GList *place_list = NULL; + int column_index = 0; + do { + ret = sqlite3_step(state); + + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("DONE...!!! : %d", ret); + break; + } + column_index = 0; + place_info_s *place = g_slice_new0(place_info_s); + + if (place == NULL) + continue; + + place->place_id = sqlite3_column_int(state, column_index++); + g_strlcpy(place->place_name, (char *) sqlite3_column_text(state, column_index++), PLACE_NAME_LEN); + place->access_type = sqlite3_column_int(state, column_index++); + g_strlcpy(place->appid, (char *) sqlite3_column_text(state, column_index++), APP_ID_LEN); + place_list = g_list_append(place_list, place); + count++; + } while (ret != SQLITE_DONE); + + *places = place_list; + *number_of_places = count; + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +int geofence_manager_get_fence_list_from_db(int *number_of_fences, GList **fences, int place_id) +{ + FUNC_ENTRANCE_SERVER; + + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *query = NULL; + int count = 0; + + if (place_id == -1) + query = sqlite3_mprintf("SELECT DISTINCT A.fence_id, A.app_id, A.geofence_type, A.access_type, A.place_id, B.latitude, B.longitude, B.radius, B.address, C.bssid, C.ssid FROM GeoFence A LEFT JOIN FenceGeocoordinate B ON A.fence_id = B.fence_id LEFT JOIN FenceBssid C ON A.fence_id = C.fence_id GROUP BY A.fence_id"); + else + query = sqlite3_mprintf("SELECT DISTINCT A.fence_id, A.app_id, A.geofence_type, A.access_type, A.place_id, B.latitude, B.longitude, B.radius, B.address, C.bssid, C.ssid FROM GeoFence A LEFT JOIN FenceGeocoordinate B ON A.fence_id = B.fence_id LEFT JOIN FenceBssid C ON A.fence_id = C.fence_id WHERE A.place_id = %d GROUP BY A.fence_id", place_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + GList *fence_list = NULL; + do { + ret = sqlite3_step(state); + + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("DONE...!!! : %d", ret); + break; + } + int column_index = 0; + + geofence_info_s *fence = g_slice_new0(geofence_info_s); + + if (fence == NULL) + continue; + + fence->fence_id = sqlite3_column_int(state, column_index++); + g_strlcpy(fence->app_id, (char *) sqlite3_column_text(state, column_index++), APP_ID_LEN); + fence->param.type = sqlite3_column_int(state, column_index++); + fence->access_type = sqlite3_column_int(state, column_index++); + fence->param.place_id = sqlite3_column_int(state, column_index++); + char *data_name = NULL; + + data_name = (char *) sqlite3_column_text(state, column_index++); + if (!data_name || !strlen(data_name)) + LOGI_GEOFENCE("ERROR: data_name is NULL!!!"); + else + fence->param.latitude = atof(data_name); + + data_name = (char *) sqlite3_column_text(state, column_index++); + if (!data_name || !strlen(data_name)) + LOGI_GEOFENCE("ERROR: data_name is NULL!!!"); + else + fence->param.longitude = atof(data_name); + + data_name = (char *) sqlite3_column_text(state, column_index++); + if (!data_name || !strlen(data_name)) + LOGI_GEOFENCE("ERROR: data_name is NULL!!!"); + else + fence->param.radius = atof(data_name); + + g_strlcpy(fence->param.address, (char *) sqlite3_column_text(state, column_index++), ADDRESS_LEN); + g_strlcpy(fence->param.bssid, (char *) sqlite3_column_text(state, column_index++), WLAN_BSSID_LEN); + g_strlcpy(fence->param.ssid, (char *) sqlite3_column_text(state, column_index++), WLAN_BSSID_LEN); + LOGI_GEOFENCE("radius = %d, bssid = %s", fence->param.radius, fence->param.bssid); + fence_list = g_list_append(fence_list, fence); + count++; + } while (ret != SQLITE_DONE); + + *fences = fence_list; + *number_of_fences = count; + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +int geofence_manager_get_fenceid_list_from_db(int *number_of_fences, GList **fences, int place_id) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *query = NULL; + int count = 0; + query = sqlite3_mprintf("SELECT fence_id FROM GeoFence WHERE place_id = %d", place_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + GList *fence_list = NULL; + int column_index = 0; + int fence_id = 0; + do { + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("DONE...!!! : %d", ret); + break; + } + fence_id = 0; + fence_id = sqlite3_column_int(state, column_index); + fence_list = g_list_append(fence_list, GINT_TO_POINTER(fence_id)); + count++; + } while (ret != SQLITE_DONE); + *fences = fence_list; + *number_of_fences = count; + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +int geofence_manager_update_geocoordinate_info(int fence_id, geocoordinate_info_s *geocoordinate_info) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(fence_id, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(geocoordinate_info, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + const char *tail; + int ret = SQLITE_OK; + + char *query = sqlite3_mprintf("UPDATE FenceGeocoordinate SET latitude = %lf, longitude = %lf, radius = %lf where fence_id = %d;", geocoordinate_info->latitude, geocoordinate_info->longitude, geocoordinate_info->radius, fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + sqlite3_free(query); + LOGI_GEOFENCE("fence_id: %d has been successfully updated.", fence_id); + return FENCE_ERR_NONE; +} + +int geofence_manager_update_place_info(int place_id, const char *place_info_name) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(place_id, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + const char *tail; + int ret = SQLITE_OK; + char *place_name = NULL; + + place_name = (char *)g_malloc0(sizeof(char)*PLACE_NAME_LEN); + g_strlcpy(place_name, place_info_name, PLACE_NAME_LEN); + + char *query = sqlite3_mprintf("UPDATE Places SET place_name = %Q where place_id = %d", place_name, place_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + g_free(place_name); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + g_free(place_name); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + g_free(place_name); + sqlite3_free(query); + LOGI_GEOFENCE("place_id: %d has been successfully updated.", place_id); + return FENCE_ERR_NONE; +} + +/** + * This function set geocoordinate info in DB. + * + * @param[in] fence_id + * @param[out] struct of geocoordinate_info_s + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_geocoordinate_info(int fence_id, geocoordinate_info_s *geocoordinate_info) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(fence_id, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(geocoordinate_info, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + int index = 0; + const char *tail; + int count = -1; + char data_name_lat[MAX_DATA_NAME] = { 0 }; + char data_name_lon[MAX_DATA_NAME] = { 0 }; + char data_name_rad[MAX_DATA_NAME] = { 0 }; + /* + char ssa_data_lat[DATA_LEN] = { 0 }; + char ssa_data_lon[DATA_LEN] = { 0 }; + char ssa_data_rad[DATA_LEN] = { 0 }; + */ + char *query = sqlite3_mprintf("INSERT INTO FenceGeocoordinate(fence_id, latitude, longitude, radius, address) VALUES (?, ?, ?, ?, ?)"); + + ret = __geofence_manager_db_get_count_of_fence_id(fence_id, FENCE_GEOCOORDINATE_TAB, &count); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Fail to get geofence_manager_db_get_count_of_fence_id [%d]", ret); + sqlite3_free(query); + return ret; + } else if (count) { /* fence id has been in FenceGeocoordinate table */ + sqlite3_free(query); + return FENCE_ERR_FENCE_ID; + } + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_bind_int(state, ++index, fence_id); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + if (password == NULL) + __geofence_manager_genarate_password(password); + + /* ssa_put : latitude*/ + ret = snprintf(data_name_lat, DATA_LEN, "%lf", geocoordinate_info->latitude); + + ret = sqlite3_bind_text(state, ++index, data_name_lat, -1, SQLITE_STATIC); + + /*ret = sqlite3_bind_double (state, ++index, geocoordinate_info->latitude);*/ + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + /* ssa_put : longitude*/ + ret = snprintf(data_name_lon, MAX_DATA_NAME, "%lf", geocoordinate_info->longitude); + if (ret < 0) { + LOGD_GEOFENCE("ERROR: String will be truncated"); + return FENCE_ERR_STRING_TRUNCATED; + } + + ret = sqlite3_bind_text(state, ++index, data_name_lon, -1, SQLITE_STATIC); + /*ret = sqlite3_bind_double (state, ++index, geocoordinate_info->longitude);*/ + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + /* ssa_put : radius*/ + ret = snprintf(data_name_rad, MAX_DATA_NAME, "%lf", geocoordinate_info->radius); + if (ret < 0) { + LOGD_GEOFENCE("ERROR: String will be truncated"); + return FENCE_ERR_STRING_TRUNCATED; + } + + ret = sqlite3_bind_text(state, ++index, data_name_rad, -1, SQLITE_STATIC); + /*ret = sqlite3_bind_double (state, ++index, geocoordinate_info->radius);*/ + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_bind_text(state, ++index, geocoordinate_info->address, -1, SQLITE_STATIC); + SQLITE3_RETURN(ret, sqlite3_errmsg(db_info_s.handle), state); + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_reset(state); + sqlite3_clear_bindings(state); + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +/** + * This function get geocoordinate info from DB. + * + * @param[in] fence_id + * @param[out] struct of geocoordinate_info_s + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_geocoordinate_info(int fence_id, geocoordinate_info_s **geocoordinate_info) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(fence_id, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + int index = 0; + char *data_name = NULL; + /* + char *ssa_data = NULL; + */ + + char *query = sqlite3_mprintf("SELECT * FROM FenceGeocoordinate where fence_id = %d;", fence_id); + + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *geocoordinate_info = (geocoordinate_info_s *)g_malloc0(sizeof(geocoordinate_info_s)); + g_return_val_if_fail(*geocoordinate_info, FENCE_ERR_INVALID_PARAMETER); + + if (password == NULL) + __geofence_manager_genarate_password(password); + + data_name = (char *) sqlite3_column_text(state, ++index); + + if (!data_name || !strlen(data_name)) { + LOGI_GEOFENCE("ERROR: data_name is NULL!!!"); + } else { + (*geocoordinate_info)->latitude = atof(data_name); + } + + data_name = (char *) sqlite3_column_text(state, ++index); + if (!data_name || !strlen(data_name)) { + LOGI_GEOFENCE("ERROR: data_name is NULL!!!"); + } else { + (*geocoordinate_info)->longitude = atof(data_name); + } + + data_name = (char *) sqlite3_column_text(state, ++index); + if (!data_name || !strlen(data_name)) { + LOGI_GEOFENCE("ERROR: data_name is NULL!!!"); + } else { + (*geocoordinate_info)->radius = atof(data_name); + } + + g_strlcpy((*geocoordinate_info)->address, (char *) sqlite3_column_text(state, ++index), ADDRESS_LEN); + + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +/** + * This function get ap list from DB. + * + * @param[in] fence_id + * @param[out] ap_list + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_ap_info(const int fence_id, GList **ap_list) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + int count = -1; + int i = 0; + wifi_info_s *wifi_info = NULL; + const char *bssid = NULL; + + char *query1 = sqlite3_mprintf("SELECT COUNT(bssid) FROM FenceGeopointWifi where fence_id = %d;", fence_id); + + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query1, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query1); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGD_GEOFENCE("Fail to get count sqlite3_step"); + sqlite3_finalize(state); + sqlite3_free(query1); + return FENCE_ERR_SQLITE_FAIL; + } + + count = sqlite3_column_int(state, 0); + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query1); + if (count <= 0) { + LOGI_GEOFENCE("ERROR: count = %d", count); + return FENCE_ERR_COUNT; + } else { + LOGD_GEOFENCE("count[%d]", count); + } + + char *query2 = sqlite3_mprintf("SELECT * FROM FenceGeopointWifi where fence_id = %d;", fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query2, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query2); + return FENCE_ERR_PREPARE; + } + + for (i = 0; i < count; i++) { + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + break; + } + wifi_info = g_slice_new0(wifi_info_s); + g_return_val_if_fail(wifi_info, -1); + if (wifi_info) { + bssid = (const char *) sqlite3_column_text(state, 1); + g_strlcpy(wifi_info->bssid, bssid, WLAN_BSSID_LEN); + *ap_list = g_list_append(*ap_list, (gpointer) wifi_info); + } + } + + sqlite3_finalize(state); + sqlite3_free(query2); + return FENCE_ERR_NONE; +} + +/*This function get place info from DB. + * + * @param[in] place_id + * @param[out] struct of place_info_s + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_place_info(int place_id, place_info_s **place_info) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(place_id, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + int index = 0; + char *data_name = NULL; + /* + char *ssa_data = NULL; + */ + char *query = sqlite3_mprintf("SELECT * FROM Places where place_id = %d;", place_id); + LOGD_GEOFENCE("current place id is [%d]", place_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + *place_info = (place_info_s *)g_malloc0(sizeof(place_info_s)); + g_return_val_if_fail(*place_info, FENCE_ERR_INVALID_PARAMETER); + + data_name = (char *)sqlite3_column_text(state, ++index); + if (!data_name || !strlen(data_name)) { + LOGI_GEOFENCE("ERROR: data_name is NULL!!!"); + } else { + (*place_info)->access_type = atof(data_name); + } + + g_strlcpy((*place_info)->place_name, (char *)sqlite3_column_text(state, ++index), PLACE_NAME_LEN); + g_strlcpy((*place_info)->appid, (char *)sqlite3_column_text(state, ++index), APP_ID_LEN); + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +/** + * This function insert ap list in DB. + * + * @param[in] fence_id + * @param[out] ap_list + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_ap_info(int fence_id, GList *ap_list) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(fence_id, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(ap_list, FENCE_ERR_INVALID_PARAMETER); + int ret = FENCE_ERR_NONE; + int count = -1; + + ret = __geofence_manager_db_get_count_of_fence_id(fence_id, FENCE_GEOPOINT_WIFI_TABLE, &count); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Fail to get geofence_manager_db_get_count_of_fence_id [%d]", ret); + return ret; + } else { + if (count) { /* fence id has been in FenceCurrentLocation table */ + LOGI_GEOFENCE("count is [%d]", count); + return FENCE_ERR_FENCE_ID; + } + } + + g_list_foreach(ap_list, (GFunc) __geofence_manager_db_insert_wifi_data_info, &fence_id); + + return FENCE_ERR_NONE; +} + +/** + * This function get bluetooth info from DB. + * + * @param[in] fence_id + * @param[out] bt_info which contained bssid of bluetooth and correspond of fence_id. + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_bssid_info(const int fence_id, bssid_info_s **bssid_info) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + int count = -1; + int i = 0; + bssid_info_s *bssid_info_from_db = NULL; + const char *bssid = NULL; + const char *ssid = NULL; + + char *query1 = sqlite3_mprintf("SELECT COUNT(bssid) FROM %s where fence_id = %d;", menu_table[FENCE_BSSID_TABLE], fence_id); + + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query1, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query1); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGD_GEOFENCE("Fail to get count sqlite3_step"); + sqlite3_finalize(state); + sqlite3_free(query1); + return FENCE_ERR_SQLITE_FAIL; + } + + count = sqlite3_column_int(state, 0); + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query1); + if (count <= 0) { + LOGI_GEOFENCE("ERROR: count = %d", count); + return FENCE_ERR_COUNT; + } else { + LOGD_GEOFENCE("count[%d]", count); + } + + char *query2 = sqlite3_mprintf("SELECT * FROM %s where fence_id = %d;", menu_table[FENCE_BSSID_TABLE], fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query2, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query2); + return FENCE_ERR_PREPARE; + } + + /*'count' should be 1. because bluetooth bssid and fence_id matched one by one.*/ + for (i = 0; i < count; i++) { + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + break; + } + bssid_info_from_db = g_slice_new0(bssid_info_s); + g_return_val_if_fail(bssid_info_from_db, -1); + if (bssid_info_from_db) { + bssid = (const char *)sqlite3_column_text(state, 1); + ssid = (const char *)sqlite3_column_text(state, 2); + g_strlcpy(bssid_info_from_db->bssid, bssid, WLAN_BSSID_LEN); + g_strlcpy(bssid_info_from_db->ssid, ssid, WLAN_BSSID_LEN); + *bssid_info = bssid_info_from_db; + } + } + + sqlite3_finalize(state); + sqlite3_free(query2); + return FENCE_ERR_NONE; +} + +int geofence_manager_update_bssid_info(const int fence_id, bssid_info_s *bssid_info) +{ + FUNC_ENTRANCE_SERVER + g_return_val_if_fail(fence_id, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(bssid_info, FENCE_ERR_INVALID_PARAMETER); + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail; + char *query = sqlite3_mprintf("UPDATE %Q SET bssid = %Q where fence_id = %d;", menu_table[FENCE_BSSID_TABLE], bssid_info->bssid, fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + sqlite3_free(query); + LOGI_GEOFENCE("Fence_id: %d has been successfully updated.", fence_id); + return FENCE_ERR_NONE; +} + +/** + * This function insert bssid information in DB. + * + * @param[in] fence_id + * @param[in] bssid_info which contained bssid of wifi or bluetooth for geofence. + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_bssid_info(int fence_id, bssid_info_s *bssid_info) +{ + FUNC_ENTRANCE_SERVER + g_return_val_if_fail(fence_id, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(bssid_info, FENCE_ERR_INVALID_PARAMETER); + int ret = FENCE_ERR_NONE; + int count = -1; + + ret = __geofence_manager_db_get_count_of_fence_id(fence_id, FENCE_BSSID_TABLE, &count); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Fail to get geofence_manager_db_get_count_of_fence_id [%d]", ret); + return ret; + } else { + if (count) { /* fence id has been in FenceBssid table */ + LOGI_GEOFENCE("count is [%d]", count); + return FENCE_ERR_FENCE_ID; + } + } + + ret = __geofence_manager_db_insert_bssid_info(fence_id, bssid_info->bssid, bssid_info->ssid); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("Fail to insert the bssid info"); + return ret; + } + return FENCE_ERR_NONE; +} + +/** + * This function get enable status from DB. + * + * @param[in] fence_id + * @param[in] status: 1 enbale, 0 disable. + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_enable_status(const int fence_id, int *status) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + + char *query = sqlite3_mprintf("SELECT enable FROM GeoFence where fence_id = %d;", fence_id); + + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *status = sqlite3_column_int(state, 0); + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function set enable on DB. + * + * @param[in] fence_id + * @param[in] status: 1 enbale, 0 disable. + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_enable_status(int fence_id, int status) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state; + int ret = SQLITE_OK; + const char *tail; + + char *query = sqlite3_mprintf("UPDATE GeoFence SET enable = %d where fence_id = %d;", status, fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function get name from DB. + * + * @param[in] fence_id + * @param[out] name + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_place_name(int place_id, char **name) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *tmp = NULL; + + char *query = sqlite3_mprintf("SELECT place_name FROM Places where place_id = %d;", place_id); + + LOGD_GEOFENCE("current place id is [%d]", place_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + tmp = (char *) sqlite3_column_text(state, 0); + if (!tmp || !strlen(tmp)) { + LOGI_GEOFENCE("ERROR: name is NULL!!!"); + } else { + *name = g_strdup(tmp); + } + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function set name on DB. + * + * @param[in] fence_id + * @param[in] name + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_place_name(int place_id, const char *name) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state; + int ret = SQLITE_OK; + const char *tail; + + char *query = sqlite3_mprintf("UPDATE Places SET place_name = %Q where place_id = %d;", name, place_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function get appid from DB. + * + * @param[in] place_id + * @param[in] appid + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_appid_from_places(int place_id, char **appid) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *id = NULL; + + char *query = sqlite3_mprintf("SELECT app_id FROM Places where place_id = %d;", place_id); + + LOGD_GEOFENCE("current place id is [%d]", place_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + id = (char *) sqlite3_column_text(state, 0); + if (!id || !strlen(id)) { + LOGI_GEOFENCE("ERROR: appid is NULL!!!"); + } else { + *appid = g_strdup(id); + } + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function set appid on DB. + * + * @param[in] place_id + * @param[in] appid. + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_appid_to_places(int place_id, char *appid) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state; + int ret = SQLITE_OK; + const char *tail; + + char *query = sqlite3_mprintf("UPDATE Places SET app_id = %Q where place_id = %d;", appid, place_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function get appid from DB. + * + * @param[in] fence_id + * @param[in] appid + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_appid_from_geofence(int fence_id, char **appid) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *id = NULL; + + char *query = sqlite3_mprintf("SELECT app_id FROM GeoFence where fence_id = %d;", fence_id); + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + id = (char *) sqlite3_column_text(state, 0); + if (!id || !strlen(id)) { + LOGI_GEOFENCE("ERROR: appid is NULL!!!"); + } else { + *appid = g_strdup(id); + } + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function set appid on DB. + * + * @param[in] fence_id + * @param[in] appid. + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_appid_to_geofence(int fence_id, char *appid) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state; + int ret = SQLITE_OK; + const char *tail; + + char *query = sqlite3_mprintf("UPDATE GeoFence SET app_id = %Q where fence_id = %d;", appid, fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function get geofence type from DB. + * + * @param[in] fence_id + * @param[in] geofence_type_e. + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_geofence_type(int fence_id, geofence_type_e *fence_type) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + + char *query = sqlite3_mprintf("SELECT geofence_type FROM GeoFence where fence_id = %d;", fence_id); + + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *fence_type = sqlite3_column_int(state, 0); + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +int geofence_manager_get_place_id(int fence_id, int *place_id) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + + char *query = sqlite3_mprintf("SELECT place_id FROM GeoFence where fence_id = %d;", fence_id); + + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *place_id = sqlite3_column_int(state, 0); + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +/** + * This function get geofence/place access type from DB. + * + * @param[in] fence_id/place_id + * @param[in] access_type_e. + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_access_type(int fence_id, int place_id, access_type_e *fence_type) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *query = NULL; + + if (place_id == -1) + query = sqlite3_mprintf("SELECT access_type FROM GeoFence WHERE fence_id = %d;", fence_id); + else if (fence_id == -1) + query = sqlite3_mprintf("SELECT access_type FROM Places WHERE place_id = %d", place_id); + + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + LOGD_GEOFENCE("current place id is [%d]", place_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *fence_type = sqlite3_column_int(state, 0); + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +/** + * This function set geofence type on DB. + * + * @param[in] fence_id + * @param[in] fence_type. + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_geofence_type(int fence_id, geofence_type_e fence_type) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state; + int ret = SQLITE_OK; + const char *tail; + + char *query = sqlite3_mprintf("UPDATE GeoFence SET geofence_type = %d where fence_id = %d;", fence_type, fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function get geofence place_id from DB. + * + * @param[in] fence_id + * @param[in] place_id + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_placeid_from_geofence(int fence_id, int *place_id) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + + char *query = sqlite3_mprintf("SELECT place_id FROM GeoFence where fence_id = %d;", fence_id); + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *place_id = sqlite3_column_int(state, 0); + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +/** + * This function get running status from DB. + * + * @param[in] fence_id + * @param[in] int + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_running_status(int fence_id, int *running_status) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + + char *query = sqlite3_mprintf("SELECT running_status FROM GeoFence where fence_id = %d;", fence_id); + + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *running_status = sqlite3_column_int(state, 0); + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +/** + * This function set running state on DB. + * + * @param[in] fence_id + * @param[in] state + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_running_status(int fence_id, int running_status) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state; + int ret = SQLITE_OK; + const char *tail; + + char *query = sqlite3_mprintf("UPDATE GeoFence SET running_status = %d where fence_id = %d;", running_status, fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/** + * This function get direction type from DB. + * + * @param[in] fence_id + * @param[in] direction + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_get_direction(int fence_id, geofence_direction_e *direction) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + + char *query = sqlite3_mprintf("SELECT direction FROM GeoFence where fence_id = %d;", fence_id); + LOGD_GEOFENCE("current fence id is [%d]", fence_id); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *direction = sqlite3_column_int(state, 0); + + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +/** + * This function set direction type on DB. + * + * @param[in] fence_id + * @param[in] direction + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_set_direction(int fence_id, geofence_direction_e direction) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state; + int ret = SQLITE_OK; + const char *tail; + + char *query = sqlite3_mprintf("UPDATE GeoFence SET direction = %d where fence_id = %d;", direction, fence_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_DONE) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_finalize(state); + sqlite3_free(query); + + return FENCE_ERR_NONE; +} + +/** + * This function remove fence from DB. + * + * @param[in] fence_id + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_delete_fence_info(int fence_id) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(fence_id, FENCE_ERR_INVALID_PARAMETER); + int ret = FENCE_ERR_NONE; + geofence_type_e fence_type = GEOFENCE_INVALID; + + ret = geofence_manager_get_geofence_type(fence_id, &fence_type); + if (FENCE_ERR_NONE != ret) { + LOGI_GEOFENCE("Fail to geofence_manager_delete_fence_point_info"); + return ret; + } + + ret = __geofence_manager_db_enable_foreign_keys(); + if (FENCE_ERR_NONE != ret) { + LOGI_GEOFENCE("Fail to geofence_manager_db_enable_foreign_keys"); + return ret; + } + + ret = __geofence_manager_delete_table(fence_id, FENCE_MAIN_TABLE); + if (FENCE_ERR_NONE != ret) { + LOGI_GEOFENCE("Fail to geofence_manager_delete_fence_point_info"); + return ret; + } + + return ret; +} + +/** + * This function remove place from DB. + * + * @param[in] place_id + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_delete_place_info(int place_id) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(place_id, FENCE_ERR_INVALID_PARAMETER); + int ret = FENCE_ERR_NONE; + + ret = __geofence_manager_db_enable_foreign_keys(); + if (FENCE_ERR_NONE != ret) { + LOGI_GEOFENCE("Fail to geofence_manager_db_enable_foreign_keys"); + return ret; + } + + ret = __geofence_manager_delete_place_table(place_id); + if (FENCE_ERR_NONE != ret) { + LOGI_GEOFENCE("Fail to geofence_manager_delete_place_info"); + return ret; + } + + return ret; +} + +/** + * This function close DB handle. + * + * @param[in] fence_id + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_close_db(void) +{ + FUNC_ENTRANCE_SERVER; + int ret = SQLITE_OK; + + if (db_info_s.handle == NULL) { + return FENCE_ERR_NONE; + } + + ret = db_util_close(db_info_s.handle); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Close DB ERROR!!!"); + return FENCE_ERR_SQLITE_FAIL; + } + + return FENCE_ERR_NONE; +} + +/** + * This function deletes all data on db. + * + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_reset(void) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + + ret = __geofence_manager_db_enable_foreign_keys(); + if (FENCE_ERR_NONE != ret) { + LOGI_GEOFENCE("Fail to geofence_manager_db_enable_foreign_keys"); + return ret; + } + + char *query_two = sqlite3_mprintf("DELETE from %Q;", menu_table[FENCE_MAIN_TABLE]); + + ret = sqlite3_prepare_v2(db_info_s.handle, query_two, -1, &state, NULL); + if (SQLITE_OK != ret) { + LOGI_GEOFENCE("Fail to connect to table. Error[%s]", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query_two); + return FENCE_ERR_SQLITE_FAIL; + } + + ret = sqlite3_step(state); + if (SQLITE_DONE != ret) { + LOGI_GEOFENCE("Fail to step. Error[%d]", ret); + sqlite3_finalize(state); + sqlite3_free(query_two); + return FENCE_ERR_SQLITE_FAIL; + } + sqlite3_reset(state); + sqlite3_free(query_two); + + char *query_three = sqlite3_mprintf("UPDATE sqlite_sequence SET seq = 0 where name = %Q;", menu_table[FENCE_MAIN_TABLE]); + + ret = sqlite3_prepare_v2(db_info_s.handle, query_three, -1, &state, NULL); + if (SQLITE_OK != ret) { + LOGI_GEOFENCE("Fail to connect to table. Error[%s]", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query_three); + return FENCE_ERR_SQLITE_FAIL; + } + + ret = sqlite3_step(state); + if (SQLITE_DONE != ret) { + LOGI_GEOFENCE("Fail to step. Error[%d]", ret); + sqlite3_finalize(state); + sqlite3_free(query_three); + return FENCE_ERR_SQLITE_FAIL; + } + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query_three); + return FENCE_ERR_NONE; +} + +/** + * This function copy source wifi info to dest wifi info. + * + * @param[in] src_wifi + * @param[out] dest_wifi + * @return FENCE_ERR_NONE on success, negative values for errors + */ +int geofence_manager_copy_wifi_info(wifi_info_s *src_wifi, wifi_info_s **dest_wifi) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(src_wifi, FENCE_ERR_INVALID_PARAMETER); + + *dest_wifi = (wifi_info_s *)g_malloc0(sizeof(wifi_info_s)); + g_return_val_if_fail(*dest_wifi, -1); + + g_strlcpy((*dest_wifi)->bssid, src_wifi->bssid, WLAN_BSSID_LEN); + + return FENCE_ERR_NONE; +} + +/** +* This function create a wifi infor . +* +* @param[in] fence_id +* @param[in] bssid +* @param[out] wifi info +* @return FENCE_ERR_NONE on success, negative values for errors +*/ +int geofence_manager_create_wifi_info(int fence_id, char *bssid, wifi_info_s **new_wifi) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(fence_id >= 0, FENCE_ERR_INVALID_PARAMETER); + g_return_val_if_fail(bssid, FENCE_ERR_INVALID_PARAMETER); + + *new_wifi = (wifi_info_s *)g_malloc0(sizeof(wifi_info_s)); + g_strlcpy((*new_wifi)->bssid, bssid, WLAN_BSSID_LEN); + + return FENCE_ERR_NONE; +} + +/** +* This function get fence id count by params such as app id and fence type and enable status . +* +* @param[in] app_id : if app_id == NULL: ALL +* @param[in] fence_type:if GEOFENCE_TYPE_INVALID == NULL: ALL fence type +* @param[in] enable_status +* @param[out] fence id count +* @return FENCE_ERR_NONE on success, negative values for errors +*/ +int geofence_manager_get_count_by_params(const char *app_id, geofence_type_e fence_type, int *count) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *query = NULL; + + if (NULL == app_id) { + if (GEOFENCE_INVALID != fence_type) { /* app_id == NULL : All and GEOFENCE_TYPE_INVALID != fence_type */ + query = sqlite3_mprintf("SELECT COUNT(fence_id) FROM GeoFence where geofence_type = %d ;", fence_type); + } else { + query = sqlite3_mprintf("SELECT COUNT(fence_id) FROM GeoFence ;"); + } + } else { /*app_id not NULL */ + if (GEOFENCE_INVALID != fence_type) { /* app_id not NULL and GEOFENCE_TYPE_INVALID != fence_type */ + query = sqlite3_mprintf("SELECT COUNT(fence_id) FROM GeoFence where app_id = %Q AND geofence_type = %d ;", app_id, fence_type); + } else { + query = sqlite3_mprintf("SELECT COUNT(fence_id) FROM GeoFence where app_id = %Q ;", app_id); + } + } + + LOGI_GEOFENCE("app_id[%s] fence_type[%d] ", app_id, fence_type); + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *count = sqlite3_column_int(state, 0); + + if (*count <= 0) { + LOGI_GEOFENCE("ERROR: count = %d", *count); + return FENCE_ERR_COUNT; + } else { + LOGI_GEOFENCE("count[%d]", *count); + } + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +/* + app_id == NULL : All, geofence_type_e : INVALID - all, IN enable_status : enable, disable or both. Output : a list of geofence_id +*/ +int geofence_manager_get_fences(const char *app_id, geofence_type_e fence_type, GList **fences) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *query = NULL; + int i = 0; + int fence_id = 0; + int count = -1; + + ret = geofence_manager_get_count_by_params(app_id, fence_type, &count); + if (ret != FENCE_ERR_NONE) { + LOGI_GEOFENCE("ERROR: geofence_manager_get_count_of_fences_by_app."); + return ret; + } + + if (NULL == app_id) { + if (GEOFENCE_INVALID != fence_type) { /* app_id == NULL : All and GEOFENCE_TYPE_INVALID != fence_type */ + query = sqlite3_mprintf("SELECT fence_id FROM GeoFence where geofence_type = %d;", fence_type); + } else { + query = sqlite3_mprintf("SELECT fence_id FROM GeoFence;"); + } + } else { /*app_id not NULL */ + if (GEOFENCE_INVALID != fence_type) { /* app_id not NULL and GEOFENCE_TYPE_INVALID != fence_type */ + query = sqlite3_mprintf("SELECT fence_id FROM GeoFence where app_id = %Q AND geofence_type = %d ;", app_id, fence_type); + } else { + query = sqlite3_mprintf("SELECT fence_id FROM GeoFence where app_id = %Q;", app_id); + } + } + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + for (i = 0; i < count; i++) { + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + break; + } + fence_id = sqlite3_column_int(state, 0); + LOGI_GEOFENCE("fence id is [%d]", fence_id); + *fences = g_list_append(*fences, (gpointer) GINT_TO_POINTER(fence_id)); + } + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +int geofence_manager_get_count_of_fences(int *count) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *query = sqlite3_mprintf("SELECT COUNT(fence_id) FROM GeoFence;"); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *count = sqlite3_column_int(state, 0); + + if (*count < 0) { + LOGI_GEOFENCE("ERROR: count = %d", *count); + return FENCE_ERR_COUNT; + } else { + LOGI_GEOFENCE("count[%d]", *count); + } + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} + +int geofence_manager_get_place_count_by_placeid(int place_id, int *count) +{ + FUNC_ENTRANCE_SERVER; + sqlite3_stmt *state = NULL; + int ret = SQLITE_OK; + const char *tail = NULL; + char *query = sqlite3_mprintf("SELECT COUNT(place_id) FROM Places WHERE place_id=%d;", place_id); + + ret = sqlite3_prepare_v2(db_info_s.handle, query, -1, &state, &tail); + if (ret != SQLITE_OK) { + LOGI_GEOFENCE("Error: %s", sqlite3_errmsg(db_info_s.handle)); + sqlite3_free(query); + return FENCE_ERR_PREPARE; + } + + ret = sqlite3_step(state); + if (ret != SQLITE_ROW) { + LOGI_GEOFENCE("sqlite3_step Error[%d] : %s", ret, sqlite3_errmsg(db_info_s.handle)); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_SQLITE_FAIL; + } + + *count = sqlite3_column_int(state, 0); + + if (*count < 0) { + LOGI_GEOFENCE("ERROR: place count = %d", *count); + return FENCE_ERR_COUNT; + } else { + LOGI_GEOFENCE("place count[%d]", *count); + } + + sqlite3_reset(state); + sqlite3_finalize(state); + sqlite3_free(query); + return FENCE_ERR_NONE; +} diff --git a/geofence-server/src/geofence_server_db.h b/geofence-server/src/geofence_server_db.h new file mode 100644 index 0000000..1d17ed4 --- /dev/null +++ b/geofence-server/src/geofence_server_db.h @@ -0,0 +1,67 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 _GEOFENCE_MANAGER_APPMAN_H_ +#define _GEOFENCE_MANAGER_APPMAN_H_ + +#include <dlog.h> +#include <glib.h> + +#include "geofence_server_data_types.h" +#include "geofence_server_private.h" + +int geofence_manager_db_init(void); +int geofence_manager_db_reset(void); +int geofence_manager_close_db(void); +int geofence_manager_set_common_info(fence_common_info_s *fence_common_info, int *fence_id); +int geofence_manager_get_place_list_from_db(int *number_of_places, GList **places); +int geofence_manager_get_fence_list_from_db(int *number_of_fences, GList **fences, int place_id); +int geofence_manager_get_fenceid_list_from_db(int *number_of_fences, GList **fences, int place_id); +int geofence_manager_get_bssid_info(int fence_id, bssid_info_s **bt_info); +int geofence_manager_update_bssid_info(const int fence_id, bssid_info_s *bssid_info); +int geofence_manager_set_bssid_info(int fence_id, bssid_info_s *bt_info); +int geofence_manager_get_ap_info(int fence_id, GList **ap_list); +int geofence_manager_set_ap_info(int fence_id, GList *ap_list); +int geofence_manager_get_place_name(int place_id, char **name); +int geofence_manager_get_place_info(int place_id, place_info_s **place_info); +int geofence_manager_get_geocoordinate_info(int fence_id, geocoordinate_info_s **geocoordinate_info); +int geofence_manager_update_geocoordinate_info(int fence_id, geocoordinate_info_s *geocoordinate_info); +int geofence_manager_set_geocoordinate_info(int fence_id, geocoordinate_info_s *geocoordinate_info); +int geofence_manager_set_place_info(place_info_s *place_info, int *place_id); +int geofence_manager_update_place_info(int place_id, const char *place_info); +int geofence_manager_get_enable_status(const int fence_id, int *status); +int geofence_manager_set_enable_status(int fence_id, int status); +int geofence_manager_get_appid_from_places(int place_id, char **appid); +int geofence_manager_set_appid_to_places(int place_id, char *appid); +int geofence_manager_get_appid_from_geofence(int fence_id, char **appid); +int geofence_manager_set_appid_to_geofence(int fence_id, char *appid); +int geofence_manager_get_geofence_type(int fence_id, geofence_type_e *fence_type); +int geofence_manager_get_place_id(int fence_id, int *place_id); +int geofence_manager_set_geofence_type(int fence_id, geofence_type_e fence_type); +int geofence_manager_get_access_type(int fence_id, int place_id, access_type_e *fence_type); +int geofence_manager_get_placeid_from_geofence(int fence_id, int *place_id); +int geofence_manager_get_running_status(int fence_id, int *status); +int geofence_manager_set_running_status(int fence_id, int status); +int geofence_manager_get_direction(int fence_id, geofence_direction_e *direction); +int geofence_manager_set_direction(int fence_id, geofence_direction_e direction); +int geofence_manager_delete_fence_info(int fence_id); +int geofence_manager_delete_place_info(int place_id); +int geofence_manager_copy_wifi_info(wifi_info_s *src_wifi, wifi_info_s **dest_wifi); +int geofence_manager_create_wifi_info(int fence_id, char *bssid, wifi_info_s **new_wifi); +int geofence_manager_get_fences(const char *app_id, geofence_type_e fence_type, GList **fences); +int geofence_manager_get_count_of_fences(int *count); +int geofence_manager_get_place_count_by_placeid(int place_id, int *count); + +#endif /* _GEOFENCE_MANAGER_APPMAN_H_ */ diff --git a/geofence-server/src/geofence_server_internal.c b/geofence-server/src/geofence_server_internal.c new file mode 100644 index 0000000..710450c --- /dev/null +++ b/geofence-server/src/geofence_server_internal.c @@ -0,0 +1,81 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "geofence_server.h" +#include "geofence_server_private.h" +#include "geofence_server_log.h" +#include "debug_util.h" + +static gint __find_custom_item_by_fence_id(gconstpointer data, gconstpointer compare_with) +{ + g_return_val_if_fail(data, 1); + g_return_val_if_fail(compare_with, -1); + int ret = -1; + + GeofenceItemData *item_data = (GeofenceItemData *)data; + int *fence_id = (int *)compare_with; + if (item_data->common_info.fence_id == *fence_id) { + LOGD_GEOFENCE("Found[%d]", *fence_id); + ret = 0; + } + + return ret; +} + +GeofenceItemData *__get_item_by_fence_id(gint fence_id, GeofenceServer *geofence_server) +{ + g_return_val_if_fail(geofence_server, NULL); + + geofence_server->geofence_list = g_list_first(geofence_server->geofence_list); + GList *found_item = NULL; + found_item = g_list_find_custom(geofence_server->geofence_list, &fence_id, __find_custom_item_by_fence_id); + if (found_item == NULL || found_item->data == NULL) { + LOGD_GEOFENCE("item_data is not found. found_item[%d]", found_item); + return NULL; + } + /*Get the item from the list and return it*/ + return (GeofenceItemData *)found_item->data; +} + +double _get_min_distance(double cur_lat, double cur_lon, GeofenceServer *geofence_server) +{ + GList *fence_list = NULL; + GList *item_list = NULL; + int fence_id = 0; + GeofenceItemData *item_data = NULL; + geocoordinate_info_s *geocoordinate_info = NULL; + double min_dist = 100000.0, distance = 0.0; + + fence_list = geofence_server->tracking_list; + + item_list = g_list_first(fence_list); + while (item_list) { + fence_id = GPOINTER_TO_INT(item_list->data); + LOGD_GEOFENCE("FENCE Id to find distance :: %d", fence_id); + + item_data = __get_item_by_fence_id(fence_id, geofence_server); + if (item_data && item_data->common_info.type == GEOFENCE_TYPE_GEOPOINT) { + geocoordinate_info = (geocoordinate_info_s *)item_data->priv; + /* get_current_position/ check_fence_in/out for geoPoint*/ + location_manager_get_distance(cur_lat, cur_lon, geocoordinate_info->latitude, geocoordinate_info->longitude, &distance); + if (distance < min_dist) + min_dist = distance; + } + item_list = g_list_next(item_list); + } + LOGD_GEOFENCE("Min : %f", min_dist); + + return min_dist; +} diff --git a/geofence-server/src/geofence_server_internal.h b/geofence-server/src/geofence_server_internal.h new file mode 100644 index 0000000..df67b63 --- /dev/null +++ b/geofence-server/src/geofence_server_internal.h @@ -0,0 +1,49 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file geofence_server_internal.h + * @brief Geofence server related internal APIs + * + */ + +#ifndef GEOFENCE_MANAGER_INTERNAL_H_ +#define GEOFENCE_MANAGER_INTERNAL_H_ + +/*gboolean _get_cell_db (GeofenceItemData *item_data); +void _set_cell_db (GeofenceItemData *item_data, gboolean is_saved); +gboolean _check_cell_out (GeofenceServer *geofence_server, cell_status_e status); +gboolean _check_cell_db_existence (GeofenceServer *geofence_server, gboolean is_enabled);*/ + +/** +* @brief Gets the min distance to next geofence +* @param[in] cur_lat The current location latitude. +* @param[in] cur_lon The current location longitude. +* @param[in] geofence_server The geofence server +* @return double +* @retval The min distance to next geofence +*/ +double _get_min_distance(double cur_lat, double cur_lon, GeofenceServer *geofence_server); + +/** +* @brief Gets the geofence using fence id +* @param[in] fence_id The geofence id +* @param[in] geofence_server The geofence server +* @return GeofenceItemData +* @retval GeofenceItemData +*/ +GeofenceItemData *__get_item_by_fence_id(gint fence_id, GeofenceServer *geofence_server); + +#endif /* GEOFENCE_MANAGER_INTERNAL_H_ */ diff --git a/geofence-server/src/geofence_server_log.c b/geofence-server/src/geofence_server_log.c new file mode 100644 index 0000000..ea882e8 --- /dev/null +++ b/geofence-server/src/geofence_server_log.c @@ -0,0 +1,83 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> +#include <vconf.h> +#include "debug_util.h" + +#define __GEOFENCE_LOG_FILE__ "/opt/usr/media/geofence_log.txt" + +int fd = -1; + +struct tm *__get_current_time() +{ + time_t now; + struct tm *cur_time; + time(&now); + cur_time = localtime(&now); + return cur_time; +} + +void _init_log() +{ + struct tm *cur_time = __get_current_time(); + char buf[256] = { 0, }; + /*fd = open(__GEOFENCE_LOG_FILE__, O_RDWR | O_APPEND | O_CREAT, 0644); + * if (fd < 0) { + * LOGI_GEOFENCE("Fail to open file[%s]", __GEOFENCE_LOG_FILE__); + * return; + * } */ + + if (cur_time != NULL) + sprintf(buf, "[%02d:%02d:%02d] -- START -- \n", cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec); + LOGI_GEOFENCE("BUF[%s]", buf); +/* write(fd, buf, strlen(buf));*/ +} + +void _deinit_log() +{ + if (fd < 0) + return; + struct tm *cur_time = __get_current_time(); + char buf[256] = { 0, }; + + if (cur_time != NULL) + sprintf(buf, "[%02d:%02d:%02d] -- END -- \n", cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec); + LOGI_GEOFENCE("BUF[%s]", buf); +/* write(fd, buf, strlen(buf));*/ + + close(fd); + fd = -1; +} + +void _print_log(const char *str) +{ + if (fd < 0) + return; + char buf[256] = { 0, }; + struct tm *cur_time = __get_current_time(); + + if (cur_time != NULL) + sprintf(buf, "[%02d:%02d:%02d] %s\n", cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec, str); + + LOGI_GEOFENCE("BUF %s", buf); +/* write(fd, buf, strlen(buf));*/ +} + diff --git a/geofence-server/src/geofence_server_log.h b/geofence-server/src/geofence_server_log.h new file mode 100644 index 0000000..5b1d7a0 --- /dev/null +++ b/geofence-server/src/geofence_server_log.h @@ -0,0 +1,37 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 _GEOFENCE_MANAGER_LOG_H_ +#define _GEOFENCE_MANAGER_LOG_H_ + +#include <time.h> + +void _init_log(); +void _deinit_log(); +void _print_log(const char *str); +struct tm *__get_current_time(); + +#define GEOFENCE_PRINT_LOG(state) { \ + char buf[256] = {0, }; \ + sprintf(buf, " [%s:%d] Status[%s]", __func__, __LINE__, #state); \ + _print_log(buf); \ + } +#define GEOFENCE_PRINT_LOG_WITH_ID(state, id) { \ + char buf[256] = {0, }; \ + sprintf(buf, " [%s:%d] Status[%s]. ID[%d]", __func__, __LINE__, #state, id); \ + _print_log(buf); \ + } + +#endif /* _GEOFENCE_MANAGER_LOG_H_ */ diff --git a/geofence-server/src/geofence_server_private.h b/geofence-server/src/geofence_server_private.h new file mode 100644 index 0000000..73e11e1 --- /dev/null +++ b/geofence-server/src/geofence_server_private.h @@ -0,0 +1,166 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file geofence_server_private.h + * @brief Geofence server related private structure and enumeration + * + */ + +#ifndef __GEOFENCE_MANAGER_PRIVATE_H__ +#define __GEOFENCE_MANAGER_PRIVATE_H__ + +#include <geofence_dbus_server.h> +#include "geofence-module.h" +#include <locations.h> +#include <alarm.h> +#include <network-wifi-intf.h> +#include "geofence_server_data_types.h" +#include "geofence_server.h" + +#include <activity_recognition.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** Length of bssid */ +#define WLAN_BSSID_LEN 18 +#define APP_ID_LEN 64 +#define ADDRESS_LEN 64 +#define PLACE_NAME_LEN 64 + +/** + * The geofence common information structure + */ +typedef struct { + int fence_id; + int enable; + geofence_fence_state_e status; + geofence_type_e type; /* Geocoordinate/WIFI/CurrentLocation/Bluetooth */ + access_type_e access_type; + char appid[APP_ID_LEN]; + int running_status; /*0-idle 1-running*/ + int place_id; +} fence_common_info_s; + +/** + * + */ +typedef struct { + int place_id; + access_type_e access_type; + char place_name[PLACE_NAME_LEN]; + char appid[APP_ID_LEN]; +} place_info_s; + +/** + *The geocoordinate structure + */ +typedef struct { + double latitude; + double longitude; + double radius; + char address[ADDRESS_LEN]; +} geocoordinate_info_s; + +typedef struct { + int place_id; + geofence_type_e type; + double latitude; + double longitude; + int radius; + char address[ADDRESS_LEN]; + char bssid[WLAN_BSSID_LEN]; + char ssid[WLAN_BSSID_LEN]; +} geofence_s; + +/* This can be substituded to GeofenceData*/ +typedef struct _geofence_info_s { + int fence_id; + char app_id[APP_ID_LEN]; + access_type_e access_type; + geofence_s param; +} geofence_info_s; + +/** + *The wifi info structure + */ +typedef struct { + char bssid[WLAN_BSSID_LEN]; +} wifi_info_s; + +/** + *The bluetooth info structure + */ +typedef struct { + char bssid[WLAN_BSSID_LEN]; + char ssid[WLAN_BSSID_LEN]; + gboolean enabled; /* bluetooth callback receive or not */ +} bssid_info_s; + +/** + *The GeofenceItemData structure + */ +typedef struct { + double distance; + bool is_wifi_status_in; + bool is_bt_status_in; + geofence_client_status_e client_status; + cell_status_e cell_status; + int smart_assist_added; + smart_assist_status_e smart_assistant_status; /* enable or not after added */ + fence_common_info_s common_info; + void *priv; /* Save (latitude, longitude and radius) or AP list */ +} GeofenceItemData; + +/** + *The GeofenceServer structure + */ +typedef struct { + GMainLoop *loop; + geofence_dbus_server_h geofence_dbus_server; + GList *geofence_list; /* list of GeofenceData for multi clients */ + GList *tracking_list; /* list of geofence ids for tracking */ + time_t last_loc_time; + time_t last_result_time; + int running_geopoint_cnt; + int running_bt_cnt; + int running_wifi_cnt; + GeofenceModCB geofence_cb; + gpointer userdata; + /* for Geometry's GPS positioning*/ + location_manager_h loc_manager; + /*FILE *log_file;*/ + int loc_started; + alarm_id_t timer_id; /* ID for timer source*/ + alarm_id_t nps_alarm_id; /* ID for WPS restart timer source*/ + alarm_id_t nps_timeout_alarm_id; + alarm_id_t wifi_alarm_id; + alarm_id_t bt_alarm_id; + + activity_type_e activity_type; + double activity_timestamp; + + activity_h activity_stationary_h; + activity_h activity_walk_h; + activity_h activity_run_h; + activity_h activity_in_vehicle_h; +} GeofenceServer; + +#ifdef __cplusplus +} +#endif +#endif /* __GEOFENCE_MANAGER_PRIVATE_H__ */ diff --git a/geofence-server/src/geofence_server_wifi.c b/geofence-server/src/geofence_server_wifi.c new file mode 100644 index 0000000..c8d840c --- /dev/null +++ b/geofence-server/src/geofence_server_wifi.c @@ -0,0 +1,151 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 <stdlib.h> +#include <vconf.h> +#include <vconf-keys.h> +#include <glib.h> + +#include "geofence_server.h" +#include "server.h" +#include "debug_util.h" +#include "geofence_server_private.h" +#include "geofence_server_db.h" +#include "geofence_server_log.h" +#include "geofence_server_internal.h" + +static void emit_wifi_geofence_inout_changed(GeofenceServer *geofence_server, int fence_id, int fence_status) +{ + LOGD_GEOFENCE("emit_wifi_geofence_inout_changed"); + char *app_id = NULL; + int ret = FENCE_ERR_NONE; + + ret = geofence_manager_get_appid_from_geofence(fence_id, &app_id); + if (ret != FENCE_ERR_NONE) { + LOGE("Error getting the app_id for fence id[%d]", fence_id); + return; + } + GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server); + if (app_id == NULL) { + LOGD_GEOFENCE("getting item data failed. fence_id [%d]", fence_id); + return; + } + if (fence_status == GEOFENCE_FENCE_STATE_IN) { + if (item_data->common_info.status != GEOFENCE_FENCE_STATE_IN) { + geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, app_id, fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_IN); + item_data->common_info.status = GEOFENCE_FENCE_STATE_IN; + } + } else if (fence_status == GEOFENCE_FENCE_STATE_OUT) { + if (item_data->common_info.status != GEOFENCE_FENCE_STATE_OUT) { + geofence_dbus_server_send_geofence_inout_changed(geofence_server->geofence_dbus_server, app_id, fence_id, item_data->common_info.access_type, GEOFENCE_EMIT_STATE_OUT); + item_data->common_info.status = GEOFENCE_FENCE_STATE_OUT; + } + } + if (app_id) + free(app_id); +} + +void wifi_device_state_changed(wifi_device_state_e state, void *user_data) +{ + FUNC_ENTRANCE_SERVER + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + g_return_if_fail(geofence_server); + + int fence_id = 0; + geofence_type_e fence_type; + GeofenceItemData *item_data = NULL; + + GList *fence_list = g_list_first(geofence_server->tracking_list); + + for (; fence_list != NULL; fence_list = g_list_next(fence_list)) { + fence_id = GPOINTER_TO_INT(fence_list->data); + item_data = NULL; + item_data = __get_item_by_fence_id(fence_id, geofence_server); + + if (item_data == NULL) + continue; + + fence_type = item_data->common_info.type; + + if (fence_type != GEOFENCE_TYPE_WIFI) + continue; + + if (state == WIFI_DEVICE_STATE_DEACTIVATED) { + LOGD_GEOFENCE("Emitted to fence_id [%d] GEOFENCE_FENCE_STATE_OUT", fence_id); + emit_wifi_geofence_inout_changed(geofence_server, fence_id, GEOFENCE_FENCE_STATE_OUT); + } + } + + LOGD_GEOFENCE("exit"); +} + +void __geofence_check_wifi_matched_bssid(wifi_connection_state_e state, char *bssid, void *user_data) +{ + LOGD_GEOFENCE("Comparing the matching bssids"); + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + GList *tracking_fences = g_list_first(geofence_server->tracking_list); + int tracking_fence_id = 0; + bssid_info_s *bssid_info = NULL; + geofence_type_e type = -1; + + /*Wifi tracking list has to be traversed here*/ + while (tracking_fences) { + tracking_fence_id = GPOINTER_TO_INT(tracking_fences->data); + tracking_fences = g_list_next(tracking_fences); + if (FENCE_ERR_NONE != geofence_manager_get_geofence_type(tracking_fence_id, &type)) { + LOGD_GEOFENCE("Error fetching the fence type/ fence does not exist"); + return; + } + if (type == GEOFENCE_TYPE_WIFI) { + if (FENCE_ERR_NONE != geofence_manager_get_bssid_info(tracking_fence_id, &bssid_info)) { + LOGD_GEOFENCE("Error fetching the fence bssid info/ fence does not exist"); + return; + } + if (!(g_ascii_strcasecmp(bssid_info->bssid, bssid))) { + LOGI_GEOFENCE("Matched wifi fence: fence_id = %d, bssid = %s", tracking_fence_id, bssid_info->bssid); + if (state == WIFI_CONNECTION_STATE_CONNECTED) { + emit_wifi_geofence_inout_changed(geofence_server, tracking_fence_id, GEOFENCE_FENCE_STATE_IN); + } else if (state == WIFI_CONNECTION_STATE_DISCONNECTED) { + emit_wifi_geofence_inout_changed(geofence_server, tracking_fence_id, GEOFENCE_FENCE_STATE_OUT); + } + break; /*Because there cannot be two APs connected at the same time*/ + } + } + } + +} + +void wifi_conn_state_changed(wifi_connection_state_e state, wifi_ap_h ap, void *user_data) +{ + LOGD_GEOFENCE("wifi_conn_state_changed"); + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + char *ap_bssid = NULL; + int rv = 0; + g_return_if_fail(geofence_server); + rv = wifi_ap_get_bssid(ap, &ap_bssid); + + if (rv != WIFI_ERROR_NONE) { + LOGD_GEOFENCE("Failed to get the bssid"); + return; + } + + if (state == WIFI_CONNECTION_STATE_CONNECTED) { + LOGD_GEOFENCE("Wifi connected to [%s].", ap_bssid); + __geofence_check_wifi_matched_bssid(state, ap_bssid, user_data); + } else if (state == WIFI_CONNECTION_STATE_DISCONNECTED) { + LOGD_GEOFENCE("Wifi disconnected with [%s].", ap_bssid); + __geofence_check_wifi_matched_bssid(state, ap_bssid, user_data); + } +} diff --git a/geofence-server/src/geofence_server_wifi.h b/geofence-server/src/geofence_server_wifi.h new file mode 100644 index 0000000..78f9df7 --- /dev/null +++ b/geofence-server/src/geofence_server_wifi.h @@ -0,0 +1,66 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file geofence_server_wifi.h + * @brief Geofence server wifi related APIs + * + */ + +#ifndef GEOFENCE_MANAGER_WIFI_H_ +#define GEOFENCE_MANAGER_WIFI_H_ + +/** +* @brief Handles the wifi scan results +* @param[in] ap_list The ap list. +* @param[in] user_data The user data. +* @see None. +*/ +void handle_scan_result(GList *ap_list, void *user_data); + +/** +* @brief Indicated the wifi scan results +* @param[in] ap_list The ap list. +* @param[in] user_data The user data. +* @see None. +*/ +void wifi_indication(GList *ap_list, void *user_data); + +/** + * @brief Gets Wifi enabled status + * @Param[in] data The status of the wifi connection + * @return gboolean + * @retval false if disabled and true if enabled + * @see None. + */ +gboolean geofence_get_enable_wifi_state(gpointer data); + +/** + * @brief Handles Wifi connection status change + * @Param[in] state The status of the wifi connection + * @Param[in] ap The wifi ap + * @Param[in] user_data The user data + * @see None. + */ +void wifi_conn_state_changed(wifi_connection_state_e state, wifi_ap_h ap, void *user_data); + +/** + * @brief Wifi device status change + * @Param[in] state The status of the wifi device + * @Param[in] user_data The user data + * @see None. + */ +void wifi_device_state_changed(wifi_device_state_e state, void *user_data); +#endif /* GEOFENCE_MANAGER_WIFI_H_ */ diff --git a/geofence-server/src/server.c b/geofence-server/src/server.c new file mode 100644 index 0000000..c21fc4b --- /dev/null +++ b/geofence-server/src/server.c @@ -0,0 +1,344 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 <stdio.h> +#include <signal.h> +#include <stdlib.h> + +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <fcntl.h> +#include <errno.h> +#include <pthread.h> +#include <string.h> + +#include "server.h" +#include "geofence_server_data_types.h" +#include "debug_util.h" + +#ifdef _TIZEN_PUBLIC_ +#include <msg.h> +#include <msg_transport.h> +#include <pmapi.h> +#endif + +#include <vconf.h> +#include <vconf-keys.h> +#include <dlog.h> + +#include <glib.h> +#include <glib-object.h> +#if !GLIB_CHECK_VERSION(2, 31, 0) +#include <glib/gthread.h> +#endif +/* for scan AP +#include <lbs_wps.h>*/ +#include <network-cm-intf.h> +#include <network-pm-intf.h> +#include <network-wifi-intf.h> +#include <network-pm-config.h> +/* for telephony*/ +#if USE_TAPI +#include <tapi_common.h> +#include <TapiUtility.h> +#endif +#include "geofence_server_private.h" +/* for bluetooth-geofence*/ +#include <bluetooth.h> +#include <wifi.h> +#include <locations.h> + +#define TIZEN_ENGINEER_MODE +#ifdef TIZEN_ENGINEER_MODE +#include "geofence_server_log.h" +#endif +#ifdef __LOCAL_TEST__ +#include <vconf.h> +#include <vconf-keys.h> +#endif +geofence_callbacks g_fence_update_cb; +void *g_fence_user_data; + +#if USE_TAPI +typedef struct { + TapiHandle *tapi_handle; +} geofence_server_t; + +geofence_server_t *g_geofence_server = NULL; + +static geofence_server_t *__initialize_geofence_data(void) +{ + g_geofence_server = (geofence_server_t *)malloc(sizeof(geofence_server_t)); + if (g_geofence_server == NULL) { + LOGI_GEOFENCE("Failed to alloc g_geofence_server"); + return NULL; + } + memset(g_geofence_server, 0x00, sizeof(geofence_server_t)); + + return g_geofence_server; +} +static void __deinitialize_geofence_data(void) +{ + if (g_geofence_server != NULL) { + free(g_geofence_server); + g_geofence_server = NULL; + } +} +#endif + +static void __geofence_network_evt_cb(net_event_info_t *event_cb, void *user_data) +{ + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + g_return_if_fail(geofence_server); + + LOGD_GEOFENCE("==CM Event callback==, Event[%d]", event_cb->Event); + + if (g_fence_update_cb.network_evt_cb) { + LOGD_GEOFENCE("geofence_network_evt_cb"); + g_fence_update_cb.network_evt_cb(event_cb, user_data); + } +} + +static void __geofence_bt_adapter_state_changed_cb(int result, bt_adapter_state_e adapter_state, void *user_data) +{ + FUNC_ENTRANCE_SERVER + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + g_return_if_fail(geofence_server); + + LOGD_GEOFENCE("bt adapter changed callback, StateChanging[%d]", result); + if (adapter_state == BT_ADAPTER_DISABLED) { + LOGD_GEOFENCE("BT_ADAPTER_DISABLED"); + if (g_fence_update_cb.bt_apater_disable_cb) { + LOGD_GEOFENCE("bt_apater_disable_cb"); + g_fence_update_cb.bt_apater_disable_cb(FALSE, user_data); + } + } else if (adapter_state == BT_ADAPTER_ENABLED) { + LOGD_GEOFENCE("BT_ADAPTER_DISABLED"); + if (g_fence_update_cb.bt_apater_disable_cb) { + LOGD_GEOFENCE("bt_apater_enable_cb"); + g_fence_update_cb.bt_apater_disable_cb(TRUE, user_data); + } + } + LOGD_GEOFENCE("exit"); +} + +static void __geofence_bt_device_connection_state_changed_cb(bool connected, bt_device_connection_info_s *conn_info, void *user_data) +{ + FUNC_ENTRANCE_SERVER + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + g_return_if_fail(geofence_server); + g_return_if_fail(conn_info); + + if (g_fence_update_cb.bt_conn_state_changed_cb) { + LOGD_GEOFENCE("bt_conn_state_changed_cb"); + g_fence_update_cb.bt_conn_state_changed_cb(connected, conn_info, user_data); + } + LOGD_GEOFENCE("exit"); +} + +static void __geofence_bt_adapter_device_discovery_state_changed_cb(int result, bt_adapter_device_discovery_state_e discovery_state, bt_adapter_device_discovery_info_s *discovery_info, void *user_data) +{ + FUNC_ENTRANCE_SERVER + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + g_return_if_fail(geofence_server); + + if (g_fence_update_cb.bt_discovery_cb) { + LOGD_GEOFENCE("bt_conn_state_changed_cb"); + g_fence_update_cb.bt_discovery_cb(result, discovery_state, discovery_info, user_data); + } + LOGD_GEOFENCE("exit"); +} + +static void __geofence_wifi_device_connection_state_changed_cb(wifi_connection_state_e state, wifi_ap_h ap, void *user_data) +{ + LOGD_GEOFENCE("__geofence_wifi_device_connection_state_changed_cb()"); + + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + g_return_if_fail(geofence_server); + + if (g_fence_update_cb.wifi_conn_state_changed_cb) { + LOGD_GEOFENCE("wifi_conn_state_changed_cb"); + g_fence_update_cb.wifi_conn_state_changed_cb(state, ap, user_data); + } +} + +static void __geofence_wifi_device_state_changed_cb(wifi_device_state_e state, void *user_data) +{ + LOGD_GEOFENCE("__geofence_wifi_device_state_changed_cb()"); + + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + g_return_if_fail(geofence_server); + + if (g_fence_update_cb.wifi_device_state_changed_cb) { + LOGD_GEOFENCE("wifi_conn_state_changed_cb"); + g_fence_update_cb.wifi_device_state_changed_cb(state, user_data); + } +} + +static void __geofence_gps_setting_changed_cb(location_method_e method, bool enable, void *user_data) +{ + LOGD_GEOFENCE("__geofence_gps_setting_changed_cb()"); + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + g_return_if_fail(geofence_server); + + if (g_fence_update_cb.gps_setting_changed_cb) { + LOGD_GEOFENCE("GPS setting changed"); + g_fence_update_cb.gps_setting_changed_cb(method, enable, user_data); + } +} + +int _geofence_initialize_geofence_server(GeofenceServer *geofence_server) +{ + FUNC_ENTRANCE_SERVER; + + int ret = 0; + +#if USE_TAPI + geofence_server_t *server = NULL; + + server = __initialize_geofence_data(); + if (server == NULL) + return -1; +#endif + + /*initialize to use bluetooth C-API*/ + ret = bt_initialize(); + if (BT_ERROR_NONE != ret) { + LOGD_GEOFENCE("bt_initialize() failed(%d).", ret); + return -1; + } + + /* register the bluetooth adapter state changed callback*/ + ret = bt_adapter_set_state_changed_cb(__geofence_bt_adapter_state_changed_cb, geofence_server); + if (BT_ERROR_NONE != ret) { + LOGD_GEOFENCE("bt_adapter_set_state_changed_cb() failed(%d).", ret); + bt_deinitialize(); + return -1; + } else { + LOGD_GEOFENCE("bt_adapter_set_state_changed_cb() success.", ret); + } + + /* register the bluetooth device connection state changed callback*/ + ret = bt_device_set_connection_state_changed_cb(__geofence_bt_device_connection_state_changed_cb, geofence_server); + if (BT_ERROR_NONE != ret) { + LOGD_GEOFENCE("bt_device_set_connection_state_changed_cb() failed(%d).", ret); + bt_adapter_unset_state_changed_cb(); + bt_deinitialize(); + return -1; + } else { + LOGD_GEOFENCE("bt_device_set_connection_state_changed_cb() success.", ret); + } + /*register for the discovery state change callback*/ + ret = bt_adapter_set_device_discovery_state_changed_cb(__geofence_bt_adapter_device_discovery_state_changed_cb, (void *)geofence_server); + if (BT_ERROR_NONE != ret) + LOGE_GEOFENCE("Failed to set the callback for discovery"); + + ret = wifi_initialize(); + if (WIFI_ERROR_NONE != ret) { + LOGD_GEOFENCE("wifi_initialize() failed(%d).", ret); + return -1; + } + + if (net_register_client((net_event_cb_t) __geofence_network_evt_cb, geofence_server) != NET_ERR_NONE) { + LOGD_GEOFENCE("net_register_client() failed"); + return -1; + } else { + LOGD_GEOFENCE("net_register_client() succeeded"); + } + + ret = wifi_set_connection_state_changed_cb(__geofence_wifi_device_connection_state_changed_cb, geofence_server); + if (WIFI_ERROR_NONE != ret) { + LOGD_GEOFENCE("wifi_set_connection_state_changed_cb() failed(%d).", ret); + wifi_deinitialize(); + return -1; + } else { + LOGD_GEOFENCE("wifi_set_connection_state_changed_cb() success.", ret); + } + + ret = wifi_set_device_state_changed_cb(__geofence_wifi_device_state_changed_cb, geofence_server); + if (WIFI_ERROR_NONE != ret) { + LOGD_GEOFENCE("wifi_set_device_state_changed_cb() failed(%d).", ret); + wifi_deinitialize(); + return -1; + } else { + LOGD_GEOFENCE("wifi_set_device_state_changed_cb() success.", ret); + } + /*Set the callback for location*/ + ret = location_manager_set_setting_changed_cb(LOCATIONS_METHOD_GPS, __geofence_gps_setting_changed_cb, geofence_server); + if (LOCATIONS_ERROR_NONE != ret) { + LOGD_GEOFENCE("location_manager_set_setting_changed_cb() failed(%d)", ret); + return -1; + } + + return 0; +} + +int _geofence_deinitialize_geofence_server() +{ + /* to denit geofence engine staff...*/ + + /* unset bluetooth device connection state changed state event callback*/ + if (bt_device_unset_connection_state_changed_cb() != BT_ERROR_NONE) { + LOGD_GEOFENCE("bt_device_unset_connection_state_changed_cb() failed.\n"); + } else { + LOGD_GEOFENCE("bt_device_unset_connection_state_changed_cb() success.\n"); + } + + /* unset bluetooth adapter changed state event callback*/ + if (bt_adapter_unset_state_changed_cb() != BT_ERROR_NONE) { + LOGD_GEOFENCE("bt_adapter_unset_state_changed_cb() failed.\n"); + } else { + LOGD_GEOFENCE("bt_adapter_unset_state_changed_cb() success.\n"); + } + + /* deinit bluetooth api*/ + if (bt_deinitialize() != BT_ERROR_NONE) { + LOGD_GEOFENCE("bt_deinitialize() failed.\n"); + } else { + LOGD_GEOFENCE("bt_deinitialize() success.\n"); + } + + /*unset the callbacks related to wifi*/ + if (wifi_unset_connection_state_changed_cb() != WIFI_ERROR_NONE) { + LOGD_GEOFENCE("wifi_unset_connection_state_changed_cb() failed.\n"); + } else { + LOGD_GEOFENCE("wifi_unset_connection_state_changed_cb() success.\n"); + } + + if (wifi_deinitialize() != WIFI_ERROR_NONE) { + LOGD_GEOFENCE("wifi_deinitialize() failed.\n"); + } else { + LOGD_GEOFENCE("wifi_deinitialize() success.\n"); + } + + if (location_manager_unset_setting_changed_cb(LOCATIONS_METHOD_GPS) != LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("GPS unsetting failed\n"); + } else { + LOGD_GEOFENCE("GPS unsetting success\n"); + } +#if USE_TAPI + __deinitialize_geofence_data(); +#endif + + return 0; +} + +int _geofence_register_update_callbacks(geofence_callbacks *geofence_callback, void *user_data) +{ + g_fence_update_cb = *geofence_callback; + g_fence_user_data = user_data; + return 0; +} diff --git a/geofence-server/src/server.h b/geofence-server/src/server.h new file mode 100644 index 0000000..c5de762 --- /dev/null +++ b/geofence-server/src/server.h @@ -0,0 +1,62 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +/** + * @file server.h + * @brief Server related APIs + * + */ + +#ifndef _GEOFENCE_SERVER_H_ +#define _GEOFENCE_SERVER_H_ + +#include "geofence_server.h" +#include "geofence_server_private.h" +#include <bluetooth.h> +#include <wifi.h> + +typedef enum { + GEOFENCE_STATE_AVAILABLE, + GEOFENCE_STATE_OUT_OF_SERVICE, + GEOFENCE_STATE_TEMPORARILY_UNAVAILABLE, +} geofence_state_t; + +/** +* @brief Initilazes geofence server +* @return int +* @retval 0 if success +* @see none +*/ +int _geofence_initialize_geofence_server(GeofenceServer *geofence_server); + +/** +* @brief Deinitilazes geofence server +* @return int +* @retval 0 if success +* @see none +*/ +int _geofence_deinitialize_geofence_server(); + +/** +* @brief Registers the update callbacks +* @param[in] geofence_callback The callbacks +* @param[in] user_data The user data +* @return int +* @retval 0 if success +* @see none +*/ +int _geofence_register_update_callbacks(geofence_callbacks *geofence_callback, void *user_data); + +#endif /* _GEOFENCE_SERVER_H_ */ diff --git a/location-geofence-server.manifest b/location-geofence-server.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/location-geofence-server.manifest @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_" /> + </request> +</manifest> diff --git a/module/CMakeLists.txt b/module/CMakeLists.txt new file mode 100644 index 0000000..6059ff9 --- /dev/null +++ b/module/CMakeLists.txt @@ -0,0 +1,22 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.0) +PROJECT(geofence) + +SET(geofence_module ${PROJECT_NAME}) + +SET(CLIENT_SRCS_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +SET(module_pkgs_LDFLAGS "${module_pkgs_LDFLAGS} -ldl") +SET(MODULE_EXTRA_CFLAGS "${MODULE_EXTRA_CFLAGS} -D_GNU_SOURCE") + +INCLUDE_DIRECTORIES(${SERVER_SRCS_DIR}/include) + +SET (CLIENT_SRCS + module_geofence_server.c + module_internal.c +) + +ADD_LIBRARY(${geofence_module} SHARED ${CLIENT_SRCS}) +TARGET_LINK_LIBRARIES(${geofence_module} ${module_pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${geofence_module} PROPERTIES VERSION ${FULLVER} SOVERSION ${MAJORVER} CLEAN_DIRECT_OUTPUT 1) +SET_TARGET_PROPERTIES(${geofence_module} PROPERTIES COMPILE_FLAGS ${MODULE_EXTRA_CFLAGS}) + +INSTALL(TARGETS ${geofence_module} DESTINATION ${LIB_DIR}/geofence/module) diff --git a/module/log.h b/module/log.h new file mode 100644 index 0000000..dd3832d --- /dev/null +++ b/module/log.h @@ -0,0 +1,44 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __MOD_LOG_H__ +#define __MOD_LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define GEOFENCE_SERVER_DLOG + +#include <dlog.h> +#define TAG_GEOFENCE_MOD "GEOFENCE_MOD" + +#define LOGD_GEOFENCE(fmt, args...) LOG(LOG_DEBUG, TAG_GEOFENCE_MOD, fmt, ##args) +#define LOGI_GEOFENCE(fmt, args...) LOG(LOG_INFO, TAG_GEOFENCE_MOD, fmt, ##args) +#define LOGW_GEOFENCE(fmt, args...) LOG(LOG_WARN, TAG_GEOFENCE_MOD, fmt, ##args) +#define LOGE_GEOFENCE(fmt, args...) LOG(LOG_ERROR, TAG_GEOFENCE_SERVER_MOD, fmt, ##args) + +#define MOD_LOGD(fmt, args...) LOG(LOG_DEBUG, TAG_GEOFENCE_MOD, fmt, ##args) +#define MOD_LOGW(fmt, args...) LOG(LOG_WARN, TAG_GEOFENCE_MOD, fmt, ##args) +#define MOD_LOGI(fmt, args...) LOG(LOG_INFO, TAG_GEOFENCE_MOD, fmt, ##args) +#define MOD_LOGE(fmt, args...) LOG(LOG_ERROR, TAG_GEOFENCE_MOD, fmt, ##args) +#define MOD_SECLOG(fmt, args...) SECURE_LOG(LOG_DEBUG, TAG_GEOFENCE_MOD, fmt, ##args) + +#define FUNC_ENTRANCE_SERVER LOGD_GEOFENCE(">>> Entered!!"); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/module/module_geofence_server.c b/module/module_geofence_server.c new file mode 100644 index 0000000..9336895 --- /dev/null +++ b/module/module_geofence_server.c @@ -0,0 +1,548 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib.h> +#include <gmodule.h> +#include <stdio.h> +#include <stdlib.h> +#include <app_manager.h> +#include <dlfcn.h> +#include <geofence_client.h> +#include "module_internal.h" +#include "log.h" + +#define GEOFENCE_MODULE_API __attribute__((visibility("default"))) G_MODULE_EXPORT +#define MYPLACES_APP_ID "org.tizen.myplace" + +/** + * This enumeration descript the geofence type. + * Should be SYNC to geofence_mananger_data_types.h + */ +typedef enum { + GEOFENCE_SERVER_TYPE_INVALID = 0, + GEOFENCE_SERVER_TYPE_GEOPOINT = 1, + GEOFENCE_SERVER_TYPE_WIFI, + GEOFENCE_SERVER_TYPE_BT +} geofence_server_type_e; + +/** + * Enumerations of the geofence bssid type. + */ +typedef enum { + GEOFENCE_BSSID_TYPE_WIFI = 0, + GEOFENCE_BSSID_TYPE_BT +} geofence_bssid_type_e; + +#define GEOFENCE_STATE_UNCERTAIN 0 +#define GEOFENCE_STATE_IN 1 +#define GEOFENCE_STATE_OUT 2 +#define _WLAN_BSSID_LEN 18/* bssid 17 + "null"*/ + +typedef struct { + int enabled; + int geofence_type; + gint geofence_id; + gdouble latitude; + gdouble longitude; + gint radius; + char bssid[_WLAN_BSSID_LEN]; +} GeofenceData; + +typedef struct { + geofence_client_dbus_h geofence_client; + GList *geofence_list; + GeofenceModCB geofence_cb; + GeofenceModEventCB geofence_event_cb; + gpointer userdata; +} GeofenceManagerData; + +#define GEOFENCE_SERVER_SERVICE_NAME "org.tizen.lbs.Providers.GeofenceServer" +#define GEOFENCE_SERVER_SERVICE_PATH "/org/tizen/lbs/Providers/GeofenceServer" + +GEOFENCE_MODULE_API int add_geopoint(void *handle, int place_id, double latitude, double longitude, int radius, const char *address, int *fence_id) +{ + MOD_LOGD("add_geopoint"); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + int geofence_id = -1; + + geofence_id = geo_client_add_geofence(geofence_manager->geofence_client, place_id, GEOFENCE_TYPE_GEOPOINT, latitude, longitude, radius, address, "", ""); + if (geofence_id == -1) + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + *fence_id = geofence_id; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int add_bssid(void *handle, int place_id, const char *bssid, const char *ssid, geofence_type_e type, int *fence_id) +{ + MOD_LOGD("add_bssid"); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + int geofence_id = -1; + + geofence_id = geo_client_add_geofence(geofence_manager->geofence_client, place_id, type, -1, -1, -1, "", bssid, ssid); + if (geofence_id == -1) + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + *fence_id = geofence_id; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int add_place(void *handle, const char *place_name, int *place_id) +{ + MOD_LOGD("add_place"); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + int placeid = -1; + + placeid = geo_client_add_place(geofence_manager->geofence_client, place_name); + if (placeid == -1) + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + *place_id = placeid; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int update_place(void *handle, int place_id, const char *place_name) +{ + MOD_LOGD("update_place"); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + int ret = geo_client_update_place(geofence_manager->geofence_client, place_id, place_name); + if (ret != GEOFENCE_CLIENT_ERROR_NONE) + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int remove_geofence(void *handle, int fence_id) +{ + MOD_LOGD("remove_geofence"); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + int ret = geo_client_delete_geofence(geofence_manager->geofence_client, fence_id); + if (ret != GEOFENCE_CLIENT_ERROR_NONE) + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int remove_place(void *handle, int place_id) +{ + MOD_LOGD("remove_place"); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + int ret = geo_client_delete_place(geofence_manager->geofence_client, place_id); + if (ret != GEOFENCE_CLIENT_ERROR_NONE) + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int enable_service(void *handle, int fence_id, bool enable) +{ + MOD_LOGD("enable_service"); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + int ret = geo_client_enable_service(geofence_manager->geofence_client, fence_id, enable); + if (ret != GEOFENCE_CLIENT_ERROR_NONE) + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +static void geofence_callback(GVariant *param, void *user_data) +{ + g_return_if_fail(user_data); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)user_data; + int fence_id, access_type, state; + char *app_id = NULL; + pid_t pid = 0; + char *appid_from_app = NULL; + g_variant_get(param, "(siii)", &app_id, &fence_id, &access_type, &state); + + MOD_LOGI("Getting the app id"); + pid = getpid(); + int ret = app_manager_get_app_id(pid, &appid_from_app); + if (ret != APP_MANAGER_ERROR_NONE) { + MOD_LOGE("Fail to get app_id from module_geofence_server. Err[%d]", ret); + return; + } + MOD_LOGI("APP ID from server : %s", app_id); + MOD_LOGI("APP ID from app manager : %s", appid_from_app); + + if (access_type == ACCESS_TYPE_PRIVATE) { + if (!(g_strcmp0(appid_from_app, app_id))) { /*Sending the alert only the app-id matches in case of private fence*/ + if (geofence_manager->geofence_cb) + geofence_manager->geofence_cb(fence_id, state, geofence_manager->userdata); + } + } else { + if (geofence_manager->geofence_cb) /*Here filteration is done in the manager as public fences cannot be restricted/filtered.*/ + geofence_manager->geofence_cb(fence_id, state, geofence_manager->userdata); + } + if (appid_from_app) + g_free(appid_from_app); + if (app_id) + g_free(app_id); +} + +static void geofence_event_callback(GVariant *param, void *user_data) +{ + g_return_if_fail(user_data); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)user_data; + int place_id, fence_id, access_type, error, state; + char *app_id = NULL; + pid_t pid = 0; + char *appid = NULL; + g_variant_get(param, "(iiisii)", &place_id, &fence_id, &access_type, &app_id, &error, &state); + + MOD_LOGI("Getting the app id"); + pid = getpid(); + int ret = app_manager_get_app_id(pid, &appid); + if (ret != APP_MANAGER_ERROR_NONE) { + MOD_LOGE("Fail to get app_id from module_geofence_server. Err[%d]", ret); + return; + } + MOD_LOGI("APP ID from server : %s", app_id); + MOD_LOGI("APP ID from app manager : %s", appid); + MOD_LOGI("Fence_ID: %d, Error: %d, State: %d", fence_id, error, state); + + if (access_type == ACCESS_TYPE_PRIVATE) { + if (!(g_strcmp0(appid, app_id))) { + if (geofence_manager->geofence_event_cb) + geofence_manager->geofence_event_cb(place_id, fence_id, error, state, geofence_manager->userdata); + } + } else if (access_type == ACCESS_TYPE_PUBLIC) { + if (!g_strcmp0(app_id, MYPLACES_APP_ID) || !g_strcmp0(appid, app_id)) { + if (geofence_manager->geofence_event_cb) + geofence_manager->geofence_event_cb(place_id, fence_id, error, state, geofence_manager->userdata); + } + } else { + if (!(g_strcmp0(appid, app_id))) { + if (geofence_manager->geofence_event_cb) + geofence_manager->geofence_event_cb(place_id, fence_id, error, state, geofence_manager->userdata); + } + } + if (appid) + g_free(appid); + if (app_id) + g_free(app_id); +} + +GEOFENCE_MODULE_API int get_place_name(void *handle, int place_id, char **place_name) +{ + GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(place_name, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + int error_code = GEOFENCE_MANAGER_ERROR_NONE; + int ret = geo_client_get_place_name(geofence_manager->geofence_client, place_id, place_name, &error_code); + if (ret != GEOFENCE_CLIENT_ERROR_NONE) + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + return error_code; +} + +GEOFENCE_MODULE_API int get_list(void *handle, int place_id, int *fence_amount, int **fence_ids, struct geofence_params_s **params) +{ + GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(fence_amount, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(fence_ids, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(params, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + if (!geofence_manager) { + *fence_amount = 0; + return GEOFENCE_MANAGER_ERROR_NONE; + } + int index = 0; + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + gchar *key; + GVariant *value; + int fence_cnt = 0; + int error_code = GEOFENCE_MANAGER_ERROR_NONE; + + /*Call the geofence_client api here....*/ + geo_client_get_list(geofence_manager->geofence_client, place_id, &iter, &fence_cnt, &error_code); + if (error_code != GEOFENCE_MANAGER_ERROR_NONE) + return error_code; + + *fence_amount = fence_cnt; + MOD_LOGI("Total fence count : %d", *fence_amount); + int *fence_id_array = (int *) g_slice_alloc0(sizeof(int)*fence_cnt); + geofence_params_s *p = (geofence_params_s *)g_slice_alloc0(sizeof(geofence_params_s)*fence_cnt); + + if (iter == NULL) { + MOD_LOGI("Iterator is null"); + } + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) { + if (!g_strcmp0(key, "fence_id")) { + fence_id_array[index] = + g_variant_get_int32(value); + } else if (!g_strcmp0(key, "place_id")) { + p[index].place_id = g_variant_get_int32(value); + } else if (!g_strcmp0(key, "geofence_type")) { + p[index].type = g_variant_get_int32(value); + } else if (!g_strcmp0(key, "latitude")) { + p[index].latitude = g_variant_get_double(value); + } else if (!g_strcmp0(key, "longitude")) { + p[index].longitude = g_variant_get_double(value); + } else if (!g_strcmp0(key, "radius")) { + p[index].radius = g_variant_get_int32(value); + } else if (!g_strcmp0(key, "address")) { + g_strlcpy(p[index].address, g_variant_get_string(value, NULL), _ADDRESS_LEN); + } else if (!g_strcmp0(key, "bssid")) { + g_strlcpy(p[index].bssid, g_variant_get_string(value, NULL), _WLAN_BSSID_LEN); + } else if (!g_strcmp0(key, "ssid")) { + g_strlcpy(p[index].ssid, g_variant_get_string(value, NULL), _WLAN_BSSID_LEN); + } + } + MOD_LOGI("Fence_id: %d, Place_id: %d, Type: %d, lat: %f, lon: %f, rad: %d, address: %s, bssid: %s, ssid: %s", fence_id_array[index], p[index].place_id, p[index].type, p[index].latitude, p[index].longitude, p[index].radius, p[index].address, p[index].bssid, p[index].ssid); + index++; + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + *params = (struct geofence_params_s *) p; + *fence_ids = fence_id_array; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int get_place_list(void *handle, int *place_amount, int **place_ids, struct place_params_s **params) +{ + GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(place_amount, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(place_ids, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(params, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + if (!geofence_manager) { + *place_amount = 0; + return GEOFENCE_MANAGER_ERROR_NONE; + } + int index = 0; + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + gchar *key; + GVariant *value; + int place_cnt = 0; + int error_code = -1; + + /*Call the geofence_client api here....*/ + geo_client_get_place_list(geofence_manager->geofence_client, &iter, &place_cnt, &error_code); + if (error_code != GEOFENCE_MANAGER_ERROR_NONE) + return error_code; + + *place_amount = place_cnt; + MOD_LOGI("Total place count : %d", *place_amount); + int *place_id_array = (int *)g_slice_alloc0(sizeof(int)*place_cnt); + place_params_s *p = (place_params_s *)g_slice_alloc0(sizeof(place_params_s)*place_cnt); + + if (iter == NULL) + MOD_LOGI("Iterator is null"); + + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) { + if (!g_strcmp0(key, "place_id")) { + place_id_array[index] = g_variant_get_int32(value); + } else if (!g_strcmp0(key, "place_name")) { + g_strlcpy(p[index].place_name, g_variant_get_string(value, NULL), _PLACE_NAME_LEN); + } + } + MOD_LOGI("place_id: %d, place_name: %s", place_id_array[index], p[index].place_name); + index++; + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + *params = (struct place_params_s *) p; + *place_ids = place_id_array; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_data) +{ + if (!g_strcmp0(sig, "GeofenceInout")) { + MOD_LOGD("GeofenceInoutChanged"); + geofence_callback(param, user_data); + } else if (!g_strcmp0(sig, "GeofenceEvent")) { + MOD_LOGD("GeofenceEventInvoked"); + geofence_event_callback(param, user_data); + } else { + MOD_LOGD("Invalid signal[%s]", sig); + } +} + +GEOFENCE_MODULE_API int start_geofence(void *handle, int fence_id) +{ + MOD_LOGD("start_geofence"); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + int ret = GEOFENCE_MANAGER_ERROR_NONE; + + MOD_LOGD("geofence-server(%x)", geofence_manager); + + ret = geo_client_start_geofence(geofence_manager->geofence_client, fence_id); + if (ret != GEOFENCE_MANAGER_ERROR_NONE) { + MOD_LOGE("Fail to start geofence_client_h. Error[%d]", ret); + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + } + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int stop_geofence(void *handle, int fence_id) +{ + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + MOD_LOGD("geofence_manager->geofence_cb : %x", geofence_manager->geofence_cb); + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(geofence_manager->geofence_client, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + int ret = GEOFENCE_CLIENT_ERROR_NONE; + + ret = geo_client_stop_geofence(geofence_manager->geofence_client, fence_id); + if (ret != GEOFENCE_MANAGER_ERROR_NONE) { + MOD_LOGE("Fail to stop. Error[%d]", ret); + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + } + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int create(void *handle, GeofenceModCB geofence_cb, + GeofenceModEventCB geofence_event_cb, void *userdata) +{ + GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(geofence_cb, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + /* create connnection */ + int ret = GEOFENCE_MANAGER_ERROR_NONE; + + geofence_manager->geofence_cb = geofence_cb; + geofence_manager->geofence_event_cb = geofence_event_cb; + geofence_manager->userdata = userdata; + + ret = geo_client_create(&(geofence_manager->geofence_client)); + if (ret != GEOFENCE_CLIENT_ERROR_NONE || !geofence_manager->geofence_client) { + MOD_LOGE("Fail to create geofence_client_dbus_h. Error[%d]", ret); + return GEOFENCE_MANAGER_ERROR_EXCEPTION; + } + + ret = geo_client_start(GEOFENCE_SERVER_SERVICE_NAME, GEOFENCE_SERVER_SERVICE_PATH, geofence_manager->geofence_client, on_signal_callback, on_signal_callback, geofence_manager); + if (ret != GEOFENCE_CLIENT_ERROR_NONE) { + if (ret == GEOFENCE_CLIENT_ACCESS_DENIED) { + MOD_LOGE("Access denied[%d]", ret); + return GEOFENCE_CLIENT_ACCESS_DENIED; + } + MOD_LOGE("Fail to start geofence_client_dbus_h. Error[%d]", ret); + geo_client_destroy(geofence_manager->geofence_client); + geofence_manager->geofence_client = NULL; + + return GEOFENCE_CLIENT_ERROR_UNKNOWN; + } + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API int destroy(void *handle) +{ + MOD_LOGD("destroy"); + + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle; + g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION); + g_return_val_if_fail(geofence_manager->geofence_client, GEOFENCE_MANAGER_ERROR_EXCEPTION); + + int ret = GEOFENCE_MANAGER_ERROR_NONE; + + ret = geo_client_stop(geofence_manager->geofence_client); + if (ret != GEOFENCE_CLIENT_ERROR_NONE) { + MOD_LOGE("Fail to stop. Error[%d]", ret); + geo_client_destroy(geofence_manager->geofence_client); + geofence_manager->geofence_client = NULL; + return GEOFENCE_CLIENT_ERROR_UNKNOWN; + } + + ret = geo_client_destroy(geofence_manager->geofence_client); + if (ret != GEOFENCE_CLIENT_ERROR_NONE) { + MOD_LOGE("Fail to destroy. Error[%d]", ret); + return GEOFENCE_CLIENT_ERROR_UNKNOWN; + } + geofence_manager->geofence_client = NULL; + geofence_manager->geofence_cb = NULL; + geofence_manager->geofence_event_cb = NULL; + geofence_manager->userdata = NULL; + + return GEOFENCE_MANAGER_ERROR_NONE; +} + +GEOFENCE_MODULE_API gpointer init(GeofenceModOps *ops) +{ + MOD_LOGD("init"); + + g_return_val_if_fail(ops, NULL); + ops->create = create; + ops->destroy = destroy; + ops->enable_service = enable_service; + ops->start_geofence = start_geofence; + ops->stop_geofence = stop_geofence; + ops->add_geopoint = add_geopoint; + ops->add_bssid = add_bssid; + ops->add_place = add_place; + ops->update_place = update_place; + ops->remove_geofence = remove_geofence; + ops->remove_place = remove_place; + ops->get_place_name = get_place_name; + ops->get_list = get_list; + ops->get_place_list = get_place_list; + + GeofenceManagerData *geofence_manager = g_new0(GeofenceManagerData, 1); + g_return_val_if_fail(geofence_manager, NULL); + + geofence_manager->geofence_cb = NULL; + geofence_manager->geofence_event_cb = NULL; + geofence_manager->userdata = NULL; + + return (gpointer) geofence_manager; +} + +GEOFENCE_MODULE_API void shutdown(gpointer handle) +{ + MOD_LOGD("shutdown"); + g_return_if_fail(handle); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle; + + if (geofence_manager->geofence_client) { + geo_client_stop(geofence_manager->geofence_client); + geo_client_destroy(geofence_manager->geofence_client); + geofence_manager->geofence_client = NULL; + } + + geofence_manager->geofence_cb = NULL; + + g_free(geofence_manager); + geofence_manager = NULL; +} diff --git a/module/module_internal.c b/module/module_internal.c new file mode 100644 index 0000000..a278ff4 --- /dev/null +++ b/module/module_internal.c @@ -0,0 +1,143 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 <stdbool.h> +#include "module_internal.h" +#include "log.h" + +/** Length of bssid */ +#define WLAN_BSSID_LEN 18 +#define APP_ID_LEN 64 +#define FENCE_NAME_LEN 64 + +#define GEOFENCE_DEFAULT_RADIUS 200 /* Default 200 m */ + +/* +* TODO: after transiting geofence-server package on CMake build following structures must be elliminated, +* because they are copying existing structures in a sub-folder geofence-server +*/ + +/** + * This enumeration describe the cell geofence in and out status. + */ +typedef enum { + CELL_UNKNOWN = -1, + CELL_OUT = 0, + CELL_IN = 1 +} cell_status_e; + +/** + * This enumeration descript the geofence fence state. + */ +typedef enum { + GEOFENCE_FENCE_STATE_UNCERTAIN = -1, + GEOFENCE_FENCE_STATE_OUT = 0, + GEOFENCE_FENCE_STATE_IN = 1, +} geofence_fence_state_e; + +/** + * The geofence common information structure + */ +typedef struct { + int fence_id; + geofence_fence_state_e status; + geofence_manager_type_e type; /* Geocoordinate/WIFI/CurrentLocation/Bluetooth */ + char fence_name[FENCE_NAME_LEN]; + char appid[APP_ID_LEN]; + int smart_assist_id; + gboolean cell_db; + time_t last_update; +} fence_common_info_s; + +/** + *The geocoordinate structure + */ +typedef struct { + double latitude; + double longitude; + double radius; +} geocoordinate_info_s; + +/** + *The wifi info structure + */ +typedef struct { + char bssid[WLAN_BSSID_LEN]; +} wifi_info_s; + +/** + *The bluetooth info structure + */ +typedef struct { + char bssid[WLAN_BSSID_LEN]; + gboolean enabled; /* bluetooth callback receive or not */ +} bssid_info_s; + +typedef enum { + GEOFENCE_CLIENT_STATUS_NONE, + GEOFENCE_CLIENT_STATUS_FIRST_LOCATION, + GEOFENCE_CLIENT_STATUS_START, + GEOFENCE_CLIENT_STATUS_RUNNING +} geofence_client_status_e; + +/** + *The GeofenceItemData structure + */ +typedef struct { + double distance; +#ifdef __WIFI_DB_SUPPORTED__ + int wifi_db_set; + wifi_status_e wifi_direction; + wifi_status_e priv_wifi_direction; +#endif + geofence_client_status_e client_status; + cell_status_e cell_status; + fence_common_info_s common_info; + void *priv; /* Save (latitude, longitude and radius) or AP list */ + + bool is_wifi_status_in; + bool is_bt_status_in; +} GeofenceItemData; + +static gint __find_custom_item_by_fence_id(gconstpointer data, gconstpointer compare_with) +{ + g_return_val_if_fail(data, 1); + g_return_val_if_fail(compare_with, -1); + int ret = -1; + + GeofenceItemData *item_data = (GeofenceItemData *) data; + int *fence_id = (int *) compare_with; + if (item_data->common_info.fence_id == *fence_id) { + ret = 0; + } + + return ret; +} + +GeofenceItemData *__get_item_by_fence_id(gint fence_id, GList *geofence_list) +{ + g_return_val_if_fail(geofence_list, NULL); + + geofence_list = g_list_first(geofence_list); + GList *found_item = NULL; + found_item = g_list_find_custom(geofence_list, &fence_id, __find_custom_item_by_fence_id); + if (found_item == NULL || found_item->data == NULL) { + MOD_LOGD("item_data is not found. found_item[%d]", found_item); + return NULL; + } + + /*Get the item from the list and return it*/ + return (GeofenceItemData *) found_item->data; +} diff --git a/module/module_internal.h b/module/module_internal.h new file mode 100644 index 0000000..9fda603 --- /dev/null +++ b/module/module_internal.h @@ -0,0 +1,102 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 __GEOFENCE_MANAGER_PRIVATE_ITEM_DATA_H__ +#define __GEOFENCE_MANAGER_PRIVATE_ITEM_DATA_H__ + +#include <glib.h> +#include <tizen_type.h> +#include <tizen_error.h> +#include "geofence-module.h" + +typedef enum { + GEOFENCE_MANAGER_ERROR_NONE = TIZEN_ERROR_NONE, /**< Success */ + GEOFENCE_MANAGER_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + GEOFENCE_MANAGER_ERROR_PERMISSION_DENIED = TIZEN_ERROR_PERMISSION_DENIED, /**< Permission denied */ + GEOFENCE_MANAGER_ERROR_NOT_SUPPORTED = TIZEN_ERROR_NOT_SUPPORTED, /**< Not supported */ + GEOFENCE_MANAGER_ERROR_NOT_INITIALIZED = TIZEN_ERROR_GEOFENCE_MANAGER | 0x01, /**< Geofence Manager is not initialized */ + GEOFENCE_MANAGER_ERROR_INVALID_ID = TIZEN_ERROR_GEOFENCE_MANAGER | 0x02, /**< Geofence ID is not exist */ + GEOFENCE_MANAGER_ERROR_EXCEPTION = TIZEN_ERROR_GEOFENCE_MANAGER | 0x03, /**< exception is occured */ + GEOFENCE_MANAGER_ERROR_ALREADY_STARTED = TIZEN_ERROR_GEOFENCE_MANAGER | 0x04, /**< Geofence is already started */ + GEOFENCE_MANAGER_ERROR_TOO_MANY_GEOFENCE = TIZEN_ERROR_GEOFENCE_MANAGER | 0x05, /**< Too many Geofence */ + GEOFENCE_MANAGER_ERROR_IPC = TIZEN_ERROR_GEOFENCE_MANAGER | 0x06, /**< Error occured in GPS/WIFI/BT */ + GEOFENCE_MANAGER_ERROR_DATABASE = TIZEN_ERROR_GEOFENCE_MANAGER | 0x07, /**< DB error occured in the server side */ + GEOFENCE_MANAGER_ERROR_PLACE_ACCESS_DENIED = TIZEN_ERROR_GEOFENCE_MANAGER | 0x08, /**< Access to specified place is denied */ + GEOFENCE_MANAGER_ERROR_GEOFENCE_ACCESS_DENIED = TIZEN_ERROR_GEOFENCE_MANAGER | 0x09, /**< Access to specified geofence is denied */ +} geofence_manager_error_e; + +typedef enum { + GEOFENCE_MANAGER_TYPE_GEOPOINT = 1, + GEOFENCE_MANAGER_TYPE_WIFI, + GEOFENCE_MANAGER_TYPE_BT, +} geofence_manager_type_e; + +typedef enum { + GEOFENCE_MANAGER_ACCESS_TYPE_PRIVATE = 1, + GEOFENCE_MANAGER_ACCESS_TYPE_PUBLIC, + GEOFENCE_MANAGER_ACCESS_TYPE_UNKNOWN, +} geofence_manager_access_type_e; + +typedef enum { + GEOFENCE_STATE_UNCERTAIN = 0, + GEOFENCE_STATE_IN, + GEOFENCE_STATE_OUT, +} geofence_state_e; + +#define _WLAN_BSSID_LEN 18 +#define _PLACE_NAME_LEN 64 +#define _ADDRESS_LEN 64 +#define _APP_ID_LEN 64 + +typedef struct { + geofence_manager_type_e type; + double latitude; + double longitude; + int radius; + char address[_ADDRESS_LEN]; + char bssid[_WLAN_BSSID_LEN]; + char ssid[_WLAN_BSSID_LEN]; + int place_id; +} geofence_params_s; + +typedef struct { + char place_name[_PLACE_NAME_LEN]; +} place_params_s; + +typedef struct { + geofence_state_e state; + int seconds; +} geofence_status_s; + +/* This can be substituted to GeofenceData*/ +typedef struct _geofence_info_s { + int fence_id; + geofence_params_s param; +} geofence_info_s; + +typedef struct _place_info_s { + int place_id; + place_params_s param; +} place_info_s; + +int geofence_item_data_get_fence_id(gpointer data, int *fence_id); +int geofence_item_data_get_params(gpointer data, geofence_params_s *p); +int geofence_item_data_get_fence_status(gpointer data, geofence_status_s *s); +int add_fence_to_list(int fence_id, const char *fence_name, const double latitude, const double longitude, int radius, const char *bssid, geofence_type_e geofence_type, GList **geofence_list); +void remove_fence_from_list(int fence_id, GList **geofence_list); +void update_fence_state(int fence_id, geofence_state_e state, GList *geofence_list); + +#endif /* __GEOFENCE_MANAGER_PRIVATE_ITEM_DATA_H__ */ diff --git a/packaging/geofence-server.service b/packaging/geofence-server.service new file mode 100644 index 0000000..d294627 --- /dev/null +++ b/packaging/geofence-server.service @@ -0,0 +1,16 @@ +[Unit] +Description=Geofence server daemon +After=tizen-runtime.target +Requires=tizen-runtime.target + +[Service] +#Type=forking +#ExecStart=/etc/rc.d/rc5.d/S91geofence-server +ExecStart=/usr/bin/geofence-server +MemoryLimit=10M +User=system +Group=system +#SmackProcessLabel=location_fw + +[Install] +WantedBy=multi-user.target diff --git a/packaging/geofence-server.spec b/packaging/geofence-server.spec new file mode 100644 index 0000000..9467188 --- /dev/null +++ b/packaging/geofence-server.spec @@ -0,0 +1,117 @@ +Name: geofence-server +Summary: Geofence Server for Tizen +Version: 0.3.9 +Release: 1 +Group: Location/Service +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source1: geofence-server.service + +%if "%{?profile}" == "tv" +ExcludeArch: %{arm} %ix86 x86_64 +%endif + +Requires(post): sqlite +Requires(post): lbs-server +BuildRequires: cmake +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(network) +#BuildRequires: pkgconfig(tapi) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(geofence-dbus) +BuildRequires: pkgconfig(gio-unix-2.0) +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(db-util) +BuildRequires: pkgconfig(alarm-service) +BuildRequires: pkgconfig(deviced) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(vconf-internal-keys) +BuildRequires: pkgconfig(capi-appfw-app-manager) +BuildRequires: pkgconfig(capi-location-manager) +#BuildRequires: pkgconfig(capi-geofence-manager) +#BuildRequires: pkgconfig(capi-telephony-network-info) +BuildRequires: pkgconfig(capi-network-wifi) +BuildRequires: pkgconfig(capi-network-bluetooth) +#BuildRequires: pkgconfig(capi-context-manager) +BuildRequires: pkgconfig(secure-storage) +BuildRequires: pkgconfig(libcore-context-manager) +Requires: sys-assert + +%description +Geofence Server for Tizen + +%package -n location-geofence-server +Summary: Geofence Server for Tizen +Group: Location/Libraries +Requires: %{name} = %{version}-%{release} + +%description -n location-geofence-server +Geofence Server for Tizen + +%package -n geofence-server-devel +Summary: Geofence Server for Tizen (Development) +Group: Location/Development +Requires: %{name} = %{version}-%{release} + +%description -n geofence-server-devel +Geofence Server for Tizen (Development) + +%prep +%setup -q + + +%build +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" + +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} \ + -DLIB_DIR=%{_libdir} -DSYSCONF_DIR=%{_sysconfdir} \ + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +if [ ! -e "$GEOFENCE_SERVER_DB_PATH" ] +then + +# create db +mkdir -p %{buildroot}/opt/dbspace +sqlite3 %{buildroot}/opt/dbspace/.geofence-server.db 'PRAGMA journal_mode = PERSIST; + CREATE TABLE Places ( place_id INTEGER PRIMARY KEY AUTOINCREMENT, access_type INTEGER, place_name TEXT NOT NULL, app_id TEXT NOT NULL); + CREATE TABLE GeoFence ( fence_id INTEGER PRIMARY KEY AUTOINCREMENT, place_id INTEGER, enable INTEGER, app_id TEXT NOT NULL, geofence_type INTEGER, access_type INTEGER, running_status INTEGER, FOREIGN KEY(place_id) REFERENCES Places(place_id) ON DELETE CASCADE); + CREATE TABLE FenceGeocoordinate ( fence_id INTEGER , latitude TEXT NOT NULL, longitude TEXT NOT NULL, radius TEXT NOT NULL, address TEXT, FOREIGN KEY(fence_id) REFERENCES GeoFence(fence_id) ON DELETE CASCADE); + CREATE TABLE FenceGeopointWifi ( fence_id INTEGER, bssid TEXT, ssid TEXT, FOREIGN KEY(fence_id) REFERENCES GeoFence(fence_id) ON DELETE CASCADE); + CREATE TABLE FenceBssid ( fence_id INTEGER, bssid TEXT, ssid TEXT, FOREIGN KEY(fence_id) REFERENCES Geofence(fence_id) ON DELETE CASCADE);' +fi + +%clean +rm -rf %{buildroot} + +%post +GEOFENCE_SERVER_DB_PATH="/opt/dbspace/.geofence-server.db" + +# geofence-server db file +chown system:system /opt/dbspace/.geofence-server.db +chown system:system /opt/dbspace/.geofence-server.db-journal +## Change geofence-server db file permissions +chmod 660 /opt/dbspace/.geofence-server.db +chmod 660 /opt/dbspace/.geofence-server.db-journal + +%postun -p /sbin/ldconfig + +%files +%manifest geofence-server.manifest +%defattr(-,system,system,-) +/usr/bin/geofence-server +/usr/share/dbus-1/system-services/org.tizen.lbs.Providers.GeofenceServer.service +/opt/dbspace/.*.db* +%config %{_sysconfdir}/dbus-1/system.d/geofence-server.conf + +%files -n location-geofence-server +%manifest location-geofence-server.manifest +%{_libdir}/geofence/module/libgeofence.so* |