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;
56 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
58 new_fence_id = geo_client_add_geofence(geofence_manager->geofence_client, geofence_manager->app_id, place_id, GEOFENCE_TYPE_GEOPOINT, latitude, longitude, radius, address, "", "", &error_code);
59 *fence_id = new_fence_id;
61 if (error_code != GEOFENCE_MANAGER_ERROR_NONE)
63 else if (new_fence_id == -1)
64 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
66 return GEOFENCE_MANAGER_ERROR_NONE;
69 EXPORT_API int add_bssid(void *handle, int place_id, const char *bssid, const char *ssid, geofence_type_e type, int *fence_id)
71 MOD_LOGD("add_bssid");
72 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
73 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
74 int new_fence_id = -1;
75 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
77 new_fence_id = geo_client_add_geofence(geofence_manager->geofence_client, geofence_manager->app_id, place_id, type, -1, -1, -1, "", bssid, ssid, &error_code);
78 *fence_id = new_fence_id;
80 if (error_code != GEOFENCE_MANAGER_ERROR_NONE)
82 else if (new_fence_id == -1)
83 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
85 return GEOFENCE_MANAGER_ERROR_NONE;
88 EXPORT_API int add_place(void *handle, const char *place_name, int *place_id)
90 MOD_LOGD("add_place");
91 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
92 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
93 int new_place_id = -1;
94 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
96 new_place_id = geo_client_add_place(geofence_manager->geofence_client, geofence_manager->app_id, place_name, &error_code);
97 *place_id = new_place_id;
99 if (error_code != GEOFENCE_MANAGER_ERROR_NONE)
101 else if (new_place_id == -1)
102 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
104 return GEOFENCE_MANAGER_ERROR_NONE;
107 EXPORT_API int update_place(void *handle, int place_id, const char *place_name)
109 MOD_LOGD("update_place");
110 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
111 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
113 int ret = geo_client_update_place(geofence_manager->geofence_client, geofence_manager->app_id, place_id, place_name);
114 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
117 return GEOFENCE_MANAGER_ERROR_NONE;
120 EXPORT_API int remove_geofence(void *handle, int fence_id)
122 MOD_LOGD("remove_geofence");
123 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
124 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
126 int ret = geo_client_delete_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id);
127 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
130 return GEOFENCE_MANAGER_ERROR_NONE;
133 EXPORT_API int remove_place(void *handle, int place_id)
135 MOD_LOGD("remove_place");
136 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
137 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
139 int ret = geo_client_delete_place(geofence_manager->geofence_client, geofence_manager->app_id, place_id);
140 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
143 return GEOFENCE_MANAGER_ERROR_NONE;
146 EXPORT_API int enable_service(void *handle, int fence_id, bool enable)
148 MOD_LOGD("enable_service");
149 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
150 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
152 int ret = geo_client_enable_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id, enable);
153 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
154 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
156 return GEOFENCE_MANAGER_ERROR_NONE;
159 static void geofence_callback(GVariant *param, void *user_data)
161 g_return_if_fail(user_data);
162 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)user_data;
163 int fence_id, access_type, state;
166 g_variant_get(param, "(siii)", &app_id, &fence_id, &access_type, &state);
168 if (access_type == ACCESS_TYPE_PRIVATE) {
169 if (!(g_strcmp0(geofence_manager->app_id, app_id))) { /*Sending the alert only the app-id matches in case of private fence*/
170 if (geofence_manager->geofence_cb)
171 geofence_manager->geofence_cb(fence_id, state, geofence_manager->userdata);
174 if (geofence_manager->geofence_cb) /*Here filteration is done in the manager as public fences cannot be restricted/filtered.*/
175 geofence_manager->geofence_cb(fence_id, state, geofence_manager->userdata);
179 static void geofence_proximity_callback(GVariant *param, void *user_data)
181 g_return_if_fail(user_data);
182 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)user_data;
183 int fence_id, access_type, proximity_state, provider;
186 g_variant_get(param, "(siiii)", &app_id, &fence_id, &access_type, &proximity_state, &provider);
188 if (access_type == ACCESS_TYPE_PRIVATE) {
189 if (!(g_strcmp0(geofence_manager->app_id, app_id))) { /*Sending the alert only the app-id matches in case of private fence*/
190 if (geofence_manager->geofence_proximity_cb)
191 geofence_manager->geofence_proximity_cb(fence_id, proximity_state, provider, geofence_manager->userdata);
194 if (geofence_manager->geofence_proximity_cb) /*Here filteration is done in the manager as public fences cannot be restricted/filtered.*/
195 geofence_manager->geofence_proximity_cb(fence_id, proximity_state, provider, geofence_manager->userdata);
199 static void geofence_event_callback(GVariant *param, void *user_data)
201 g_return_if_fail(user_data);
202 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)user_data;
203 int place_id, fence_id, access_type, error, state;
206 g_variant_get(param, "(iiisii)", &place_id, &fence_id, &access_type, &app_id, &error, &state);
209 MOD_LOGD("place_id: %d, fence_id: %d, Error: %d, State: %d(0x%x", place_id, fence_id, error, state, state);
210 MOD_LOGD("app_id: %s", geofence_manager->app_id);
212 if (access_type == ACCESS_TYPE_PUBLIC) {
213 if (!g_strcmp0(app_id, MYPLACES_APP_ID) || !g_strcmp0(geofence_manager->app_id, app_id)) {
214 if (geofence_manager->geofence_event_cb)
215 geofence_manager->geofence_event_cb(place_id, fence_id, error, state, geofence_manager->userdata);
218 if (!(g_strcmp0(geofence_manager->app_id, app_id))) {
219 if (geofence_manager->geofence_event_cb)
220 geofence_manager->geofence_event_cb(place_id, fence_id, error, state, geofence_manager->userdata);
225 EXPORT_API int get_place_name(void *handle, int place_id, char **place_name)
227 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
228 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
229 g_return_val_if_fail(place_name, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
231 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
232 int ret = geo_client_get_place_name(geofence_manager->geofence_client, geofence_manager->app_id, place_id, place_name, &error_code);
233 if (ret != GEOFENCE_CLIENT_ERROR_NONE)
238 EXPORT_API int get_geofences(void *handle, int place_id, int *fence_amount, int **fence_ids, geofence_s **params)
240 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
241 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
242 g_return_val_if_fail(fence_amount, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
243 g_return_val_if_fail(fence_ids, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
244 g_return_val_if_fail(params, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
246 if (!geofence_manager) {
248 return GEOFENCE_MANAGER_ERROR_NONE;
251 GVariantIter *iter = NULL;
252 GVariantIter *iter_row = NULL;
256 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
258 int ret = geo_client_get_geofences(geofence_manager->geofence_client, geofence_manager->app_id, place_id, &iter, &fence_cnt, &error_code);
259 if (ret != GEOFENCE_MANAGER_ERROR_NONE)
261 else if (error_code != GEOFENCE_MANAGER_ERROR_NONE)
264 *fence_amount = fence_cnt;
265 MOD_LOGD("Total fence count : %d", *fence_amount);
266 int *fence_id_array = (int *) g_slice_alloc0(sizeof(int) *fence_cnt);
267 geofence_s *p = (geofence_s *) g_slice_alloc0(sizeof(geofence_s) *fence_cnt);
269 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
270 while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
271 if (!g_strcmp0(key, "fence_id")) {
272 fence_id_array[index] =
273 g_variant_get_int32(value);
274 } else if (!g_strcmp0(key, "place_id")) {
275 p[index].place_id = g_variant_get_int32(value);
276 } else if (!g_strcmp0(key, "geofence_type")) {
277 p[index].type = g_variant_get_int32(value);
278 } else if (!g_strcmp0(key, "latitude")) {
279 p[index].latitude = g_variant_get_double(value);
280 } else if (!g_strcmp0(key, "longitude")) {
281 p[index].longitude = g_variant_get_double(value);
282 } else if (!g_strcmp0(key, "radius")) {
283 p[index].radius = g_variant_get_int32(value);
284 } else if (!g_strcmp0(key, "address")) {
285 g_strlcpy(p[index].address, g_variant_get_string(value, NULL), ADDRESS_LEN);
286 } else if (!g_strcmp0(key, "bssid")) {
287 g_strlcpy(p[index].bssid, g_variant_get_string(value, NULL), WLAN_BSSID_LEN);
288 } else if (!g_strcmp0(key, "ssid")) {
289 g_strlcpy(p[index].ssid, g_variant_get_string(value, NULL), WLAN_BSSID_LEN);
292 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);
294 g_variant_iter_free(iter_row);
297 g_variant_iter_free(iter);
298 *params = (geofence_s *) p;
299 *fence_ids = fence_id_array;
301 return GEOFENCE_MANAGER_ERROR_NONE;
304 EXPORT_API int get_places(void *handle, int *place_amount, int **place_ids, place_s **params)
306 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
307 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
308 g_return_val_if_fail(place_amount, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
309 g_return_val_if_fail(place_ids, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
310 g_return_val_if_fail(params, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
312 if (!geofence_manager) {
314 return GEOFENCE_MANAGER_ERROR_NONE;
317 GVariantIter *iter = NULL;
318 GVariantIter *iter_row = NULL;
322 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
324 /*Call the geofence_client api here....*/
325 int ret = geo_client_get_places(geofence_manager->geofence_client, geofence_manager->app_id, &iter, &place_cnt, &error_code);
326 if (ret != GEOFENCE_MANAGER_ERROR_NONE)
328 if (error_code != GEOFENCE_MANAGER_ERROR_NONE)
331 *place_amount = place_cnt;
332 MOD_LOGI("Total place count : %d", *place_amount);
333 int *place_id_array = (int *)g_slice_alloc0(sizeof(int) *place_cnt);
334 place_s *p = (place_s *)g_slice_alloc0(sizeof(place_s) *place_cnt);
337 MOD_LOGI("Iterator is null");
339 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
340 while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
341 if (!g_strcmp0(key, "place_id"))
342 place_id_array[index] = g_variant_get_int32(value);
343 else if (!g_strcmp0(key, "place_name"))
344 g_strlcpy(p[index].place_name, g_variant_get_string(value, NULL), PLACE_NAME_LEN);
346 MOD_LOGI("place_id: %d, place_name: %s", place_id_array[index], p[index].place_name);
348 g_variant_iter_free(iter_row);
352 g_variant_iter_free(iter);
354 *params = (place_s *)p;
355 *place_ids = place_id_array;
357 return GEOFENCE_MANAGER_ERROR_NONE;
360 static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_data)
362 if (!g_strcmp0(sig, "GeofenceInout")) {
363 MOD_LOGD("GeofenceInoutChanged");
364 geofence_callback(param, user_data);
365 } else if (!g_strcmp0(sig, "GeofenceProximity")) {
366 MOD_LOGD("GeofenceProximityChanged");
367 geofence_proximity_callback(param, user_data);
368 } else if (!g_strcmp0(sig, "GeofenceEvent")) {
369 MOD_LOGD("GeofenceEventInvoked");
370 geofence_event_callback(param, user_data);
372 MOD_LOGD("Invalid signal[%s]", sig);
376 EXPORT_API int start_geofence(void *handle, int fence_id)
378 MOD_LOGD("start_geofence");
379 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
380 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION);
382 int ret = GEOFENCE_MANAGER_ERROR_NONE;
384 MOD_LOGD("geofence-server(%x)", geofence_manager);
386 ret = geo_client_start_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id);
387 if (ret != GEOFENCE_MANAGER_ERROR_NONE) {
388 MOD_LOGE("Fail to start geofence_client_h. Error[%d]", ret);
392 return GEOFENCE_MANAGER_ERROR_NONE;
395 EXPORT_API int stop_geofence(void *handle, int fence_id)
397 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
398 MOD_LOGD("geofence_manager->geofence_cb : %x", geofence_manager->geofence_cb);
399 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
400 g_return_val_if_fail(geofence_manager->geofence_client, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
402 int ret = GEOFENCE_CLIENT_ERROR_NONE;
404 ret = geo_client_stop_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id);
405 if (ret != GEOFENCE_MANAGER_ERROR_NONE) {
406 MOD_LOGE("Fail to stop. Error[%d]", ret);
410 return GEOFENCE_MANAGER_ERROR_NONE;
413 EXPORT_API int create(void *handle, GeofenceModCB geofence_cb, GeofenceModProximityCB geofence_proximity_cb, GeofenceModEventCB geofence_event_cb, void *userdata)
415 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
416 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
417 g_return_val_if_fail(geofence_cb, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
419 /* create connnection */
420 int ret = GEOFENCE_MANAGER_ERROR_NONE;
422 geofence_manager->geofence_cb = geofence_cb;
423 geofence_manager->geofence_proximity_cb = geofence_proximity_cb;
424 geofence_manager->geofence_event_cb = geofence_event_cb;
425 geofence_manager->userdata = userdata;
427 ret = geo_client_create(&(geofence_manager->geofence_client));
428 if (ret != GEOFENCE_CLIENT_ERROR_NONE || !geofence_manager->geofence_client) {
429 MOD_LOGE("Fail to create geofence_client_dbus_h. Error[%d]", ret);
430 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
433 MOD_LOGD("geofence_manager->geofence_client: %p", geofence_manager->geofence_client);
434 ret = geo_client_start(geofence_manager->geofence_client, on_signal_callback, geofence_manager);
436 if (ret != GEOFENCE_CLIENT_ERROR_NONE) {
437 if (ret == GEOFENCE_CLIENT_ACCESS_DENIED) {
438 MOD_LOGE("Access denied[%d]", ret);
439 return GEOFENCE_CLIENT_ACCESS_DENIED;
441 MOD_LOGE("Fail to start geofence_client_dbus_h. Error[%d]", ret);
442 geo_client_destroy(geofence_manager->geofence_client);
443 geofence_manager->geofence_client = NULL;
445 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
448 return GEOFENCE_MANAGER_ERROR_NONE;
451 EXPORT_API int destroy(void *handle)
455 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
456 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
457 g_return_val_if_fail(geofence_manager->geofence_client, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
459 int ret = GEOFENCE_MANAGER_ERROR_NONE;
461 ret = geo_client_stop(geofence_manager->geofence_client);
462 if (ret != GEOFENCE_CLIENT_ERROR_NONE) {
463 MOD_LOGE("Fail to stop. Error[%d]", ret);
464 geo_client_destroy(geofence_manager->geofence_client);
465 geofence_manager->geofence_client = NULL;
466 return GEOFENCE_MANAGER_ERROR_IPC;
469 ret = geo_client_destroy(geofence_manager->geofence_client);
470 if (ret != GEOFENCE_CLIENT_ERROR_NONE) {
471 MOD_LOGE("Fail to destroy. Error[%d]", ret);
472 return GEOFENCE_MANAGER_ERROR_IPC;
474 geofence_manager->geofence_client = NULL;
475 geofence_manager->geofence_cb = NULL;
476 geofence_manager->geofence_event_cb = NULL;
477 geofence_manager->userdata = NULL;
479 return GEOFENCE_MANAGER_ERROR_NONE;
482 static void __get_caller_app_id(void *handle)
484 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
485 g_return_if_fail(geofence_manager);
487 gchar *app_id = NULL;
492 ret = app_manager_get_app_id(pid, &app_id);
493 if (ret != APP_MANAGER_ERROR_NONE) {
494 MOD_LOGE("Fail to get app_id from module_geofence_server. Err[%d]", ret);
496 MOD_LOGD("app_id: %s", app_id);
497 geofence_manager->app_id = app_id;
501 EXPORT_API gpointer init(GeofenceModOps *ops)
505 g_return_val_if_fail(ops, NULL);
506 ops->create = create;
507 ops->destroy = destroy;
508 ops->enable_service = enable_service;
509 ops->start_geofence = start_geofence;
510 ops->stop_geofence = stop_geofence;
511 ops->add_geopoint = add_geopoint;
512 ops->add_bssid = add_bssid;
513 ops->remove_geofence = remove_geofence;
514 ops->get_geofences = get_geofences;
516 ops->add_place = add_place;
517 ops->update_place = update_place;
518 ops->remove_place = remove_place;
519 ops->get_place_name = get_place_name;
520 ops->get_places = get_places;
522 GeofenceManagerData *geofence_manager = g_new0(GeofenceManagerData, 1);
523 g_return_val_if_fail(geofence_manager, NULL);
525 geofence_manager->geofence_cb = NULL;
526 geofence_manager->geofence_proximity_cb = NULL;
527 geofence_manager->geofence_event_cb = NULL;
528 geofence_manager->userdata = NULL;
530 __get_caller_app_id(geofence_manager);
532 return (gpointer) geofence_manager;
535 EXPORT_API void shutdown(gpointer handle)
537 MOD_LOGD("shutdown");
538 g_return_if_fail(handle);
539 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
541 if (geofence_manager->geofence_client) {
542 geo_client_stop(geofence_manager->geofence_client);
543 geo_client_destroy(geofence_manager->geofence_client);
544 geofence_manager->geofence_client = NULL;
547 geofence_manager->geofence_cb = NULL;
548 g_free(geofence_manager->app_id);
549 g_free(geofence_manager);
550 geofence_manager = NULL;