Fix for UTC error case
[platform/core/connectivity/wifi-mesh-manager.git] / src / mesh-request.c
1 /*
2  * Network Configuration Module
3  *
4  * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
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 #include <stdlib.h>
20
21 #include <glib.h>
22 #include <gio/gio.h>
23
24 #include "mesh.h"
25 #include "mesh-log.h"
26 #include "mesh-util.h"
27 #include "mesh-service-interface.h"
28 #include "mesh-generated-code.h"
29
30 #include "mesh-bridge.h"
31 #include "mesh-netlink.h"
32 #include "mesh-interface.h"
33 #include "mesh-request.h"
34 #include "mesh-softap.h"
35 #include "mesh-gdbus.h"
36
37 int mesh_request_set_mesh_gate(const char* bridge_interface,
38                 const char* mesh_interface, const char* external_interface)
39 {
40         int ret = MESHD_ERROR_NONE;
41         bool state = FALSE;
42
43         ret = mesh_interface_check_external_exists(external_interface, &state);
44         if (MESHD_ERROR_NONE != ret) {
45                 MESH_LOGE("Failed to get external interface state !");
46                 return MESHD_ERROR_OPERATION_FAILED;
47         }
48         MESH_LOGD("  Ethernet cable state [%s]",
49                 (state) ? "Connected" : "Disconnected");
50
51         /* Turn STP on */
52         ret = mesh_bridge_set_stp(bridge_interface, TRUE);
53         if (MESHD_ERROR_NONE != ret) {
54                 MESH_LOGE("Failed to turn STP on !");
55                 return ret;
56         }
57
58         /* Set mesh parameters */
59         ret = mesh_netlink_set_mesh_parameter(mesh_interface,
60                         "mesh_hwmp_rootmode", 4);
61         if (MESHD_ERROR_NONE != ret)
62                 MESH_LOGE("Failed to set [mesh_hwmp_rootmode] : 4");
63
64         ret = mesh_netlink_set_mesh_parameter(mesh_interface,
65                         "mesh_gate_announcements", 1);
66         if (MESHD_ERROR_NONE != ret)
67                 MESH_LOGE("Failed to set [mesh_gate_announcements] : 1");
68
69         return MESHD_ERROR_NONE;
70 }
71
72 int mesh_request_unset_mesh_gate(const char* bridge_interface,
73                 const char* mesh_interface, const char* external_interface)
74 {
75         int ret = MESHD_ERROR_NONE;
76
77         NOTUSED(external_interface);
78
79         /* Set mesh parameters */
80         ret = mesh_netlink_set_mesh_parameter(mesh_interface,
81                         "mesh_hwmp_rootmode", 0);
82         if (MESHD_ERROR_NONE != ret)
83                 MESH_LOGE("Failed to set [mesh_hwmp_rootmode] : 0");
84
85         ret = mesh_netlink_set_mesh_parameter(mesh_interface,
86                         "mesh_gate_announcements", 0);
87         if (MESHD_ERROR_NONE != ret)
88                 MESH_LOGE("Failed to set [mesh_gate_announcements] : 0");
89
90         /* Turn STP off */
91         ret = mesh_bridge_set_stp(bridge_interface, FALSE);
92         if (MESHD_ERROR_NONE != ret) {
93                 MESH_LOGE("Failed to turn STP off!");
94                 return ret;
95         }
96
97         return MESHD_ERROR_NONE;
98 }
99
100 int mesh_request_add_bridge_interface(const char* bridge_interface,
101                 const char* interface)
102 {
103         int ret = MESHD_ERROR_NONE;
104
105         if (NULL == bridge_interface || NULL == interface) {
106                 MESH_LOGE("Invalid parameters");
107                 return MESHD_ERROR_INVALID_PARAMETER;
108         }
109
110         MESH_LOGD("Adding interface[%s] into bridge[%s]...", interface, bridge_interface);
111
112         /* Add external interface into bridge */
113         ret = mesh_bridge_add_interface(bridge_interface, interface);
114         if (MESHD_ERROR_NONE != ret) {
115                 MESH_LOGE("Failed to add interface !");
116                 return ret;
117         }
118
119         /* Make external interface down */
120         ret = mesh_interface_set(interface, NULL, MESH_INTERFACE_DOWN);
121         if (MESHD_ERROR_NONE != ret) {
122                 MESH_LOGE("Failed to change external interface state");
123                 return ret;
124         }
125
126         /* Make external interface up with cleared IP */
127         ret = mesh_interface_set(interface, "0.0.0.0", MESH_INTERFACE_UP);
128         if (MESHD_ERROR_NONE != ret) {
129                 MESH_LOGE("Failed to change external interface state");
130                 return ret;
131         }
132
133         return MESHD_ERROR_NONE;
134 }
135
136 int mesh_request_remove_bridge_interface(const char* bridge_interface,
137                 const char* interface)
138 {
139         int ret = MESHD_ERROR_NONE;
140
141         if (NULL == bridge_interface || NULL == interface) {
142                 MESH_LOGE("Invalid parameters");
143                 return MESHD_ERROR_INVALID_PARAMETER;
144         }
145
146         MESH_LOGD("Removing interface[%s] from bridge[%s]...", interface, bridge_interface);
147
148         /* Remove external interface into bridge */
149         ret = mesh_bridge_del_interface(bridge_interface, interface);
150         if (MESHD_ERROR_NONE != ret) {
151                 MESH_LOGE("Failed to remove interface !");
152                 return ret;
153         }
154
155         return MESHD_ERROR_NONE;
156 }
157
158 int mesh_request_set_softap_config(const char* softap_interface,
159                 const char *ssid, const char* mode, int channel, int visibility,
160                 int max_sta, int security, const char* passphrase)
161 {
162         int ret = MESHD_ERROR_NONE;
163
164         MESH_LOGD("Setting configuration for SoftAP");
165
166         ret = mesh_softap_set_configuration(softap_interface, ssid, mode, channel,
167                         visibility, max_sta, security, passphrase);
168         if (MESHD_ERROR_NONE != ret) {
169                 MESH_LOGE("Failed to set Configuration for SoftAP");
170                 return ret;
171         }
172
173         return ret;
174 }
175
176 int mesh_request_enable_softap(
177                 const char* bridge_interface, const char* softap_interface)
178 {
179         int ret = MESHD_ERROR_NONE;
180
181         MESH_LOGD("Request to turn SoftAP on");
182         ret = mesh_softap_enable_softap(softap_interface);
183         if (MESHD_ERROR_NONE != ret) {
184                 MESH_LOGE("Failed to mesh_softap_enable_softap");
185                 return ret;
186         }
187
188         /* Add softAP interface into bridge */
189         ret = mesh_request_add_bridge_interface(bridge_interface, softap_interface);
190         if (MESHD_ERROR_NONE != ret)
191                 return ret;
192
193         return ret;
194 }
195
196 int mesh_request_disable_softap(
197                 const char* bridge_interface, const char* softap_interface)
198 {
199         int ret = MESHD_ERROR_NONE;
200
201         MESH_LOGD("Request to turn SoftAP off");
202         ret = mesh_softap_disable_softap();
203
204         /* Remove softAP interface from bridge */
205         ret = mesh_request_remove_bridge_interface(bridge_interface, softap_interface);
206         if (MESHD_ERROR_NONE != ret)
207                 return ret;
208
209         return ret;
210 }
211
212 int mesh_request_get_station_info(const char* mesh_interface, GList **station_list)
213 {
214         int ret = MESHD_ERROR_NONE;
215
216         MESH_LOGD("Request to get station info");
217
218         /* Get station info */
219         ret = mesh_netlink_get_station_info(mesh_interface, station_list);
220         if (MESHD_ERROR_NONE != ret)
221                 return ret;
222
223         return MESHD_ERROR_NONE;
224 }
225
226 int mesh_request_get_mpath_info(const char* mesh_interface, GList **mpath_list)
227 {
228         int ret = MESHD_ERROR_NONE;
229
230         MESH_LOGD("Request to get mpath info");
231
232         /* Get MPath info */
233         ret = mesh_netlink_get_mpath_info(mesh_interface, mpath_list);
234         if (MESHD_ERROR_NONE != ret)
235                 return ret;
236
237         return MESHD_ERROR_NONE;
238 }
239
240 int mesh_request_register_event_handler()
241 {
242         int ret = MESHD_ERROR_NONE;
243
244         MESH_LOGD("Request to register mesh event handler");
245
246         /* Get MPath info */
247         ret = mesh_netlink_register_event_handler();
248         if (MESHD_ERROR_NONE != ret)
249                 return ret;
250
251         return MESHD_ERROR_NONE;
252 }
253
254 int mesh_request_unregister_event_handler()
255 {
256         int ret = MESHD_ERROR_NONE;
257
258         MESH_LOGD("Request to unregister mesh event handler");
259
260         /* Get MPath info */
261         ret = mesh_netlink_unregister_event_handler();
262         if (MESHD_ERROR_NONE != ret)
263                 return ret;
264
265         return MESHD_ERROR_NONE;
266 }
267
268 int mesh_request_enable_network(mesh_service *service)
269 {
270         int ret;
271         if (NULL == service) {
272                 MESH_LOGE("Invalid parameter");
273                 return MESHD_ERROR_INVALID_PARAMETER;
274         }
275
276         MESH_LOGD("[IPC] Enable mesh network");
277
278         ret = mesh_gdbus_create_mesh_interface(service);
279         if (MESHD_ERROR_NONE != ret) {
280                 MESH_LOGE("Failed to create mesh network");
281                 return ret;
282         }
283
284         return MESHD_ERROR_NONE;
285 }
286
287 int mesh_request_disable_network(mesh_service *service)
288 {
289         int ret;
290         if (NULL == service) {
291                 MESH_LOGE("Invalid parameter");
292                 return MESHD_ERROR_INVALID_PARAMETER;
293         }
294
295         MESH_LOGD("[IPC] Disable mesh network");
296
297         ret = mesh_gdbus_remove_mesh_interface(service);
298         if (MESHD_ERROR_NONE != ret) {
299                 MESH_LOGE("Failed to create mesh network");
300                 return ret;
301         }
302
303         return MESHD_ERROR_NONE;
304 }
305
306 int mesh_request_scan(mesh_service *service)
307 {
308         int ret;
309         if (NULL == service) {
310                 MESH_LOGE("Invalid parameter");
311                 return MESHD_ERROR_INVALID_PARAMETER;
312         }
313
314         MESH_LOGD("[IPC] Request scan for mesh network");
315
316         ret = mesh_gdbus_mesh_scan(service);
317         if (MESHD_ERROR_NONE != ret) {
318                 MESH_LOGE("Failed to request scan for mesh network");
319                 return ret;
320         }
321
322         return MESHD_ERROR_NONE;
323 }
324
325 int mesh_request_specific_scan(mesh_service *service, gchar *mesh_id, gint channel)
326 {
327         int ret;
328         if (NULL == service) {
329                 MESH_LOGE("Invalid parameter");
330                 return MESHD_ERROR_INVALID_PARAMETER;
331         }
332
333         MESH_LOGD("[IPC] Request specific scan for mesh network");
334
335         ret = mesh_gdbus_mesh_specific_scan(service, mesh_id, channel);
336         if (MESHD_ERROR_NONE != ret) {
337                 MESH_LOGE("Failed to request specific scan for mesh network");
338                 return ret;
339         }
340
341         return MESHD_ERROR_NONE;
342 }
343
344 int mesh_request_cancel_scan(mesh_service *service)
345 {
346         int ret;
347         if (NULL == service) {
348                 MESH_LOGE("Invalid parameter");
349                 return MESHD_ERROR_INVALID_PARAMETER;
350         }
351
352         MESH_LOGD("[IPC] Cancel scan for mesh network");
353
354         ret = mesh_gdbus_mesh_cancel_scan(service);
355         if (MESHD_ERROR_NONE != ret) {
356                 MESH_LOGE("Failed to cancel scan for mesh network");
357                 return ret;
358         }
359
360         return MESHD_ERROR_NONE;
361 }
362
363 int mesh_request_get_networks(mesh_service *service)
364 {
365         int ret;
366         if (NULL == service) {
367                 MESH_LOGE("Invalid parameter");
368                 return MESHD_ERROR_INVALID_PARAMETER;
369         }
370
371         MESH_LOGD("[IPC] Get mesh networks");
372
373         ret = mesh_gdbus_get_mesh_networks(service);
374         if (MESHD_ERROR_NONE != ret) {
375                 MESH_LOGE("Failed to get mesh networks !");
376                 return ret;
377         }
378
379         return MESHD_ERROR_NONE;
380 }
381
382 static int _select_matched_network(GList *scanned_network,
383                 const char *mesh_id, int mesh_channel, meshd_security_type_e sec,
384                 mesh_scan_result_s **info)
385 {
386         int ret = MESHD_ERROR_NONE;
387         GList *iter = NULL;
388         mesh_scan_result_s *item = NULL;
389         gboolean found = FALSE;
390
391         meshd_check_null_ret_error("scanned_network", scanned_network,
392                         MESHD_ERROR_INVALID_PARAMETER);
393
394         iter = scanned_network;
395         while (iter != NULL) {
396                 item = (mesh_scan_result_s*)iter->data;
397
398                 if (g_strcmp0(mesh_id, item->mesh_id) == 0) {
399                         if (item->channel == mesh_channel && item->security == sec) {
400                                 *info = item;
401                                 found = TRUE;
402                                 break;
403                         }
404                 }
405                 iter = g_list_next(iter);
406         }
407
408         if (FALSE == found)
409                 return MESHD_ERROR_NO_DATA;
410
411         return ret;
412 }
413
414 int mesh_request_get_joined_network(mesh_service *service)
415 {
416         int ret;
417
418         if (NULL == service) {
419                 MESH_LOGE("Invalid parameter");
420                 return MESHD_ERROR_INVALID_PARAMETER;
421         }
422
423         MESH_LOGD("[IPC] Get joined mesh network");
424
425         ret = mesh_gdbus_get_joined_mesh_network(service);
426         if (MESHD_ERROR_NONE != ret) {
427                 MESH_LOGE("Failed to get joined mesh network");
428                 return ret;
429         }
430
431         return MESHD_ERROR_NONE;
432 }
433
434 int mesh_request_get_connected_peers(mesh_service *service)
435 {
436         int ret;
437
438         if (NULL == service) {
439                 MESH_LOGE("Invalid parameter");
440                 return MESHD_ERROR_INVALID_PARAMETER;
441         }
442
443         MESH_LOGD("[IPC] Get connected mesh peers");
444
445         ret = mesh_gdbus_get_connected_peers(service);
446         if (MESHD_ERROR_NONE != ret) {
447                 MESH_LOGE("Failed to get connected mesh peers");
448                 return ret;
449         }
450
451         return MESHD_ERROR_NONE;
452 }
453
454 int mesh_request_create_mesh_network(mesh_service *service, gchar *mesh_id,
455                 gint channel, meshd_security_type_e sec)
456 {
457         int ret;
458
459         if (NULL == service) {
460                 MESH_LOGE("Invalid parameter");
461                 return MESHD_ERROR_INVALID_PARAMETER;
462         }
463
464         MESH_LOGD("[IPC] Create a new mesh network");
465
466         ret = mesh_gdbus_create_network(service, mesh_id, channel, sec);
467         if (MESHD_ERROR_NONE != ret) {
468                 MESH_LOGE("Failed to create mesh network");
469                 return ret;
470         }
471
472         return MESHD_ERROR_NONE;
473 }
474
475 int mesh_request_connect_mesh_network(mesh_service *service, gchar *mesh_id,
476                 gint channel, meshd_security_type_e sec, gchar *passphrase)
477 {
478         int ret;
479         mesh_scan_result_s *info = NULL;
480
481         if (NULL == service) {
482                 MESH_LOGE("Invalid parameter");
483                 return MESHD_ERROR_INVALID_PARAMETER;
484         }
485
486         MESH_LOGD("[IPC] Connect mesh network");
487
488         /* Get mesh_id and channel from saved network */
489         ret = _select_matched_network(service->scanned_mesh_network,
490                         mesh_id, channel, sec, &info);
491         if (MESHD_ERROR_NONE != ret) {
492                 MESH_LOGE("Failed to mesh_network_get_first_mesh_network");
493                 return ret;
494         }
495
496         /* Set passphrase */
497         if (MESHD_SECURITY_NONE != sec) {
498                 if (NULL != passphrase) {
499                         ret = mesh_gdbus_set_passphrase(service, info, passphrase);
500                         if (MESHD_ERROR_NONE != ret) {
501                                 MESH_LOGE("Failed to set passphrase for mesh network");
502                                 return ret;
503                         }
504                 } else {
505                         MESH_LOGE("Passphrase is required !");
506                         return MESHD_ERROR_INVALID_PARAMETER;
507                 }
508         }
509
510         ret = mesh_gdbus_connect_network(service, info);
511         if (MESHD_ERROR_NONE != ret) {
512                 MESH_LOGE("Failed to connect mesh network");
513                 return ret;
514         }
515
516         return MESHD_ERROR_NONE;
517 }
518
519 int mesh_request_disconnect_mesh_network(mesh_service *service,
520                 gchar *mesh_id, gint channel, meshd_security_type_e sec)
521 {
522         int ret;
523         mesh_scan_result_s *info = NULL;
524
525         if (NULL == service) {
526                 MESH_LOGE("Invalid parameter");
527                 return MESHD_ERROR_INVALID_PARAMETER;
528         }
529
530         MESH_LOGD("[IPC] Disconnect mesh network");
531
532         /* Get mesh_id and channel from saved network */
533         ret = _select_matched_network(service->scanned_mesh_network,
534                         mesh_id, channel, sec, &info);
535         if (MESHD_ERROR_NONE != ret) {
536                 MESH_LOGE("Failed to _select_matched_network");
537                 return ret;
538         }
539
540         ret = mesh_gdbus_disconnect_network(service, info);
541         if (MESHD_ERROR_NONE != ret) {
542                 MESH_LOGE("Failed to disconnect mesh network");
543                 return ret;
544         }
545
546         return MESHD_ERROR_NONE;
547 }
548
549 int mesh_request_remove_mesh_network(mesh_service *service,
550                 gchar *mesh_id, gint channel, meshd_security_type_e sec)
551 {
552         int ret;
553         mesh_scan_result_s *info = NULL;
554
555         if (NULL == service) {
556                 MESH_LOGE("Invalid parameter");
557                 return MESHD_ERROR_INVALID_PARAMETER;
558         }
559
560         MESH_LOGD("[IPC] Remove mesh network");
561
562         /* Get mesh_id and channel from saved network */
563         ret = _select_matched_network(service->scanned_mesh_network,
564                         mesh_id, channel, sec, &info);
565         if (MESHD_ERROR_NONE != ret) {
566                 MESH_LOGE("Failed to _select_matched_network");
567                 return ret;
568         }
569
570         ret = mesh_gdbus_remove_network(service, info);
571         if (MESHD_ERROR_NONE != ret) {
572                 MESH_LOGE("Failed to remove mesh network");
573                 return ret;
574         }
575
576         return MESHD_ERROR_NONE;
577 }
578
579 /* Notifications */
580 void mesh_notify_scan_done()
581 {
582         NetMesh *object = meshd_dbus_get_object();
583
584         net_mesh_emit_scan_done(object);
585 }
586
587 void mesh_notify_connection_state(const char* mesh_id, const char* bssid,
588                 int channel, meshd_security_type_e sec, meshd_connection_state_e state)
589 {
590         NetMesh *object = meshd_dbus_get_object();
591
592         net_mesh_emit_connection_state(object, mesh_id, bssid, channel, (int)sec, (int)state);
593 }
594
595 void mesh_notify_station_joined(const char* bssid)
596 {
597         NetMesh *object = meshd_dbus_get_object();
598
599         net_mesh_emit_sta_joined(object, bssid);
600 }
601
602 void mesh_notify_station_left(const char* bssid)
603 {
604         NetMesh *object = meshd_dbus_get_object();
605
606         net_mesh_emit_sta_left(object, bssid);
607 }