2 * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
4 * @author: Abhay Agarwal <ay.agarwal@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
24 #include "wifi-location-plugin.h"
25 #include "wifi-location-plugin-util.h"
27 #define NAME "wifi-location-plugin"
28 #define AUTHOR "Samsung"
31 #define DETECTION_WINDOW_DEFAULT 55 /* 55 seconds */
33 #define DETECTION_STARTED 1
34 #define DETECTION_STOPPED 0
36 static unsigned int wifi_location_detection_window = DETECTION_WINDOW_DEFAULT;
37 static const uas_callbacks_t *uas_cbs = NULL;
38 static GSList *dev_list = NULL;
39 static int wifi_location_detection_type = 0;
40 static guint stop_scan_timer = 0;
42 static void __report_absence(gpointer data, gpointer user_data)
46 /* TODO: Implement this function */
51 static void __reset_devices(gpointer data, gpointer user_data)
53 /* TODO: Implement this function */
57 static int __stop_scan()
60 int ret = UAS_STATUS_SUCCESS;
62 g_slist_foreach(dev_list, __reset_devices, NULL);
65 ret = _wifi_location_plugin_stop_scan();
66 retv_if_with_log(UAS_STATUS_SUCCESS != ret, ret, "return %d", ret);
68 /* Send detection stopped */
69 if (uas_cbs && uas_cbs->detection_state_cb) {
70 uas_cbs->detection_state_cb(PLUGIN_ID, DETECTION_STOPPED);
72 UA_WIFI_LOCATION_ERR("uas_cbs not ready");
75 /* Reset detection flags */
76 wifi_location_detection_type = 0;
82 static gboolean __stop_scan_expired_timer_cb(gpointer user_data)
84 int ret = UAS_STATUS_SUCCESS;
88 /* Report absence for undetected devices */
89 g_slist_foreach(dev_list, __report_absence, NULL);
93 retv_if_with_log(UAS_STATUS_SUCCESS != ret, FALSE, "return %d", ret);
98 static int __start_scan(gpointer user_data, int scan_mode)
101 int ret = UAS_STATUS_SUCCESS;
103 ret = _wifi_location_plugin_start_scan(scan_mode);
104 retv_if_with_log(UAS_STATUS_SUCCESS != ret, ret, "return %d", ret);
106 if (0 < stop_scan_timer)
107 g_source_remove(stop_scan_timer);
108 stop_scan_timer = g_timeout_add_seconds(wifi_location_detection_window,
109 __stop_scan_expired_timer_cb, NULL);
111 /* Send detection started */
112 if (uas_cbs && uas_cbs->detection_state_cb) {
113 uas_cbs->detection_state_cb(PLUGIN_ID, DETECTION_STARTED);
115 UA_WIFI_LOCATION_ERR("uas_cbs not ready");
116 ret = UAS_STATUS_FAIL;
123 static int init(const uas_callbacks_t *callbacks)
126 int ret = UAS_STATUS_SUCCESS;
129 return UAS_STATUS_FAIL;
131 retv_if(NULL != uas_cbs, UAS_STATUS_ALREADY_DONE);
133 /* TODO: Check wifi location system support */
135 /* Initialize wifi-location */
136 ret = wifi_location_initialize();
137 retv_if_with_log(WIFI_LOCATION_ERROR_NONE != ret,
138 UAS_STATUS_FAIL, "return %d", ret);
143 return UAS_STATUS_SUCCESS;
146 static int deinit(void)
149 int ret = UAS_STATUS_SUCCESS;
152 g_slist_free_full(dev_list, g_free);
156 /* Deinitialize wifi-location */
157 ret = wifi_location_deinitialize();
158 retv_if_with_log(WIFI_LOCATION_ERROR_NONE != ret,
159 UAS_STATUS_FAIL, "return %d", ret);
164 return UAS_STATUS_SUCCESS;
167 static int get_state(int *state)
170 int ret = UAS_STATUS_SUCCESS;
172 retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
173 retv_if(NULL == state, UAS_STATUS_FAIL);
175 /* TODO: Get wifi-location state */
176 *state = UAS_STATE_READY;
182 static int get_capability(uas_capability_e *capability)
186 retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
187 retv_if(NULL == capability, UAS_STATUS_FAIL);
189 *capability = UAS_SUPPORT_USER;
192 return UAS_STATUS_SUCCESS;
195 static int add_device(uas_device_info_t *device)
198 uas_wifi_location_info_t *wifi_location_info;
200 retv_if(NULL == device, UAS_STATUS_FAIL);
201 retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
204 _wifi_location_plugin_util_get_wifi_location_info_from_dev_info(device);
205 retv_if_with_log(NULL == wifi_location_info, UAS_STATUS_FAIL,
206 "_wifi_location_plugin_util_get_wifi_location_info_from_dev_info");
208 g_idle_add(_wifi_location_plugin_add_device, wifi_location_info);
211 return UAS_STATUS_SUCCESS;
214 static int remove_device(uas_device_info_t *device)
217 int ret = UAS_STATUS_SUCCESS;
219 uas_wifi_location_info_t *wifi_location_info = NULL;
221 retv_if(NULL == device, UAS_STATUS_FAIL);
222 retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
224 for (l = dev_list; NULL != l; l = g_slist_next(l)) {
225 wifi_location_info = l->data;
227 if (!wifi_location_info) {
228 UA_WIFI_LOCATION_ERR("data in dev list is NULL");
232 if (!strncasecmp(wifi_location_info->device_id, device->device_id,
233 UAS_DEVICE_ID_MAX_LEN))
236 retv_if(NULL == l, UAS_STATUS_ALREADY_DONE);
238 dev_list = g_slist_remove(dev_list, wifi_location_info);
239 g_free(wifi_location_info);
245 static int start_detection(unsigned int detection_type, int scan_mode)
249 int ret = UAS_STATUS_SUCCESS;
251 retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
252 retv_if(detection_type == (wifi_location_detection_type & detection_type),
253 UAS_STATUS_ALREADY_DONE);
255 /* Check if detection already in progress */
256 if (0 != wifi_location_detection_type)
259 /* Start detection */
260 ret = __start_scan(NULL, scan_mode);
261 retv_if_with_log(UAS_STATUS_SUCCESS != ret, ret, "return %d", ret);
264 wifi_location_detection_type |= detection_type;
265 UA_WIFI_LOCATION_INFO_C("wifi_location_detection_type = 0x%8.8X", wifi_location_detection_type);
271 static int stop_detection(unsigned int detection_type)
274 int ret = UAS_STATUS_SUCCESS;
276 retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
277 retv_if(0 == (wifi_location_detection_type & detection_type),
278 UAS_STATUS_ALREADY_DONE);
282 retv_if_with_log(UAS_STATUS_SUCCESS != ret, ret, "return %d", ret);
284 wifi_location_detection_type &= ~detection_type;
285 UA_WIFI_LOCATION_INFO_C("wifi_location_detection_type = 0x%8.8X",
286 wifi_location_detection_type);
287 if (0 != wifi_location_detection_type)
290 /* Remove stop scan timer */
291 if (0 < stop_scan_timer) {
292 g_source_remove(stop_scan_timer);
294 UA_WIFI_LOCATION_INFO("Stop scan timer removed");
302 static int set_detection_window(unsigned int detection_window)
306 retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
308 wifi_location_detection_window = detection_window;
311 return UAS_STATUS_SUCCESS;
314 static uas_api_t wifi_location_api = {
317 .get_state = get_state,
318 .get_capability = get_capability,
319 .set_registered_devices = NULL,
320 .add_device = add_device,
321 .remove_device = remove_device,
322 .start_detection = start_detection,
323 .stop_detection = stop_detection,
324 .set_low_power_mode = NULL,
325 .set_detection_window = set_detection_window,
326 .set_detection_threshold = NULL,
327 .scan_active_devices = NULL,
328 .cancel_active_device_scan = NULL,
329 .add_ibeacon_adv = NULL,
332 static int module_init(uas_api_t **api)
336 *api = &wifi_location_api;
342 static int module_deinit(void)
350 UAS_MODULE_ADD(UAS_PLUGIN_ID_WIFI_LOCATION, NAME, AUTHOR, VERSION, module_init, module_deinit);
352 void _wifi_location_plugin_handle_device_added(int status,
353 uas_wifi_location_info_t *wifi_location_info)
356 uas_device_info_t *dev_info;
358 ret_if(NULL == wifi_location_info);
360 dev_info = _wifi_location_plugin_util_get_dev_info_from_wifi_location_info(
362 if (NULL == dev_info) {
363 /* Device Addition failed */
364 UA_WIFI_LOCATION_ERR(
365 "_wifi_location_plugin_util_get_dev_info_from_wifi_location_info failed");
366 if (uas_cbs && uas_cbs->device_added_cb)
367 uas_cbs->device_added_cb(PLUGIN_ID, UAS_STATUS_FAIL, NULL);
372 if (UAS_STATUS_SUCCESS == status) {
373 dev_list = g_slist_prepend(dev_list,
374 g_memdup(wifi_location_info,
375 sizeof(uas_wifi_location_info_t)));
377 /* Save current time */
378 dev_info->last_seen = _wifi_location_plugin_util_get_curr_time();
380 /* Send device Addition callback */
381 if (uas_cbs && uas_cbs->device_added_cb) {
382 uas_cbs->device_added_cb(PLUGIN_ID, status, dev_info);
384 UA_WIFI_LOCATION_ERR("uas_cbs not ready");
387 _wifi_location_plugin_util_uas_device_info_free(dev_info);