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);
247 GVariantIter *iter = NULL;
248 GVariantIter *iter_row = NULL;
252 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
254 int ret = geo_client_get_geofences(geofence_manager->geofence_client, geofence_manager->app_id, place_id, &iter, &fence_cnt, &error_code);
255 if (ret != GEOFENCE_MANAGER_ERROR_NONE)
257 else if (error_code != GEOFENCE_MANAGER_ERROR_NONE)
260 *fence_amount = fence_cnt;
261 MOD_LOGD("Total fence count : %d", *fence_amount);
262 int *fence_id_array = (int *) g_slice_alloc0(sizeof(int) *fence_cnt);
263 geofence_s *p = (geofence_s *) g_slice_alloc0(sizeof(geofence_s) *fence_cnt);
265 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
266 while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
267 if (!g_strcmp0(key, "fence_id")) {
268 fence_id_array[index] =
269 g_variant_get_int32(value);
270 } else if (!g_strcmp0(key, "place_id")) {
271 p[index].place_id = g_variant_get_int32(value);
272 } else if (!g_strcmp0(key, "geofence_type")) {
273 p[index].type = g_variant_get_int32(value);
274 } else if (!g_strcmp0(key, "latitude")) {
275 p[index].latitude = g_variant_get_double(value);
276 } else if (!g_strcmp0(key, "longitude")) {
277 p[index].longitude = g_variant_get_double(value);
278 } else if (!g_strcmp0(key, "radius")) {
279 p[index].radius = g_variant_get_int32(value);
280 } else if (!g_strcmp0(key, "address")) {
281 g_strlcpy(p[index].address, g_variant_get_string(value, NULL), ADDRESS_LEN);
282 } else if (!g_strcmp0(key, "bssid")) {
283 g_strlcpy(p[index].bssid, g_variant_get_string(value, NULL), WLAN_BSSID_LEN);
284 } else if (!g_strcmp0(key, "ssid")) {
285 g_strlcpy(p[index].ssid, g_variant_get_string(value, NULL), WLAN_BSSID_LEN);
288 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);
290 g_variant_iter_free(iter_row);
293 g_variant_iter_free(iter);
294 *params = (geofence_s *) p;
295 *fence_ids = fence_id_array;
297 return GEOFENCE_MANAGER_ERROR_NONE;
300 EXPORT_API int get_places(void *handle, int *place_amount, int **place_ids, place_s **params)
302 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
303 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
304 g_return_val_if_fail(place_amount, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
305 g_return_val_if_fail(place_ids, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
306 g_return_val_if_fail(params, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
309 GVariantIter *iter = NULL;
310 GVariantIter *iter_row = NULL;
314 int error_code = GEOFENCE_MANAGER_ERROR_NONE;
316 /*Call the geofence_client api here....*/
317 int ret = geo_client_get_places(geofence_manager->geofence_client, geofence_manager->app_id, &iter, &place_cnt, &error_code);
318 if (ret != GEOFENCE_MANAGER_ERROR_NONE)
320 if (error_code != GEOFENCE_MANAGER_ERROR_NONE)
323 *place_amount = place_cnt;
324 MOD_LOGI("Total place count : %d", *place_amount);
325 int *place_id_array = (int *)g_slice_alloc0(sizeof(int) *place_cnt);
326 place_s *p = (place_s *)g_slice_alloc0(sizeof(place_s) *place_cnt);
329 MOD_LOGI("Iterator is null");
331 while (g_variant_iter_next(iter, "a{sv}", &iter_row)) {
332 while (g_variant_iter_loop(iter_row, "{sv}", &key, &value)) {
333 if (!g_strcmp0(key, "place_id"))
334 place_id_array[index] = g_variant_get_int32(value);
335 else if (!g_strcmp0(key, "place_name"))
336 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);
344 g_variant_iter_free(iter);
346 *params = (place_s *)p;
347 *place_ids = place_id_array;
349 return GEOFENCE_MANAGER_ERROR_NONE;
352 static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_data)
354 if (!g_strcmp0(sig, "GeofenceInout")) {
355 MOD_LOGD("GeofenceInoutChanged");
356 geofence_callback(param, user_data);
357 } else if (!g_strcmp0(sig, "GeofenceProximity")) {
358 MOD_LOGD("GeofenceProximityChanged");
359 geofence_proximity_callback(param, user_data);
360 } else if (!g_strcmp0(sig, "GeofenceEvent")) {
361 MOD_LOGD("GeofenceEventInvoked");
362 geofence_event_callback(param, user_data);
364 MOD_LOGD("Invalid signal[%s]", sig);
368 EXPORT_API int start_geofence(void *handle, int fence_id)
370 MOD_LOGD("start_geofence");
371 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
372 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_EXCEPTION);
374 int ret = GEOFENCE_MANAGER_ERROR_NONE;
376 MOD_LOGD("geofence-server(%p)", (void*)geofence_manager);
378 ret = geo_client_start_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id);
379 if (ret != GEOFENCE_MANAGER_ERROR_NONE) {
380 MOD_LOGE("Fail to start geofence_client_h. Error[%d]", ret);
384 return GEOFENCE_MANAGER_ERROR_NONE;
387 EXPORT_API int stop_geofence(void *handle, int fence_id)
389 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
390 MOD_LOGD("geofence_manager->geofence_cb : %p", geofence_manager->geofence_cb);
391 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
392 g_return_val_if_fail(geofence_manager->geofence_client, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
394 int ret = GEOFENCE_CLIENT_ERROR_NONE;
396 ret = geo_client_stop_geofence(geofence_manager->geofence_client, geofence_manager->app_id, fence_id);
397 if (ret != GEOFENCE_MANAGER_ERROR_NONE) {
398 MOD_LOGE("Fail to stop. Error[%d]", ret);
402 return GEOFENCE_MANAGER_ERROR_NONE;
405 EXPORT_API int create(void *handle, GeofenceModCB geofence_cb, GeofenceModProximityCB geofence_proximity_cb, GeofenceModEventCB geofence_event_cb, void *userdata)
407 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
408 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
409 g_return_val_if_fail(geofence_cb, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
411 /* create connnection */
412 int ret = GEOFENCE_MANAGER_ERROR_NONE;
414 geofence_manager->geofence_cb = geofence_cb;
415 geofence_manager->geofence_proximity_cb = geofence_proximity_cb;
416 geofence_manager->geofence_event_cb = geofence_event_cb;
417 geofence_manager->userdata = userdata;
419 ret = geo_client_create(&(geofence_manager->geofence_client));
420 if (ret != GEOFENCE_CLIENT_ERROR_NONE || !geofence_manager->geofence_client) {
421 MOD_LOGE("Fail to create geofence_client_dbus_h. Error[%d]", ret);
422 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
425 MOD_LOGD("geofence_manager->geofence_client: %p", geofence_manager->geofence_client);
426 ret = geo_client_start(geofence_manager->geofence_client, on_signal_callback, geofence_manager);
428 if (ret != GEOFENCE_CLIENT_ERROR_NONE) {
429 if (ret == GEOFENCE_CLIENT_ACCESS_DENIED) {
430 MOD_LOGE("Access denied[%d]", ret);
431 return GEOFENCE_CLIENT_ACCESS_DENIED;
433 MOD_LOGE("Fail to start geofence_client_dbus_h. Error[%d]", ret);
434 geo_client_destroy(geofence_manager->geofence_client);
435 geofence_manager->geofence_client = NULL;
437 return GEOFENCE_CLIENT_ERROR_DBUS_CALL;
440 return GEOFENCE_MANAGER_ERROR_NONE;
443 EXPORT_API int destroy(void *handle)
447 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
448 g_return_val_if_fail(geofence_manager, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
449 g_return_val_if_fail(geofence_manager->geofence_client, GEOFENCE_MANAGER_ERROR_INVALID_PARAMETER);
451 int ret = GEOFENCE_MANAGER_ERROR_NONE;
453 ret = geo_client_stop(geofence_manager->geofence_client);
454 if (ret != GEOFENCE_CLIENT_ERROR_NONE) {
455 MOD_LOGE("Fail to stop. Error[%d]", ret);
456 geo_client_destroy(geofence_manager->geofence_client);
457 geofence_manager->geofence_client = NULL;
458 return GEOFENCE_MANAGER_ERROR_IPC;
461 ret = geo_client_destroy(geofence_manager->geofence_client);
462 if (ret != GEOFENCE_CLIENT_ERROR_NONE) {
463 MOD_LOGE("Fail to destroy. Error[%d]", ret);
464 return GEOFENCE_MANAGER_ERROR_IPC;
466 geofence_manager->geofence_client = NULL;
467 geofence_manager->geofence_cb = NULL;
468 geofence_manager->geofence_event_cb = NULL;
469 geofence_manager->userdata = NULL;
471 return GEOFENCE_MANAGER_ERROR_NONE;
474 static void __get_caller_app_id(void *handle)
476 GeofenceManagerData *geofence_manager = (GeofenceManagerData *)handle;
477 g_return_if_fail(geofence_manager);
479 gchar *app_id = NULL;
484 ret = app_manager_get_app_id(pid, &app_id);
485 if (ret != APP_MANAGER_ERROR_NONE) {
486 MOD_LOGE("No app_id. Set app_id to RequestbyFramework");
487 geofence_manager->app_id = g_strdup("RequestbyFramework");
489 MOD_LOGD("app_id: %s", app_id);
490 geofence_manager->app_id = app_id;
494 EXPORT_API gpointer init(GeofenceModOps *ops)
498 g_return_val_if_fail(ops, NULL);
499 ops->create = create;
500 ops->destroy = destroy;
501 ops->enable_service = enable_service;
502 ops->start_geofence = start_geofence;
503 ops->stop_geofence = stop_geofence;
504 ops->add_geopoint = add_geopoint;
505 ops->add_bssid = add_bssid;
506 ops->remove_geofence = remove_geofence;
507 ops->get_geofences = get_geofences;
509 ops->add_place = add_place;
510 ops->update_place = update_place;
511 ops->remove_place = remove_place;
512 ops->get_place_name = get_place_name;
513 ops->get_places = get_places;
515 GeofenceManagerData *geofence_manager = g_new0(GeofenceManagerData, 1);
516 g_return_val_if_fail(geofence_manager, NULL);
518 geofence_manager->geofence_cb = NULL;
519 geofence_manager->geofence_proximity_cb = NULL;
520 geofence_manager->geofence_event_cb = NULL;
521 geofence_manager->userdata = NULL;
523 __get_caller_app_id(geofence_manager);
525 return (gpointer) geofence_manager;
528 EXPORT_API void shutdown(gpointer handle)
530 MOD_LOGD("shutdown");
531 g_return_if_fail(handle);
532 GeofenceManagerData *geofence_manager = (GeofenceManagerData *) handle;
534 if (geofence_manager->geofence_client) {
535 geo_client_stop(geofence_manager->geofence_client);
536 geo_client_destroy(geofence_manager->geofence_client);
537 geofence_manager->geofence_client = NULL;
540 geofence_manager->geofence_cb = NULL;
541 g_free(geofence_manager->app_id);
542 g_free(geofence_manager);
543 geofence_manager = NULL;