Add getting global ipaddr function
[platform/core/api/thread.git] / tests / thread-test / thread-network.c
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <sys/time.h>
22 #include <sys/socket.h>
23 #include <unistd.h>
24 #include <errno.h>
25
26 #include <glib.h>
27 #include <gio/gio.h>
28
29 #include "thread.h"
30 #include "thread-menu.h"
31 #include "thread-type.h"
32 #include "thread-log.h"
33 #include "thread-util.h"
34
35 static char g_name[NETWORK_DATA_SIZE + 1] = {"Thread-test"};
36 static char g_key[NETWORK_DATA_SIZE + 1];
37 static char g_pskc[NETWORK_DATA_SIZE + 1];
38 static char g_str_channel[NETWORK_DATA_SIZE + 1] = {"07fff800"};
39 static char g_str_extended_panid[NETWORK_DATA_SIZE + 1] = {"18446744073709551615"}; /* UINT64_MAX */
40 static char g_str_panid[NETWORK_DATA_SIZE + 1] = {"65535"}; /* UINT16_MAX */
41 static char g_str_buf_length[NETWORK_DATA_SIZE + 1];
42 static char g_str_tlvs_buffer[2*NETWORK_DATA_SIZE + 1];
43 static thread_network_h g_network;
44
45 static char g_str_ipaddr_type[NETWORK_DATA_SIZE + 1] = "0";
46 static char g_str_ipaddr[NETWORK_DATA_SIZE + 1];
47
48 static uint8_t g_ipv6_address[THREAD_IPV6_ADDRESS_SIZE];
49
50 static int run_thread_network_destroy_operational_network(MManager *mm, struct menu_data *menu)
51 {
52         FUNC_ENTRY;
53         thread_instance_h g_instance = mm->t_instance;
54         if (g_instance == NULL)
55                 goto OUT;
56
57         int ret = thread_unset_operational_network(g_instance);
58         if (ret == THREAD_ERROR_NONE)
59                 msg("thread_unset_operational_network success");
60         else
61                 msg("thread_unset_operational_network failed");
62
63         ret = thread_network_destroy(g_network);
64         if (ret == THREAD_ERROR_NONE)
65                 msg("thread_network_destroy success");
66         else
67                 msg("thread_network_destroy failed");
68 OUT:
69         FUNC_EXIT;
70         return RET_SUCCESS;
71 }
72
73 static int run_thread_network_create_operational_network(MManager *mm, struct menu_data *menu)
74 {
75         FUNC_ENTRY;
76         uint32_t channel = 0;
77         uint64_t extended_panid = 0;
78         uint16_t panid = 0;
79         thread_instance_h g_instance = mm->t_instance;
80         if (g_instance == NULL)
81                 goto OUT;
82
83         sscanf(g_str_channel, "%x", &channel);
84         sscanf(g_str_extended_panid, "%zu", (size_t *)&extended_panid);
85         sscanf(g_str_panid, "%hu", &panid);
86
87         int ret = thread_network_create(&g_network);
88         if (ret == THREAD_ERROR_NONE)
89                 msg("thread_network_create success");
90         else
91                 msg("thread_network_create failed");
92
93         ret = thread_network_set_name(g_network, g_name);
94         if (ret == THREAD_ERROR_NONE)
95                 msg("thread_network_set_name success");
96         else
97                 msg("thread_network_set_name failed");
98
99         ret = thread_network_set_key(g_network, g_key);
100         if (ret == THREAD_ERROR_NONE)
101                 msg("thread_network_set_key success");
102         else
103                 msg("thread_network_set_key failed");
104
105         ret = thread_network_set_pskc(g_network, g_pskc);
106         if (ret == THREAD_ERROR_NONE)
107                 msg("thread_network_set_pskc success");
108         else
109                 msg("thread_network_set_pskc failed");
110
111         ret = thread_network_set_channel(g_network, channel);
112         if (ret == THREAD_ERROR_NONE)
113                 msg("thread_network_set_channel success");
114         else
115                 msg("thread_network_set_channel failed");
116
117         ret = thread_network_set_extended_panid(g_network, extended_panid);
118         if (ret == THREAD_ERROR_NONE)
119                 msg("thread_network_set_extended_panid success");
120         else
121                 msg("thread_network_set_extended_panid failed");
122
123         ret = thread_network_set_panid(g_network, panid);
124         if (ret == THREAD_ERROR_NONE)
125                 msg("thread_network_set_panid success");
126         else
127                 msg("thread_network_set_panid failed");
128
129         ret = thread_set_operational_network(g_instance, g_network);
130         if (ret == THREAD_ERROR_NONE)
131                 msg("thread_set_operational_network success");
132         else
133                 msg("thread_set_operational_network failed");
134 OUT:
135         FUNC_EXIT;
136         return RET_SUCCESS;
137 }
138
139 static int run_thread_network_set_active_dataset_tlvs(MManager *mm, struct menu_data *menu)
140 {
141         FUNC_ENTRY;
142         thread_instance_h g_instance = mm->t_instance;
143         if (g_instance == NULL)
144                 goto OUT;
145
146         int buf_length;
147         uint8_t tlvs_buffer[1024];
148
149         sscanf(g_str_buf_length, "%d", &buf_length);
150         msg("Set active dataset tlvs size: %d :: %s",
151                                 buf_length, g_str_tlvs_buffer);
152
153         if (!buf_length || buf_length > (MENU_DATA_SIZE + 1)) {
154                 msg("Invalid Input");
155                 goto OUT;
156         }
157         for (int i = 0; i < buf_length; i++) {
158                 char subbuff[3];
159                 memcpy(subbuff, &g_str_tlvs_buffer[2*i], 2);
160                 subbuff[2] = '\0';
161                 tlvs_buffer[i] = (uint8_t)strtol(subbuff, NULL, 16);
162         }
163
164         int ret = thread_network_set_active_dataset_tlvs(
165                         g_instance, tlvs_buffer, buf_length);
166         if (ret == THREAD_ERROR_NONE)
167                 msg("thread_network_set_active_dataset_tlvs success");
168         else
169                 msg("thread_network_set_active_dataset_tlvs failed");
170 OUT:
171         FUNC_EXIT;
172         return RET_SUCCESS;
173 }
174
175 static int run_thread_network_get_active_dataset_tlvs(MManager *mm, struct menu_data *menu)
176 {
177         FUNC_ENTRY;
178
179         uint8_t *tlvs_buffer = NULL;
180         char buf[1024];
181         int buf_length;
182
183         thread_instance_h g_instance = mm->t_instance;
184         if (g_instance == NULL)
185                 goto OUT;
186
187         int ret = thread_network_get_active_dataset_tlvs(g_instance, &tlvs_buffer, &buf_length);
188         if (ret == THREAD_ERROR_NONE) {
189                 msg("thread_network_get_active_dataset_tlvs success");
190
191                 for (int i = 0; i < buf_length; i++)
192                         snprintf(buf + i*2, 3, "%2.2x", tlvs_buffer[i]);
193
194                 msg("Active dataset tlvs size: %d :: %s", buf_length, buf);
195         } else {
196                 msg("thread_network_get_active_dataset_tlvs failed");
197         }
198 OUT:
199         if (tlvs_buffer)
200                 free(tlvs_buffer);
201
202         FUNC_EXIT;
203         return RET_SUCCESS;
204 }
205
206 static int run_thread_network_attach(MManager *mm, struct menu_data *menu)
207 {
208         FUNC_ENTRY;
209         thread_instance_h g_instance = mm->t_instance;
210         if (g_instance == NULL)
211                 goto OUT;
212
213         int ret = thread_network_attach(g_instance);
214         if (ret == THREAD_ERROR_NONE)
215                 msg("thread_network_attach success");
216         else
217                 msg("thread_network_attach failed");
218 OUT:
219         FUNC_EXIT;
220         return RET_SUCCESS;
221 }
222
223 static int run_thread_network_detach(MManager *mm, struct menu_data *menu)
224 {
225         FUNC_ENTRY;
226         thread_instance_h g_instance = mm->t_instance;
227         if (g_instance == NULL)
228                 goto OUT;
229
230         int ret = thread_network_detach(g_instance);
231         if (ret == THREAD_ERROR_NONE)
232                 msg("thread_network_detach success");
233         else
234                 msg("thread_network_detach failed");
235 OUT:
236         FUNC_EXIT;
237         return RET_SUCCESS;
238 }
239
240 static void __get_ipaddr_callback(int index, char* ipaddr,
241                         thread_ipaddr_type_e ipaddr_type, void *user_data) {
242         FUNC_ENTRY;
243
244         if (index == 1)
245                 msg("IP address type: %s", _thread_ipaddr_type_to_string(ipaddr_type));
246         msg("IP address count: %d, ipv6 address: %s", index, ipaddr);
247
248         FUNC_EXIT;
249 }
250
251 static int run_thread_get_ipaddr(MManager *mm, struct menu_data *menu)
252 {
253         FUNC_ENTRY;
254         thread_instance_h g_instance = mm->t_instance;
255         if (g_instance == NULL)
256                 goto OUT;
257
258         int type = atoi(g_str_ipaddr_type);
259         thread_ipaddr_type_e ipaddr_type;
260         switch (type) {
261         case 0:
262                 ipaddr_type = THREAD_IPADDR_TYPE_ALL;
263                 break;
264         case 1:
265                 ipaddr_type = THREAD_IPADDR_TYPE_LINK_LOCAL;
266                 break;
267         case 2:
268                 ipaddr_type = THREAD_IPADDR_TYPE_RLOC;
269                 break;
270         case 3:
271                 ipaddr_type = THREAD_IPADDR_TYPE_MLEID;
272                 break;
273         default:
274                 goto OUT;
275         }
276
277         int ret = thread_get_ipaddr(g_instance, __get_ipaddr_callback, ipaddr_type, NULL);
278         if (ret == THREAD_ERROR_NONE)
279                 msg("thread_get_ipaddr success");
280         else
281                 msg("thread_get_ipaddr failed");
282 OUT:
283         FUNC_EXIT;
284         return RET_SUCCESS;
285 }
286
287 static int run_thread_add_ipaddr(MManager *mm, struct menu_data *menu)
288 {
289         FUNC_ENTRY;
290         thread_instance_h g_instance = mm->t_instance;
291         if (g_instance == NULL)
292                 goto OUT;
293
294         int ret = _preprocess_ipv6_prefix(g_str_ipaddr, g_ipv6_address);
295         retv_if(ret != THREAD_ERROR_NONE, ret);
296
297         ret = thread_add_ipaddr(g_instance, g_ipv6_address);
298         if (ret == THREAD_ERROR_NONE)
299                 msg("thread_add_ipaddr success");
300         else
301                 msg("thread_add_ipaddr failed");
302 OUT:
303         FUNC_EXIT;
304         return RET_SUCCESS;
305 }
306
307 static int run_thread_remove_ipaddr(MManager *mm, struct menu_data *menu)
308 {
309         FUNC_ENTRY;
310         thread_instance_h g_instance = mm->t_instance;
311         if (g_instance == NULL)
312                 goto OUT;
313
314         int ret = _preprocess_ipv6_prefix(g_str_ipaddr, g_ipv6_address);
315         retv_if(ret != THREAD_ERROR_NONE, ret);
316
317         ret = thread_remove_ipaddr(g_instance, g_ipv6_address);
318         if (ret == THREAD_ERROR_NONE)
319                 msg("thread_remove_ipaddr success");
320         else
321                 msg("thread_remove_ipaddr failed");
322 OUT:
323         FUNC_EXIT;
324         return RET_SUCCESS;
325 }
326
327 static int run_thread_get_global_ipaddr(MManager *mm, struct menu_data *menu)
328 {
329         FUNC_ENTRY;
330         thread_instance_h g_instance = mm->t_instance;
331         const char *ipaddr;
332         if (g_instance == NULL)
333                 goto OUT;
334
335         int ret = thread_get_global_ipaddr(g_instance, &ipaddr);
336         if (ret == THREAD_ERROR_NONE) {
337                 msg("thread_get_ipaddr_global success");
338                 msg("ipaddr: %s", ipaddr);
339         } else {
340                 msg("thread_get_ipaddr_global failed");
341         }
342 OUT:
343         FUNC_EXIT;
344         return RET_SUCCESS;
345 }
346
347 static struct menu_data menu_thread_network_set_active_dataset_tlvs[] = {
348         { "1", "Tlvs_buffer len", NULL, NULL, g_str_buf_length},
349         { "2", "Tlvs_buffer", NULL, NULL, g_str_tlvs_buffer},
350         { "3", "run", NULL, run_thread_network_set_active_dataset_tlvs, NULL},
351         { NULL, NULL, },
352 };
353
354 static struct menu_data menu_thread_network_create_operational_network[] = {
355         { "1", "Network Name", NULL, NULL, g_name},
356         { "2", "Network Key", NULL, NULL, g_key},
357         { "3", "Network pskc", NULL, NULL, g_pskc},
358         { "4", "Network Channel", NULL, NULL, g_str_channel},
359         { "5", "Network Extended Panid", NULL, NULL, g_str_extended_panid},
360         { "6", "Network panid", NULL, NULL, g_str_panid},
361         { "7", "run", NULL, run_thread_network_create_operational_network, NULL},
362         { NULL, NULL, },
363 };
364
365 static struct menu_data menu_thread_get_ipaddr[] = {
366         { "1", "Node Addr Type: ALL > 0, LINK LOCAL > 1, RLOC > 2, MLEID > 3",
367                                 NULL, NULL, g_str_ipaddr_type},
368         { "2", "run", NULL, run_thread_get_ipaddr, NULL},
369         { NULL, NULL, },
370 };
371
372 static struct menu_data menu_thread_add_ipaddr[] = {
373         { "1", "Type IPv6 address", NULL, NULL, g_str_ipaddr},
374         { "2", "run", NULL, run_thread_add_ipaddr, NULL},
375         { NULL, NULL, },
376 };
377
378 static struct menu_data menu_thread_remove_ipaddr[] = {
379         { "1", "Type IPv6 address", NULL, NULL, g_str_ipaddr},
380         { "2", "run", NULL, run_thread_remove_ipaddr, NULL},
381         { NULL, NULL, },
382 };
383
384 struct menu_data menu_thread_network[] = {
385         { "1", "thread_network_create_operational_network",
386                 menu_thread_network_create_operational_network, NULL, NULL},
387         { "2", "thread_network_destroy_operational_network",
388                 NULL, run_thread_network_destroy_operational_network, NULL },
389         { "3", "thread_network_set_active_dataset_tlvs",
390                 menu_thread_network_set_active_dataset_tlvs, NULL, NULL},
391         { "4", "thread_network_get_active_dataset_tlvs",
392                 NULL, run_thread_network_get_active_dataset_tlvs, NULL },
393         { "5", "thread_network_attach",
394                 NULL, run_thread_network_attach, NULL},
395         { "6", "thread_network_detach",
396                 NULL, run_thread_network_detach, NULL},
397         { "7", "thread_get_ipaddr",
398                 menu_thread_get_ipaddr, NULL, NULL},
399         { "8", "thread_add_ipaddr",
400                 menu_thread_add_ipaddr, NULL, NULL},
401         { "9", "thread_remove_ipaddr",
402                 menu_thread_remove_ipaddr, NULL, NULL},
403         { "10", "thread_get_global_ipaddr",
404                 NULL, run_thread_get_global_ipaddr, NULL},
405         { NULL, NULL, },
406 };
407