8ac2c77fceeee2cd32c24447a3a435a9e477a9ac
[platform/core/connectivity/ua-plugin-wifi-location.git] / src / wifi-location-plugin.c
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * @author: Abhay Agarwal <ay.agarwal@samsung.com>
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <glib.h>
24 #include "wifi-location-plugin.h"
25 #include "wifi-location-plugin-util.h"
26
27 #define NAME    "wifi-location-plugin"
28 #define AUTHOR  "Samsung"
29 #define VERSION "0.1"
30
31 #define DETECTION_WINDOW_DEFAULT        55 /* 55 seconds */
32
33 #define DETECTION_STARTED 1
34 #define DETECTION_STOPPED 0
35
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;
41
42 static void __report_absence(gpointer data, gpointer user_data)
43 {
44         FUNC_ENTER;
45
46         /* TODO: Implement this function */
47
48         FUNC_EXIT;
49 }
50
51 static void __reset_devices(gpointer data, gpointer user_data)
52 {
53         /* TODO: Implement this function */
54         return;
55 }
56
57 static int __stop_scan()
58 {
59         FUNC_ENTER;
60         int ret = UAS_STATUS_SUCCESS;
61
62         g_slist_foreach(dev_list, __reset_devices, NULL);
63
64         /* TODO: stop scan */
65         if (UAS_STATUS_SUCCESS != ret) {
66                 UA_WIFI_LOCATION_ERR("Fail to stop wifi_location scan [%d]", ret);
67                 return ret;
68         }
69
70         /* Send detection stopped */
71         if (uas_cbs && uas_cbs->detection_state_cb) {
72                 uas_cbs->detection_state_cb(PLUGIN_ID, DETECTION_STOPPED);
73         } else {
74                 UA_WIFI_LOCATION_ERR("uas_cbs not ready");
75         }
76
77         /* Reset detection flags */
78         wifi_location_detection_type = 0;
79
80         FUNC_EXIT;
81         return ret;
82 }
83
84 static gboolean __stop_scan_expired_timer_cb(gpointer user_data)
85 {
86         int ret = UAS_STATUS_SUCCESS;
87
88         stop_scan_timer = 0;
89
90         /* Report absence for undetected devices */
91         g_slist_foreach(dev_list, __report_absence, NULL);
92
93         /* Stop detection */
94         ret = __stop_scan();
95         retv_if_with_log(UAS_STATUS_SUCCESS != ret, FALSE, "return %d", ret);
96
97         return FALSE;
98 }
99
100 static int __start_scan(gpointer user_data, int scan_mode)
101 {
102         FUNC_ENTER;
103         int ret = UAS_STATUS_SUCCESS;
104
105         ret = _wifi_location_plugin_start_scan(scan_mode);
106         retv_if_with_log(UAS_STATUS_SUCCESS != ret, ret, "return %d", ret);
107
108         if (0 < stop_scan_timer)
109                 g_source_remove(stop_scan_timer);
110         stop_scan_timer = g_timeout_add_seconds(wifi_location_detection_window,
111                                         __stop_scan_expired_timer_cb, NULL);
112
113         /* Send detection started */
114         if (uas_cbs && uas_cbs->detection_state_cb) {
115                 uas_cbs->detection_state_cb(PLUGIN_ID, DETECTION_STARTED);
116         } else {
117                 UA_WIFI_LOCATION_ERR("uas_cbs not ready");
118                 ret = UAS_STATUS_FAIL;
119         }
120
121         FUNC_EXIT;
122         return ret;
123 }
124
125 static int init(const uas_callbacks_t *callbacks)
126 {
127         FUNC_ENTER;
128         int ret = UAS_STATUS_SUCCESS;
129
130         if (!callbacks)
131                 return UAS_STATUS_FAIL;
132
133         retv_if(NULL != uas_cbs, UAS_STATUS_ALREADY_DONE);
134
135         /* TODO: Check wifi location system support */
136
137         /* Initialize wifi-location */
138         ret = wifi_location_initialize();
139         retv_if_with_log(WIFI_LOCATION_ERROR_NONE != ret,
140                         UAS_STATUS_FAIL, "return %d", ret);
141
142         uas_cbs = callbacks;
143
144         FUNC_EXIT;
145         return UAS_STATUS_SUCCESS;
146 }
147
148 static int deinit(void)
149 {
150         FUNC_ENTER;
151         int ret = UAS_STATUS_SUCCESS;
152
153         if (dev_list) {
154                 g_slist_free_full(dev_list, g_free);
155                 dev_list = NULL;
156         }
157
158         /* Deinitialize wifi-location */
159         ret = wifi_location_deinitialize();
160         retv_if_with_log(WIFI_LOCATION_ERROR_NONE != ret,
161                         UAS_STATUS_FAIL, "return %d", ret);
162
163         uas_cbs = NULL;
164
165         FUNC_EXIT;
166         return UAS_STATUS_SUCCESS;
167 }
168
169 static int get_state(int *state)
170 {
171         FUNC_ENTER;
172         int ret = UAS_STATUS_SUCCESS;
173
174         retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
175         retv_if(NULL == state, UAS_STATUS_FAIL);
176
177         /* TODO: Get wifi-location state */
178         *state = UAS_STATE_READY;
179
180         FUNC_EXIT;
181         return ret;
182 }
183
184 static int get_capability(uas_capability_e *capability)
185 {
186         FUNC_ENTER;
187
188         retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
189         retv_if(NULL == capability, UAS_STATUS_FAIL);
190
191         *capability = UAS_SUPPORT_USER;
192
193         FUNC_EXIT;
194         return UAS_STATUS_SUCCESS;
195 }
196
197 static int start_detection(unsigned int detection_type, int scan_mode)
198 {
199         FUNC_ENTER;
200
201         int ret = UAS_STATUS_SUCCESS;
202
203         retv_if(NULL == uas_cbs, UAS_STATUS_NOT_READY);
204         retv_if(detection_type == (wifi_location_detection_type & detection_type),
205                         UAS_STATUS_ALREADY_DONE);
206
207         /* Check if detection already in progress */
208         if (0 != wifi_location_detection_type)
209                 goto done;
210
211         /* Start detection */
212         ret = __start_scan(NULL, scan_mode);
213         retv_if_with_log(UAS_STATUS_SUCCESS != ret, ret, "return %d", ret);
214
215 done:
216         wifi_location_detection_type |= detection_type;
217         UA_WIFI_LOCATION_INFO_C("wifi_location_detection_type = 0x%8.8X", wifi_location_detection_type);
218
219         FUNC_EXIT;
220         return ret;
221 }
222
223 static uas_api_t wifi_location_api = {
224         .init = init,
225         .deinit = deinit,
226         .get_state = get_state,
227         .get_capability = get_capability,
228         .set_registered_devices = NULL,
229         .add_device = NULL,
230         .remove_device = NULL,
231         .start_detection = start_detection,
232         .stop_detection = NULL,
233         .set_low_power_mode = NULL,
234         .set_detection_window = NULL,
235         .set_detection_threshold = NULL,
236         .scan_active_devices = NULL,
237         .cancel_active_device_scan = NULL,
238         .add_ibeacon_adv = NULL,
239 };
240
241 static int module_init(uas_api_t **api)
242 {
243         FUNC_ENTER;
244
245         *api = &wifi_location_api;
246
247         FUNC_EXIT;
248         return 0;
249 }
250
251 static int module_deinit(void)
252 {
253         FUNC_ENTER;
254
255         FUNC_EXIT;
256         return 0;
257 }
258
259 UAS_MODULE_ADD(UAS_PLUGIN_ID_WIFI_LOCATION, NAME, AUTHOR, VERSION, module_init, module_deinit);