2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <stdint.h> /* for uint8_t etc */
23 #include <system_info.h>
32 #include "icd-payload.h"
35 #include "icd-ioty-type.h"
36 #include "icd-ioty-ocprocess.h"
38 #define ICD_UUID_LENGTH 37
40 static const char *ICD_SYSTEM_INFO_TIZEN_ID = "http://tizen.org/system/tizenid";
44 char *tizen_device_id;
47 static icd_tizen_info_s icd_tizen_info;
49 static GMutex icd_csdk_mutex;
51 void icd_ioty_csdk_lock()
53 g_mutex_lock(&icd_csdk_mutex);
57 void icd_ioty_csdk_unlock()
59 g_mutex_unlock(&icd_csdk_mutex);
63 GThread* icd_ioty_init(const char *addr, unsigned short port)
69 OCStackResult result = OCInit(addr, port, OC_CLIENT_SERVER);
70 if (OC_STACK_OK != result) {
71 ERR("OCInit() Fail(%d)", result);
75 DBG("OCInit() Success");
77 thread = g_thread_try_new("packet_receive_thread", icd_ioty_ocprocess_thread,
80 ERR("g_thread_try_new() Fail(%s)", error->message);
89 void icd_ioty_deinit(GThread *thread)
93 icd_ioty_ocprocess_stop();
94 g_thread_join(thread);
97 if (OC_STACK_OK != result)
98 ERR("OCStop() Fail(%d)", result);
102 OCResourceHandle icd_ioty_register_resource(const char *uri_path,
103 const char* const* res_types, int ifaces, uint8_t properties)
108 OCResourceHandle handle;
109 const char *res_iface = NULL;
111 if (IOTCON_INTERFACE_DEFAULT & ifaces) {
112 res_iface = IC_INTERFACE_DEFAULT;
113 ifaces ^= IOTCON_INTERFACE_DEFAULT;
114 } else if (IOTCON_INTERFACE_LINK & ifaces) {
115 res_iface = IC_INTERFACE_LINK;
116 ifaces ^= IOTCON_INTERFACE_LINK;
117 } else if (IOTCON_INTERFACE_BATCH & ifaces) {
118 res_iface = IC_INTERFACE_BATCH;
119 ifaces ^= IOTCON_INTERFACE_BATCH;
120 } else if (IOTCON_INTERFACE_GROUP & ifaces) {
121 res_iface = IC_INTERFACE_GROUP;
122 ifaces ^= IOTCON_INTERFACE_GROUP;
124 ERR("Invalid interface type(%d)", ifaces);
128 /* Secure option is not supported yet. */
129 properties = (properties & OC_SECURE)? (properties ^ OC_SECURE):properties;
131 icd_ioty_csdk_lock();
132 ret = OCCreateResource(&handle, res_types[0], res_iface, uri_path,
133 icd_ioty_ocprocess_req_handler, NULL, properties);
134 icd_ioty_csdk_unlock();
135 if (OC_STACK_OK != ret) {
136 ERR("OCCreateResource() Fail(%d)", ret);
140 for (i = 1; res_types[i]; i++)
141 icd_ioty_bind_type(handle, res_types[i]);
143 if (IOTCON_INTERFACE_DEFAULT & ifaces)
144 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_DEFAULT);
145 if (IOTCON_INTERFACE_LINK & ifaces)
146 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_LINK);
147 if (IOTCON_INTERFACE_BATCH & ifaces)
148 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_BATCH);
149 if (IOTCON_INTERFACE_GROUP & ifaces)
150 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_GROUP);
156 int icd_ioty_unregister_resource(OCResourceHandle handle)
160 icd_ioty_csdk_lock();
161 ret = OCDeleteResource(handle);
162 icd_ioty_csdk_unlock();
164 if (OC_STACK_OK != ret) {
165 ERR("OCDeleteResource() Fail(%d)", ret);
166 return icd_ioty_convert_error(ret);
169 return IOTCON_ERROR_NONE;
173 int icd_ioty_bind_interface(OCResourceHandle handle, iotcon_interface_e iface)
176 OCStackResult result;
177 char *resource_interface;
179 ret = ic_utils_convert_interface_flag(iface, &resource_interface);
180 if (IOTCON_ERROR_NONE != ret) {
181 ERR("ic_utils_convert_interface_flag(%d) Fail(%d)", iface, ret);
185 icd_ioty_csdk_lock();
186 result = OCBindResourceInterfaceToResource(handle, resource_interface);
187 icd_ioty_csdk_unlock();
189 if (OC_STACK_OK != result) {
190 ERR("OCBindResourceInterfaceToResource() Fail(%d)", result);
191 return icd_ioty_convert_error(result);
194 return IOTCON_ERROR_NONE;
198 int icd_ioty_bind_type(OCResourceHandle handle, const char *resource_type)
202 icd_ioty_csdk_lock();
203 ret = OCBindResourceTypeToResource(handle, resource_type);
204 icd_ioty_csdk_unlock();
206 if (OC_STACK_OK != ret) {
207 ERR("OCBindResourceTypeToResource() Fail(%d)", ret);
208 return icd_ioty_convert_error(ret);
211 return IOTCON_ERROR_NONE;
215 int icd_ioty_bind_resource(OCResourceHandle parent, OCResourceHandle child)
219 icd_ioty_csdk_lock();
220 ret = OCBindResource(parent, child);
221 icd_ioty_csdk_unlock();
223 if (OC_STACK_OK != ret) {
224 ERR("OCBindResource() Fail(%d)", ret);
225 return icd_ioty_convert_error(ret);
228 return IOTCON_ERROR_NONE;
232 int icd_ioty_unbind_resource(OCResourceHandle parent, OCResourceHandle child)
236 icd_ioty_csdk_lock();
237 ret = OCUnBindResource(parent, child);
238 icd_ioty_csdk_unlock();
240 if (OC_STACK_OK != ret) {
241 ERR("OCUnBindResource() Fail(%d)", ret);
242 return icd_ioty_convert_error(ret);
245 return IOTCON_ERROR_NONE;
249 int icd_ioty_notify(OCResourceHandle handle, GVariant *msg, GVariant *observers)
251 int i, error_code, obs_length, msg_length;
253 GVariantIter obs_iter, msg_iter;
255 OCRepPayload *payload;
257 g_variant_iter_init(&obs_iter, observers);
258 obs_length = g_variant_iter_n_children(&obs_iter);
260 /* Variable-length Array */
261 OCObservationId obs_ids[obs_length];
263 for (i = 0; i < obs_length; i++)
264 g_variant_iter_loop(&obs_iter, "i", &obs_ids[i]);
266 g_variant_iter_init(&msg_iter, msg);
267 msg_length = g_variant_iter_n_children(&msg_iter);
269 g_variant_iter_loop(&msg_iter, "(iv)", &error_code, &repr_gvar);
270 /* TODO : How to use error_code. */
271 payload = icd_payload_representation_from_gvariant(repr_gvar);
274 icd_ioty_csdk_lock();
275 /* TODO : QoS is come from lib. */
277 ret = OCNotifyListOfObservers(handle, obs_ids, obs_length, payload, OC_LOW_QOS);
279 ret = OCNotifyAllObservers(handle, OC_LOW_QOS);
281 icd_ioty_csdk_unlock();
283 if (OC_STACK_NO_OBSERVERS == ret) {
284 WARN("No Observers. Stop Notifying");
285 return IOTCON_ERROR_NONE;
286 } else if (OC_STACK_OK != ret) {
287 ERR("OCNotifyListOfObservers() Fail(%d)", ret);
288 return icd_ioty_convert_error(ret);
291 return IOTCON_ERROR_NONE;
295 static int _ioty_get_header_options(GVariantIter *src, int src_size,
296 OCHeaderOption dest[], int dest_size)
300 unsigned short option_id;
302 RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
304 if (dest_size < src_size) {
305 ERR("Exceed Size(%d)", src_size);
306 return IOTCON_ERROR_INVALID_PARAMETER;
309 while (g_variant_iter_loop(src, "(q&s)", &option_id, &option_data)) {
310 dest[i].protocolID = OC_COAP_ID;
311 dest[i].optionID = option_id;
312 dest[i].optionLength = strlen(option_data) + 1;
313 memcpy(dest[i].optionData, option_data, dest[i].optionLength);
317 return IOTCON_ERROR_NONE;
321 int icd_ioty_send_response(GVariant *resp)
325 GVariantIter *options;
327 OCEntityHandlerResponse response = {0};
328 int result, error_code, options_size;
329 int64_t request_handle, resource_handle;
331 g_variant_get(resp, "(&sia(qs)ivxx)",
340 response.requestHandle = ICD_INT64_TO_POINTER(request_handle);
341 response.resourceHandle = ICD_INT64_TO_POINTER(resource_handle);
342 response.ehResult = (OCEntityHandlerResult)result;
344 if (OC_EH_RESOURCE_CREATED == response.ehResult)
345 snprintf(response.resourceUri, sizeof(response.resourceUri), "%s", new_uri_path);
347 options_size = g_variant_iter_n_children(options);
348 response.numSendVendorSpecificHeaderOptions = options_size;
350 if (0 != options_size) {
351 int ret= _ioty_get_header_options(options,
352 response.numSendVendorSpecificHeaderOptions,
353 response.sendVendorSpecificHeaderOptions,
354 sizeof(response.sendVendorSpecificHeaderOptions)
355 / sizeof(response.sendVendorSpecificHeaderOptions[0]));
357 if (IOTCON_ERROR_NONE != ret)
358 ERR("_ioty_get_header_options() Fail(%d)", ret);
360 g_variant_iter_free(options);
362 response.payload = (OCPayload*)icd_payload_representation_from_gvariant(repr_gvar);
364 /* related to block transfer */
365 response.persistentBufferFlag = 0;
367 icd_ioty_csdk_lock();
368 ret = OCDoResponse(&response);
369 icd_ioty_csdk_unlock();
371 if (OC_STACK_OK != ret) {
372 ERR("OCDoResponse() Fail(%d)", ret);
373 return icd_ioty_convert_error(ret);
376 return IOTCON_ERROR_NONE;
380 static void _ioty_free_signal_context(void *data)
382 icd_sig_ctx_s *context = data;
383 free(context->bus_name);
388 int icd_ioty_find_resource(const char *host_address, const char *resource_type,
389 unsigned int signum, const char *bus_name)
392 OCStackResult result;
393 icd_sig_ctx_s *context;
394 char uri[PATH_MAX] = {0};
395 OCCallbackData cbdata = {0};
396 OCConnectivityType oic_conn_type;
397 iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
399 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address)) {
400 len = snprintf(uri, sizeof(uri), "%s", OC_RSRVD_WELL_KNOWN_URI);
402 len = snprintf(uri, sizeof(uri), ICD_IOTY_COAP"%s%s", host_address,
403 OC_RSRVD_WELL_KNOWN_URI);
405 if (len <= 0 || sizeof(uri) <= len) {
406 ERR("snprintf() Fail(%d)", len);
407 return IOTCON_ERROR_IO_ERROR;
410 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
411 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
413 context = calloc(1, sizeof(icd_sig_ctx_s));
414 if (NULL == context) {
415 ERR("calloc() Fail(%d)", errno);
416 return IOTCON_ERROR_OUT_OF_MEMORY;
419 context->bus_name = ic_utils_strdup(bus_name);
420 context->signum = signum;
422 cbdata.context = context;
423 cbdata.cb = icd_ioty_ocprocess_find_cb;
424 cbdata.cd = _ioty_free_signal_context;
426 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
428 icd_ioty_csdk_lock();
429 /* TODO : QoS is come from lib. */
430 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
431 OC_LOW_QOS, &cbdata, NULL, 0);
432 icd_ioty_csdk_unlock();
434 if (OC_STACK_OK != result) {
435 ERR("OCDoResource() Fail(%d)", result);
436 free(context->bus_name);
438 return icd_ioty_convert_error(result);
441 return IOTCON_ERROR_NONE;
446 * returned string SHOULD be released by you
448 static char* _icd_ioty_resource_generate_uri(char *uri_path, GVariant *query)
451 bool loop_first = true;
453 GVariantIter query_iter;
454 char uri_buf[PATH_MAX] = {0};
456 len = snprintf(uri_buf, sizeof(uri_buf), "%s", uri_path);
458 /* remove suffix '/' */
459 if ('/' == uri_buf[strlen(uri_buf) - 1]) {
460 uri_buf[strlen(uri_buf) - 1] = '\0';
464 g_variant_iter_init(&query_iter, query);
466 while (g_variant_iter_loop(&query_iter, "(&s&s)", &key, &value)) {
469 DBG("query exist. key(%s), value(%s)", key, value);
471 if (true == loop_first) {
472 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "?%s=%s", key, value);
475 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "&%s=%s", key, value);
481 return strdup(uri_buf);
485 void icd_ioty_complete(int type, GDBusMethodInvocation *invocation, GVariant *value)
489 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
492 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
495 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
497 case ICD_CRUD_DELETE:
498 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
501 ic_dbus_complete_get_tizen_info(icd_dbus_get_object(), invocation, value);
507 void icd_ioty_complete_error(int type, GDBusMethodInvocation *invocation, int ret_val)
513 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
514 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
517 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
518 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
521 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
522 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
524 case ICD_CRUD_DELETE:
525 value = g_variant_new("(a(qs)i)", NULL, ret_val);
526 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
529 value = g_variant_new("(ssi)", IC_STR_NULL, IC_STR_NULL, ret_val);
530 ic_dbus_complete_get_tizen_info(icd_dbus_get_object(), invocation, value);
536 static gboolean _icd_ioty_crud(int type, icDbus *object, GDBusMethodInvocation *invocation,
537 GVariant *resource, GVariant *query, GVariant *repr)
541 OCStackResult result;
542 GVariantIter *options;
543 OCCallbackData cbdata = {0};
544 int conn_type, options_size;
545 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
546 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
547 OCHeaderOption *oic_options_ptr = NULL;
548 OCPayload *payload = NULL;
549 OCConnectivityType oic_conn_type;
550 OCDevAddr dev_addr = {0};
554 cbdata.cb = icd_ioty_ocprocess_get_cb;
555 rest_type = OC_REST_GET;
558 cbdata.cb = icd_ioty_ocprocess_put_cb;
559 rest_type = OC_REST_PUT;
562 cbdata.cb = icd_ioty_ocprocess_post_cb;
563 rest_type = OC_REST_POST;
565 case ICD_CRUD_DELETE:
566 cbdata.cb = icd_ioty_ocprocess_delete_cb;
567 rest_type = OC_REST_DELETE;
570 ERR("Invalid CRUD Type(%d)", type);
574 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
581 uri = _icd_ioty_resource_generate_uri(uri_path, query);
583 ERR("_icd_ioty_resource_generate_uri() Fail");
584 g_variant_iter_free(options);
585 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_INVALID_PARAMETER);
589 case ICD_CRUD_DELETE:
590 uri = strdup(uri_path);
594 cbdata.context = invocation;
596 options_size = g_variant_iter_n_children(options);
597 if (0 != options_size) {
598 int ret = _ioty_get_header_options(options, options_size, oic_options,
599 sizeof(oic_options) / sizeof(oic_options[0]));
600 if (IOTCON_ERROR_NONE != ret) {
601 ERR("_ioty_get_header_options() Fail(%d)", ret);
603 g_variant_iter_free(options);
604 icd_ioty_complete_error(type, invocation, ret);
607 oic_options_ptr = oic_options;
609 g_variant_iter_free(options);
612 payload = (OCPayload*)icd_payload_representation_from_gvariant(repr);
614 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
616 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
620 case IOTCON_CONNECTIVITY_IPV4:
621 dev_host = strtok_r(host, ":", &ptr);
622 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
623 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
625 case IOTCON_CONNECTIVITY_IPV6:
626 dev_host = strtok_r(host, "]", &ptr);
627 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
628 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
631 ERR("Invalid Connectivitiy Type");
632 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_IOTIVITY);
637 icd_ioty_csdk_lock();
638 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
639 result = OCDoResource(NULL, rest_type, uri, &dev_addr, payload, oic_conn_type,
640 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
641 icd_ioty_csdk_unlock();
645 if (OC_STACK_OK != result) {
646 ERR("OCDoResource() Fail(%d)", result);
647 icd_ioty_complete_error(type, invocation, icd_ioty_convert_error(result));
654 gboolean icd_ioty_get(icDbus *object, GDBusMethodInvocation *invocation,
655 GVariant *resource, GVariant *query)
657 return _icd_ioty_crud(ICD_CRUD_GET, object, invocation, resource, query, NULL);
661 gboolean icd_ioty_put(icDbus *object, GDBusMethodInvocation *invocation,
662 GVariant *resource, GVariant *repr, GVariant *query)
664 return _icd_ioty_crud(ICD_CRUD_PUT, object, invocation, resource, query, repr);
668 gboolean icd_ioty_post(icDbus *object, GDBusMethodInvocation *invocation,
669 GVariant *resource, GVariant *repr, GVariant *query)
671 return _icd_ioty_crud(ICD_CRUD_POST, object, invocation, resource, query, repr);
675 gboolean icd_ioty_delete(icDbus *object, GDBusMethodInvocation *invocation,
678 return _icd_ioty_crud(ICD_CRUD_DELETE, object, invocation, resource, NULL, NULL);
682 OCDoHandle icd_ioty_observer_start(GVariant *resource, int observe_type, GVariant *query,
683 unsigned int signal_number, const char *bus_name)
688 OCStackResult result;
689 GVariantIter *options;
690 icd_sig_ctx_s *context;
691 OCCallbackData cbdata = {0};
692 int conn_type, options_size;
693 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
694 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
695 OCHeaderOption *oic_options_ptr = NULL;
696 OCConnectivityType oic_conn_type;
697 OCDevAddr dev_addr = {0};
699 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
702 uri = _icd_ioty_resource_generate_uri(uri_path, query);
704 ERR("_icd_ioty_resource_generate_uri() Fail");
705 g_variant_iter_free(options);
709 if (IOTCON_OBSERVE == observe_type)
710 method = OC_REST_OBSERVE;
711 else if (IOTCON_OBSERVE_ALL == observe_type)
712 method = OC_REST_OBSERVE_ALL;
714 method = OC_REST_OBSERVE_ALL;
716 context = calloc(1, sizeof(icd_sig_ctx_s));
717 if (NULL == context) {
718 ERR("calloc() Fail(%d)", errno);
721 context->bus_name = ic_utils_strdup(bus_name);
722 context->signum = signal_number;
724 cbdata.context = context;
725 cbdata.cb = icd_ioty_ocprocess_observe_cb;
726 cbdata.cd = _ioty_free_signal_context;
728 options_size = g_variant_iter_n_children(options);
729 if (0 != options_size) {
730 int ret = _ioty_get_header_options(options, options_size, oic_options,
731 sizeof(oic_options) / sizeof(oic_options[0]));
732 if (IOTCON_ERROR_NONE != ret) {
733 ERR("_ioty_get_header_options() Fail(%d)", ret);
734 free(context->bus_name);
737 g_variant_iter_free(options);
740 oic_options_ptr = oic_options;
742 g_variant_iter_free(options);
744 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
746 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
750 case IOTCON_CONNECTIVITY_IPV4:
751 dev_host = strtok_r(host, ":", &ptr);
752 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
753 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
755 case IOTCON_CONNECTIVITY_IPV6:
756 dev_host = strtok_r(host, "]", &ptr);
757 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
758 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
761 ERR("Invalid Connectivitiy Type");
762 free(context->bus_name);
768 icd_ioty_csdk_lock();
769 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
770 result = OCDoResource(&handle, method, uri, &dev_addr, NULL, oic_conn_type,
771 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
772 icd_ioty_csdk_unlock();
774 if (OC_STACK_OK != result) {
775 ERR("OCDoResource() Fail(%d)", result);
776 free(context->bus_name);
785 int icd_ioty_observer_stop(OCDoHandle handle, GVariant *options)
789 GVariantIter options_iter;
790 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
791 OCHeaderOption *oic_options_ptr = NULL;
793 g_variant_iter_init(&options_iter, options);
795 options_size = g_variant_iter_n_children(&options_iter);
796 if (0 != options_size) {
797 int ret = _ioty_get_header_options(&options_iter, options_size, oic_options,
798 sizeof(oic_options) / sizeof(oic_options[0]));
799 if (IOTCON_ERROR_NONE != ret) {
800 ERR("_ioty_get_header_options() Fail(%d)", ret);
803 oic_options_ptr = oic_options;
806 icd_ioty_csdk_lock();
807 ret = OCCancel(handle, OC_HIGH_QOS, oic_options_ptr, options_size);
808 icd_ioty_csdk_unlock();
809 if (OC_STACK_OK != ret) {
810 ERR("OCCancel() Fail(%d)", ret);
811 return icd_ioty_convert_error(ret);
814 return IOTCON_ERROR_NONE;
818 int icd_ioty_register_device_info(char *device_name)
820 OCStackResult result;
821 OCDeviceInfo device_info = {0};
823 RETV_IF(NULL == device_name, IOTCON_ERROR_INVALID_PARAMETER);
825 device_info.deviceName = device_name;
827 icd_ioty_csdk_lock();
828 result = OCSetDeviceInfo(device_info);
829 icd_ioty_csdk_unlock();
831 if (OC_STACK_OK != result) {
832 ERR("OCSetDeviceInfo() Fail(%d)", result);
833 return icd_ioty_convert_error(result);
836 icd_tizen_info.device_name = strdup(device_name);
838 return IOTCON_ERROR_NONE;
842 int icd_ioty_register_platform_info(char *platform_id,
843 char *manufacturer_name,
844 char *manufacturer_url,
846 char *date_of_manufacture,
847 char *platform_version,
850 char *firmware_version,
854 OCStackResult result;
855 OCPlatformInfo platform_info = {0};
857 platform_info.platformID = platform_id;
858 platform_info.manufacturerName = manufacturer_name;
859 platform_info.manufacturerUrl = manufacturer_url;
860 platform_info.modelNumber = model_number;
861 platform_info.dateOfManufacture = date_of_manufacture;
862 platform_info.platformVersion = platform_version;
863 platform_info.operatingSystemVersion = os_version;
864 platform_info.hardwareVersion = hw_version;
865 platform_info.firmwareVersion = firmware_version;
866 platform_info.supportUrl = support_url;
867 platform_info.systemTime = system_time;
869 icd_ioty_csdk_lock();
870 result = OCSetPlatformInfo(platform_info);
871 icd_ioty_csdk_unlock();
873 if (OC_STACK_OK != result) {
874 ERR("OCSetPlatformInfo() Fail(%d)", result);
875 return icd_ioty_convert_error(result);
878 return IOTCON_ERROR_NONE;
882 int icd_ioty_get_info(int type, const char *host_address, unsigned int signal_number,
883 const char *bus_name)
885 OCStackResult result;
886 icd_sig_ctx_s *context;
887 OCCallbackData cbdata = {0};
888 char uri[PATH_MAX] = {0};
889 char *uri_path = NULL;
890 iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
891 OCConnectivityType oic_conn_type;
893 if (ICD_DEVICE_INFO == type)
894 uri_path = OC_RSRVD_DEVICE_URI;
895 else if (ICD_PLATFORM_INFO == type)
896 uri_path = OC_RSRVD_PLATFORM_URI;
898 return IOTCON_ERROR_INVALID_PARAMETER;
900 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address))
901 snprintf(uri, sizeof(uri), "%s", uri_path);
903 snprintf(uri, sizeof(uri), "%s%s", host_address, uri_path);
905 context = calloc(1, sizeof(icd_sig_ctx_s));
906 if (NULL == context) {
907 ERR("calloc() Fail(%d)", errno);
908 return IOTCON_ERROR_OUT_OF_MEMORY;
910 context->bus_name = ic_utils_strdup(bus_name);
911 context->signum = signal_number;
913 cbdata.context = context;
914 cbdata.cb = icd_ioty_ocprocess_info_cb;
915 cbdata.cd = _ioty_free_signal_context;
917 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
919 icd_ioty_csdk_lock();
920 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
921 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
922 OC_LOW_QOS, &cbdata, NULL, 0);
923 icd_ioty_csdk_unlock();
925 if (OC_STACK_OK != result) {
926 ERR("OCDoResource() Fail(%d)", result);
927 free(context->bus_name);
929 return icd_ioty_convert_error(result);
932 return IOTCON_ERROR_NONE;
935 static int _icd_ioty_get_tizen_id(char **tizen_device_id)
938 char *tizen_id = NULL;
940 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_TIZEN_ID, &tizen_id);
941 if (SYSTEM_INFO_ERROR_NONE != ret) {
942 ERR("system_info_get_platform_string() Fail(%d)", ret);
943 return IOTCON_ERROR_SYSTEM;
945 *tizen_device_id = tizen_id;
947 return IOTCON_ERROR_NONE;
951 int icd_ioty_set_tizen_info()
955 OCResourceHandle handle;
956 char *tizen_device_id = NULL;
958 result = _icd_ioty_get_tizen_id(&tizen_device_id);
959 if (IOTCON_ERROR_NONE != result) {
960 ERR("_icd_ioty_get_tizen_id() Fail(%d)", result);
964 icd_tizen_info.tizen_device_id = tizen_device_id;
965 DBG("tizen_device_id : %s", icd_tizen_info.tizen_device_id);
967 icd_ioty_csdk_lock();
968 ret = OCCreateResource(&handle,
969 ICD_IOTY_TIZEN_INFO_TYPE,
970 IC_INTERFACE_DEFAULT,
971 ICD_IOTY_TIZEN_INFO_URI,
972 icd_ioty_ocprocess_tizen_info_handler,
975 icd_ioty_csdk_unlock();
976 if (OC_STACK_OK != ret) {
977 ERR("OCCreateResource() Fail(%d)", ret);
978 return icd_ioty_convert_error(ret);
981 return IOTCON_ERROR_NONE;
985 gboolean icd_ioty_get_tizen_info(icDbus *object, GDBusMethodInvocation *invocation,
986 const gchar *host_address)
988 OCStackResult result;
989 OCDevAddr dev_addr = {0};
990 OCCallbackData cbdata = {0};
991 OCConnectivityType oic_conn_type;
992 char host[PATH_MAX] = {0};
993 char *dev_host, *ptr = NULL;
994 int conn_type = IOTCON_CONNECTIVITY_IPV4;
996 snprintf(host, sizeof(host), "%s", host_address);
998 cbdata.cb = icd_ioty_ocprocess_get_tizen_info_cb;
999 cbdata.context = invocation;
1001 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
1002 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
1005 switch (conn_type) {
1006 case IOTCON_CONNECTIVITY_IPV4:
1007 dev_host = strtok_r(host, ":", &ptr);
1008 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
1009 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
1011 case IOTCON_CONNECTIVITY_IPV6:
1012 dev_host = strtok_r(host, "]", &ptr);
1013 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
1014 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
1017 ERR("Invalid Connectivitiy Type");
1018 icd_ioty_complete_error(ICD_TIZEN_INFO, invocation, IOTCON_ERROR_IOTIVITY);
1022 icd_ioty_csdk_lock();
1023 result = OCDoResource(NULL, OC_REST_GET, ICD_IOTY_TIZEN_INFO_URI, &dev_addr, NULL,
1024 oic_conn_type, OC_LOW_QOS, &cbdata, NULL, 0);
1025 icd_ioty_csdk_unlock();
1027 if (OC_STACK_OK != result) {
1028 ERR("OCDoResource() Fail(%d)", result);
1029 icd_ioty_complete_error(ICD_TIZEN_INFO, invocation, icd_ioty_convert_error(result));
1037 int icd_ioty_tizen_info_get_property(char **device_name, char **tizen_device_id)
1039 RETV_IF(NULL == device_name, IOTCON_ERROR_INVALID_PARAMETER);
1040 RETV_IF(NULL == tizen_device_id, IOTCON_ERROR_INVALID_PARAMETER);
1042 *device_name = icd_tizen_info.device_name;
1043 *tizen_device_id = icd_tizen_info.tizen_device_id;
1045 return IOTCON_ERROR_NONE;
1049 OCDoHandle icd_ioty_subscribe_presence(const char *host_address,
1050 const char *resource_type, unsigned int signal_number, const char *bus_name)
1054 OCStackResult result;
1055 char uri[PATH_MAX] = {0};
1056 OCCallbackData cbdata = {0};
1057 icd_sig_ctx_s *context;
1059 len = snprintf(uri, sizeof(uri), "%s%s", host_address, OC_RSRVD_PRESENCE_URI);
1060 if (len <= 0 || sizeof(uri) <= len) {
1061 ERR("snprintf() Fail(%d)", len);
1065 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
1066 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
1068 context = calloc(1, sizeof(icd_sig_ctx_s));
1069 if (NULL == context) {
1070 ERR("calloc() Fail(%d)", errno);
1073 context->bus_name = ic_utils_strdup(bus_name);
1074 context->signum = signal_number;
1076 cbdata.context = context;
1077 cbdata.cb = icd_ioty_ocprocess_presence_cb;
1078 cbdata.cd = _ioty_free_signal_context;
1080 /* In case of IPV4 or IPV6, connectivity type is CT_ADAPTER_IP in iotivity 0.9.2 */
1081 icd_ioty_csdk_lock();
1082 result = OCDoResource(&handle, OC_REST_PRESENCE, uri, NULL, NULL, CT_ADAPTER_IP,
1083 OC_LOW_QOS, &cbdata, NULL, 0);
1084 icd_ioty_csdk_unlock();
1086 if (OC_STACK_OK != result) {
1087 ERR("OCDoResource() Fail(%d)", result);
1088 free(context->bus_name);
1096 int icd_ioty_unsubscribe_presence(OCDoHandle handle)
1100 icd_ioty_csdk_lock();
1101 ret = OCCancel(handle, OC_LOW_QOS, NULL, 0);
1102 icd_ioty_csdk_unlock();
1103 if (OC_STACK_OK != ret) {
1104 ERR("OCCancel() Fail(%d)", ret);
1105 return icd_ioty_convert_error(ret);
1108 return IOTCON_ERROR_NONE;
1112 int icd_ioty_start_presence(unsigned int time_to_live)
1116 icd_ioty_csdk_lock();
1117 ret = OCStartPresence(time_to_live);
1118 icd_ioty_csdk_unlock();
1119 if (OC_STACK_OK != ret) {
1120 ERR("OCStartPresence() Fail(%d)", ret);
1121 return icd_ioty_convert_error(ret);
1124 return IOTCON_ERROR_NONE;
1128 int icd_ioty_stop_presence()
1132 icd_ioty_csdk_lock();
1133 ret = OCStopPresence();
1134 icd_ioty_csdk_unlock();
1135 if (OC_STACK_OK != ret) {
1136 ERR("OCStopPresence() Fail(%d)", ret);
1137 return icd_ioty_convert_error(ret);
1140 return IOTCON_ERROR_NONE;