Add new dbus method to get SoftAP Config options
[platform/core/connectivity/wifi-mesh-manager.git] / src / wmesh-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 "wmesh.h"
25 #include "wmesh-log.h"
26 #include "wmesh-util.h"
27 #include "wmesh-service-interface.h"
28 #include "wmesh-generated-code.h"
29
30 #include "wmesh-bridge.h"
31 #include "wmesh-netlink.h"
32 #include "wmesh-interface.h"
33 #include "wmesh-request.h"
34 #include "wmesh-softap.h"
35 #include "wmesh-gdbus.h"
36
37 int wmesh_request_set_mesh_gate(const char* bridge_interface,
38                 const char* mesh_interface, const char* external_interface)
39 {
40         int ret = WMESHD_ERROR_NONE;
41         bool state = FALSE;
42
43         ret = wmesh_interface_check_external_exists(external_interface, &state);
44         if (WMESHD_ERROR_NONE != ret) {
45                 WMESH_LOGE("Failed to get external interface state !");
46                 return WMESHD_ERROR_OPERATION_FAILED;
47         }
48         WMESH_LOGD("  Ethernet cable state [%s]",
49                 (state) ? "Connected" : "Disconnected");
50
51         /* Turn STP on */
52         ret = wmesh_bridge_set_stp(bridge_interface, TRUE);
53         if (WMESHD_ERROR_NONE != ret) {
54                 WMESH_LOGE("Failed to turn STP on !");
55                 return ret;
56         }
57
58         /* Set mesh parameters */
59         ret = wmesh_netlink_set_mesh_parameter(mesh_interface,
60                         "mesh_hwmp_rootmode", 4);
61         if (WMESHD_ERROR_NONE != ret)
62                 WMESH_LOGE("Failed to set [mesh_hwmp_rootmode] : 4");
63
64         ret = wmesh_netlink_set_mesh_parameter(mesh_interface,
65                         "mesh_gate_announcements", 1);
66         if (WMESHD_ERROR_NONE != ret)
67                 WMESH_LOGE("Failed to set [mesh_gate_announcements] : 1");
68
69         return WMESHD_ERROR_NONE;
70 }
71
72 int wmesh_request_unset_mesh_gate(const char* bridge_interface,
73                 const char* mesh_interface, const char* external_interface)
74 {
75         int ret = WMESHD_ERROR_NONE;
76
77         NOTUSED(external_interface);
78
79         /* Set mesh parameters */
80         ret = wmesh_netlink_set_mesh_parameter(mesh_interface,
81                         "mesh_hwmp_rootmode", 0);
82         if (WMESHD_ERROR_NONE != ret)
83                 WMESH_LOGE("Failed to set [mesh_hwmp_rootmode] : 0");
84
85         ret = wmesh_netlink_set_mesh_parameter(mesh_interface,
86                         "mesh_gate_announcements", 0);
87         if (WMESHD_ERROR_NONE != ret)
88                 WMESH_LOGE("Failed to set [mesh_gate_announcements] : 0");
89
90         /* Turn STP off */
91         ret = wmesh_bridge_set_stp(bridge_interface, FALSE);
92         if (WMESHD_ERROR_NONE != ret) {
93                 WMESH_LOGE("Failed to turn STP off!");
94                 return ret;
95         }
96
97         return WMESHD_ERROR_NONE;
98 }
99
100 int wmesh_request_add_bridge_interface(const char* bridge_interface,
101                 const char* interface)
102 {
103         int ret = WMESHD_ERROR_NONE;
104
105         if (NULL == bridge_interface || NULL == interface) {
106                 WMESH_LOGE("Invalid parameters");
107                 return WMESHD_ERROR_INVALID_PARAMETER;
108         }
109
110         WMESH_LOGD("Adding interface[%s] into bridge[%s]...", interface, bridge_interface);
111
112         /* Add external interface into bridge */
113         ret = wmesh_bridge_add_interface(bridge_interface, interface);
114         if (WMESHD_ERROR_NONE != ret) {
115                 WMESH_LOGE("Failed to add interface !");
116                 return ret;
117         }
118
119         /* Make external interface down */
120         ret = wmesh_interface_set(interface, NULL, WMESH_INTERFACE_DOWN);
121         if (WMESHD_ERROR_NONE != ret) {
122                 WMESH_LOGE("Failed to change external interface state");
123                 return ret;
124         }
125
126         /* Make external interface up with cleared IP */
127         ret = wmesh_interface_set(interface, "0.0.0.0", WMESH_INTERFACE_UP);
128         if (WMESHD_ERROR_NONE != ret) {
129                 WMESH_LOGE("Failed to change external interface state");
130                 return ret;
131         }
132
133         return WMESHD_ERROR_NONE;
134 }
135
136 int wmesh_request_remove_bridge_interface(const char* bridge_interface,
137                 const char* interface)
138 {
139         int ret = WMESHD_ERROR_NONE;
140
141         if (NULL == bridge_interface || NULL == interface) {
142                 WMESH_LOGE("Invalid parameters");
143                 return WMESHD_ERROR_INVALID_PARAMETER;
144         }
145
146         WMESH_LOGD("Removing interface[%s] from bridge[%s]...", interface, bridge_interface);
147
148         ret = wmesh_interface_check_bridge_interface_exists(bridge_interface, interface);
149         if (WMESHD_ERROR_NONE != ret) {
150                 WMESH_LOGD("Interface is not exist in bridge");
151                 return WMESHD_ERROR_NONE;
152         }
153
154         /* Remove external interface into bridge */
155         ret = wmesh_bridge_del_interface(bridge_interface, interface);
156         if (WMESHD_ERROR_NONE != ret) {
157                 WMESH_LOGE("Failed to remove interface !");
158                 return ret;
159         }
160
161         return WMESHD_ERROR_NONE;
162 }
163
164 int wmesh_request_set_softap_config(const char* softap_interface,
165                 const char *ssid, const char* mode, int channel, int visibility,
166                 int max_sta, int security, const char* passphrase)
167 {
168         int ret = WMESHD_ERROR_NONE;
169
170         WMESH_LOGD("Setting configuration for SoftAP");
171
172         ret = wmesh_softap_set_configuration(softap_interface, ssid, mode, channel,
173                         visibility, max_sta, security, passphrase);
174         if (WMESHD_ERROR_NONE != ret) {
175                 WMESH_LOGE("Failed to set Configuration for SoftAP");
176                 return ret;
177         }
178
179         return ret;
180 }
181
182 int wmesh_request_get_softap_config(char **softap_interface, char **ssid,
183                         char **mode, int *channel, int *visibility,
184                 int *max_sta, int *security, char **passphrase)
185 {
186         int ret = WMESHD_ERROR_NONE;
187
188         WMESH_LOGD("Get configuration for SoftAP");
189
190         ret = wmesh_softap_get_configuration(softap_interface, ssid, mode, channel,
191                         visibility, max_sta, security, passphrase);
192         if (WMESHD_ERROR_NONE != ret) {
193                 WMESH_LOGE("Failed to get Configuration for SoftAP");
194                 return ret;
195         }
196
197         return ret;
198 }
199
200 int wmesh_request_enable_softap(
201                 const char* bridge_interface, const char* softap_interface)
202 {
203         int ret = WMESHD_ERROR_NONE;
204
205         WMESH_LOGD("Request to turn SoftAP on");
206         ret = wmesh_softap_enable_softap(softap_interface);
207         if (WMESHD_ERROR_NONE != ret) {
208                 WMESH_LOGE("Failed to wmesh_softap_enable_softap");
209                 return ret;
210         }
211
212         /* Add softAP interface into bridge */
213         ret = wmesh_request_add_bridge_interface(bridge_interface, softap_interface);
214         if (WMESHD_ERROR_NONE != ret) {
215                 wmesh_softap_disable_softap();
216                 return ret;
217         }
218
219         return ret;
220 }
221
222 int wmesh_request_disable_softap(
223                 const char* bridge_interface, const char* softap_interface)
224 {
225         int ret = WMESHD_ERROR_NONE;
226
227         WMESH_LOGD("Request to turn SoftAP off");
228         ret = wmesh_softap_disable_softap();
229
230         /* Remove softAP interface from bridge */
231         ret = wmesh_request_remove_bridge_interface(bridge_interface, softap_interface);
232         if (WMESHD_ERROR_NONE != ret)
233                 return ret;
234
235         return ret;
236 }
237
238 int wmesh_request_get_station_info(const char* mesh_interface, GList **station_list)
239 {
240         int ret = WMESHD_ERROR_NONE;
241
242         WMESH_LOGD("Request to get station info");
243
244         /* Get station info */
245         ret = wmesh_netlink_get_station_info(mesh_interface, station_list);
246         if (WMESHD_ERROR_NONE != ret)
247                 return ret;
248
249         return WMESHD_ERROR_NONE;
250 }
251
252 int wmesh_request_get_mpath_info(const char* mesh_interface, GList **mpath_list)
253 {
254         int ret = WMESHD_ERROR_NONE;
255
256         WMESH_LOGD("Request to get mpath info");
257
258         /* Get MPath info */
259         ret = wmesh_netlink_get_mpath_info(mesh_interface, mpath_list);
260         if (WMESHD_ERROR_NONE != ret)
261                 return ret;
262
263         return WMESHD_ERROR_NONE;
264 }
265
266 int wmesh_request_get_meshconf_info(wmesh_service *service)
267 {
268         int ret = WMESHD_ERROR_NONE;
269
270         WMESH_LOGD("Request to get meshconf info");
271
272         /* Get MPath info */
273         ret = wmesh_netlink_get_meshconf_info(service);
274         if (WMESHD_ERROR_NONE != ret)
275                 return ret;
276
277         return WMESHD_ERROR_NONE;
278 }
279
280 int wmesh_request_register_event_handler()
281 {
282         int ret = WMESHD_ERROR_NONE;
283
284         WMESH_LOGD("Request to register mesh event handler");
285
286         /* Get MPath info */
287         ret = wmesh_netlink_register_event_handler();
288         if (WMESHD_ERROR_NONE != ret)
289                 return ret;
290
291         return WMESHD_ERROR_NONE;
292 }
293
294 int wmesh_request_unregister_event_handler()
295 {
296         int ret = WMESHD_ERROR_NONE;
297
298         WMESH_LOGD("Request to unregister mesh event handler");
299
300         /* Get MPath info */
301         ret = wmesh_netlink_unregister_event_handler();
302         if (WMESHD_ERROR_NONE != ret)
303                 return ret;
304
305         return WMESHD_ERROR_NONE;
306 }
307
308 int wmesh_request_enable_network(wmesh_service *service)
309 {
310         int ret;
311         wmesh_interface_s *info = NULL;
312
313         if (NULL == service) {
314                 WMESH_LOGE("Invalid parameter");
315                 return WMESHD_ERROR_INVALID_PARAMETER;
316         }
317
318         WMESH_LOGD("[IPC] Enable mesh network");
319
320         /* Check if mesh interface exists */
321         info = service->interface_info;
322         ret = wmesh_interface_check(info->mesh_interface);
323         if (WMESHD_ERROR_NONE == ret) {
324                 /* Interface already exists */
325                 return WMESHD_ERROR_NONE;
326         }
327
328         ret = wmesh_gdbus_create_mesh_interface(service);
329         if (WMESHD_ERROR_NONE != ret) {
330                 WMESH_LOGE("Failed to create mesh network");
331                 return ret;
332         }
333
334         return WMESHD_ERROR_NONE;
335 }
336
337 int wmesh_request_disable_network(wmesh_service *service)
338 {
339         int ret;
340         if (NULL == service) {
341                 WMESH_LOGE("Invalid parameter");
342                 return WMESHD_ERROR_INVALID_PARAMETER;
343         }
344
345         WMESH_LOGD("[IPC] Disable mesh network");
346
347         ret = wmesh_gdbus_remove_mesh_interface(service);
348         if (WMESHD_ERROR_NONE != ret) {
349                 WMESH_LOGE("Failed to disable mesh network");
350                 return ret;
351         }
352
353         return WMESHD_ERROR_NONE;
354 }
355
356 int wmesh_request_scan(wmesh_service *service)
357 {
358         int ret;
359         if (NULL == service) {
360                 WMESH_LOGE("Invalid parameter");
361                 return WMESHD_ERROR_INVALID_PARAMETER;
362         }
363
364         WMESH_LOGD("[IPC] Request scan for mesh network");
365
366         ret = wmesh_gdbus_mesh_scan(service);
367         if (WMESHD_ERROR_NONE != ret) {
368                 WMESH_LOGE("Failed to request scan for mesh network");
369                 return ret;
370         }
371
372         return WMESHD_ERROR_NONE;
373 }
374
375 int wmesh_request_specific_scan(wmesh_service *service, gchar *mesh_id, gint channel)
376 {
377         int ret;
378         if (NULL == service) {
379                 WMESH_LOGE("Invalid parameter");
380                 return WMESHD_ERROR_INVALID_PARAMETER;
381         }
382
383         WMESH_LOGD("[IPC] Request specific scan for mesh network");
384
385         ret = wmesh_gdbus_mesh_specific_scan(service, mesh_id, channel);
386         if (WMESHD_ERROR_NONE != ret) {
387                 WMESH_LOGE("Failed to request specific scan for mesh network");
388                 return ret;
389         }
390
391         return WMESHD_ERROR_NONE;
392 }
393
394 int wmesh_request_cancel_scan(wmesh_service *service)
395 {
396         int ret;
397         if (NULL == service) {
398                 WMESH_LOGE("Invalid parameter");
399                 return WMESHD_ERROR_INVALID_PARAMETER;
400         }
401
402         WMESH_LOGD("[IPC] Cancel scan for mesh network");
403
404         ret = wmesh_gdbus_mesh_cancel_scan(service);
405         if (WMESHD_ERROR_NONE != ret) {
406                 WMESH_LOGE("Failed to cancel scan for mesh network");
407                 return ret;
408         }
409
410         return WMESHD_ERROR_NONE;
411 }
412
413 int wmesh_request_get_networks(wmesh_service *service)
414 {
415         int ret;
416         if (NULL == service) {
417                 WMESH_LOGE("Invalid parameter");
418                 return WMESHD_ERROR_INVALID_PARAMETER;
419         }
420
421         WMESH_LOGD("[IPC] Get mesh networks");
422
423         ret = wmesh_gdbus_get_mesh_networks(service);
424         if (WMESHD_ERROR_NONE != ret) {
425                 WMESH_LOGE("Failed to get mesh networks !");
426                 return ret;
427         }
428
429         return WMESHD_ERROR_NONE;
430 }
431
432 static int _select_matched_network(GList *scanned_network,
433                 const char *mesh_id, int mesh_channel, wmeshd_security_type_e sec,
434                 wmesh_scan_result_s **info)
435 {
436         int ret = WMESHD_ERROR_NONE;
437         GList *iter = NULL;
438         wmesh_scan_result_s *item = NULL;
439         gboolean found = FALSE;
440
441         wmeshd_check_null_ret_error("scanned_network", scanned_network,
442                         WMESHD_ERROR_INVALID_PARAMETER);
443
444         iter = scanned_network;
445         while (iter != NULL) {
446                 item = (wmesh_scan_result_s*)iter->data;
447
448                 if (g_strcmp0(mesh_id, item->mesh_id) == 0) {
449                         if (item->channel == mesh_channel && item->security == sec) {
450                                 *info = item;
451                                 found = TRUE;
452                                 break;
453                         }
454                 }
455                 iter = g_list_next(iter);
456         }
457
458         if (FALSE == found)
459                 return WMESHD_ERROR_NO_DATA;
460
461         return ret;
462 }
463
464 int wmesh_request_get_joined_network(wmesh_service *service)
465 {
466         int ret;
467
468         if (NULL == service) {
469                 WMESH_LOGE("Invalid parameter");
470                 return WMESHD_ERROR_INVALID_PARAMETER;
471         }
472
473         WMESH_LOGD("[IPC] Get joined mesh network");
474
475         ret = wmesh_gdbus_get_joined_mesh_network(service);
476         if (WMESHD_ERROR_NONE != ret) {
477                 WMESH_LOGE("Failed to get joined mesh network");
478                 return ret;
479         }
480
481         return WMESHD_ERROR_NONE;
482 }
483
484 int wmesh_request_get_connected_peers(wmesh_service *service)
485 {
486         int ret;
487
488         if (NULL == service) {
489                 WMESH_LOGE("Invalid parameter");
490                 return WMESHD_ERROR_INVALID_PARAMETER;
491         }
492
493         WMESH_LOGD("[IPC] Get connected mesh peers");
494
495         ret = wmesh_gdbus_get_connected_peers(service);
496         if (WMESHD_ERROR_NONE != ret) {
497                 WMESH_LOGE("Failed to get connected mesh peers");
498                 return ret;
499         }
500
501         return WMESHD_ERROR_NONE;
502 }
503
504 int wmesh_request_create_mesh_network(wmesh_service *service, gchar *mesh_id,
505                 gint channel, wmeshd_security_type_e sec)
506 {
507         int ret;
508
509         if (NULL == service) {
510                 WMESH_LOGE("Invalid parameter");
511                 return WMESHD_ERROR_INVALID_PARAMETER;
512         }
513
514         WMESH_LOGD("[IPC] Create a new mesh network");
515
516         ret = wmesh_gdbus_create_network(service, mesh_id, channel, sec);
517         if (WMESHD_ERROR_NONE != ret) {
518                 WMESH_LOGE("Failed to create mesh network");
519                 return ret;
520         }
521
522         return WMESHD_ERROR_NONE;
523 }
524
525 int wmesh_request_connect_mesh_network(wmesh_service *service, gchar *mesh_id,
526                 gint channel, wmeshd_security_type_e sec, gchar *passphrase)
527 {
528         int ret;
529         wmesh_scan_result_s *info = NULL;
530
531         if (NULL == service) {
532                 WMESH_LOGE("Invalid parameter");
533                 return WMESHD_ERROR_INVALID_PARAMETER;
534         }
535
536         WMESH_LOGD("[IPC] Connect mesh network");
537
538         /* Get mesh_id and channel from saved network */
539         ret = _select_matched_network(service->scanned_mesh_network,
540                         mesh_id, channel, sec, &info);
541         if (WMESHD_ERROR_NONE != ret) {
542                 WMESH_LOGE("Failed to mesh_network_get_first_mesh_network");
543                 return ret;
544         }
545
546         /* Set passphrase */
547         if (WMESHD_SECURITY_NONE != sec) {
548                 if (NULL != passphrase) {
549                         ret = wmesh_gdbus_set_passphrase(service, info, passphrase);
550                         if (WMESHD_ERROR_NONE != ret) {
551                                 WMESH_LOGE("Failed to set passphrase for mesh network");
552                                 return ret;
553                         }
554                 } else {
555                         WMESH_LOGE("Passphrase is required !");
556                         return WMESHD_ERROR_INVALID_PARAMETER;
557                 }
558         }
559
560         ret = wmesh_gdbus_connect_network(service, info);
561         if (WMESHD_ERROR_NONE != ret) {
562                 WMESH_LOGE("Failed to connect mesh network");
563                 return ret;
564         }
565
566         return WMESHD_ERROR_NONE;
567 }
568
569 int wmesh_request_disconnect_mesh_network(wmesh_service *service,
570                 gchar *mesh_id, gint channel, wmeshd_security_type_e sec)
571 {
572         int ret;
573         wmesh_scan_result_s *info = NULL;
574
575         if (NULL == service) {
576                 WMESH_LOGE("Invalid parameter");
577                 return WMESHD_ERROR_INVALID_PARAMETER;
578         }
579
580         WMESH_LOGD("[IPC] Disconnect mesh network");
581
582         /* Get mesh_id and channel from saved network */
583         ret = _select_matched_network(service->scanned_mesh_network,
584                         mesh_id, channel, sec, &info);
585         if (WMESHD_ERROR_NONE != ret) {
586                 WMESH_LOGE("Failed to _select_matched_network");
587                 return ret;
588         }
589
590         ret = wmesh_gdbus_disconnect_network(service, info);
591         if (WMESHD_ERROR_NONE != ret) {
592                 WMESH_LOGE("Failed to disconnect mesh network");
593                 return ret;
594         }
595
596         return WMESHD_ERROR_NONE;
597 }
598
599 int wmesh_request_remove_mesh_network(wmesh_service *service,
600                 gchar *mesh_id, gint channel, wmeshd_security_type_e sec)
601 {
602         int ret;
603         wmesh_scan_result_s *info = NULL;
604
605         if (NULL == service) {
606                 WMESH_LOGE("Invalid parameter");
607                 return WMESHD_ERROR_INVALID_PARAMETER;
608         }
609
610         WMESH_LOGD("[IPC] Remove mesh network");
611
612         /* Get mesh_id and channel from saved network */
613         ret = _select_matched_network(service->scanned_mesh_network,
614                         mesh_id, channel, sec, &info);
615         if (WMESHD_ERROR_NONE != ret) {
616                 WMESH_LOGE("Failed to _select_matched_network");
617                 return ret;
618         }
619
620         ret = wmesh_gdbus_remove_network(service, info);
621         if (WMESHD_ERROR_NONE != ret) {
622                 WMESH_LOGE("Failed to remove mesh network");
623                 return ret;
624         }
625
626         return WMESHD_ERROR_NONE;
627 }
628
629 /* Notifications */
630 void wmesh_notify_scan_done()
631 {
632         NetWmesh *object = wmeshd_dbus_get_object();
633
634         net_wmesh_emit_scan_done(object);
635 }
636
637 void wmesh_notify_connection_state(const char* mesh_id, const char* bssid,
638                 int channel, wmeshd_security_type_e sec, wmeshd_connection_state_e state)
639 {
640         NetWmesh *object = wmeshd_dbus_get_object();
641
642         net_wmesh_emit_connection_state(object, mesh_id, bssid, channel, (int)sec, (int)state);
643 }
644
645 void wmesh_notify_station_joined(const char* bssid)
646 {
647         NetWmesh *object = wmeshd_dbus_get_object();
648
649         net_wmesh_emit_sta_joined(object, bssid);
650 }
651
652 void wmesh_notify_station_left(const char* bssid)
653 {
654         NetWmesh *object = wmeshd_dbus_get_object();
655
656         net_wmesh_emit_sta_left(object, bssid);
657 }