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