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