diff options
author | jomui <jongmun.woo@samsung.com> | 2015-10-15 18:26:02 +0900 |
---|---|---|
committer | jomui <jongmun.woo@samsung.com> | 2015-12-02 11:37:01 +0900 |
commit | 908b0baa42c7d2e2a497d136f38e4849876390de (patch) | |
tree | 7ffc595521f35b2f741825f47f6a9e50c3cac426 | |
parent | 8195f60b212a1ba53765a88d2299af1eb1cb30e8 (diff) | |
download | geofence-server-908b0baa42c7d2e2a497d136f38e4849876390de.tar.gz geofence-server-908b0baa42c7d2e2a497d136f38e4849876390de.tar.bz2 geofence-server-908b0baa42c7d2e2a497d136f38e4849876390de.zip |
1.apply WPS for geofencesubmit/tizen/20151207.113951submit/tizen/20151207.112925submit/tizen/20151204.080736accepted/tizen/wearable/20151207.123926accepted/tizen/tv/20151207.123903accepted/tizen/mobile/20151207.123846
2.add new geofence API for proximity(except BLE)
Signed-off-by: jomui <jongmun.woo@samsung.com>
Change-Id: I38169daa7d5e537bbe9c58abfc0a99a4dce7a21b
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | geofence-server/CMakeLists.txt | 1 | ||||
-rw-r--r-- | geofence-server/include/geofence_server_data_types.h | 24 | ||||
-rw-r--r-- | geofence-server/src/geofence_server.c | 1043 | ||||
-rw-r--r-- | geofence-server/src/geofence_server.h | 12 | ||||
-rw-r--r-- | geofence-server/src/geofence_server_bluetooth.c | 33 | ||||
-rwxr-xr-x | geofence-server/src/geofence_server_db.c | 4 | ||||
-rw-r--r-- | geofence-server/src/geofence_server_internal.c | 10 | ||||
-rw-r--r-- | geofence-server/src/geofence_server_internal.h | 2 | ||||
-rw-r--r-- | geofence-server/src/geofence_server_private.h | 34 | ||||
-rw-r--r-- | geofence-server/src/geofence_server_wifi.c | 65 | ||||
-rw-r--r-- | geofence-server/src/geofence_server_wifi.h | 8 | ||||
-rw-r--r-- | geofence-server/src/server.c | 29 | ||||
-rw-r--r-- | module/module_geofence_server.c | 29 | ||||
-rw-r--r-- | packaging/geofence-server.spec | 35 |
15 files changed, 1087 insertions, 244 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 42e70c4..961bf22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ 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 libtzplatform-config") +SET(server_dp "${common_dp} network vconf vconf-internal-keys capi-system-info 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 libtzplatform-config") SET(module_dp "${common_dp} gmodule-2.0 capi-geofence-manager") # Set required packages diff --git a/geofence-server/CMakeLists.txt b/geofence-server/CMakeLists.txt index 207974b..6d66d70 100644 --- a/geofence-server/CMakeLists.txt +++ b/geofence-server/CMakeLists.txt @@ -8,7 +8,6 @@ AUX_SOURCE_DIRECTORY(src SERVER_SRCS) INCLUDE_DIRECTORIES(src include) -#Process will be launched by systemd. TODO: checking dbus auto activation 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) diff --git a/geofence-server/include/geofence_server_data_types.h b/geofence-server/include/geofence_server_data_types.h index 89e26b3..71339ff 100644 --- a/geofence-server/include/geofence_server_data_types.h +++ b/geofence-server/include/geofence_server_data_types.h @@ -40,7 +40,7 @@ typedef enum { geofence_status_t; /** - * This enumeration descript the geofence fence state. + * This enumeration describe the geofence fence state. */ typedef enum { GEOFENCE_EMIT_STATE_UNCERTAIN = 0, @@ -49,7 +49,7 @@ typedef enum { } geofence_emit_state_e; /** - * This enumeration descript the geofence fence state. + * This enumeration describe the geofence fence state. */ typedef enum { GEOFENCE_FENCE_STATE_UNCERTAIN = -1, @@ -58,7 +58,25 @@ typedef enum { } geofence_fence_state_e; /** - * This enumeration descript the geofence state. + * This enumeration describe the geofence proximity state. + */ +typedef enum { + GEOFENCE_PROXIMITY_UNCERTAIN = 0, + GEOFENCE_PROXIMITY_FAR, + GEOFENCE_PROXIMITY_NEAR, + GEOFENCE_PROXIMITY_IMMEDIATE, +} geofence_proximity_state_e; + +typedef enum { + GEOFENCE_PROXIMITY_PROVIDER_LOCATION = 0, + GEOFENCE_PROXIMITY_PROVIDER_WIFI, + GEOFENCE_PROXIMITY_PROVIDER_BLUETOOTH, + GEOFENCE_PROXIMITY_PROVIDER_BLE, + GEOFENCE_PROXIMITY_PROVIDER_SENSOR, +} geofence_proximity_provider_e; + +/** + * This enumeration describe the geofence state. */ typedef enum { GEOFENCE_DIRECTION_BOTH = 0, diff --git a/geofence-server/src/geofence_server.c b/geofence-server/src/geofence_server.c index 0fac348..7e2da1c 100644 --- a/geofence-server/src/geofence_server.c +++ b/geofence-server/src/geofence_server.c @@ -23,6 +23,8 @@ #include <dd-display.h> #include <vconf.h> #include <vconf-internal-wifi-keys.h> +#include <vconf-internal-dnet-keys.h> +#include <vconf-internal-location-keys.h> #include "geofence_server_data_types.h" #include "geofence_server.h" #include "server.h" @@ -34,29 +36,50 @@ #include "geofence_server_internal.h" #include "geofence_server_bluetooth.h" #include <wifi.h> +#include <network-wifi-intf.h> +#include <system_info.h> #define TIZEN_ENGINEER_MODE #ifdef TIZEN_ENGINEER_MODE #include "geofence_server_log.h" #endif -#define TIME_INTERVAL 5 +#define WPS_ACCURACY_TOLERANCE 100 +#define GPS_TRIGGER_BOUNDARY 1000 #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 GPS_TIMEOUT 60 +#define WPS_TIMEOUT 60 #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 int __gps_alarm_cb(alarm_id_t alarm_id, void *user_data); +static int __wps_alarm_cb(alarm_id_t alarm_id, void *user_data); +static int __gps_timeout_cb(alarm_id_t alarm_id, void *user_data); +static int __wps_timeout_cb(alarm_id_t alarm_id, void *user_data); static void __add_left_fences(gpointer user_data); static void __start_activity_service(GeofenceServer *geofence_server); static void __stop_activity_service(GeofenceServer *geofence_server); +static void __set_interval_for_gps(double min_distance, int min_fence_id, void *user_data); static void __activity_cb(activity_type_e type, const activity_data_h data, double timestamp, activity_error_e error, void *user_data); +static bool __isWifiOn(void); +static bool __isDataConnected(void); + +static bool __is_support_wps() +{ + const char *wps_feature = "http://tizen.org/feature/location.wps"; + bool is_wps_supported = false; + system_info_get_platform_bool(wps_feature, &is_wps_supported); + if (is_wps_supported == true) { + location_manager_is_enabled_method(LOCATIONS_METHOD_WPS, &is_wps_supported); + } + + return is_wps_supported; +} static const char *__convert_wifi_error_to_string(wifi_error_e err_type) { @@ -173,30 +196,30 @@ static int __emit_fence_inout(GeofenceServer *geofence_server, int fence_id, geo } if (state == GEOFENCE_FENCE_STATE_IN) { - LOGD_GEOFENCE("FENCE_IN to be set, current state: %d", - item_data->common_info.status); + /*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; } + LOGD_GEOFENCE("%d : FENCE_IN", fence_id); #ifdef TIZEN_ENGINEER_MODE - GEOFENCE_PRINT_LOG("FENCE_IN") + 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); + /*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; } + LOGD_GEOFENCE("%d : FENCE_OUT", fence_id); #ifdef TIZEN_ENGINEER_MODE - GEOFENCE_PRINT_LOG("FENCE_OUT") + GEOFENCE_PRINT_LOG("FENCE_OUT"); #endif } else { LOGD_GEOFENCE("Fence status [%d]", item_data->common_info.status); @@ -209,60 +232,110 @@ static int __emit_fence_inout(GeofenceServer *geofence_server, int fence_id, geo return ret; } +static int __emit_fence_proximity(GeofenceServer *geofence_server, int fence_id, geofence_proximity_state_e state) +{ + FUNC_ENTRANCE_SERVER; + g_return_val_if_fail(geofence_server, -1); + GeofenceItemData *item_data = __get_item_by_fence_id(fence_id, geofence_server); + if (item_data) { + geofence_dbus_server_send_geofence_proximity_changed(geofence_server->geofence_dbus_server, item_data->common_info.appid, fence_id, item_data->common_info.access_type, state, GEOFENCE_PROXIMITY_PROVIDER_LOCATION); + item_data->common_info.proximity_status = state; + } else { + LOGD_GEOFENCE("Invalid item_data"); + return -1; + } + return 0; +} + +static void __check_proximity_for_fence(double distance, int fence_id, int radius, geofence_proximity_state_e current_state, void *user_data) +{ + FUNC_ENTRANCE_SERVER; + geofence_proximity_state_e state = GEOFENCE_PROXIMITY_UNCERTAIN; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + if (distance <= 50.0) { + state = GEOFENCE_PROXIMITY_IMMEDIATE; + } else if (distance > 50.0 && distance <= 100.0) { + state = GEOFENCE_PROXIMITY_NEAR; + } else if (distance > 100.0 && distance <= radius) { + state = GEOFENCE_PROXIMITY_FAR; + } + if (current_state != state) + LOGD_GEOFENCE("PROXIMITY ALERTING for fence: %d, alert: %d, distance: %f", fence_id, state, distance); + __emit_fence_proximity(geofence_server, fence_id, state); +} + 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); + LOGD_GEOFENCE("FENCE_OUT : based on distance. Distance[%f] for fence id: %d at (%f, %f)", distance, fence_id, latitude, longitude); status = GEOFENCE_FENCE_STATE_OUT; } else { - LOGD_GEOFENCE("FENCE_IN : based on distance. Distance[%f]", distance); + LOGD_GEOFENCE("FENCE_IN : based on distance. Distance[%f] for fence id: %d at (%f, %f)", distance, fence_id, latitude, longitude); status = GEOFENCE_FENCE_STATE_IN; } + /* Alert for the proximity */ + /*if (status == GEOFENCE_FENCE_STATE_IN) {*/ + __check_proximity_for_fence(distance, item_data->common_info.fence_id, geocoordinate_info->radius, item_data->common_info.proximity_status, geofence_server); + /*}*/ + 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 __stop_gps_alarms(void *user_data) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + /*Stop the gps interval alarm if it is running...*/ + if (geofence_server->gps_alarm_id != -1) { + /*LOGI_GEOFENCE("GPS interval timer removed. ID[%d]", geofence_server->gps_alarm_id);*/ + geofence_server->gps_alarm_id = _geofence_remove_alarm(geofence_server->gps_alarm_id); + } + /*Stop the timeout alarm if it is running...*/ + if (geofence_server->gps_timeout_alarm_id != -1) { + /*LOGI_GEOFENCE("Timeout timer removed for gps. ID[%d]", geofence_server->gps_timeout_alarm_id);*/ + geofence_server->gps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->gps_timeout_alarm_id); + } +} + +static void __stop_wps_alarms(void *user_data) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + /*Stop the wps interval alarm if it is running...*/ + if (geofence_server->wps_alarm_id != -1) { + /*LOGI_GEOFENCE("WPS interval timer removed. ID[%d]", geofence_server->wps_alarm_id);*/ + geofence_server->wps_alarm_id = _geofence_remove_alarm(geofence_server->wps_alarm_id); + } + /*Stop the timeout alarm if it is running...*/ + if (geofence_server->wps_timeout_alarm_id != -1) { + /*LOGI_GEOFENCE("Timeout timer removed for wps. ID[%d]", geofence_server->wps_timeout_alarm_id);*/ + geofence_server->wps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->wps_timeout_alarm_id); + } +} + 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"); @@ -279,28 +352,233 @@ static void __check_current_location_cb(double latitude, double longitude, doubl } 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) +static int __start_wps_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_wps_manager == NULL) { + ret = location_manager_create(LOCATIONS_METHOD_WPS, &geofence_server->loc_wps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("Fail to create location_manager_h for wps: %d", ret); + return FENCE_ERR_UNKNOWN; + } + } + if (geofence_server->loc_wps_started == FALSE) { + ret = location_manager_set_position_updated_cb(geofence_server->loc_wps_manager, callback, 1, (void *) geofence_server); + if (ret != LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("Fail to set callback for wps. %d", ret); + return FENCE_ERR_UNKNOWN; + } + ret = location_manager_start(geofence_server->loc_wps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("Fail to start. %d", ret); + location_manager_unset_position_updated_cb(geofence_server->loc_wps_manager); + location_manager_destroy(geofence_server->loc_wps_manager); + geofence_server->loc_wps_manager = NULL; + return FENCE_ERR_UNKNOWN; + } + if (geofence_server->wps_timeout_alarm_id == -1) + geofence_server->wps_timeout_alarm_id = _geofence_add_alarm(WPS_TIMEOUT, __wps_timeout_cb, geofence_server); + + geofence_server->loc_wps_started = TRUE; + } else { + LOGD_GEOFENCE("loc_wps_started TRUE"); + } + + return ret; +} + +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_gps_manager == NULL) { + ret = location_manager_create(LOCATIONS_METHOD_GPS, &geofence_server->loc_gps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("Fail to create location_manager_h: %d", ret); + return FENCE_ERR_UNKNOWN; + } + } + + if (geofence_server->loc_gps_started == FALSE) { + ret = location_manager_set_position_updated_cb(geofence_server->loc_gps_manager, callback, geofence_server->gps_trigger_interval, (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_gps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("Fail to start. %d", ret); + location_manager_unset_position_updated_cb(geofence_server->loc_gps_manager); + location_manager_destroy(geofence_server->loc_gps_manager); + geofence_server->loc_gps_manager = NULL; + return FENCE_ERR_UNKNOWN; + } + if (geofence_server->gps_timeout_alarm_id == -1) + geofence_server->gps_timeout_alarm_id = _geofence_add_alarm(GPS_TIMEOUT, __gps_timeout_cb, geofence_server); + + geofence_server->loc_gps_started = TRUE; + } else { + LOGD_GEOFENCE("loc_gps_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_gps_started == TRUE) { + ret = location_manager_stop(geofence_server->loc_gps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + return; + } + geofence_server->loc_gps_started = FALSE; + ret = location_manager_unset_position_updated_cb(geofence_server->loc_gps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + return; + } + } + + if (geofence_server->loc_gps_manager != NULL) { + ret = location_manager_destroy(geofence_server->loc_gps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + return; + } + geofence_server->loc_gps_manager = NULL; + } +} + +static void __stop_wps_positioning(gpointer userdata) +{ + FUNC_ENTRANCE_SERVER; + g_return_if_fail(userdata); + GeofenceServer *geofence_server = (GeofenceServer *) userdata; + int ret = 0; + if (geofence_server->loc_wps_started == TRUE) { + ret = location_manager_stop(geofence_server->loc_wps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + LOGI_GEOFENCE("Unable to stop the wps"); + return; + } + geofence_server->loc_wps_started = FALSE; + ret = location_manager_unset_position_updated_cb(geofence_server->loc_wps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + LOGI_GEOFENCE("Unable to unset the callback"); + return; + } + } + + if (geofence_server->loc_wps_manager != NULL) { + ret = location_manager_destroy(geofence_server->loc_wps_manager); + if (ret != LOCATIONS_ERROR_NONE) { + LOGI_GEOFENCE("Unable to destroy the wps manager"); + return; + } + geofence_server->loc_wps_manager = NULL; + } +} + +static int __get_time_diff(int timestamp) +{ + int current_time = 0; + int timediff = 0; + current_time = (g_get_real_time()/1000000); + timediff = current_time - timestamp; + return timediff; +} + +static void __process_best_location(GeofenceServer *geofence_server) +{ + FUNC_ENTRANCE_SERVER; + + int gpsdiff = 0; + int wpsdiff = 0; + + /* Check if any of the fix is null just return. It doesn't make sense to compare if only one fix is available*/ + if (geofence_server->gps_fix_info == NULL || geofence_server->wps_fix_info == NULL) + return; + + /*Calculate the time difference*/ + gpsdiff = __get_time_diff(geofence_server->gps_fix_info->timestamp); + wpsdiff = __get_time_diff(geofence_server->wps_fix_info->timestamp); + + if (gpsdiff < wpsdiff) { + if ((geofence_server->gps_fix_info->timestamp - geofence_server->wps_fix_info->timestamp) <= 20) { + if (geofence_server->gps_fix_info->accuracy <= geofence_server->wps_fix_info->accuracy) { + LOGI_GEOFENCE("Using GPS fix"); + __check_current_location_cb(geofence_server->gps_fix_info->latitude, geofence_server->gps_fix_info->longitude, 0.0, geofence_server->gps_fix_info->timestamp, geofence_server); + } else { + LOGI_GEOFENCE("Using WPS fix"); + __check_current_location_cb(geofence_server->wps_fix_info->latitude, geofence_server->wps_fix_info->longitude, 0.0, geofence_server->wps_fix_info->timestamp, geofence_server); + } + } else { + LOGI_GEOFENCE("Time diff is more. So using latest GPS fix"); + __check_current_location_cb(geofence_server->gps_fix_info->latitude, geofence_server->gps_fix_info->longitude, 0.0, geofence_server->gps_fix_info->timestamp, geofence_server); + } + } else { + if ((geofence_server->wps_fix_info->timestamp - geofence_server->gps_fix_info->timestamp) <= 20) { + if (geofence_server->wps_fix_info->accuracy <= geofence_server->gps_fix_info->accuracy) { + LOGI_GEOFENCE("Using WPS fix"); + __check_current_location_cb(geofence_server->wps_fix_info->latitude, geofence_server->wps_fix_info->longitude, 0.0, geofence_server->wps_fix_info->timestamp, geofence_server); + } else { + LOGI_GEOFENCE("Using GPS fix"); + __check_current_location_cb(geofence_server->gps_fix_info->latitude, geofence_server->gps_fix_info->longitude, 0.0, geofence_server->gps_fix_info->timestamp, geofence_server); + } + } else { + LOGI_GEOFENCE("Time diff is more. So using latest WPS fix"); + __check_current_location_cb(geofence_server->wps_fix_info->latitude, geofence_server->wps_fix_info->longitude, 0.0, geofence_server->wps_fix_info->timestamp, geofence_server); + } + } +} + +static void __geofence_standalone_gps_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; + int min_fence_id = 0; + double hor_acc = 0.0; + double ver_acc = 0.0; + location_accuracy_level_e level; + int ret = LOCATIONS_ERROR_NONE; + + /* Allocate memory for the location_info structure */ + if (geofence_server->gps_fix_info == NULL) { + geofence_server->gps_fix_info = (location_fix_info_s *)g_malloc(sizeof(location_fix_info_s)); + } + /* Store the location information in the structure for future use*/ + if (geofence_server->gps_fix_info != NULL) { + geofence_server->gps_fix_info->latitude = latitude; + geofence_server->gps_fix_info->longitude = longitude; + ret = location_manager_get_accuracy(geofence_server->loc_gps_manager, &level, &hor_acc, &ver_acc); + if (ret == LOCATIONS_ERROR_NONE) { + LOGI_GEOFENCE("hor_acc:%f, ver_acc:%f", hor_acc, ver_acc); + LOGD_GEOFENCE("*****%f, %f********", latitude, longitude); + geofence_server->gps_fix_info->accuracy = hor_acc; + } + } /*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); + if (geofence_server->gps_timeout_alarm_id != -1) { + /*LOGI_GEOFENCE("Removing the timeout alarm from restart gps");*/ + geofence_server->gps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->gps_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); + distance = _get_min_distance(latitude, longitude, &min_fence_id, geofence_server); if (distance < 200) { LOGD_GEOFENCE("interval: 1 secs"); @@ -344,18 +622,226 @@ static void __geofence_position_changed_cb(double latitude, double longitude, do interval = interval * 5; else if (geofence_server->activity_type == ACTIVITY_RUN) interval = interval * 3; + LOGD_GEOFENCE("Unsetting the position_updated_cb"); + location_manager_unset_position_updated_cb(geofence_server->loc_gps_manager); + location_manager_stop(geofence_server->loc_gps_manager); + geofence_server->loc_gps_started = FALSE; - LOGI_GEOFENCE("Setting the interval of alrm %d s", interval); + LOGI_GEOFENCE("Setting the gps interval of alrm %d s", interval); + if (geofence_server->gps_alarm_id == -1) { + LOGI_GEOFENCE("Setting the gps alarm from the callback"); + geofence_server->gps_alarm_id = _geofence_add_alarm(interval, __gps_alarm_cb, geofence_server); + } +} - 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); +static void __geofence_gps_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 hor_acc = 0.0; + double ver_acc = 0.0; + GeofenceItemData *item_data = NULL; + int min_fence_id = -1; + int min_distance = 0; + location_accuracy_level_e level; + int ret = LOCATIONS_ERROR_NONE; + + /*Remove the timeout callback that might be running when requesting for fix.*/ + if (geofence_server->gps_timeout_alarm_id != -1) { + /*LOGI_GEOFENCE("Removing the timeout alarm from restart gps");*/ + geofence_server->gps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->gps_timeout_alarm_id); + } + + /* Allocate memory for the location_info structure */ + if (geofence_server->gps_fix_info == NULL) { + geofence_server->gps_fix_info = (location_fix_info_s *)g_malloc(sizeof(location_fix_info_s)); + } + + /* Store the location information in the structure for future use*/ + if (geofence_server->gps_fix_info != NULL) { + geofence_server->gps_fix_info->latitude = latitude; + geofence_server->gps_fix_info->longitude = longitude; + geofence_server->gps_fix_info->timestamp = (g_get_real_time()/1000000); /* microsecs->millisecs->secs */ + ret = location_manager_get_accuracy(geofence_server->loc_gps_manager, &level, &hor_acc, &ver_acc); + if (ret == LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("hor_acc:%f, ver_acc:%f", hor_acc, ver_acc); + LOGD_GEOFENCE("*****%f, %f********", latitude, longitude); + geofence_server->gps_fix_info->accuracy = hor_acc; + } + } else { + LOGD_GEOFENCE("Invalid GPS fix data"); + return; + } + geofence_server->last_loc_time = timestamp; + + if (geofence_server->wps_fix_info && __get_time_diff(geofence_server->wps_fix_info->timestamp) <= 20 && geofence_server->gps_fix_info->accuracy <= 50.0) { + LOGI_GEOFENCE("Going for fix comparison from gps fix"); + __process_best_location(geofence_server); + /* Using GPS fix from this point. So stop WPS alarms which trigger next WPS request session */ + __stop_wps_alarms(geofence_server); + } else if (geofence_server->gps_fix_info->accuracy <= 50.0) { + LOGI_GEOFENCE("Emitting from GPS fix directly"); + __check_current_location_cb(latitude, longitude, altitude, timestamp, user_data); + /* Using GPS fix from point. So stop WPS alarms which trigger next WPS request session */ + __stop_wps_alarms(geofence_server); + } + + location_manager_unset_position_updated_cb(geofence_server->loc_gps_manager); + location_manager_stop(geofence_server->loc_gps_manager); + geofence_server->loc_gps_started = FALSE; + + /*Get minimum distance and fence_id of the nearest tracking fence*/ + if (geofence_server->gps_fix_info) { + min_distance = _get_min_distance(geofence_server->gps_fix_info->latitude, geofence_server->gps_fix_info->longitude, &min_fence_id, geofence_server); + item_data = __get_item_by_fence_id(min_fence_id, geofence_server); + if (item_data && geofence_server->loc_gps_started_by_wps == TRUE) { + LOGI_GEOFENCE("******Setting the GPS interval******"); + __set_interval_for_gps(min_distance, min_fence_id, user_data); + } + } +} + +static void __geofence_wps_position_changed_cb(double latitude, double longitude, double altitude, time_t timestamp, void *user_data) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + GeofenceItemData *item_data = NULL; + double min_distance = 0.0; + int min_fence_id = 0; + double hor_acc = 0.0; + double ver_acc = 0.0; + int gps_state = 0; + location_accuracy_level_e level; + int ret = LOCATIONS_ERROR_NONE; + int interval = 0; + + /* Allocate memory for the location_info structure */ + if (geofence_server->wps_fix_info == NULL) { + geofence_server->wps_fix_info = (location_fix_info_s *)g_malloc(sizeof(location_fix_info_s)); + } + /*Remove the timeout callback that might be running when requesting for fix.*/ + if (geofence_server->wps_timeout_alarm_id != -1) { + /*LOGI_GEOFENCE("Removing the timeout alarm from restart gps");*/ + geofence_server->wps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->wps_timeout_alarm_id); + } + /* Store the location information in the structure for future use*/ + if (geofence_server->wps_fix_info != NULL) { + geofence_server->wps_fix_info->latitude = latitude; + geofence_server->wps_fix_info->longitude = longitude; + geofence_server->wps_fix_info->timestamp = (g_get_real_time()/1000000); /* microsecs->millisecs->secs */ + ret = location_manager_get_accuracy(geofence_server->loc_wps_manager, &level, &hor_acc, &ver_acc); + if (ret == LOCATIONS_ERROR_NONE) { + LOGD_GEOFENCE("hor_acc:%f, ver_acc:%f", hor_acc, ver_acc); + LOGD_GEOFENCE("*****%f, %f********", latitude, longitude); + geofence_server->wps_fix_info->accuracy = hor_acc; + } + } else { + LOGD_GEOFENCE("Invalid WPS fix data"); + return; + } + + /*Get minimum distance and fence_id of the nearest tracking fence*/ + min_distance = _get_min_distance(latitude, longitude, &min_fence_id, geofence_server); + LOGI_GEOFENCE("Nearest fence id: %d, distance: %f", min_fence_id, min_distance); + + item_data = __get_item_by_fence_id(min_fence_id, geofence_server); + + if (!item_data) + return;/* There is no valid fence with this fence id. So return*/ + + geocoordinate_info_s *geocoordinate_info = (geocoordinate_info_s *)item_data->priv; + + double interval_dist = (min_distance - geocoordinate_info->radius) - geofence_server->wps_fix_info->accuracy; + LOGI_GEOFENCE("Distance for interval: %f", interval_dist); + if (interval_dist < 15000) { + interval = interval_dist/25; /*secs*/ /*Assuming 90 km/hr of speed - So 25 mtrs covered in 1 sec*/ + } else if (interval_dist >= 15000 && interval_dist < 18000) { + interval = 10 * 60; /* 10 mins */ + } else if (interval_dist >= 18000 && interval_dist < 20000) { + interval = 12 * 60; /* 12 mins */ + } else if (interval_dist >= 20000) { + interval = 15 * 60; /*15 mins*/ + } + if (interval < 15) + interval = 15; /*15 sec */ + + location_manager_unset_position_updated_cb(geofence_server->loc_wps_manager); + location_manager_stop(geofence_server->loc_wps_manager); + geofence_server->loc_wps_started = FALSE; + + LOGI_GEOFENCE("Setting the wps interval of %d secs", interval); + if (geofence_server->wps_alarm_id == -1) { + LOGI_GEOFENCE("Setting the wps alarm from the callback"); + geofence_server->wps_alarm_id = _geofence_add_alarm(interval, __wps_alarm_cb, geofence_server); + } + + /* Get the GPS state here */ + vconf_get_int(VCONFKEY_LOCATION_ENABLED, &gps_state); + if (gps_state == 1) { + if (geofence_server->wps_fix_info->accuracy <= 100.0 && geofence_server->loc_gps_started_by_wps == false) {/*This works when GPS is not running or GPS timeout happens*/ + __check_current_location_cb(latitude, longitude, altitude, timestamp, user_data); + } else if (item_data->common_info.status == GEOFENCE_FENCE_STATE_UNCERTAIN) { + __check_current_location_cb(latitude, longitude, altitude, timestamp, user_data); + } + if (geofence_server->loc_gps_started_by_wps == FALSE && geofence_server->loc_gps_started == FALSE) { + if (min_distance <= (geocoordinate_info->radius + GPS_TRIGGER_BOUNDARY)) { + LOGD_GEOFENCE("Triggering GPS"); + /*LOGD_GEOFENCE("(GPS TRIGGER) GPS started at lat:%f, lon:%f for fence_id:%d at distance:%f", latitude, longitude, min_fence_id, min_distance);*/ + if (FENCE_ERR_NONE == __start_gps_positioning(geofence_server, __geofence_gps_position_changed_cb)) + geofence_server->loc_gps_started_by_wps = true; + else + LOGI_GEOFENCE("Error starting GPS/ GPS is off"); + } + } + } else + __check_current_location_cb(latitude, longitude, altitude, timestamp, user_data); /* Its WPS only mode so no need to worry abt accuracy */ +} + +static void __set_interval_for_gps(double min_distance, int min_fence_id, void *user_data) +{ + FUNC_ENTRANCE_SERVER; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + GeofenceItemData *item_data = NULL; + bool isSwitched = false; + item_data = __get_item_by_fence_id(min_fence_id, geofence_server); + if (item_data && geofence_server->gps_fix_info) { + geocoordinate_info_s *geocoordinate_info = (geocoordinate_info_s *)item_data->priv; + if (geofence_server->gps_trigger_interval == 1 && (min_distance > (geocoordinate_info->radius + 100 + geofence_server->gps_fix_info->accuracy) && min_distance <= (geocoordinate_info->radius + 1000))) { + isSwitched = true; + LOGI_GEOFENCE("Setting the GPS interval as 5 secs"); + geofence_server->gps_trigger_interval = 5; + /*LOGI_GEOFENCE("(GPS SWITCH) GPS changed from 1 to 5 sec at lat:%f, lon:%f for fence_id:%d at distance:%f", geofence_server->gps_fix_info->latitude, geofence_server->gps_fix_info->longitude, min_fence_id, min_distance);*/ + } else if (geofence_server->gps_trigger_interval == 5 && min_distance <= (geocoordinate_info->radius + 100 + geofence_server->gps_fix_info->accuracy)) { + isSwitched = true; + LOGI_GEOFENCE("Setting the GPS interval as 1 secs"); + geofence_server->gps_trigger_interval = 1; + /*LOGI_GEOFENCE("(GPS SWITCH) GPS changed from 5 to 1 sec at lat:%f, lon:%f for fence_id:%d at distance:%f", geofence_server->gps_fix_info->latitude, geofence_server->gps_fix_info->longitude, min_fence_id, min_distance);*/ + } else if (min_distance > (geocoordinate_info->radius + 1000)) { + /* Already stopped. Just that GPS trigger alarm wont be scheduled again */ + /*LOGI_GEOFENCE("(GPS TRIGGER) GPS stopped at lat:%f, lon:%f for fence:%d at distance:%f", geofence_server->gps_fix_info->latitude, geofence_server->gps_fix_info->longitude, min_fence_id, min_distance);*/ + geofence_server->loc_gps_started_by_wps = false; + /*No need of GPS. So stop GPS and start the WPS from here*/ + location_manager_unset_position_updated_cb(geofence_server->loc_gps_manager); + location_manager_stop(geofence_server->loc_gps_manager); + geofence_server->loc_gps_started = FALSE; + __start_wps_positioning(geofence_server, __geofence_wps_position_changed_cb);/* Stopping the GPS here. So start using wps */ + } + if ((geofence_server->loc_gps_started_by_wps == true && isSwitched == true) || geofence_server->gps_trigger_interval > 1) { + LOGI_GEOFENCE("Setting the gps interval of %d secs during wps session", geofence_server->gps_trigger_interval); + if (geofence_server->gps_alarm_id == -1) { + /*Switching the interval for GPS. So stop and start using alarm*/ + location_manager_unset_position_updated_cb(geofence_server->loc_gps_manager); + location_manager_stop(geofence_server->loc_gps_manager); + geofence_server->loc_gps_started = FALSE; + LOGI_GEOFENCE("Setting the gps alarm from the callback"); + geofence_server->gps_alarm_id = _geofence_add_alarm(geofence_server->gps_trigger_interval, __gps_alarm_cb, geofence_server); + } + } } - return; } -static void __check_tracking_list(const char *bssid, void *user_data, - geofence_type_e type) +#if 0 +static void __check_tracking_list(const char *bssid, void *user_data, geofence_type_e type) { FUNC_ENTRANCE_SERVER; GeofenceServer *geofence_server = (GeofenceServer *) user_data; @@ -391,9 +877,11 @@ static void __check_tracking_list(const char *bssid, void *user_data, } } } +#endif 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) { +#if 0 GeofenceServer *geofence_server = (GeofenceServer *) user_data; GeofenceItemData *item_data = NULL; int i; @@ -431,19 +919,40 @@ void bt_adapter_device_discovery_state_cb(int result, bt_adapter_device_discover __check_tracking_list(discovery_info->remote_address, geofence_server, GEOFENCE_TYPE_BT); } } +#endif } +/*static double __getProximityDistance(double rssi_rec) +{ + FUNC_ENTRANCE_SERVER; + double d = 0; + double d0 = 1.0; + double rssi = rssi_rec; + double rssi0 = -40.9117; + double inter = 0; + + inter = (rssi0 - rssi)/(10 * ETA); + d = d0 * math.pow(10, inter); + return d; +}*/ + 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); + /*GList *tracking_fences = g_list_first(geofence_server->tracking_list); GeofenceItemData *item_data = NULL; - int tracking_fence_id = 0; + int tracking_fence_id = 0;*/ + net_wifi_state_t network_state = WIFI_UNKNOWN; + int ret = -1; + int wps_state = 0; + int gps_state = 0; switch (event_cb->Event) { +#if 0 case NET_EVENT_WIFI_SCAN_IND: + LOGD_GEOFENCE("Got WIFI scan Ind : %d\n", event_cb->Error); net_profile_info_t *profiles = NULL; @@ -479,99 +988,172 @@ static void geofence_network_evt_cb(net_event_info_t *event_cb, void *user_data) } } - 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; + break; +#endif + case NET_EVENT_WIFI_POWER_IND: + LOGI_GEOFENCE("WIFI ON/OFF indication"); + vconf_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &wps_state); + vconf_get_int(VCONFKEY_LOCATION_ENABLED, &gps_state); + if (__is_support_wps() == true && geofence_server->running_geopoint_cnt > 0) { + ret = net_get_wifi_state(&network_state, (net_profile_name_t*)event_cb->ProfileName); + if (ret == 0) { + if (network_state == WIFI_OFF) { + LOGI_GEOFENCE("WIFI is OFF"); + /* In Tizen device(Kiran) WPS is not supported if WIFI is switched off */ + __stop_wps_positioning(geofence_server); + __stop_wps_alarms(geofence_server); + if (geofence_server->loc_gps_started_by_wps == true) { + __stop_gps_positioning(geofence_server); /*Stop the gps if it was started by wps*/ + __stop_gps_alarms(geofence_server); + geofence_server->loc_gps_started_by_wps = false; + } + if (gps_state == 1) { + ret = __start_gps_positioning(geofence_server, __geofence_standalone_gps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start standalone gps positioning. Error[%d]", ret); + } + } + } else { + if (__isDataConnected() == true) {/*&& wps_state == 1) {*/ + LOGI_GEOFENCE("DATA CONNECTION IS TRUE"); + if (wps_state == 1) { + LOGI_GEOFENCE("WPS STATE IS 1"); + __stop_gps_positioning(geofence_server); /* Stop the gps which is running as wps can be used*/ + __stop_gps_alarms(geofence_server); + /**** Start the WPS as mobile data is connected and wifi and wps are on *******/ + ret = __start_wps_positioning(geofence_server, __geofence_wps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start wps positioning. Error[%d]", ret); + } + } + } + } + } + } else { + LOGE_GEOFENCE("WPS is not supported"); } - } - - 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; + break; + case NET_EVENT_OPEN_IND: + LOGI_GEOFENCE("Mobile internet connected"); + vconf_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &wps_state); + if (__is_support_wps() == true && geofence_server->running_geopoint_cnt > 0 && wps_state == 1 && __isWifiOn() == true && __isDataConnected() == true) { + /**** Start the WPS as mobile data is connected and wifi is on *******/ + if (geofence_server->loc_gps_started_by_wps == false && geofence_server->loc_gps_started == true) { + __stop_gps_positioning(geofence_server); /*GPS should be stopped only if it is running standalone*/ + __stop_gps_alarms(geofence_server); + } + ret = __start_wps_positioning(geofence_server, __geofence_wps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start wps positioning. Error[%d]", ret); + } } - - ret = location_manager_start(geofence_server->loc_manager); - if (ret != LOCATIONS_ERROR_NONE) { - LOGD_GEOFENCE("Fail to start. %d", ret); - return FENCE_ERR_UNKNOWN; + break; + case NET_EVENT_CLOSE_IND: + LOGI_GEOFENCE("Mobile internet disconnected"); + if (__is_support_wps() == true && geofence_server->running_geopoint_cnt > 0 && geofence_server->loc_wps_started == true) { + /***** Start standalone gps as mobile data is disconnected *****/ + __stop_wps_positioning(geofence_server); + __stop_wps_alarms(geofence_server); + if (geofence_server->loc_gps_started_by_wps == true) { + __stop_gps_positioning(geofence_server); /*Stop the gps if it was started by wps*/ + __stop_gps_alarms(geofence_server); + geofence_server->loc_gps_started_by_wps = false; + } + ret = __start_gps_positioning(geofence_server, __geofence_standalone_gps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start standalone gps positioning. Error[%d]", ret); + } } - if (geofence_server->nps_timeout_alarm_id == -1) - geofence_server->nps_timeout_alarm_id = _geofence_add_alarm(NPS_TIMEOUT, __nps_timeout_cb, geofence_server); + break; + default: + break; + } +} - geofence_server->loc_started = TRUE; +static int __gps_timeout_cb(alarm_id_t alarm_id, void *user_data) +{ + LOGI_GEOFENCE("__gps_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->gps_timeout_alarm_id = -1; /*resetting the alarm id*/ + /*Stop the gps for sometime when there is no fix*/ + __stop_gps_positioning(geofence_server); + if (geofence_server->loc_gps_started_by_wps == FALSE) { + geofence_server->gps_alarm_id = _geofence_add_alarm(1 * 60, __gps_alarm_cb, geofence_server); } else { - LOGD_GEOFENCE("loc_started TRUE"); + geofence_server->loc_gps_started_by_wps = FALSE; } - - return ret; + return 0; } -static void __stop_gps_positioning(gpointer userdata) +static int __gps_alarm_cb(alarm_id_t alarm_id, void *user_data) { - 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; - } + LOGI_GEOFENCE("__gps_alarm_cb"); + g_return_val_if_fail(user_data, -1); + LOGD_GEOFENCE("gps alarm_id : %d", alarm_id); + int ret = FENCE_ERR_NONE; + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + if (geofence_server->gps_alarm_id != -1) { + /*LOGI_GEOFENCE("GPS interval timer removed. ID[%d]", geofence_server->gps_alarm_id);*/ + geofence_server->gps_alarm_id = _geofence_remove_alarm(geofence_server->gps_alarm_id); + geofence_server->gps_alarm_id = -1; } - - if (geofence_server->loc_manager != NULL) { - ret = location_manager_destroy(geofence_server->loc_manager); - if (ret != LOCATIONS_ERROR_NONE) { - return; + if (geofence_server->loc_gps_started_by_wps == true) { + ret = __start_gps_positioning(geofence_server, __geofence_gps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start gps positioning. Error[%d]", ret); + } + } else { + ret = __start_gps_positioning(geofence_server, __geofence_standalone_gps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start standalone gps positioning. Error[%d]", ret); } - geofence_server->loc_manager = NULL; } + return 0; } -static int __nps_timeout_cb(alarm_id_t alarm_id, void *user_data) +static int __wps_timeout_cb(alarm_id_t alarm_id, void *user_data) { - LOGI_GEOFENCE("__nps_timeout_cb"); + LOGI_GEOFENCE("__wps_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); + if (geofence_server->wps_timeout_alarm_id != -1) { + /*LOGI_GEOFENCE("WPS timeout timer removed. ID[%d]", geofence_server->wps_timeout_alarm_id);*/ + geofence_server->wps_timeout_alarm_id = _geofence_remove_alarm(geofence_server->wps_timeout_alarm_id); + geofence_server->wps_timeout_alarm_id = -1; /*resetting the alarm id*/ + } + /*Stop the wps for sometime when there is no fix*/ + __stop_wps_positioning(geofence_server); + geofence_server->wps_alarm_id = _geofence_add_alarm(10, __wps_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) +static int __wps_alarm_cb(alarm_id_t alarm_id, void *user_data) { - LOGI_GEOFENCE("__nps_alarm_cb"); + LOGI_GEOFENCE("__wps_alarm_cb"); g_return_val_if_fail(user_data, -1); - LOGD_GEOFENCE("alarm_id : %d", alarm_id); + LOGD_GEOFENCE("wps alarm_id : %d", alarm_id); + int ret = FENCE_ERR_NONE; GeofenceServer *geofence_server = (GeofenceServer *) user_data; - __start_gps_positioning(geofence_server, __geofence_position_changed_cb); - geofence_server->nps_alarm_id = -1; + if (geofence_server->wps_alarm_id != -1) { + /*LOGI_GEOFENCE("WPS interval timer removed. ID[%d]", geofence_server->wps_alarm_id);*/ + geofence_server->wps_alarm_id = _geofence_remove_alarm(geofence_server->wps_alarm_id); + geofence_server->wps_alarm_id = -1; + } + if (__is_support_wps() == true && __isWifiOn() == true && __isDataConnected() == true) { + ret = __start_wps_positioning(geofence_server, __geofence_wps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start wps positioning. Error[%d]", ret); + } + } else { + ret = __start_gps_positioning(geofence_server, __geofence_standalone_gps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start standalone gps positioning. Error[%d]", ret); + } + } return 0; } @@ -585,57 +1167,87 @@ static void gps_setting_changed_cb(location_method_e method, bool enable, GeofenceItemData *item_data = NULL; int tracking_fence_id = 0; int ret = FENCE_ERR_NONE; + int wps_state = 0; + int gps_state = 0; + /* Get the wps status */ + vconf_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &wps_state); + vconf_get_int(VCONFKEY_LOCATION_ENABLED, &gps_state); + 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); + if (method == LOCATIONS_METHOD_GPS) { + LOGI_GEOFENCE("Stopping the GPS from settings callback"); + __stop_gps_positioning(geofence_server); + __stop_gps_alarms(geofence_server); + + if (wps_state == 0) { /* If data is connected then WPS will be running and alerts will be given through WPS*/ + 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 (method == LOCATIONS_METHOD_WPS) { + LOGI_GEOFENCE("Stopping the WPS from settings callback"); + __stop_wps_positioning(geofence_server); + __stop_wps_alarms(geofence_server); + + if (gps_state == 0) { /* If data is connected then WPS will be running and alerts will be given through WPS*/ + 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); + } + } + return; + } + /* stop the gps if it was started by WPS */ + if (geofence_server->loc_gps_started_by_wps == true) { + __stop_gps_positioning(geofence_server); + __stop_gps_alarms(geofence_server); + geofence_server->loc_gps_started_by_wps = false; /*So that WPS will use GPS if needed in its next fix(wps fix)*/ + } + if (geofence_server->loc_gps_started == false && gps_state == 1) {/*As WPS is turned off standalone GPS should be used for tracking the fence*/ + ret = __start_gps_positioning(geofence_server, __geofence_standalone_gps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start gps positioning. Error[%d]", ret); + return; + } } } + if (geofence_server->loc_gps_started_by_wps == true) { + geofence_server->loc_gps_started_by_wps = false; /*So that WPS will use GPS if needed in its next fix(wps fix)*/ + } } 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 (method == LOCATIONS_METHOD_GPS) { + geofence_server->loc_gps_started_by_wps = false; /* So that WPS will use GPS if needed in its next fix(wps fix) */ + if (wps_state == 0) { /*If wps is on then WPS would be already running. So no need to start GPS*/ + ret = __start_gps_positioning(geofence_server, __geofence_standalone_gps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start gps positioning. Error[%d]", ret); + return; + } + } + } else if (method == LOCATIONS_METHOD_WPS) { + if (__isWifiOn() == true && __isDataConnected() == true) {/* Start WPS positioning */ + ret = __start_wps_positioning(geofence_server, __geofence_wps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start wps positioning. Error[%d]", ret); + return; + } + } + if (geofence_server->loc_wps_started == true) {/* If WPS is successfully started, switch off gps*/ + __stop_gps_positioning(geofence_server); + __stop_gps_alarms(geofence_server); + } } } } -#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) @@ -776,20 +1388,20 @@ static void __stop_geofence_service(gint fence_id, const gchar *app_id, gpointer LOGI_GEOFENCE("Removed geopoint fence: %d from tracking list", fence_id); if (geofence_server->running_geopoint_cnt <= 0) { - /*Stopping GPS...*/ + /*Stopping GPS...WPS*/ __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); + if (geofence_server->gps_fix_info != NULL) { + g_free(geofence_server->gps_fix_info); + geofence_server->gps_fix_info = NULL; } - /*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); + geofence_server->loc_gps_started_by_wps = false; + __stop_wps_positioning(geofence_server); + if (geofence_server->wps_fix_info != NULL) { + g_free(geofence_server->wps_fix_info); + geofence_server->wps_fix_info = NULL; } - + __stop_gps_alarms(geofence_server); + __stop_wps_alarms(geofence_server); __stop_activity_service(geofence_server); } } else if (item_data->common_info.type == GEOFENCE_TYPE_BT) { @@ -802,12 +1414,15 @@ static void __stop_geofence_service(gint fence_id, const gchar *app_id, gpointer } 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 (geofence_server->connectedTrackingWifiFenceId == fence_id) /*It means this fence is connected and it is stopped now*/ + geofence_server->connectedTrackingWifiFenceId = -1; } 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; + item_data->common_info.proximity_status = GEOFENCE_PROXIMITY_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); @@ -823,6 +1438,44 @@ static void __stop_geofence_service(gint fence_id, const gchar *app_id, gpointer __emit_fence_event(geofence_server, place_id, fence_id, access_type, app_id, GEOFENCE_SERVER_ERROR_NONE, GEOFENCE_MANAGE_FENCE_STOPPED); } + +static bool __isWifiOn(void) +{ + int network_state = -1; + vconf_get_int(VCONFKEY_WIFI_STATE, &network_state); + if (network_state == 0) + return false; + return true; +} + +static bool __isDataConnected(void) +{ + bool isDataConnected = false; + int network_state = -1; + int data_state = -1; + + int rv = vconf_get_int(VCONFKEY_NETWORK_WIFI_STATE, &network_state); + if (rv == 0) { + if (network_state == VCONFKEY_NETWORK_WIFI_CONNECTED) { + LOGI_GEOFENCE("USING WIFI DATA"); + isDataConnected = true; + } + } + if (isDataConnected == false) { + rv = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &network_state); + if (rv == 0) { + if (network_state == VCONFKEY_NETWORK_CELLULAR_ON) { + rv = vconf_get_int(VCONFKEY_DNET_STATE, &data_state); + if (data_state == VCONFKEY_DNET_NORMAL_CONNECTED) { + LOGI_GEOFENCE("USING MOBILE DATA"); + isDataConnected = true; + } + } + } + } + return isDataConnected; +} + static int dbus_add_fence_cb(const gchar *app_id, gint place_id, gint geofence_type, @@ -879,6 +1532,7 @@ static int dbus_add_fence_cb(const gchar *app_id, } item_data->common_info.enable = 1; item_data->common_info.status = GEOFENCE_FENCE_STATE_UNCERTAIN; + item_data->common_info.proximity_status = GEOFENCE_PROXIMITY_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); @@ -1440,15 +2094,25 @@ static void dbus_start_geofence_cb(gint fence_id, const gchar *app_id, gpointer 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; + + if (__is_support_wps() == true && __isDataConnected() == true && __isWifiOn() == true) { + ret = __start_wps_positioning(geofence_server, __geofence_wps_position_changed_cb); + if (ret != FENCE_ERR_NONE) { + LOGE_GEOFENCE("Fail to start wps 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; + } + } else { + ret = __start_gps_positioning(geofence_server, __geofence_standalone_gps_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]"); @@ -1536,6 +2200,7 @@ static void dbus_start_geofence_cb(gint fence_id, const gchar *app_id, gpointer 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; + geofence_server->connectedTrackingWifiFenceId = fence_id; } else { status_to_be_emitted = GEOFENCE_FENCE_STATE_OUT; } @@ -1939,11 +2604,18 @@ static void __init_geofencemanager(GeofenceServer *geofence_server) { FUNC_ENTRANCE_SERVER; - geofence_server->loc_started = FALSE; - + geofence_server->loc_gps_started_by_wps = false; + geofence_server->loc_gps_started = false; + geofence_server->loc_wps_started = false; + geofence_server->connectedTrackingWifiFenceId = -1; + geofence_server->gps_fix_info = NULL; + geofence_server->wps_fix_info = NULL; + geofence_server->gps_trigger_interval = 1; /* 1 sec by default*/ geofence_server->timer_id = -1; - geofence_server->nps_alarm_id = -1; - geofence_server->nps_timeout_alarm_id = -1; + geofence_server->gps_alarm_id = -1; + geofence_server->wps_alarm_id = -1; + geofence_server->gps_timeout_alarm_id = -1; + geofence_server->wps_timeout_alarm_id = -1; geofence_server->geofence_list = NULL; geofence_server->tracking_list = NULL; geofence_server->running_geopoint_cnt = 0; @@ -2105,7 +2777,7 @@ static void _glib_log(const gchar *log_domain, GLogLevelFlags log_level, const g int main(int argc, char **argv) { GeofenceServer *geofenceserver = NULL; - + LOGI_GEOFENCE("----------------Starting Server -----------------------------"); /*Callback registrations*/ geofence_callbacks cb; cb.bt_conn_state_changed_cb = bt_conn_state_changed; @@ -2115,11 +2787,10 @@ int main(int argc, char **argv) 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; - + cb.wifi_rssi_level_changed_cb = wifi_rssi_level_changed; #if !GLIB_CHECK_VERSION(2, 35, 0) g_type_init(); #endif - geofenceserver = g_new0(GeofenceServer, 1); if (!geofenceserver) { LOGI_GEOFENCE("GeofenceServer create fail"); diff --git a/geofence-server/src/geofence_server.h b/geofence-server/src/geofence_server.h index a001d51..d85bec2 100644 --- a/geofence-server/src/geofence_server.h +++ b/geofence-server/src/geofence_server.h @@ -99,6 +99,17 @@ typedef void (*geofence_bt_adapter_device_discovery_state_changed_cb)(int result */ typedef void (*geofence_gps_setting_changed_cb)(location_method_e method, bool enable, void *user_data); + +/** + * @brief Called when the RSSI of connected Wi-Fi is changed. + * @since_tizen 2.3 + * @param[in] rssi_level The level of RSSI + * @param[in] user_data The user data passed from the callback registration function + * @see wifi_set_rssi_level_changed_cb() + * @see wifi_unset_rssi_level_changed_cb() + */ +typedef void(*geofence_wifi_rssi_level_changed_cb)(wifi_rssi_level_e rssi_level, void *user_data); + /** * Geofence callback structure. */ @@ -110,6 +121,7 @@ struct geofence_callbacks_s { 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; + geofence_wifi_rssi_level_changed_cb wifi_rssi_level_changed_cb; }; typedef struct geofence_callbacks_s geofence_callbacks; diff --git a/geofence-server/src/geofence_server_bluetooth.c b/geofence-server/src/geofence_server_bluetooth.c index f756c31..7da4b66 100644 --- a/geofence-server/src/geofence_server_bluetooth.c +++ b/geofence-server/src/geofence_server_bluetooth.c @@ -37,6 +37,35 @@ static gboolean __geofence_check_fence_status(int fence_status, GeofenceItemData return ret; } +static void emit_bt_geofence_proximity_changed(GeofenceServer *geofence_server, int fence_id, int fence_proximity_status) +{ + FUNC_ENTRANCE_SERVER + LOGD_GEOFENCE("emit_bt_geofence_proximity_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 (item_data == NULL) { + LOGD_GEOFENCE("getting item data failed. fence_id [%d]", fence_id); + g_free(app_id); + return; + } + + if (fence_proximity_status != item_data->common_info.proximity_status) { + geofence_dbus_server_send_geofence_proximity_changed(geofence_server->geofence_dbus_server, app_id, fence_id, item_data->common_info.access_type, fence_proximity_status, GEOFENCE_PROXIMITY_PROVIDER_BLUETOOTH); + item_data->common_info.proximity_status = fence_proximity_status; + } + + if (app_id) + free(app_id); +} + + static void emit_bt_geofence_inout_changed(GeofenceServer *geofence_server, GeofenceItemData *item_data, int fence_status) { FUNC_ENTRANCE_SERVER @@ -102,16 +131,18 @@ static void __geofence_check_bt_fence_type(gboolean connected, const char *bssid } LOGD_GEOFENCE("bt_info->bssid [%s]", bt_info_from_db->bssid); - if (g_ascii_strcasecmp(bt_info_from_db->bssid, bssid) == 0) { + if (!g_ascii_strcasecmp(bt_info_from_db->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(bt_info_from_db->bssid, "-", ':'), bssid)) { 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); + emit_bt_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_NEAR); } } 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); + emit_bt_geofence_proximity_changed(geofence_server, fence_id, GEOFENCE_PROXIMITY_FAR); } } } diff --git a/geofence-server/src/geofence_server_db.c b/geofence-server/src/geofence_server_db.c index 31ae357..a7c9916 100755 --- a/geofence-server/src/geofence_server_db.c +++ b/geofence-server/src/geofence_server_db.c @@ -714,10 +714,6 @@ int geofence_manager_db_init(void) struct stat stat; int open_flag = 0; - /* - geofence_db_file = g_strdup_printf("%s/%s", GEOFENCE_DB_PATH, GEOFENCE_DB_FILE); - */ - if (__check_db_file()) { LOGW_GEOFENCE("db(%s) file doesn't exist.", GEOFENCE_DB_FILE); open_flag = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| SQLITE_OPEN_FULLMUTEX; diff --git a/geofence-server/src/geofence_server_internal.c b/geofence-server/src/geofence_server_internal.c index d71b96c..51a002e 100644 --- a/geofence-server/src/geofence_server_internal.c +++ b/geofence-server/src/geofence_server_internal.c @@ -49,14 +49,14 @@ GeofenceItemData *__get_item_by_fence_id(gint fence_id, GeofenceServer *geofence return (GeofenceItemData *)found_item->data; } -double _get_min_distance(double cur_lat, double cur_lon, GeofenceServer *geofence_server) +double _get_min_distance(double cur_lat, double cur_lon, int *min_fence_id, 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; + double min_dist = -1.0, distance = 0.0; fence_list = geofence_server->tracking_list; @@ -70,12 +70,14 @@ double _get_min_distance(double cur_lat, double cur_lon, GeofenceServer *geofenc 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) + if ((min_dist == -1.0) || (distance < min_dist)) { min_dist = distance; + *min_fence_id = fence_id; + } } item_list = g_list_next(item_list); } - LOGD_GEOFENCE("Min : %f", min_dist); + LOGD_GEOFENCE("Min fence_id: %d, Min distance : %f", *min_fence_id, min_dist); return min_dist; } diff --git a/geofence-server/src/geofence_server_internal.h b/geofence-server/src/geofence_server_internal.h index df67b63..0db4f8a 100644 --- a/geofence-server/src/geofence_server_internal.h +++ b/geofence-server/src/geofence_server_internal.h @@ -35,7 +35,7 @@ gboolean _check_cell_db_existence (GeofenceServer *geofence_server, gboolean is_ * @return double * @retval The min distance to next geofence */ -double _get_min_distance(double cur_lat, double cur_lon, GeofenceServer *geofence_server); +double _get_min_distance(double cur_lat, double cur_lon, int *min_fence_id, GeofenceServer *geofence_server); /** * @brief Gets the geofence using fence id diff --git a/geofence-server/src/geofence_server_private.h b/geofence-server/src/geofence_server_private.h index f109450..ace6796 100644 --- a/geofence-server/src/geofence_server_private.h +++ b/geofence-server/src/geofence_server_private.h @@ -28,7 +28,7 @@ #include <network-wifi-intf.h> #include "geofence_server_data_types.h" #include "geofence_server.h" - +#include <stdio.h> #include <activity_recognition.h> #ifdef __cplusplus @@ -48,6 +48,7 @@ typedef struct { int fence_id; int enable; geofence_fence_state_e status; + geofence_proximity_state_e proximity_status; geofence_type_e type; /* Geocoordinate/WIFI/CurrentLocation/Bluetooth */ access_type_e access_type; char appid[APP_ID_LEN]; @@ -71,6 +72,17 @@ typedef struct { typedef struct { double latitude; double longitude; + double accuracy; + int timestamp; +} location_fix_info_s; + + +/** + *The geocoordinate structure + */ +typedef struct { + double latitude; + double longitude; double radius; char address[ADDRESS_LEN]; } geocoordinate_info_s; @@ -132,6 +144,9 @@ typedef struct { geofence_dbus_server_h geofence_dbus_server; GList *geofence_list; /* list of geofence list for multi clients */ GList *tracking_list; /* list of geofence ids for tracking */ + location_fix_info_s *gps_fix_info; + location_fix_info_s *wps_fix_info; + int gps_trigger_interval; time_t last_loc_time; time_t last_result_time; int running_geopoint_cnt; @@ -142,13 +157,18 @@ typedef struct { #endif gpointer userdata; /* for Geometry's GPS positioning*/ - location_manager_h loc_manager; - /*FILE *log_file;*/ - int loc_started; + location_manager_h loc_gps_manager; + location_manager_h loc_wps_manager; + FILE *log_file; + int loc_gps_started_by_wps; + int loc_gps_started; + int loc_wps_started; + int connectedTrackingWifiFenceId; 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 gps_alarm_id; /* ID for WPS restart timer source*/ + alarm_id_t gps_timeout_alarm_id; + alarm_id_t wps_timeout_alarm_id; + alarm_id_t wps_alarm_id; alarm_id_t bt_alarm_id; activity_type_e activity_type; diff --git a/geofence-server/src/geofence_server_wifi.c b/geofence-server/src/geofence_server_wifi.c index 9c770e3..31e983d 100644 --- a/geofence-server/src/geofence_server_wifi.c +++ b/geofence-server/src/geofence_server_wifi.c @@ -58,6 +58,67 @@ static void emit_wifi_geofence_inout_changed(GeofenceServer *geofence_server, in free(app_id); } +static void emit_wifi_geofence_proximity_changed(GeofenceServer *geofence_server, int fence_id, int fence_proximity_status) +{ + FUNC_ENTRANCE_SERVER + LOGD_GEOFENCE("emit_wifi_geofence_proximity_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 (item_data == NULL) { + LOGD_GEOFENCE("getting item data failed. fence_id [%d]", fence_id); + g_free(app_id); + return; + } + + if (fence_proximity_status != item_data->common_info.proximity_status) { + geofence_dbus_server_send_geofence_proximity_changed(geofence_server->geofence_dbus_server, app_id, fence_id, item_data->common_info.access_type, fence_proximity_status, GEOFENCE_PROXIMITY_PROVIDER_WIFI); + item_data->common_info.proximity_status = fence_proximity_status; + } + + if (app_id) + free(app_id); +} + +void wifi_rssi_level_changed(wifi_rssi_level_e rssi_level, void *user_data) +{ + FUNC_ENTRANCE_SERVER + GeofenceServer *geofence_server = (GeofenceServer *) user_data; + g_return_if_fail(geofence_server); + wifi_ap_h ap_h; + char *bssid = NULL; + geofence_proximity_state_e state = GEOFENCE_PROXIMITY_UNCERTAIN; + wifi_error_e rv = WIFI_ERROR_NONE; + LOGI_GEOFENCE("running cnt: %d, connected id: %d", geofence_server->running_wifi_cnt, geofence_server->connectedTrackingWifiFenceId); + if (geofence_server->running_wifi_cnt > 0 && geofence_server->connectedTrackingWifiFenceId != -1) { + rv = wifi_get_connected_ap(&ap_h); + if (rv != WIFI_ERROR_NONE) { + LOGE_GEOFENCE("Fail to get the connected AP: Error - %d", rv); + return; + } + rv = wifi_ap_get_bssid(ap_h, &bssid); + if (rv != WIFI_ERROR_NONE) { + LOGI_GEOFENCE("Fail to get the bssid: [%d]", rv); + } else { + /*Emit the proximity alert here using mConnectedFenceId*/ + if (rssi_level == WIFI_RSSI_LEVEL_4) + state = GEOFENCE_PROXIMITY_IMMEDIATE; + else if (rssi_level == WIFI_RSSI_LEVEL_3) + state = GEOFENCE_PROXIMITY_NEAR; + else + state = GEOFENCE_PROXIMITY_FAR; + + emit_wifi_geofence_proximity_changed(geofence_server, geofence_server->connectedTrackingWifiFenceId, state); + } + } +} + void wifi_device_state_changed(wifi_device_state_e state, void *user_data) { FUNC_ENTRANCE_SERVER @@ -114,12 +175,14 @@ void __geofence_check_wifi_matched_bssid(wifi_connection_state_e state, char *bs LOGD_GEOFENCE("Error fetching the fence bssid info/ fence does not exist"); return; } - if (!(g_ascii_strcasecmp(bssid_info->bssid, bssid))) { + if (!g_ascii_strcasecmp(bssid_info->bssid, bssid) || !g_ascii_strcasecmp(g_strdelimit(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); + geofence_server->connectedTrackingWifiFenceId = tracking_fence_id; } else if (state == WIFI_CONNECTION_STATE_DISCONNECTED) { emit_wifi_geofence_inout_changed(geofence_server, tracking_fence_id, GEOFENCE_FENCE_STATE_OUT); + geofence_server->connectedTrackingWifiFenceId = -1; } break; /*Because there cannot be two APs connected at the same time*/ } diff --git a/geofence-server/src/geofence_server_wifi.h b/geofence-server/src/geofence_server_wifi.h index 78f9df7..3932ab7 100644 --- a/geofence-server/src/geofence_server_wifi.h +++ b/geofence-server/src/geofence_server_wifi.h @@ -63,4 +63,12 @@ void wifi_conn_state_changed(wifi_connection_state_e state, wifi_ap_h ap, void * * @see None. */ void wifi_device_state_changed(wifi_device_state_e state, void *user_data); + +/** + * @brief Wifi AP rssi level change + * @Param[in] rssi_level The level of the RSSI received + * @Param[in] user_data The user data + * @see None. +**/ +void wifi_rssi_level_changed(wifi_rssi_level_e rssi_level, void *user_data); #endif /* GEOFENCE_MANAGER_WIFI_H_ */ diff --git a/geofence-server/src/server.c b/geofence-server/src/server.c index e259c0d..d86e853 100644 --- a/geofence-server/src/server.c +++ b/geofence-server/src/server.c @@ -188,6 +188,18 @@ static void __geofence_wifi_device_state_changed_cb(wifi_device_state_e state, v } } +static void __geofence_wifi_rssi_level_changed_cb(wifi_rssi_level_e rssi_level, void *user_data) +{ + LOGD_GEOFENCE("__geofence_wifi_rssi_level_changed_cb()"); + GeofenceServer *geofence_server = (GeofenceServer *)user_data; + g_return_if_fail(geofence_server); + + if (g_fence_update_cb.wifi_rssi_level_changed_cb) { + LOGD_GEOFENCE("wifi_rssi_level_changed_cb"); + g_fence_update_cb.wifi_rssi_level_changed_cb(rssi_level, 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()"); @@ -280,12 +292,29 @@ int _geofence_initialize_geofence_server(GeofenceServer *geofence_server) } else { LOGD_GEOFENCE("wifi_set_device_state_changed_cb() success.", ret); } + + ret = wifi_set_rssi_level_changed_cb(__geofence_wifi_rssi_level_changed_cb, geofence_server); + if (WIFI_ERROR_NONE != ret) { + LOGD_GEOFENCE("wifi_set_rssi_level_changed_cb() failed(%d).", ret); + ret = wifi_deinitialize(); + if (ret != WIFI_ERROR_NONE) + LOGD_GEOFENCE("wifi_deinitialize() failed(%d).", ret); + return -1; + } else { + LOGD_GEOFENCE("wifi_set_rssi_level_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; } + ret = location_manager_set_setting_changed_cb(LOCATIONS_METHOD_WPS, __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; } diff --git a/module/module_geofence_server.c b/module/module_geofence_server.c index b6a30da..3d51053 100644 --- a/module/module_geofence_server.c +++ b/module/module_geofence_server.c @@ -41,6 +41,7 @@ typedef enum { typedef struct { geofence_client_dbus_h geofence_client; GeofenceModCB geofence_cb; + GeofenceModProximityCB geofence_proximity_cb; GeofenceModEventCB geofence_event_cb; gchar *app_id; gpointer userdata; @@ -166,6 +167,26 @@ static void geofence_callback(GVariant *param, void *user_data) } } +static void geofence_proximity_callback(GVariant *param, void *user_data) +{ + g_return_if_fail(user_data); + GeofenceManagerData *geofence_manager = (GeofenceManagerData *)user_data; + int fence_id, access_type, proximity_state, provider; + char *app_id = NULL; + + g_variant_get(param, "(siiii)", &app_id, &fence_id, &access_type, &proximity_state, &provider); + + if (access_type == ACCESS_TYPE_PRIVATE) { + if (!(g_strcmp0(geofence_manager->app_id, app_id))) { /*Sending the alert only the app-id matches in case of private fence*/ + if (geofence_manager->geofence_proximity_cb) + geofence_manager->geofence_proximity_cb(fence_id, proximity_state, provider, geofence_manager->userdata); + } + } else { + if (geofence_manager->geofence_proximity_cb) /*Here filteration is done in the manager as public fences cannot be restricted/filtered.*/ + geofence_manager->geofence_proximity_cb(fence_id, proximity_state, provider, geofence_manager->userdata); + } +} + static void geofence_event_callback(GVariant *param, void *user_data) { g_return_if_fail(user_data); @@ -331,6 +352,9 @@ static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_ if (!g_strcmp0(sig, "GeofenceInout")) { MOD_LOGD("GeofenceInoutChanged"); geofence_callback(param, user_data); + } else if (!g_strcmp0(sig, "GeofenceProximity")) { + MOD_LOGD("GeofenceProximityChanged"); + geofence_proximity_callback(param, user_data); } else if (!g_strcmp0(sig, "GeofenceEvent")) { MOD_LOGD("GeofenceEventInvoked"); geofence_event_callback(param, user_data); @@ -376,8 +400,7 @@ EXPORT_API int stop_geofence(void *handle, int fence_id) return GEOFENCE_MANAGER_ERROR_NONE; } -EXPORT_API int create(void *handle, GeofenceModCB geofence_cb, - GeofenceModEventCB geofence_event_cb, void *userdata) +EXPORT_API int create(void *handle, GeofenceModCB geofence_cb, GeofenceModProximityCB geofence_proximity_cb, GeofenceModEventCB geofence_event_cb, void *userdata) { GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle; g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER); @@ -387,6 +410,7 @@ EXPORT_API int create(void *handle, GeofenceModCB geofence_cb, int ret = GEOFENCE_MANAGER_ERROR_NONE; geofence_manager->geofence_cb = geofence_cb; + geofence_manager->geofence_proximity_cb = geofence_proximity_cb; geofence_manager->geofence_event_cb = geofence_event_cb; geofence_manager->userdata = userdata; @@ -492,6 +516,7 @@ EXPORT_API gpointer init(GeofenceModOps *ops) g_return_val_if_fail(geofence_manager, NULL); geofence_manager->geofence_cb = NULL; + geofence_manager->geofence_proximity_cb = NULL; geofence_manager->geofence_event_cb = NULL; geofence_manager->userdata = NULL; diff --git a/packaging/geofence-server.spec b/packaging/geofence-server.spec index 90d7172..8321894 100644 --- a/packaging/geofence-server.spec +++ b/packaging/geofence-server.spec @@ -1,6 +1,6 @@ Name: geofence-server Summary: Geofence Server for Tizen -Version: 0.4.1 +Version: 0.4.2 Release: 1 Group: Location/Service License: Apache-2.0 @@ -26,14 +26,12 @@ BuildRequires: pkgconfig(alarm-service) BuildRequires: pkgconfig(deviced) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(vconf-internal-keys) +BuildRequires: pkgconfig(capi-system-info) BuildRequires: pkgconfig(capi-appfw-app-manager) BuildRequires: pkgconfig(capi-location-manager) BuildRequires: pkgconfig(capi-network-wifi) BuildRequires: pkgconfig(capi-network-bluetooth) BuildRequires: pkgconfig(libcore-context-manager) -#BuildRequires: pkgconfig(tapi) -#BuildRequires: pkgconfig(capi-telephony-network-info) -#BuildRequires: pkgconfig(capi-context-manager) BuildRequires: pkgconfig(capi-geofence-manager) BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: capi-geofence-manager-plugin-devel @@ -62,42 +60,15 @@ make %{?jobs:-j%jobs} rm -rf %{buildroot} %make_install -#[Workaround] create service file for systemd mkdir -p %{buildroot}%{_unitdir_user}/default.target.wants install -m 644 %{SOURCE1} %{buildroot}%{_unitdir_user}/geofence-server.service ln -s ../geofence-server.service %{buildroot}%{_unitdir_user}/default.target.wants/geofence-server.service -%if 0 -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 -%endif - %clean rm -rf %{buildroot} %post -%if 0 -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 -%endif - %postun -p /sbin/ldconfig %files @@ -106,10 +77,8 @@ chmod 660 /opt/dbspace/.geofence-server.db-journal /usr/bin/geofence-server /usr/share/dbus-1/services/org.tizen.lbs.Providers.GeofenceServer.service -#/opt/dbspace/.*.db* %config %{_sysconfdir}/dbus-1/session.d/geofence-server.conf -#[Workaround] create service file for systemd %{_unitdir_user}/geofence-server.service %{_unitdir_user}/default.target.wants/geofence-server.service |