1 /* Copyright 2014 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
24 #include <app_manager.h>
26 #include <geofence_client.h>
27 #include <geofence_module.h>
30 #define GEOFENCE_SERVER_SERVICE_NAME "org.tizen.lbs.Providers.GeofenceServer"
31 #define GEOFENCE_SERVER_SERVICE_PATH "/org/tizen/lbs/Providers/GeofenceServer"
33 #define MYPLACES_APP_ID "org.tizen.myplace"
36 ACCESS_TYPE_PRIVATE = 1,
42 geofence_client_dbus_h geofence_client;
43 GeofenceModCB geofence_cb;
44 GeofenceModProximityCB geofence_proximity_cb;
45 GeofenceModEventCB geofence_event_cb;
48 } GeofenceManagerData;
50 EXPORT_API int add_geopoint(void *handle, int place_id, double latitude, double longitude, int radius, const char *address, int *fence_id)
52 MOD_LOGD("add_geopoint");
53 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
54 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
55 int new_fence_id = -1;
57 new_fence_id = geo_client_add_geofence(geofence_manager->geofence_client, geofence_manager->app_id, place_id, GEOFENCE_TYPE_GEOPOINT, latitude, longitude, radius, address, "", "");
58 *fence_id = new_fence_id;
60 if (new_fence_id == -1)
61 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
63 return GEOFENCE_MANAGER_ERROR_NONE;
66 EXPORT_API int add_bssid(void *handle, int place_id, const char *bssid, const char *ssid, geofence_type_e type, int *fence_id)
68 MOD_LOGD("add_bssid");
69 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
70 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
71 int new_fence_id = -1;
73 new_fence_id = geo_client_add_geofence(geofence_manager->geofence_client, geofence_manager->app_id, place_id, type, -1, -1, -1, "", bssid, ssid);
74 *fence_id = new_fence_id;
76 if (new_fence_id == -1)
77 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
79 return GEOFENCE_MANAGER_ERROR_NONE;
82 EXPORT_API int add_place(void *handle, const char *place_name, int *place_id)
84 MOD_LOGD("add_place");
85 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
86 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
87 int new_place_id = -1;
89 new_place_id = geo_client_add_place(geofence_manager->geofence_client, geofence_manager->app_id, place_name);
90 *place_id = new_place_id;
92 if (new_place_id == -1)
93 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
95 return GEOFENCE_MANAGER_ERROR_NONE;
98 EXPORT_API int update_place(void *handle, int place_id, const char *place_name)
100 MOD_LOGD("update_place");
101 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
102 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
104 int ret = geo_client_update_place(geofence_manager->geofence_client, geofence_manager->app_id, place_id, place_name);
105 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
106 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
108 return GEOFENCE_MANAGER_ERROR_NONE;
111 EXPORT_API int remove_geofence(void *handle, int fence_id)
113 MOD_LOGD("remove_geofence");
114 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
115 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
117 int ret = geo_client_delete_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id);
118 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
119 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
121 return GEOFENCE_MANAGER_ERROR_NONE;
124 EXPORT_API int remove_place(void *handle, int place_id)
126 MOD_LOGD("remove_place");
127 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
128 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
130 int ret = geo_client_delete_place(geofence_manager->geofence_client, geofence_manager->app_id, place_id);
131 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
132 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
134 return GEOFENCE_MANAGER_ERROR_NONE;
137 EXPORT_API int enable_service(void *handle, int fence_id, bool enable)
139 MOD_LOGD("enable_service");
140 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
141 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
143 int ret = geo_client_enable_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id, enable);
144 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
145 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
147 return GEOFENCE_MANAGER_ERROR_NONE;
150 static void geofence_callback(GVariant *param, void *user_data)
152 g_return_if_fail(user_data);
153 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)user_data;
154 int fence_id, access_type, state;
157 g_variant_get(param, "(siii)", &app_id, &fence_id, &access_type, &state);
159 if (access_type == ACCESS_TYPE_PRIVATE) {
160 if (!(g_strcmp0(geofence_manager->app_id, app_id))) { /*Sending the alert only the app-id matches in case of private fence*/
161 if (geofence_manager->geofence_cb)
162 geofence_manager->geofence_cb(fence_id, state, geofence_manager->userdata);
165 if (geofence_manager->geofence_cb) /*Here filteration is done in the manager as public fences cannot be restricted/filtered.*/
166 geofence_manager->geofence_cb(fence_id, state, geofence_manager->userdata);
170 static void geofence_proximity_callback(GVariant *param, void *user_data)
172 g_return_if_fail(user_data);
173 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)user_data;
174 int fence_id, access_type, proximity_state, provider;
177 g_variant_get(param, "(siiii)", &app_id, &fence_id, &access_type, &proximity_state, &provider);
179 if (access_type == ACCESS_TYPE_PRIVATE) {
180 if (!(g_strcmp0(geofence_manager->app_id, app_id))) { /*Sending the alert only the app-id matches in case of private fence*/
181 if (geofence_manager->geofence_proximity_cb)
182 geofence_manager->geofence_proximity_cb(fence_id, proximity_state, provider, geofence_manager->userdata);
185 if (geofence_manager->geofence_proximity_cb) /*Here filteration is done in the manager as public fences cannot be restricted/filtered.*/
186 geofence_manager->geofence_proximity_cb(fence_id, proximity_state, provider, geofence_manager->userdata);
190 static void geofence_event_callback(GVariant *param, void *user_data)
192 g_return_if_fail(user_data);
193 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)user_data;
194 int place_id, fence_id, access_type, error, state;
197 g_variant_get(param, "(iiisii)", &place_id, &fence_id, &access_type, &app_id, &error, &state);
200 MOD_LOGD("place_id: %d, fence_id: %d, Error: %d, State: %d(0x%x", place_id, fence_id, error, state, state);
201 MOD_LOGD("app_id: %s", geofence_manager->app_id);
203 if (access_type == ACCESS_TYPE_PUBLIC) {
204 if (!g_strcmp0(app_id, MYPLACES_APP_ID) || !g_strcmp0(geofence_manager->app_id, app_id)) {
205 if (geofence_manager->geofence_event_cb)
206 geofence_manager->geofence_event_cb(place_id, fence_id, error, state, geofence_manager->userdata);
209 if (!(g_strcmp0(geofence_manager->app_id, app_id))) {
210 if (geofence_manager->geofence_event_cb)
211 geofence_manager->geofence_event_cb(place_id, fence_id, error, state, geofence_manager->userdata);
216 EXPORT_API int get_place_name(void *handle, int place_id, char **place_name)
218 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
219 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
220 g_return_val_if_fail(place_name, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
222 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
223 int ret = geo_client_get_place_name(geofence_manager->geofence_client, geofence_manager->app_id, place_id, place_name, &error_code);
224 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
225 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
229 EXPORT_API int get_geofences(void *handle, int place_id, int *fence_amount, int **fence_ids, geofence_s **params)
231 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
232 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
233 g_return_val_if_fail(fence_amount, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
234 g_return_val_if_fail(fence_ids, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
235 g_return_val_if_fail(params, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
237 if (!geofence_manager) {
239 return GEOFENCE_MANAGER_ERROR_NONE;
242 GVariantIter *iter = NULL;
243 GVariantIter *iter_row = NULL;
247 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
249 int ret = geo_client_get_geofences(geofence_manager->geofence_client, geofence_manager->app_id, place_id, &iter, &fence_cnt, &error_code);
250 if (error_code != GEOFENCE_MANAGER_ERROR_NONE)
252 else if (ret != GEOFENCE_MANAGER_ERROR_NONE)
253 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
255 *fence_amount = fence_cnt;
256 MOD_LOGD("Total fence count : %d", *fence_amount);
257 int *fence_id_array = (int *) g_slice_alloc0(sizeof(int) * fence_cnt);
258 geofence_s *p = (geofence_s *) g_slice_alloc0(sizeof(geofence_s) * fence_cnt);
261 MOD_LOGI("Iterator is null");
263 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
264 while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
265 if (!g_strcmp0(key, "fence_id")) {
266 fence_id_array[index] =
267 g_variant_get_int32(value);
268 } else if (!g_strcmp0(key, "place_id")) {
269 p[index].place_id = g_variant_get_int32(value);
270 } else if (!g_strcmp0(key, "geofence_type")) {
271 p[index].type = g_variant_get_int32(value);
272 } else if (!g_strcmp0(key, "latitude")) {
273 p[index].latitude = g_variant_get_double(value);
274 } else if (!g_strcmp0(key, "longitude")) {
275 p[index].longitude = g_variant_get_double(value);
276 } else if (!g_strcmp0(key, "radius")) {
277 p[index].radius = g_variant_get_int32(value);
278 } else if (!g_strcmp0(key, "address")) {
279 g_strlcpy(p[index].address, g_variant_get_string(value, NULL), ADDRESS_LEN);
280 } else if (!g_strcmp0(key, "bssid")) {
281 g_strlcpy(p[index].bssid, g_variant_get_string(value, NULL), WLAN_BSSID_LEN);
282 } else if (!g_strcmp0(key, "ssid")) {
283 g_strlcpy(p[index].ssid, g_variant_get_string(value, NULL), WLAN_BSSID_LEN);
286 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);
288 g_variant_iter_free(iter_row);
290 g_variant_iter_free(iter);
291 *params = (geofence_s *) p;
292 *fence_ids = fence_id_array;
294 return GEOFENCE_MANAGER_ERROR_NONE;
297 EXPORT_API int get_places(void *handle, int *place_amount, int **place_ids, place_s **params)
299 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
300 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
301 g_return_val_if_fail(place_amount, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
302 g_return_val_if_fail(place_ids, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
303 g_return_val_if_fail(params, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
305 if (!geofence_manager) {
307 return GEOFENCE_MANAGER_ERROR_NONE;
310 GVariantIter *iter = NULL;
311 GVariantIter *iter_row = NULL;
317 /*Call the geofence_client api here....*/
318 geo_client_get_places(geofence_manager->geofence_client, geofence_manager->app_id, &iter, &place_cnt, &error_code);
319 if (error_code != GEOFENCE_MANAGER_ERROR_NONE)
322 *place_amount = place_cnt;
323 MOD_LOGI("Total place count : %d", *place_amount);
324 int *place_id_array = (int *)g_slice_alloc0(sizeof(int) * place_cnt);
325 place_s *p = (place_s *)g_slice_alloc0(sizeof(place_s) * place_cnt);
328 MOD_LOGI("Iterator is null");
330 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
331 while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
332 if (!g_strcmp0(key, "place_id")) {
333 place_id_array[index] = g_variant_get_int32(value);
334 } else if (!g_strcmp0(key, "place_name")) {
335 g_strlcpy(p[index].place_name, g_variant_get_string(value, NULL), PLACE_NAME_LEN);
338 MOD_LOGI("place_id: %d, place_name: %s", place_id_array[index], p[index].place_name);
340 g_variant_iter_free(iter_row);
342 g_variant_iter_free(iter);
343 *params = (place_s *)p;
345 *place_ids = place_id_array;
347 return GEOFENCE_MANAGER_ERROR_NONE;
350 static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_data)
352 if (!g_strcmp0(sig, "GeofenceInout")) {
353 MOD_LOGD("GeofenceInoutChanged");
354 geofence_callback(param, user_data);
355 } else if (!g_strcmp0(sig, "GeofenceProximity")) {
356 MOD_LOGD("GeofenceProximityChanged");
357 geofence_proximity_callback(param, user_data);
358 } else if (!g_strcmp0(sig, "GeofenceEvent")) {
359 MOD_LOGD("GeofenceEventInvoked");
360 geofence_event_callback(param, user_data);
362 MOD_LOGD("Invalid signal[%s]", sig);
366 EXPORT_API int start_geofence(void *handle, int fence_id)
368 MOD_LOGD("start_geofence");
369 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
370 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION);
372 int ret = GEOFENCE_MANAGER_ERROR_NONE;
374 MOD_LOGD("geofence-server(%x)", geofence_manager);
376 ret = geo_client_start_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id);
377 if (ret != GEOFENCE_MANAGER_ERROR_NONE) {
378 MOD_LOGE("Fail to start geofence_client_h. Error[%d]", ret);
379 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
382 return GEOFENCE_MANAGER_ERROR_NONE;
385 EXPORT_API int stop_geofence(void *handle, int fence_id)
387 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
388 MOD_LOGD("geofence_manager->geofence_cb : %x", geofence_manager->geofence_cb);
389 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
390 g_return_val_if_fail(geofence_manager->geofence_client, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
392 int ret = GEOFENCE_CLIENT_ERROR_NONE;
394 ret = geo_client_stop_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id);
395 if (ret != GEOFENCE_MANAGER_ERROR_NONE) {
396 MOD_LOGE("Fail to stop. Error[%d]", ret);
397 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
400 return GEOFENCE_MANAGER_ERROR_NONE;
403 EXPORT_API int create(void *handle, GeofenceModCB geofence_cb, GeofenceModProximityCB geofence_proximity_cb, GeofenceModEventCB geofence_event_cb, void *userdata)
405 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
406 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
407 g_return_val_if_fail(geofence_cb, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
409 /* create connnection */
410 int ret = GEOFENCE_MANAGER_ERROR_NONE;
412 geofence_manager->geofence_cb = geofence_cb;
413 geofence_manager->geofence_proximity_cb = geofence_proximity_cb;
414 geofence_manager->geofence_event_cb = geofence_event_cb;
415 geofence_manager->userdata = userdata;
417 ret = geo_client_create(&(geofence_manager->geofence_client));
418 if (ret != GEOFENCE_CLIENT_ERROR_NONE || !geofence_manager->geofence_client) {
419 MOD_LOGE("Fail to create geofence_client_dbus_h. Error[%d]", ret);
420 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
423 MOD_LOGD("geofence_manager->geofence_client: %p", geofence_manager->geofence_client);
424 ret = geo_client_start(geofence_manager->geofence_client, on_signal_callback, geofence_manager);
426 if (ret != GEOFENCE_CLIENT_ERROR_NONE) {
427 if (ret == GEOFENCE_CLIENT_ACCESS_DENIED) {
428 MOD_LOGE("Access denied[%d]", ret);
429 return GEOFENCE_CLIENT_ACCESS_DENIED;
431 MOD_LOGE("Fail to start geofence_client_dbus_h. Error[%d]", ret);
432 geo_client_destroy(geofence_manager->geofence_client);
433 geofence_manager->geofence_client = NULL;
435 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
438 return GEOFENCE_MANAGER_ERROR_NONE;
441 EXPORT_API int destroy(void *handle)
445 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
446 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
447 g_return_val_if_fail(geofence_manager->geofence_client, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
449 int ret = GEOFENCE_MANAGER_ERROR_NONE;
451 ret = geo_client_stop(geofence_manager->geofence_client);
452 if (ret != GEOFENCE_CLIENT_ERROR_NONE) {
453 MOD_LOGE("Fail to stop. Error[%d]", ret);
454 geo_client_destroy(geofence_manager->geofence_client);
455 geofence_manager->geofence_client = NULL;
456 return GEOFENCE_MANAGER_ERROR_IPC;
459 ret = geo_client_destroy(geofence_manager->geofence_client);
460 if (ret != GEOFENCE_CLIENT_ERROR_NONE) {
461 MOD_LOGE("Fail to destroy. Error[%d]", ret);
462 return GEOFENCE_MANAGER_ERROR_IPC;
464 geofence_manager->geofence_client = NULL;
465 geofence_manager->geofence_cb = NULL;
466 geofence_manager->geofence_event_cb = NULL;
467 geofence_manager->userdata = NULL;
469 return GEOFENCE_MANAGER_ERROR_NONE;
472 static void __get_caller_app_id(void *handle)
474 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
475 g_return_if_fail(geofence_manager);
477 gchar *app_id = NULL;
482 ret = app_manager_get_app_id(pid, &app_id);
483 if (ret != APP_MANAGER_ERROR_NONE) {
484 MOD_LOGE("Fail to get app_id from module_geofence_server. Err[%d]", ret);
486 MOD_LOGD("app_id: %s", app_id);
487 geofence_manager->app_id = app_id;
491 EXPORT_API gpointer init(GeofenceModOps *ops)
495 g_return_val_if_fail(ops, NULL);
496 ops->create = create;
497 ops->destroy = destroy;
498 ops->enable_service = enable_service;
499 ops->start_geofence = start_geofence;
500 ops->stop_geofence = stop_geofence;
501 ops->add_geopoint = add_geopoint;
502 ops->add_bssid = add_bssid;
503 ops->remove_geofence = remove_geofence;
504 ops->get_geofences = get_geofences;
506 ops->add_place = add_place;
507 ops->update_place = update_place;
508 ops->remove_place = remove_place;
509 ops->get_place_name = get_place_name;
510 ops->get_places = get_places;
512 GeofenceManagerData *geofence_manager = g_new0(GeofenceManagerData, 1);
513 g_return_val_if_fail(geofence_manager, NULL);
515 geofence_manager->geofence_cb = NULL;
516 geofence_manager->geofence_proximity_cb = NULL;
517 geofence_manager->geofence_event_cb = NULL;
518 geofence_manager->userdata = NULL;
520 __get_caller_app_id(geofence_manager);
522 return (gpointer) geofence_manager;
525 EXPORT_API void shutdown(gpointer handle)
527 MOD_LOGD("shutdown");
528 g_return_if_fail(handle);
529 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
531 if (geofence_manager->geofence_client) {
532 geo_client_stop(geofence_manager->geofence_client);
533 geo_client_destroy(geofence_manager->geofence_client);
534 geofence_manager->geofence_client = NULL;
537 geofence_manager->geofence_cb = NULL;
538 g_free(geofence_manager->app_id);
539 g_free(geofence_manager);
540 geofence_manager = NULL;