Fix FC when cloning representation
[platform/core/iot/iotcon.git] / test / iotcon-test-basic-client.c
1 /*
2  * Copyright (c) 2015 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 #include <stdlib.h>
17 #include <glib.h>
18 #include <tizen_type.h>
19
20 #include <iotcon.h>
21 #include "test.h"
22
23 static char *door_resource_device_id;
24 static GList *device_id_list;
25
26 #define DOOR_RESOURCE_URI_PREFIX "/door"
27 #define DOOR_RESOURCE_TYPE "org.tizen.door"
28
29 static void _on_response(iotcon_remote_resource_h resource, iotcon_error_e err,
30                 iotcon_request_type_e request_type, iotcon_response_h response, void *user_data);
31
32 static void _on_observe(iotcon_remote_resource_h resource, iotcon_error_e err,
33                 int sequece_number, iotcon_response_h response, void *user_data)
34 {
35         int ret;
36         bool opened;
37         static int i = 0;
38         iotcon_state_h state;
39         iotcon_representation_h repr;
40         iotcon_response_result_e response_result;
41
42         ret = iotcon_response_get_result(response, &response_result);
43         if (IOTCON_ERROR_NONE != ret) {
44                 ERR("iotcon_response_get_result() Fail(%d)", ret);
45                 return;
46         }
47
48         if (IOTCON_RESPONSE_OK != response_result) {
49                 ERR("_on_response_observe Response error(%d)", response_result);
50                 return;
51         }
52
53         ret = iotcon_response_get_representation(response, &repr);
54         if (IOTCON_ERROR_NONE != ret) {
55                 ERR("iotcon_response_get_representation() Fail(%d)", ret);
56                 return;
57         }
58
59         ret = iotcon_representation_get_state(repr, &state);
60         if (IOTCON_ERROR_NONE != ret) {
61                 ERR("iotcon_representation_get_state() Fail(%d)", ret);
62                 return;
63         }
64
65         ret = iotcon_state_get_bool(state, "opened", &opened);
66         if (IOTCON_ERROR_NONE != ret) {
67                 ERR("iotcon_state_get_bool() Fail(%d)", ret);
68                 return;
69         }
70
71         INFO("notify_cb information");
72         switch (opened) {
73         case true:
74                 INFO("[Door] opened.");
75                 break;
76         case false:
77                 INFO("[Door] closed.");
78                 break;
79         default:
80                 break;
81         }
82
83         if (5 == i++) {
84                 iotcon_remote_resource_observe_deregister(resource);
85                 iotcon_remote_resource_destroy(resource);
86         }
87 }
88
89 static void _on_response_delete(iotcon_remote_resource_h resource,
90                 iotcon_response_h response, void *user_data)
91 {
92         int ret;
93         iotcon_response_result_e response_result;
94
95         ret = iotcon_response_get_result(response, &response_result);
96         if (IOTCON_ERROR_NONE != ret) {
97                 ERR("iotcon_response_get_result() Fail(%d)", ret);
98                 return;
99         }
100
101         if (IOTCON_RESPONSE_OK != response_result
102                         && IOTCON_RESPONSE_RESULT_DELETED != response_result) {
103                 ERR("_on_response_delete Response error(%d)", response_result);
104                 return;
105         }
106         INFO("DELETE request was successful");
107
108         /* delete callback operations */
109
110         iotcon_remote_resource_destroy(resource);
111 }
112
113 static void _on_response_post(iotcon_remote_resource_h resource,
114                 iotcon_response_h response, void *user_data)
115 {
116         iotcon_state_h recv_state;
117         char *host, *created_uri_path;
118         int ret, ifaces = 0;
119         iotcon_connectivity_type_e connectivity_type;
120         iotcon_response_result_e response_result;
121         iotcon_resource_types_h types = NULL;
122         iotcon_remote_resource_h new_door_resource;
123         iotcon_representation_h recv_repr = NULL;
124
125         ret = iotcon_response_get_result(response, &response_result);
126         if (IOTCON_ERROR_NONE != ret) {
127                 ERR("iotcon_response_get_result() Fail(%d)", ret);
128                 return;
129         }
130
131         if (IOTCON_RESPONSE_OK != response_result
132                         && IOTCON_RESPONSE_RESOURCE_CREATED != response_result) {
133                 ERR("_on_response_post Response error(%d)", response_result);
134                 return;
135         }
136         INFO("POST request was successful");
137
138         ret = iotcon_response_get_representation(response, &recv_repr);
139                 if (IOTCON_ERROR_NONE != ret) {
140                 ERR("iotcon_response_get_representation() Fail(%d)", ret);
141                 return;
142         }
143
144         ret = iotcon_representation_get_state(recv_repr, &recv_state);
145         if (IOTCON_ERROR_NONE != ret) {
146                 ERR("iotcon_representation_get_state() Fail(%d)", ret);
147                 return;
148         }
149
150         ret = iotcon_state_get_str(recv_state, "createduripath", &created_uri_path);
151         if (IOTCON_ERROR_NONE != ret) {
152                 ERR("iotcon_state_get_str() Fail(%d)", ret);
153                 return;
154         }
155         DBG("New resource created : %s", created_uri_path);
156
157         ret = iotcon_remote_resource_get_host_address(resource, &host);
158         if (IOTCON_ERROR_NONE != ret) {
159                 ERR("iotcon_remote_resource_get_host_address() Fail(%d)", ret);
160                 return;
161         }
162
163         ret = iotcon_remote_resource_get_connectivity_type(resource, &connectivity_type);
164         if (IOTCON_ERROR_NONE != ret) {
165                 ERR("iotcon_remote_resource_get_connectivity_type() Fail(%d)", ret);
166                 return;
167         }
168
169         ret = iotcon_remote_resource_get_types(resource, &types);
170         if (IOTCON_ERROR_NONE != ret) {
171                 ERR("iotcon_remote_resource_get_types() Fail(%d)", ret);
172                 return;
173         }
174
175         ret = iotcon_remote_resource_get_interfaces(resource, &ifaces);
176         if (IOTCON_ERROR_NONE != ret) {
177                 ERR("iotcon_remote_resource_get_interfaces() Fail(%d)", ret);
178                 return;
179         }
180
181         ret = iotcon_remote_resource_create(host, connectivity_type, created_uri_path,
182                         IOTCON_RESOURCE_NO_PROPERTY, types, ifaces, &new_door_resource);
183         if (IOTCON_ERROR_NONE != ret) {
184                 ERR("iotcon_remote_resource_create() Fail(%d)", ret);
185                 return;
186         }
187
188         ret = iotcon_remote_resource_delete(new_door_resource, _on_response, NULL);
189         if (IOTCON_ERROR_NONE != ret) {
190                 ERR("iotcon_remote_resource_delete() Fail(%d)", ret);
191                 iotcon_remote_resource_destroy(new_door_resource);
192                 return;
193         }
194 }
195
196 static void _on_response_put(iotcon_remote_resource_h resource, iotcon_response_h response,
197                 void *user_data)
198 {
199         int ret;
200         iotcon_response_result_e response_result;
201         iotcon_representation_h send_repr;
202
203         ret = iotcon_response_get_result(response, &response_result);
204         if (IOTCON_ERROR_NONE != ret) {
205                 ERR("iotcon_response_get_result() Fail(%d)", ret);
206                 return;
207         }
208
209         if (IOTCON_RESPONSE_OK != response_result) {
210                 ERR("_on_response_put Response error(%d)", response_result);
211                 return;
212         }
213         INFO("PUT request was successful");
214
215         ret = iotcon_representation_create(&send_repr);
216         if (IOTCON_ERROR_NONE != ret) {
217                 ERR("iotcon_representation_create() Fail(%d)", ret);
218                 return;
219         }
220
221         /* send POST request */
222         ret = iotcon_remote_resource_post(resource, send_repr, NULL, _on_response, NULL);
223         if (IOTCON_ERROR_NONE != ret)
224                 ERR("iotcon_remote_resource_post() Fail(%d)", ret);
225
226         iotcon_representation_destroy(send_repr);
227 }
228
229 static void _on_response_get(iotcon_remote_resource_h resource,
230                 iotcon_response_h response, void *user_data)
231 {
232         int ret;
233         bool opened = true;
234         iotcon_response_result_e response_result;
235         iotcon_representation_h send_repr;
236         iotcon_representation_h recv_repr;
237         iotcon_state_h send_state;
238         iotcon_state_h recv_state = NULL;
239
240         ret = iotcon_response_get_result(response, &response_result);
241         if (IOTCON_ERROR_NONE != ret) {
242                 ERR("iotcon_response_get_result() Fail(%d)", ret);
243                 return;
244         }
245
246         if (IOTCON_RESPONSE_OK != response_result) {
247                 ERR("_on_response_get Response error(%d)", response_result);
248                 return;
249         }
250
251         /* get the resource host address */
252         char *resource_host = NULL;
253         iotcon_remote_resource_get_host_address(resource, &resource_host);
254         INFO("resource host : %s", resource_host);
255
256         ret = iotcon_response_get_representation(response, &recv_repr);
257         if (IOTCON_ERROR_NONE != ret) {
258                 ERR("iotcon_response_get_representation() Fail(%d)", ret);
259                 return;
260         }
261
262         ret = iotcon_representation_get_state(recv_repr, &recv_state);
263         if (IOTCON_ERROR_NONE != ret) {
264                 ERR("iotcon_representation_get_state() Fail(%d)", ret);
265                 return;
266         }
267
268         ret = iotcon_state_get_bool(recv_state, "opened", &opened);
269         if (IOTCON_ERROR_NONE != ret) {
270                 ERR("iotcon_state_get_bool() Fail(%d)", ret);
271                 return;
272         }
273
274         ret = iotcon_representation_create(&send_repr);
275         if (IOTCON_ERROR_NONE != ret) {
276                 ERR("iotcon_representation_create() Fail(%d)", ret);
277                 return;
278         }
279
280         ret = iotcon_state_create(&send_state);
281         if (IOTCON_ERROR_NONE != ret) {
282                 ERR("iotcon_state_create() Fail(%d)", ret);
283                 iotcon_representation_destroy(send_repr);
284                 return;
285         }
286
287         ret = iotcon_state_add_bool(send_state, "opened", !opened);
288         if (IOTCON_ERROR_NONE != ret) {
289                 ERR("iotcon_state_add_bool() Fail(%d)", ret);
290                 iotcon_state_destroy(send_state);
291                 iotcon_representation_destroy(send_repr);
292                 return;
293         }
294
295         ret = iotcon_representation_set_state(send_repr, send_state);
296         if (IOTCON_ERROR_NONE != ret) {
297                 ERR("iotcon_representation_set_state() Fail(%d)", ret);
298                 iotcon_state_destroy(send_state);
299                 iotcon_representation_destroy(send_repr);
300                 return;
301         }
302
303         iotcon_state_destroy(send_state);
304
305         /* send PUT request */
306         ret = iotcon_remote_resource_put(resource, send_repr, NULL, _on_response, NULL);
307         if (IOTCON_ERROR_NONE != ret)
308                 ERR("iotcon_remote_resource_put() Fail(%d)", ret);
309
310         iotcon_representation_destroy(send_repr);
311 }
312
313 static bool _get_res_type_cb(const char *string, void *user_data)
314 {
315         char *resource_uri_path = user_data;
316
317         DBG("[%s] resource type : %s", resource_uri_path, string);
318
319         return IOTCON_FUNC_CONTINUE;
320 }
321
322 static void _presence_handler(iotcon_presence_h presence, iotcon_error_e err,
323                 iotcon_presence_response_h response, void *user_data)
324 {
325         char *host_address;
326         char *resource_type;
327         int ret;
328         iotcon_presence_result_e result;
329         iotcon_presence_trigger_e trigger;
330         iotcon_connectivity_type_e connectivity_type;
331
332         RETM_IF(IOTCON_ERROR_NONE != err, "_presence_handler error(%d)", err);
333
334         ret = iotcon_presence_response_get_result(response, &result);
335         if (IOTCON_ERROR_NONE != ret) {
336                 ERR("iotcon_presence_response_get_result() Fail(%d)", ret);
337                 return;
338         }
339
340         if (IOTCON_PRESENCE_OK == result) {
341                 ret = iotcon_presence_response_get_trigger(response, &trigger);
342                 if (IOTCON_ERROR_NONE != ret) {
343                         ERR("iotcon_presence_response_get_trigger() Fail(%d)", ret);
344                         return;
345                 }
346         }
347
348         ret = iotcon_presence_response_get_host_address(response, &host_address);
349         if (IOTCON_ERROR_NONE != ret) {
350                 ERR("iotcon_presence_response_get_host_address() Fail(%d)", ret);
351                 return;
352         }
353
354         ret = iotcon_presence_response_get_connectivity_type(response, &connectivity_type);
355         if (IOTCON_ERROR_NONE != ret) {
356                 ERR("iotcon_presence_response_get_connectivity_type() Fail(%d)", ret);
357                 return;
358         }
359
360         ret = iotcon_presence_response_get_resource_type(response, &resource_type);
361         if (IOTCON_ERROR_NONE != ret) {
362                 ERR("iotcon_presence_response_get_resource_type() Fail(%d)", ret);
363                 return;
364         }
365
366         INFO("_presence_handler");
367         INFO("result : %d", result);
368         if (IOTCON_PRESENCE_OK == result)
369                 INFO("trigger : %d", trigger);
370         INFO("host_address : %s", host_address);
371         INFO("resource_type : %s", resource_type);
372 }
373
374 static int _device_id_compare(const void *a, const void *b)
375 {
376         return strcmp(a, b);
377 }
378
379 static void _on_response(iotcon_remote_resource_h resource, iotcon_error_e err,
380                 iotcon_request_type_e request_type, iotcon_response_h response, void *user_data)
381 {
382         RETM_IF(IOTCON_ERROR_NONE != err, "_on_response error(%d)", err);
383         INFO("request(%d) was successful", request_type);
384
385         switch (request_type) {
386         case IOTCON_REQUEST_GET:
387                 _on_response_get(resource, response, user_data);
388                 break;
389         case IOTCON_REQUEST_PUT:
390                 _on_response_put(resource, response, user_data);
391                 break;
392         case IOTCON_REQUEST_POST:
393                 _on_response_post(resource, response, user_data);
394                 break;
395         case IOTCON_REQUEST_DELETE:
396                 _on_response_delete(resource, response, user_data);
397                 break;
398         default:
399                 ERR("Invalid request type (%d)", request_type);
400                 return;
401         }
402 }
403
404 static void _found_resource(iotcon_remote_resource_h resource, iotcon_error_e result,
405                 void *user_data)
406 {
407         GList *node;
408         char *resource_host;
409         char *resource_uri_path;
410         char *resource_device_id;
411         iotcon_presence_h presence_handle;
412         iotcon_resource_types_h resource_types;
413         int ret, resource_interfaces;
414         iotcon_connectivity_type_e connectivity_type;
415         iotcon_remote_resource_h resource_clone = NULL;
416
417         RETM_IF(IOTCON_ERROR_NONE != result, "Invalid result(%d)", result);
418
419         if (NULL == resource)
420                 return;
421
422         INFO("===== resource found =====");
423
424         /* get the resource URI */
425         ret = iotcon_remote_resource_get_uri_path(resource, &resource_uri_path);
426         if (IOTCON_ERROR_NONE != ret) {
427                 ERR("iotcon_remote_resource_get_uri_path() Fail(%d)", ret);
428                 return;
429         }
430
431         /* get the device unique id.
432          * this is unique per-server independent on how it was discovered. */
433         ret = iotcon_remote_resource_get_device_id(resource, &resource_device_id);
434         if (IOTCON_ERROR_NONE != ret) {
435                 ERR("iotcon_remote_resource_get_device_id() Fail(%d)", ret);
436                 return;
437         }
438         DBG("[%s] resource device id : %s", resource_uri_path, resource_device_id);
439
440         node = g_list_find_custom(device_id_list, resource_device_id, _device_id_compare);
441
442         if (node && TEST_STR_EQUAL == strncmp(DOOR_RESOURCE_URI_PREFIX, resource_uri_path,
443                         strlen(DOOR_RESOURCE_URI_PREFIX))) {
444                 DBG("uri_path \"%s\" already found. skip !", resource_uri_path);
445                 return;
446         }
447
448         door_resource_device_id = strdup(resource_device_id);
449         if (NULL == door_resource_device_id) {
450                 ERR("strdup(door_resource_device_id) Fail");
451                 return;
452         }
453
454         device_id_list = g_list_append(device_id_list, door_resource_device_id);
455
456         /* get the resource host address */
457         ret = iotcon_remote_resource_get_host_address(resource, &resource_host);
458         if (IOTCON_ERROR_NONE != ret) {
459                 ERR("iotcon_remote_resource_get_host_address() Fail(%d)", ret);
460                 device_id_list = g_list_remove(device_id_list, door_resource_device_id);
461                 free(door_resource_device_id);
462                 return;
463         }
464         DBG("[%s] resource host : %s", resource_uri_path, resource_host);
465
466         ret = iotcon_remote_resource_get_connectivity_type(resource, &connectivity_type);
467         if (IOTCON_ERROR_NONE != ret) {
468                 ERR("iotcon_remote_resource_get_connectivity_type() Fail(%d)", ret);
469                 device_id_list = g_list_remove(device_id_list, door_resource_device_id);
470                 free(door_resource_device_id);
471                 return;
472         }
473
474         /* get the resource interfaces */
475         ret = iotcon_remote_resource_get_interfaces(resource, &resource_interfaces);
476         if (IOTCON_ERROR_NONE != ret) {
477                 ERR("iotcon_remote_resource_get_interfaces() Fail(%d)", ret);
478                 device_id_list = g_list_remove(device_id_list, door_resource_device_id);
479                 free(door_resource_device_id);
480                 return;
481         }
482         if (IOTCON_INTERFACE_DEFAULT & resource_interfaces)
483                 DBG("[%s] resource interface : DEFAULT_INTERFACE", resource_uri_path);
484         if (IOTCON_INTERFACE_LINK & resource_interfaces)
485                 DBG("[%s] resource interface : LINK_INTERFACE", resource_uri_path);
486         if (IOTCON_INTERFACE_BATCH & resource_interfaces)
487                 DBG("[%s] resource interface : BATCH_INTERFACE", resource_uri_path);
488         if (IOTCON_INTERFACE_GROUP & resource_interfaces)
489                 DBG("[%s] resource interface : GROUP_INTERFACE", resource_uri_path);
490
491         /* get the resource types */
492         ret = iotcon_remote_resource_get_types(resource, &resource_types);
493         if (IOTCON_ERROR_NONE != ret) {
494                 ERR("iotcon_remote_resource_get_types() Fail(%d)", ret);
495                 device_id_list = g_list_remove(device_id_list, door_resource_device_id);
496                 free(door_resource_device_id);
497                 return;
498         }
499
500         ret = iotcon_resource_types_foreach(resource_types, _get_res_type_cb,
501                         resource_uri_path);
502         if (IOTCON_ERROR_NONE != ret) {
503                 ERR("iotcon_resource_types_foreach() Fail(%d)", ret);
504                 device_id_list = g_list_remove(device_id_list, door_resource_device_id);
505                 free(door_resource_device_id);
506                 return;
507         }
508
509         ret = iotcon_add_presence_cb(resource_host, connectivity_type, DOOR_RESOURCE_TYPE,
510                         _presence_handler, NULL, &presence_handle);
511         if (IOTCON_ERROR_NONE != ret) {
512                 ERR("iotcon_add_presence_cb() Fail(%d)", ret);
513                 device_id_list = g_list_remove(device_id_list, door_resource_device_id);
514                 free(door_resource_device_id);
515                 return;
516         }
517
518         if (TEST_STR_EQUAL == strncmp(DOOR_RESOURCE_URI_PREFIX, resource_uri_path,
519                         strlen(DOOR_RESOURCE_URI_PREFIX))) {
520                 iotcon_query_h query;
521
522                 ret = iotcon_remote_resource_clone(resource, &resource_clone);
523                 if (IOTCON_ERROR_NONE != ret) {
524                         ERR("iotcon_remote_resource_clone() Fail(%d)", ret);
525                         device_id_list = g_list_remove(device_id_list, door_resource_device_id);
526                         free(door_resource_device_id);
527                         return;
528                 }
529
530                 ret = iotcon_remote_resource_observe_register(resource_clone,
531                                 IOTCON_OBSERVE_IGNORE_OUT_OF_ORDER, NULL, _on_observe, NULL);
532
533                 if (IOTCON_ERROR_NONE != ret) {
534                         ERR("iotcon_remote_resource_observe_register() Fail(%d)", ret);
535                         device_id_list = g_list_remove(device_id_list, door_resource_device_id);
536                         free(door_resource_device_id);
537                         return;
538                 }
539
540                 ret = iotcon_query_create(&query);
541                 if (IOTCON_ERROR_NONE != ret) {
542                         ERR("iotcon_query_create() Fail(%d)", ret);
543                         device_id_list = g_list_remove(device_id_list, door_resource_device_id);
544                         free(door_resource_device_id);
545                         return;
546                 }
547
548                 ret = iotcon_query_add(query, "query_key", "query_value");
549                 if (IOTCON_ERROR_NONE != ret) {
550                         ERR("iotcon_query_add() Fail(%d)", ret);
551                         iotcon_query_destroy(query);
552                         device_id_list = g_list_remove(device_id_list, door_resource_device_id);
553                         free(door_resource_device_id);
554                         return;
555                 }
556
557                 /* send GET Request */
558                 ret = iotcon_remote_resource_get(resource_clone, query, _on_response, NULL);
559                 if (IOTCON_ERROR_NONE != ret)
560                         ERR("iotcon_remote_resource_get() Fail(%d)", ret);
561
562                 iotcon_query_destroy(query);
563         }
564
565         device_id_list = g_list_remove(device_id_list, door_resource_device_id);
566         free(door_resource_device_id);
567 }
568
569 int main(int argc, char **argv)
570 {
571         FN_CALL;
572         int ret;
573         GMainLoop *loop;
574
575         loop = g_main_loop_new(NULL, FALSE);
576
577         /* connect iotcon */
578         ret = iotcon_connect();
579         if (IOTCON_ERROR_NONE != ret) {
580                 ERR("iotcon_connect() Fail(%d)", ret);
581                 return -1;
582         }
583
584         /* find door typed resources */
585         ret = iotcon_find_resource(IOTCON_MULTICAST_ADDRESS, IOTCON_CONNECTIVITY_IPV4,
586                         DOOR_RESOURCE_TYPE, false, _found_resource, NULL);
587         if (IOTCON_ERROR_NONE != ret) {
588                 ERR("iotcon_find_resource() Fail(%d)", ret);
589                 iotcon_disconnect();
590                 return -1;
591         }
592
593         g_main_loop_run(loop);
594         g_main_loop_unref(loop);
595
596         g_list_free_full(device_id_list, free);
597
598         /* disconnect iotcon */
599         iotcon_disconnect();
600
601         return 0;
602 }