2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
4 * Contact: Jin Yoon <jinny.yoon@samsung.com>
5 * Geunsun Lee <gs86.lee@samsung.com>
6 * Eunyoung Lee <ey928.lee@samsung.com>
7 * Junkyu Han <junkyu.han@samsung.com>
9 * Licensed under the Flora License, Version 1.1 (the License);
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://floralicense.org/license/
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an AS IS BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
27 #include <app_common.h>
30 #include "connectivity.h"
32 #define DEVICE_NAME "Dr.Evil's device"
34 #define URI_PATH_LEN 64
35 #define URI_PATH "/door/1"
38 static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data);
40 static int _send_response(iotcon_request_h request, iotcon_representation_h representation, iotcon_response_result_e result)
43 iotcon_response_h response;
45 ret = iotcon_response_create(request, &response);
46 retv_if(IOTCON_ERROR_NONE != ret, -1);
48 ret = iotcon_response_set_result(response, result);
49 goto_if(IOTCON_ERROR_NONE != ret, error);
51 ret = iotcon_response_set_representation(response, representation);
52 goto_if(IOTCON_ERROR_NONE != ret, error);
54 ret = iotcon_response_send(response);
55 goto_if(IOTCON_ERROR_NONE != ret, error);
57 iotcon_response_destroy(response);
62 iotcon_response_destroy(response);
66 static void _destroy_representation(iotcon_representation_h representation)
68 ret_if(!representation);
69 iotcon_representation_destroy(representation);
72 static iotcon_representation_h _create_representation_with_bool(connectivity_resource_s *resource_info, const char *key, bool value)
74 iotcon_attributes_h attributes = NULL;
75 iotcon_representation_h representation = NULL;
76 char *uri_path = NULL;
79 ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
80 retv_if(IOTCON_ERROR_NONE != ret, NULL);
82 ret = iotcon_representation_create(&representation);
83 retv_if(IOTCON_ERROR_NONE != ret, NULL);
85 ret = iotcon_attributes_create(&attributes);
86 goto_if(IOTCON_ERROR_NONE != ret, error);
88 ret = iotcon_representation_set_uri_path(representation, uri_path);
89 goto_if(IOTCON_ERROR_NONE != ret, error);
91 ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
92 goto_if(IOTCON_ERROR_NONE != ret, error);
94 ret = iotcon_attributes_add_bool(attributes, key, value);
95 goto_if(IOTCON_ERROR_NONE != ret, error);
97 ret = iotcon_representation_set_attributes(representation, attributes);
98 goto_if(IOTCON_ERROR_NONE != ret, error);
100 iotcon_attributes_destroy(attributes);
102 return representation;
105 if (attributes) iotcon_attributes_destroy(attributes);
106 if (representation) iotcon_representation_destroy(representation);
111 static iotcon_representation_h _create_representation_with_int(connectivity_resource_s *resource_info, const char *key, int value)
113 iotcon_attributes_h attributes = NULL;
114 iotcon_representation_h representation = NULL;
115 char *uri_path = NULL;
118 ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
119 retv_if(IOTCON_ERROR_NONE != ret, NULL);
121 ret = iotcon_representation_create(&representation);
122 retv_if(IOTCON_ERROR_NONE != ret, NULL);
124 ret = iotcon_attributes_create(&attributes);
125 goto_if(IOTCON_ERROR_NONE != ret, error);
127 ret = iotcon_representation_set_uri_path(representation, uri_path);
128 goto_if(IOTCON_ERROR_NONE != ret, error);
130 ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
131 goto_if(IOTCON_ERROR_NONE != ret, error);
133 ret = iotcon_attributes_add_int(attributes, key, value);
134 goto_if(IOTCON_ERROR_NONE != ret, error);
136 ret = iotcon_representation_set_attributes(representation, attributes);
137 goto_if(IOTCON_ERROR_NONE != ret, error);
139 iotcon_attributes_destroy(attributes);
141 return representation;
144 if (attributes) iotcon_attributes_destroy(attributes);
145 if (representation) iotcon_representation_destroy(representation);
150 static iotcon_representation_h _create_representation_with_double(connectivity_resource_s *resource_info, const char *key, double value)
152 iotcon_attributes_h attributes = NULL;
153 iotcon_representation_h representation = NULL;
154 char *uri_path = NULL;
157 ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
158 retv_if(IOTCON_ERROR_NONE != ret, NULL);
160 ret = iotcon_representation_create(&representation);
161 retv_if(IOTCON_ERROR_NONE != ret, NULL);
163 ret = iotcon_attributes_create(&attributes);
164 goto_if(IOTCON_ERROR_NONE != ret, error);
166 ret = iotcon_representation_set_uri_path(representation, uri_path);
167 goto_if(IOTCON_ERROR_NONE != ret, error);
169 ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
170 goto_if(IOTCON_ERROR_NONE != ret, error);
172 ret = iotcon_attributes_add_double(attributes, key, value);
173 goto_if(IOTCON_ERROR_NONE != ret, error);
175 ret = iotcon_representation_set_attributes(representation, attributes);
176 goto_if(IOTCON_ERROR_NONE != ret, error);
178 iotcon_attributes_destroy(attributes);
180 return representation;
183 if (attributes) iotcon_attributes_destroy(attributes);
184 if (representation) iotcon_representation_destroy(representation);
189 static iotcon_representation_h _create_representation_with_str(connectivity_resource_s *resource_info, const char *key, char *value)
191 iotcon_attributes_h attributes = NULL;
192 iotcon_representation_h representation = NULL;
193 char *uri_path = NULL;
196 ret = iotcon_resource_get_uri_path(resource_info->res, &uri_path);
197 retv_if(IOTCON_ERROR_NONE != ret, NULL);
199 ret = iotcon_representation_create(&representation);
200 retv_if(IOTCON_ERROR_NONE != ret, NULL);
202 ret = iotcon_attributes_create(&attributes);
203 goto_if(IOTCON_ERROR_NONE != ret, error);
205 ret = iotcon_representation_set_uri_path(representation, uri_path);
206 goto_if(IOTCON_ERROR_NONE != ret, error);
208 ret = iotcon_attributes_add_str(attributes, PATH, resource_info->path);
209 goto_if(IOTCON_ERROR_NONE != ret, error);
211 ret = iotcon_attributes_add_str(attributes, key, value);
212 goto_if(IOTCON_ERROR_NONE != ret, error);
214 ret = iotcon_representation_set_attributes(representation, attributes);
215 goto_if(IOTCON_ERROR_NONE != ret, error);
217 iotcon_attributes_destroy(attributes);
219 return representation;
222 if (attributes) iotcon_attributes_destroy(attributes);
223 if (representation) iotcon_representation_destroy(representation);
228 static void _print_iotcon_error(int err_no)
231 case IOTCON_ERROR_NOT_SUPPORTED:
232 _E("IOTCON_ERROR_NOT_SUPPORTED");
234 case IOTCON_ERROR_PERMISSION_DENIED:
235 _E("IOTCON_ERROR_PERMISSION_DENIED");
237 case IOTCON_ERROR_INVALID_PARAMETER:
238 _E("IOTCON_ERROR_INVALID_PARAMETER");
241 _E("Error : [%d]", err_no);
246 int connectivity_notify_bool(connectivity_resource_s *resource_info, const char *key, bool value)
248 iotcon_representation_h representation;
251 retv_if(!resource_info, -1);
252 retv_if(!resource_info->observers, -1);
254 _D("Notify the value[%d]", value);
256 representation = _create_representation_with_bool(resource_info, key, value);
257 retv_if(!representation, -1);
259 ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
260 if (IOTCON_ERROR_NONE != ret) {
261 _I("There are some troubles for notifying value[%d]", ret);
262 _print_iotcon_error(ret);
266 _destroy_representation(representation);
271 int connectivity_notify_int(connectivity_resource_s *resource_info, const char *key, int value)
273 iotcon_representation_h representation;
276 retv_if(!resource_info, -1);
277 retv_if(!resource_info->observers, -1);
279 _D("Notify the value[%d]", value);
281 representation = _create_representation_with_int(resource_info, key, value);
282 retv_if(!representation, -1);
284 ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
285 if (IOTCON_ERROR_NONE != ret) {
286 _I("There are some troubles for notifying value[%d]", ret);
287 _print_iotcon_error(ret);
291 _destroy_representation(representation);
296 int connectivity_notify_double(connectivity_resource_s *resource_info, const char *key, double value)
298 iotcon_representation_h representation;
301 retv_if(!resource_info, -1);
302 retv_if(!resource_info->observers, -1);
304 _D("Notify the value[%f]", value);
306 representation = _create_representation_with_double(resource_info, key, value);
307 retv_if(!representation, -1);
309 ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
310 if (IOTCON_ERROR_NONE != ret) {
311 _I("There are some troubles for notifying value[%d]", ret);
312 _print_iotcon_error(ret);
316 _destroy_representation(representation);
321 int connectivity_notify_string(connectivity_resource_s *resource_info, const char *key, char *value)
323 iotcon_representation_h representation;
326 retv_if(!resource_info, -1);
327 retv_if(!resource_info->observers, -1);
329 _D("Notify all members [%s]", value);
331 representation = _create_representation_with_str(resource_info, key, value);
332 retv_if(!representation, -1);
334 ret = iotcon_resource_notify(resource_info->res, representation, resource_info->observers, IOTCON_QOS_LOW);
335 if (IOTCON_ERROR_NONE != ret) {
336 //_I("There are some troubles for notifying value[%d]", ret);
337 _print_iotcon_error(ret);
341 _destroy_representation(representation);
346 static bool _query_cb(const char *key, const char *value, void *user_data)
348 _D("Key : [%s], Value : [%s]", key, value);
350 return IOTCON_FUNC_CONTINUE;
353 static int _handle_query(iotcon_request_h request)
355 iotcon_query_h query = NULL;
358 ret = iotcon_request_get_query(request, &query);
359 retv_if(IOTCON_ERROR_NONE != ret, -1);
361 if (query) iotcon_query_foreach(query, _query_cb, NULL);
366 static int _handle_request_by_crud_type(iotcon_request_h request, connectivity_resource_s *resource_info)
368 iotcon_request_type_e type;
371 ret = iotcon_request_get_request_type(request, &type);
372 retv_if(IOTCON_ERROR_NONE != ret, -1);
375 case IOTCON_REQUEST_GET:
376 _I("Do not support 'get' query");
378 case IOTCON_REQUEST_PUT:
379 _I("Do not support 'put' query");
381 case IOTCON_REQUEST_POST:
382 _I("Do not support 'post' query");
384 case IOTCON_REQUEST_DELETE:
385 _I("Do not support 'delete' query");
388 _E("Cannot reach here");
392 retv_if(0 != ret, -1);
397 static int _handle_observer(iotcon_request_h request, iotcon_observers_h observers)
399 iotcon_observe_type_e observe_type;
403 ret = iotcon_request_get_observe_type(request, &observe_type);
404 retv_if(IOTCON_ERROR_NONE != ret, -1);
406 if (IOTCON_OBSERVE_REGISTER == observe_type) {
407 ret = iotcon_request_get_observe_id(request, &observe_id);
408 retv_if(IOTCON_ERROR_NONE != ret, -1);
410 _I("Add an observer : %d", observe_id);
412 ret = iotcon_observers_add(observers, observe_id);
413 retv_if(IOTCON_ERROR_NONE != ret, -1);
414 } else if (IOTCON_OBSERVE_DEREGISTER == observe_type) {
415 ret = iotcon_request_get_observe_id(request, &observe_id);
416 retv_if(IOTCON_ERROR_NONE != ret, -1);
418 _I("Remove an observer : %d", observe_id);
420 ret = iotcon_observers_remove(observers, observe_id);
421 retv_if(IOTCON_ERROR_NONE != ret, -1);
427 static void _request_resource_handler(iotcon_resource_h resource, iotcon_request_h request, void *user_data)
429 connectivity_resource_s *resource_info = user_data;
431 char *host_address = NULL;
435 ret = iotcon_request_get_host_address(request, &host_address);
436 goto_if(IOTCON_ERROR_NONE != ret, error);
438 _D("Host address : %s", host_address);
440 ret = _handle_query(request);
441 goto_if(IOTCON_ERROR_NONE != ret, error);
443 ret = _handle_request_by_crud_type(request, resource_info);
444 goto_if(0 != ret, error);
446 ret = _handle_observer(request, resource_info->observers);
447 goto_if(0 != ret, error);
452 _send_response(request, NULL, IOTCON_RESPONSE_ERROR);
455 static void _copy_file(const char *in_filename, const char *out_filename)
457 char buf[BUFSIZE] = { 0, };
462 ret_if(!in_filename);
463 ret_if(!out_filename);
465 in = fopen(in_filename, "r");
468 out = fopen(out_filename, "w");
469 goto_if(!out, error);
472 while ((nread = fread(buf, 1, sizeof(buf), in)) > 0) {
473 if (fwrite(buf, 1, nread, out) < nread) {
474 _E("critical error to copy a file");
488 int connectivity_init(void)
492 _copy_file(CBOR_FILE_IN_RES, CBOR_FILE_IN_DATA);
494 ret = iotcon_initialize(CBOR_FILE_IN_DATA);
495 retv_if(IOTCON_ERROR_NONE != ret, -1);
497 ret = iotcon_set_device_name(DEVICE_NAME);
498 goto_if(IOTCON_ERROR_NONE != ret, error);
503 iotcon_deinitialize();
507 int connectivity_fini(void)
509 iotcon_deinitialize();
513 void connectivity_unset_resource(connectivity_resource_s *resource_info)
515 ret_if(!resource_info);
516 if (resource_info->observers) iotcon_observers_destroy(resource_info->observers);
517 if (resource_info->res) iotcon_resource_destroy(resource_info->res);
518 if (resource_info->path) free(resource_info->path);
522 int connectivity_set_resource(const char *path, const char *type, connectivity_resource_s **out_resource_info)
524 iotcon_resource_types_h resource_types = NULL;
525 iotcon_resource_interfaces_h ifaces = NULL;
526 connectivity_resource_s *resource_info = NULL;
532 retv_if(!out_resource_info, -1);
534 resource_info = calloc(1, sizeof(connectivity_resource_s));
535 retv_if(!resource_info, -1);
537 resource_info->path = strdup(path);
538 goto_if(!resource_info->path, error);
540 _D("Path : [%s]", resource_info->path);
542 ret = iotcon_resource_types_create(&resource_types);
543 goto_if(IOTCON_ERROR_NONE != ret, error);
545 ret = iotcon_resource_types_add(resource_types, type);
546 goto_if(IOTCON_ERROR_NONE != ret, error);
548 ret = iotcon_resource_interfaces_create(&ifaces);
549 goto_if(IOTCON_ERROR_NONE != ret, error);
551 ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_DEFAULT);
552 goto_if(IOTCON_ERROR_NONE != ret, error);
554 ret = iotcon_resource_interfaces_add(ifaces, IOTCON_INTERFACE_BATCH);
555 goto_if(IOTCON_ERROR_NONE != ret, error);
558 IOTCON_RESOURCE_DISCOVERABLE |
559 IOTCON_RESOURCE_OBSERVABLE |
560 IOTCON_RESOURCE_SECURE;
562 ret = iotcon_resource_create(URI_PATH,
566 _request_resource_handler,
568 &resource_info->res);
569 goto_if(IOTCON_ERROR_NONE != ret, error);
571 ret = iotcon_observers_create(&resource_info->observers);
572 goto_if(IOTCON_ERROR_NONE != ret, error);
574 iotcon_resource_types_destroy(resource_types);
575 iotcon_resource_interfaces_destroy(ifaces);
576 *out_resource_info = resource_info;
581 if (ifaces) iotcon_resource_interfaces_destroy(ifaces);
582 if (resource_types) iotcon_resource_types_destroy(resource_types);
583 if (resource_info->res) iotcon_resource_destroy(resource_info->res);
584 if (resource_info->path) free(resource_info->path);
585 if (resource_info) free(resource_info);