Demonize hostapd
[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         ret = mesh_interface_check_bridge_interface_exists(bridge_interface, interface);
149         if (MESHD_ERROR_NONE != ret) {
150                 MESH_LOGD("Interface is not exist in bridge");
151                 return MESHD_ERROR_NONE;
152         }
153
154         /* Remove external interface into bridge */
155         ret = mesh_bridge_del_interface(bridge_interface, interface);
156         if (MESHD_ERROR_NONE != ret) {
157                 MESH_LOGE("Failed to remove interface !");
158                 return ret;
159         }
160
161         return MESHD_ERROR_NONE;
162 }
163
164 int mesh_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 = MESHD_ERROR_NONE;
169
170         MESH_LOGD("Setting configuration for SoftAP");
171
172         ret = mesh_softap_set_configuration(softap_interface, ssid, mode, channel,
173                         visibility, max_sta, security, passphrase);
174         if (MESHD_ERROR_NONE != ret) {
175                 MESH_LOGE("Failed to set Configuration for SoftAP");
176                 return ret;
177         }
178
179         return ret;
180 }
181
182 int mesh_request_enable_softap(
183                 const char* bridge_interface, const char* softap_interface)
184 {
185         int ret = MESHD_ERROR_NONE;
186
187         MESH_LOGD("Request to turn SoftAP on");
188         ret = mesh_softap_enable_softap(softap_interface);
189         if (MESHD_ERROR_NONE != ret) {
190                 MESH_LOGE("Failed to mesh_softap_enable_softap");
191                 return ret;
192         }
193
194         /* Add softAP interface into bridge */
195         ret = mesh_request_add_bridge_interface(bridge_interface, softap_interface);
196         if (MESHD_ERROR_NONE != ret) {
197                 mesh_softap_disable_softap();
198                 return ret;
199         }
200
201         return ret;
202 }
203
204 int mesh_request_disable_softap(
205                 const char* bridge_interface, const char* softap_interface)
206 {
207         int ret = MESHD_ERROR_NONE;
208
209         MESH_LOGD("Request to turn SoftAP off");
210         ret = mesh_softap_disable_softap();
211
212         /* Remove softAP interface from bridge */
213         ret = mesh_request_remove_bridge_interface(bridge_interface, softap_interface);
214         if (MESHD_ERROR_NONE != ret)
215                 return ret;
216
217         return ret;
218 }
219
220 int mesh_request_get_station_info(const char* mesh_interface, GList **station_list)
221 {
222         int ret = MESHD_ERROR_NONE;
223
224         MESH_LOGD("Request to get station info");
225
226         /* Get station info */
227         ret = mesh_netlink_get_station_info(mesh_interface, station_list);
228         if (MESHD_ERROR_NONE != ret)
229                 return ret;
230
231         return MESHD_ERROR_NONE;
232 }
233
234 int mesh_request_get_mpath_info(const char* mesh_interface, GList **mpath_list)
235 {
236         int ret = MESHD_ERROR_NONE;
237
238         MESH_LOGD("Request to get mpath info");
239
240         /* Get MPath info */
241         ret = mesh_netlink_get_mpath_info(mesh_interface, mpath_list);
242         if (MESHD_ERROR_NONE != ret)
243                 return ret;
244
245         return MESHD_ERROR_NONE;
246 }
247
248 int mesh_request_register_event_handler()
249 {
250         int ret = MESHD_ERROR_NONE;
251
252         MESH_LOGD("Request to register mesh event handler");
253
254         /* Get MPath info */
255         ret = mesh_netlink_register_event_handler();
256         if (MESHD_ERROR_NONE != ret)
257                 return ret;
258
259         return MESHD_ERROR_NONE;
260 }
261
262 int mesh_request_unregister_event_handler()
263 {
264         int ret = MESHD_ERROR_NONE;
265
266         MESH_LOGD("Request to unregister mesh event handler");
267
268         /* Get MPath info */
269         ret = mesh_netlink_unregister_event_handler();
270         if (MESHD_ERROR_NONE != ret)
271                 return ret;
272
273         return MESHD_ERROR_NONE;
274 }
275
276 int mesh_request_enable_network(mesh_service *service)
277 {
278         int ret;
279         mesh_interface_s *info = NULL;
280
281         if (NULL == service) {
282                 MESH_LOGE("Invalid parameter");
283                 return MESHD_ERROR_INVALID_PARAMETER;
284         }
285
286         MESH_LOGD("[IPC] Enable mesh network");
287
288         /* Check if mesh interface exists */
289         info = service->interface_info;
290         ret = mesh_interface_check(info->mesh_interface);
291         if (MESHD_ERROR_NONE == ret) {
292                 /* Interface already exists */
293                 return MESHD_ERROR_NONE;
294         }
295
296         ret = mesh_gdbus_create_mesh_interface(service);
297         if (MESHD_ERROR_NONE != ret) {
298                 MESH_LOGE("Failed to create mesh network");
299                 return ret;
300         }
301
302         return MESHD_ERROR_NONE;
303 }
304
305 int mesh_request_disable_network(mesh_service *service)
306 {
307         int ret;
308         if (NULL == service) {
309                 MESH_LOGE("Invalid parameter");
310                 return MESHD_ERROR_INVALID_PARAMETER;
311         }
312
313         MESH_LOGD("[IPC] Disable mesh network");
314
315         ret = mesh_gdbus_remove_mesh_interface(service);
316         if (MESHD_ERROR_NONE != ret) {
317                 MESH_LOGE("Failed to disable mesh network");
318                 return ret;
319         }
320
321         return MESHD_ERROR_NONE;
322 }
323
324 int mesh_request_scan(mesh_service *service)
325 {
326         int ret;
327         if (NULL == service) {
328                 MESH_LOGE("Invalid parameter");
329                 return MESHD_ERROR_INVALID_PARAMETER;
330         }
331
332         MESH_LOGD("[IPC] Request scan for mesh network");
333
334         ret = mesh_gdbus_mesh_scan(service);
335         if (MESHD_ERROR_NONE != ret) {
336                 MESH_LOGE("Failed to request scan for mesh network");
337                 return ret;
338         }
339
340         return MESHD_ERROR_NONE;
341 }
342
343 int mesh_request_specific_scan(mesh_service *service, gchar *mesh_id, gint channel)
344 {
345         int ret;
346         if (NULL == service) {
347                 MESH_LOGE("Invalid parameter");
348                 return MESHD_ERROR_INVALID_PARAMETER;
349         }
350
351         MESH_LOGD("[IPC] Request specific scan for mesh network");
352
353         ret = mesh_gdbus_mesh_specific_scan(service, mesh_id, channel);
354         if (MESHD_ERROR_NONE != ret) {
355                 MESH_LOGE("Failed to request specific scan for mesh network");
356                 return ret;
357         }
358
359         return MESHD_ERROR_NONE;
360 }
361
362 int mesh_request_cancel_scan(mesh_service *service)
363 {
364         int ret;
365         if (NULL == service) {
366                 MESH_LOGE("Invalid parameter");
367                 return MESHD_ERROR_INVALID_PARAMETER;
368         }
369
370         MESH_LOGD("[IPC] Cancel scan for mesh network");
371
372         ret = mesh_gdbus_mesh_cancel_scan(service);
373         if (MESHD_ERROR_NONE != ret) {
374                 MESH_LOGE("Failed to cancel scan for mesh network");
375                 return ret;
376         }
377
378         return MESHD_ERROR_NONE;
379 }
380
381 int mesh_request_get_networks(mesh_service *service)
382 {
383         int ret;
384         if (NULL == service) {
385                 MESH_LOGE("Invalid parameter");
386                 return MESHD_ERROR_INVALID_PARAMETER;
387         }
388
389         MESH_LOGD("[IPC] Get mesh networks");
390
391         ret = mesh_gdbus_get_mesh_networks(service);
392         if (MESHD_ERROR_NONE != ret) {
393                 MESH_LOGE("Failed to get mesh networks !");
394                 return ret;
395         }
396
397         return MESHD_ERROR_NONE;
398 }
399
400 static int _select_matched_network(GList *scanned_network,
401                 const char *mesh_id, int mesh_channel, meshd_security_type_e sec,
402                 mesh_scan_result_s **info)
403 {
404         int ret = MESHD_ERROR_NONE;
405         GList *iter = NULL;
406         mesh_scan_result_s *item = NULL;
407         gboolean found = FALSE;
408
409         meshd_check_null_ret_error("scanned_network", scanned_network,
410                         MESHD_ERROR_INVALID_PARAMETER);
411
412         iter = scanned_network;
413         while (iter != NULL) {
414                 item = (mesh_scan_result_s*)iter->data;
415
416                 if (g_strcmp0(mesh_id, item->mesh_id) == 0) {
417                         if (item->channel == mesh_channel && item->security == sec) {
418                                 *info = item;
419                                 found = TRUE;
420                                 break;
421                         }
422                 }
423                 iter = g_list_next(iter);
424         }
425
426         if (FALSE == found)
427                 return MESHD_ERROR_NO_DATA;
428
429         return ret;
430 }
431
432 int mesh_request_get_joined_network(mesh_service *service)
433 {
434         int ret;
435
436         if (NULL == service) {
437                 MESH_LOGE("Invalid parameter");
438                 return MESHD_ERROR_INVALID_PARAMETER;
439         }
440
441         MESH_LOGD("[IPC] Get joined mesh network");
442
443         ret = mesh_gdbus_get_joined_mesh_network(service);
444         if (MESHD_ERROR_NONE != ret) {
445                 MESH_LOGE("Failed to get joined mesh network");
446                 return ret;
447         }
448
449         return MESHD_ERROR_NONE;
450 }
451
452 int mesh_request_get_connected_peers(mesh_service *service)
453 {
454         int ret;
455
456         if (NULL == service) {
457                 MESH_LOGE("Invalid parameter");
458                 return MESHD_ERROR_INVALID_PARAMETER;
459         }
460
461         MESH_LOGD("[IPC] Get connected mesh peers");
462
463         ret = mesh_gdbus_get_connected_peers(service);
464         if (MESHD_ERROR_NONE != ret) {
465                 MESH_LOGE("Failed to get connected mesh peers");
466                 return ret;
467         }
468
469         return MESHD_ERROR_NONE;
470 }
471
472 int mesh_request_create_mesh_network(mesh_service *service, gchar *mesh_id,
473                 gint channel, meshd_security_type_e sec)
474 {
475         int ret;
476
477         if (NULL == service) {
478                 MESH_LOGE("Invalid parameter");
479                 return MESHD_ERROR_INVALID_PARAMETER;
480         }
481
482         MESH_LOGD("[IPC] Create a new mesh network");
483
484         ret = mesh_gdbus_create_network(service, mesh_id, channel, sec);
485         if (MESHD_ERROR_NONE != ret) {
486                 MESH_LOGE("Failed to create mesh network");
487                 return ret;
488         }
489
490         return MESHD_ERROR_NONE;
491 }
492
493 int mesh_request_connect_mesh_network(mesh_service *service, gchar *mesh_id,
494                 gint channel, meshd_security_type_e sec, gchar *passphrase)
495 {
496         int ret;
497         mesh_scan_result_s *info = NULL;
498
499         if (NULL == service) {
500                 MESH_LOGE("Invalid parameter");
501                 return MESHD_ERROR_INVALID_PARAMETER;
502         }
503
504         MESH_LOGD("[IPC] Connect mesh network");
505
506         /* Get mesh_id and channel from saved network */
507         ret = _select_matched_network(service->scanned_mesh_network,
508                         mesh_id, channel, sec, &info);
509         if (MESHD_ERROR_NONE != ret) {
510                 MESH_LOGE("Failed to mesh_network_get_first_mesh_network");
511                 return ret;
512         }
513
514         /* Set passphrase */
515         if (MESHD_SECURITY_NONE != sec) {
516                 if (NULL != passphrase) {
517                         ret = mesh_gdbus_set_passphrase(service, info, passphrase);
518                         if (MESHD_ERROR_NONE != ret) {
519                                 MESH_LOGE("Failed to set passphrase for mesh network");
520                                 return ret;
521                         }
522                 } else {
523                         MESH_LOGE("Passphrase is required !");
524                         return MESHD_ERROR_INVALID_PARAMETER;
525                 }
526         }
527
528         ret = mesh_gdbus_connect_network(service, info);
529         if (MESHD_ERROR_NONE != ret) {
530                 MESH_LOGE("Failed to connect mesh network");
531                 return ret;
532         }
533
534         return MESHD_ERROR_NONE;
535 }
536
537 int mesh_request_disconnect_mesh_network(mesh_service *service,
538                 gchar *mesh_id, gint channel, meshd_security_type_e sec)
539 {
540         int ret;
541         mesh_scan_result_s *info = NULL;
542
543         if (NULL == service) {
544                 MESH_LOGE("Invalid parameter");
545                 return MESHD_ERROR_INVALID_PARAMETER;
546         }
547
548         MESH_LOGD("[IPC] Disconnect mesh network");
549
550         /* Get mesh_id and channel from saved network */
551         ret = _select_matched_network(service->scanned_mesh_network,
552                         mesh_id, channel, sec, &info);
553         if (MESHD_ERROR_NONE != ret) {
554                 MESH_LOGE("Failed to _select_matched_network");
555                 return ret;
556         }
557
558         ret = mesh_gdbus_disconnect_network(service, info);
559         if (MESHD_ERROR_NONE != ret) {
560                 MESH_LOGE("Failed to disconnect mesh network");
561                 return ret;
562         }
563
564         return MESHD_ERROR_NONE;
565 }
566
567 int mesh_request_remove_mesh_network(mesh_service *service,
568                 gchar *mesh_id, gint channel, meshd_security_type_e sec)
569 {
570         int ret;
571         mesh_scan_result_s *info = NULL;
572
573         if (NULL == service) {
574                 MESH_LOGE("Invalid parameter");
575                 return MESHD_ERROR_INVALID_PARAMETER;
576         }
577
578         MESH_LOGD("[IPC] Remove mesh network");
579
580         /* Get mesh_id and channel from saved network */
581         ret = _select_matched_network(service->scanned_mesh_network,
582                         mesh_id, channel, sec, &info);
583         if (MESHD_ERROR_NONE != ret) {
584                 MESH_LOGE("Failed to _select_matched_network");
585                 return ret;
586         }
587
588         ret = mesh_gdbus_remove_network(service, info);
589         if (MESHD_ERROR_NONE != ret) {
590                 MESH_LOGE("Failed to remove mesh network");
591                 return ret;
592         }
593
594         return MESHD_ERROR_NONE;
595 }
596
597 /* Notifications */
598 void mesh_notify_scan_done()
599 {
600         NetMesh *object = meshd_dbus_get_object();
601
602         net_mesh_emit_scan_done(object);
603 }
604
605 void mesh_notify_connection_state(const char* mesh_id, const char* bssid,
606                 int channel, meshd_security_type_e sec, meshd_connection_state_e state)
607 {
608         NetMesh *object = meshd_dbus_get_object();
609
610         net_mesh_emit_connection_state(object, mesh_id, bssid, channel, (int)sec, (int)state);
611 }
612
613 void mesh_notify_station_joined(const char* bssid)
614 {
615         NetMesh *object = meshd_dbus_get_object();
616
617         net_mesh_emit_sta_joined(object, bssid);
618 }
619
620 void mesh_notify_station_left(const char* bssid)
621 {
622         NetMesh *object = meshd_dbus_get_object();
623
624         net_mesh_emit_sta_left(object, bssid);
625 }