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 */
31 #include "icd-payload.h"
34 #include "icd-ioty-type.h"
35 #include "icd-ioty-ocprocess.h"
37 static GMutex icd_csdk_mutex;
39 void icd_ioty_csdk_lock()
41 g_mutex_lock(&icd_csdk_mutex);
45 void icd_ioty_csdk_unlock()
47 g_mutex_unlock(&icd_csdk_mutex);
51 GThread* icd_ioty_init(const char *addr, unsigned short port)
57 OCStackResult result = OCInit(addr, port, OC_CLIENT_SERVER);
58 if (OC_STACK_OK != result) {
59 ERR("OCInit() Fail(%d)", result);
63 DBG("OCInit() Success");
65 thread = g_thread_try_new("packet_receive_thread", icd_ioty_ocprocess_thread,
68 ERR("g_thread_try_new() Fail(%s)", error->message);
77 void icd_ioty_deinit(GThread *thread)
81 icd_ioty_ocprocess_stop();
82 g_thread_join(thread);
85 if (OC_STACK_OK != result)
86 ERR("OCStop() Fail(%d)", result);
90 OCResourceHandle icd_ioty_register_resource(const char *uri_path,
91 const char* const* res_types, int ifaces, uint8_t properties)
96 OCResourceHandle handle;
97 const char *res_iface = NULL;
99 if (IOTCON_INTERFACE_DEFAULT & ifaces) {
100 res_iface = IC_INTERFACE_DEFAULT;
101 ifaces ^= IOTCON_INTERFACE_DEFAULT;
102 } else if (IOTCON_INTERFACE_LINK & ifaces) {
103 res_iface = IC_INTERFACE_LINK;
104 ifaces ^= IOTCON_INTERFACE_LINK;
105 } else if (IOTCON_INTERFACE_BATCH & ifaces) {
106 res_iface = IC_INTERFACE_BATCH;
107 ifaces ^= IOTCON_INTERFACE_BATCH;
108 } else if (IOTCON_INTERFACE_GROUP & ifaces) {
109 res_iface = IC_INTERFACE_GROUP;
110 ifaces ^= IOTCON_INTERFACE_GROUP;
112 ERR("Invalid interface type(%d)", ifaces);
116 /* Secure option is not supported yet. */
117 properties = (properties & OC_SECURE)? (properties ^ OC_SECURE):properties;
119 icd_ioty_csdk_lock();
120 ret = OCCreateResource(&handle, res_types[0], res_iface, uri_path,
121 icd_ioty_ocprocess_req_handler, NULL, properties);
122 icd_ioty_csdk_unlock();
123 if (OC_STACK_OK != ret) {
124 ERR("OCCreateResource() Fail(%d)", ret);
128 for (i = 1; res_types[i]; i++)
129 icd_ioty_bind_type(handle, res_types[i]);
131 if (IOTCON_INTERFACE_DEFAULT & ifaces)
132 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_DEFAULT);
133 if (IOTCON_INTERFACE_LINK & ifaces)
134 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_LINK);
135 if (IOTCON_INTERFACE_BATCH & ifaces)
136 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_BATCH);
137 if (IOTCON_INTERFACE_GROUP & ifaces)
138 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_GROUP);
144 int icd_ioty_unregister_resource(OCResourceHandle handle)
148 icd_ioty_csdk_lock();
149 ret = OCDeleteResource(handle);
150 icd_ioty_csdk_unlock();
152 if (OC_STACK_OK != ret) {
153 ERR("OCDeleteResource() Fail(%d)", ret);
154 return icd_ioty_convert_error(ret);
157 return IOTCON_ERROR_NONE;
161 int icd_ioty_bind_interface(OCResourceHandle handle, iotcon_interface_e iface)
164 OCStackResult result;
165 char *resource_interface;
167 ret = ic_utils_convert_interface_flag(iface, &resource_interface);
168 if (IOTCON_ERROR_NONE != ret) {
169 ERR("ic_utils_convert_interface_flag(%d) Fail(%d)", iface, ret);
173 icd_ioty_csdk_lock();
174 result = OCBindResourceInterfaceToResource(handle, resource_interface);
175 icd_ioty_csdk_unlock();
177 if (OC_STACK_OK != result) {
178 ERR("OCBindResourceInterfaceToResource() Fail(%d)", result);
179 return icd_ioty_convert_error(result);
182 return IOTCON_ERROR_NONE;
186 int icd_ioty_bind_type(OCResourceHandle handle, const char *resource_type)
190 icd_ioty_csdk_lock();
191 ret = OCBindResourceTypeToResource(handle, resource_type);
192 icd_ioty_csdk_unlock();
194 if (OC_STACK_OK != ret) {
195 ERR("OCBindResourceTypeToResource() Fail(%d)", ret);
196 return icd_ioty_convert_error(ret);
199 return IOTCON_ERROR_NONE;
203 int icd_ioty_bind_resource(OCResourceHandle parent, OCResourceHandle child)
207 icd_ioty_csdk_lock();
208 ret = OCBindResource(parent, child);
209 icd_ioty_csdk_unlock();
211 if (OC_STACK_OK != ret) {
212 ERR("OCBindResource() Fail(%d)", ret);
213 return icd_ioty_convert_error(ret);
216 return IOTCON_ERROR_NONE;
220 int icd_ioty_unbind_resource(OCResourceHandle parent, OCResourceHandle child)
224 icd_ioty_csdk_lock();
225 ret = OCUnBindResource(parent, child);
226 icd_ioty_csdk_unlock();
228 if (OC_STACK_OK != ret) {
229 ERR("OCUnBindResource() Fail(%d)", ret);
230 return icd_ioty_convert_error(ret);
233 return IOTCON_ERROR_NONE;
237 int icd_ioty_notify_list_of_observers(OCResourceHandle handle, GVariant *msg,
240 int i, error_code, obs_length;
242 GVariantIter obs_iter, msg_iter;
244 OCRepPayload *payload;
246 g_variant_iter_init(&obs_iter, observers);
247 obs_length = g_variant_iter_n_children(&obs_iter);
249 /* Variable-length Array */
250 OCObservationId obs_ids[obs_length];
252 for (i = 0; i < obs_length; i++)
253 g_variant_iter_loop(&obs_iter, "i", &obs_ids[i]);
255 g_variant_iter_init(&msg_iter, msg);
256 g_variant_iter_loop(&msg_iter, "(iv)", &error_code, &repr_gvar);
257 /* TODO : How to use error_code. */
259 payload = icd_payload_representation_from_gvariant(repr_gvar);
261 icd_ioty_csdk_lock();
262 /* TODO : QoS is come from lib. */
263 ret = OCNotifyListOfObservers(handle, obs_ids, obs_length, payload, OC_LOW_QOS);
264 icd_ioty_csdk_unlock();
266 if (OC_STACK_NO_OBSERVERS == ret) {
267 WARN("No Observers. Stop Notifying");
268 return IOTCON_ERROR_NONE;
269 } else if (OC_STACK_OK != ret) {
270 ERR("OCNotifyListOfObservers() Fail(%d)", ret);
271 return icd_ioty_convert_error(ret);
274 return IOTCON_ERROR_NONE;
278 int icd_ioty_notify_all(OCResourceHandle handle)
282 icd_ioty_csdk_lock();
283 /* TODO : QoS is come from lib. */
284 ret = OCNotifyAllObservers(handle, OC_LOW_QOS);
285 icd_ioty_csdk_unlock();
287 if (OC_STACK_NO_OBSERVERS == ret) {
288 WARN("No Observers. Stop Notifying");
289 return IOTCON_ERROR_NONE;
290 } else if (OC_STACK_OK != ret) {
291 ERR("OCNotifyAllObservers() Fail(%d)", ret);
292 return icd_ioty_convert_error(ret);
295 return IOTCON_ERROR_NONE;
299 static int _ioty_get_header_options(GVariantIter *src, int src_size,
300 OCHeaderOption dest[], int dest_size)
304 unsigned short option_id;
306 RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
308 if (dest_size < src_size) {
309 ERR("Exceed Size(%d)", src_size);
310 return IOTCON_ERROR_INVALID_PARAMETER;
313 while (g_variant_iter_loop(src, "(q&s)", &option_id, &option_data)) {
314 dest[i].protocolID = OC_COAP_ID;
315 dest[i].optionID = option_id;
316 dest[i].optionLength = strlen(option_data) + 1;
317 memcpy(dest[i].optionData, option_data, dest[i].optionLength);
321 return IOTCON_ERROR_NONE;
325 int icd_ioty_send_response(GVariant *resp)
329 GVariantIter *options;
331 OCEntityHandlerResponse response = {0};
332 int result, error_code, options_size;
333 int64_t request_handle, resource_handle;
335 g_variant_get(resp, "(&sia(qs)ivxx)",
344 response.requestHandle = ICD_INT64_TO_POINTER(request_handle);
345 response.resourceHandle = ICD_INT64_TO_POINTER(resource_handle);
346 response.ehResult = (OCEntityHandlerResult)result;
348 if (OC_EH_RESOURCE_CREATED == response.ehResult)
349 snprintf(response.resourceUri, sizeof(response.resourceUri), "%s", new_uri_path);
351 options_size = g_variant_iter_n_children(options);
352 response.numSendVendorSpecificHeaderOptions = options_size;
354 if (0 != options_size) {
355 int ret= _ioty_get_header_options(options,
356 response.numSendVendorSpecificHeaderOptions,
357 response.sendVendorSpecificHeaderOptions,
358 sizeof(response.sendVendorSpecificHeaderOptions)
359 / sizeof(response.sendVendorSpecificHeaderOptions[0]));
361 if (IOTCON_ERROR_NONE != ret)
362 ERR("_ioty_get_header_options() Fail(%d)", ret);
364 g_variant_iter_free(options);
366 response.payload = (OCPayload*)icd_payload_representation_from_gvariant(repr_gvar);
368 /* related to block transfer */
369 response.persistentBufferFlag = 0;
371 icd_ioty_csdk_lock();
372 ret = OCDoResponse(&response);
373 icd_ioty_csdk_unlock();
375 if (OC_STACK_OK != ret) {
376 ERR("OCDoResponse() Fail(%d)", ret);
377 return icd_ioty_convert_error(ret);
380 return IOTCON_ERROR_NONE;
384 static void _ioty_free_signal_context(void *data)
386 icd_sig_ctx_s *context = data;
387 free(context->bus_name);
392 int icd_ioty_find_resource(const char *host_address, const char *resource_type,
393 unsigned int signum, const char *bus_name)
396 OCStackResult result;
397 icd_sig_ctx_s *context;
398 char uri[PATH_MAX] = {0};
399 OCCallbackData cbdata = {0};
400 OCConnectivityType oic_conn_type;
401 iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
403 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address)) {
404 len = snprintf(uri, sizeof(uri), "%s", OC_RSRVD_WELL_KNOWN_URI);
406 len = snprintf(uri, sizeof(uri), ICD_IOTY_COAP"%s%s", host_address,
407 OC_RSRVD_WELL_KNOWN_URI);
409 if (len <= 0 || sizeof(uri) <= len) {
410 ERR("snprintf() Fail(%d)", len);
411 return IOTCON_ERROR_IO_ERROR;
414 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
415 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
417 context = calloc(1, sizeof(icd_sig_ctx_s));
418 if (NULL == context) {
419 ERR("calloc() Fail(%d)", errno);
420 return IOTCON_ERROR_OUT_OF_MEMORY;
423 context->bus_name = ic_utils_strdup(bus_name);
424 context->signum = signum;
426 cbdata.context = context;
427 cbdata.cb = icd_ioty_ocprocess_find_cb;
428 cbdata.cd = _ioty_free_signal_context;
430 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
432 icd_ioty_csdk_lock();
433 /* TODO : QoS is come from lib. */
434 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
435 OC_LOW_QOS, &cbdata, NULL, 0);
436 icd_ioty_csdk_unlock();
438 if (OC_STACK_OK != result) {
439 ERR("OCDoResource() Fail(%d)", result);
440 free(context->bus_name);
442 return icd_ioty_convert_error(result);
445 return IOTCON_ERROR_NONE;
450 * returned string SHOULD be released by you
452 static char* _icd_ioty_resource_generate_uri(char *uri_path, GVariant *query)
455 bool loop_first = true;
457 GVariantIter query_iter;
458 char uri_buf[PATH_MAX] = {0};
460 len = snprintf(uri_buf, sizeof(uri_buf), "%s", uri_path);
462 /* remove suffix '/' */
463 if ('/' == uri_buf[strlen(uri_buf) - 1]) {
464 uri_buf[strlen(uri_buf) - 1] = '\0';
468 g_variant_iter_init(&query_iter, query);
470 while (g_variant_iter_loop(&query_iter, "(&s&s)", &key, &value)) {
473 DBG("query exist. key(%s), value(%s)", key, value);
475 if (true == loop_first) {
476 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "?%s=%s", key, value);
479 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "&%s=%s", key, value);
485 return strdup(uri_buf);
489 void icd_ioty_complete(int type, GDBusMethodInvocation *invocation, GVariant *value)
493 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
496 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
499 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
501 case ICD_CRUD_DELETE:
502 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
508 void icd_ioty_complete_error(int type, GDBusMethodInvocation *invocation, int ret_val)
514 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
515 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
518 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
519 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
522 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
523 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
525 case ICD_CRUD_DELETE:
526 value = g_variant_new("(a(qs)i)", NULL, ret_val);
527 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
533 static gboolean _icd_ioty_crud(int type, icDbus *object, GDBusMethodInvocation *invocation,
534 GVariant *resource, GVariant *query, GVariant *repr)
538 OCStackResult result;
539 GVariantIter *options;
540 OCCallbackData cbdata = {0};
541 int conn_type, options_size;
542 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
543 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
544 OCHeaderOption *oic_options_ptr = NULL;
545 OCPayload *payload = NULL;
546 OCConnectivityType oic_conn_type;
547 OCDevAddr dev_addr = {0};
551 cbdata.cb = icd_ioty_ocprocess_get_cb;
552 rest_type = OC_REST_GET;
555 cbdata.cb = icd_ioty_ocprocess_put_cb;
556 rest_type = OC_REST_PUT;
559 cbdata.cb = icd_ioty_ocprocess_post_cb;
560 rest_type = OC_REST_POST;
562 case ICD_CRUD_DELETE:
563 cbdata.cb = icd_ioty_ocprocess_delete_cb;
564 rest_type = OC_REST_DELETE;
567 ERR("Invalid CRUD Type(%d)", type);
571 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
578 uri = _icd_ioty_resource_generate_uri(uri_path, query);
580 ERR("_icd_ioty_resource_generate_uri() Fail");
581 g_variant_iter_free(options);
582 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_INVALID_PARAMETER);
586 case ICD_CRUD_DELETE:
587 uri = strdup(uri_path);
591 cbdata.context = invocation;
593 options_size = g_variant_iter_n_children(options);
594 if (0 != options_size) {
595 int ret = _ioty_get_header_options(options, options_size, oic_options,
596 sizeof(oic_options) / sizeof(oic_options[0]));
597 if (IOTCON_ERROR_NONE != ret) {
598 ERR("_ioty_get_header_options() Fail(%d)", ret);
600 g_variant_iter_free(options);
601 icd_ioty_complete_error(type, invocation, ret);
604 oic_options_ptr = oic_options;
606 g_variant_iter_free(options);
609 payload = (OCPayload*)icd_payload_representation_from_gvariant(repr);
611 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
613 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
617 case IOTCON_CONNECTIVITY_IPV4:
618 dev_host = strtok_r(host, ":", &ptr);
619 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
620 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
622 case IOTCON_CONNECTIVITY_IPV6:
623 dev_host = strtok_r(host, "]", &ptr);
624 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
625 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
628 ERR("Invalid Connectivitiy Type");
629 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_IOTIVITY);
634 icd_ioty_csdk_lock();
635 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
636 result = OCDoResource(NULL, rest_type, uri, &dev_addr, payload, oic_conn_type,
637 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
638 icd_ioty_csdk_unlock();
642 if (OC_STACK_OK != result) {
643 ERR("OCDoResource() Fail(%d)", result);
644 return icd_ioty_convert_error(result);
651 gboolean icd_ioty_get(icDbus *object, GDBusMethodInvocation *invocation,
652 GVariant *resource, GVariant *query)
654 return _icd_ioty_crud(ICD_CRUD_GET, object, invocation, resource, query, NULL);
658 gboolean icd_ioty_put(icDbus *object, GDBusMethodInvocation *invocation,
659 GVariant *resource, GVariant *repr, GVariant *query)
661 return _icd_ioty_crud(ICD_CRUD_PUT, object, invocation, resource, query, repr);
665 gboolean icd_ioty_post(icDbus *object, GDBusMethodInvocation *invocation,
666 GVariant *resource, GVariant *repr, GVariant *query)
668 return _icd_ioty_crud(ICD_CRUD_POST, object, invocation, resource, query, repr);
672 gboolean icd_ioty_delete(icDbus *object, GDBusMethodInvocation *invocation,
675 return _icd_ioty_crud(ICD_CRUD_DELETE, object, invocation, resource, NULL, NULL);
679 OCDoHandle icd_ioty_observer_start(GVariant *resource, int observe_type, GVariant *query,
680 unsigned int signal_number, const char *bus_name)
685 OCStackResult result;
686 GVariantIter *options;
687 icd_sig_ctx_s *context;
688 OCCallbackData cbdata = {0};
689 int conn_type, options_size;
690 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
691 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
692 OCHeaderOption *oic_options_ptr = NULL;
693 OCConnectivityType oic_conn_type;
694 OCDevAddr dev_addr = {0};
696 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
699 uri = _icd_ioty_resource_generate_uri(uri_path, query);
701 ERR("_icd_ioty_resource_generate_uri() Fail");
702 g_variant_iter_free(options);
706 if (IOTCON_OBSERVE == observe_type)
707 method = OC_REST_OBSERVE;
708 else if (IOTCON_OBSERVE_ALL == observe_type)
709 method = OC_REST_OBSERVE_ALL;
711 method = OC_REST_OBSERVE_ALL;
713 context = calloc(1, sizeof(icd_sig_ctx_s));
714 if (NULL == context) {
715 ERR("calloc() Fail(%d)", errno);
718 context->bus_name = ic_utils_strdup(bus_name);
719 context->signum = signal_number;
721 cbdata.context = context;
722 cbdata.cb = icd_ioty_ocprocess_observe_cb;
723 cbdata.cd = _ioty_free_signal_context;
725 options_size = g_variant_iter_n_children(options);
726 if (0 != options_size) {
727 int ret = _ioty_get_header_options(options, options_size, oic_options,
728 sizeof(oic_options) / sizeof(oic_options[0]));
729 if (IOTCON_ERROR_NONE != ret) {
730 ERR("_ioty_get_header_options() Fail(%d)", ret);
731 free(context->bus_name);
734 g_variant_iter_free(options);
737 oic_options_ptr = oic_options;
739 g_variant_iter_free(options);
741 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
743 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
747 case IOTCON_CONNECTIVITY_IPV4:
748 dev_host = strtok_r(host, ":", &ptr);
749 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
750 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
752 case IOTCON_CONNECTIVITY_IPV6:
753 dev_host = strtok_r(host, "]", &ptr);
754 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
755 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
758 ERR("Invalid Connectivitiy Type");
759 free(context->bus_name);
765 icd_ioty_csdk_lock();
766 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
767 result = OCDoResource(&handle, method, uri, &dev_addr, NULL, oic_conn_type,
768 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
769 icd_ioty_csdk_unlock();
771 if (OC_STACK_OK != result) {
772 ERR("OCDoResource() Fail(%d)", result);
773 free(context->bus_name);
782 int icd_ioty_observer_stop(OCDoHandle handle, GVariant *options)
786 GVariantIter options_iter;
787 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
788 OCHeaderOption *oic_options_ptr = NULL;
790 g_variant_iter_init(&options_iter, options);
792 options_size = g_variant_iter_n_children(&options_iter);
793 if (0 != options_size) {
794 int ret = _ioty_get_header_options(&options_iter, options_size, oic_options,
795 sizeof(oic_options) / sizeof(oic_options[0]));
796 if (IOTCON_ERROR_NONE != ret) {
797 ERR("_ioty_get_header_options() Fail(%d)", ret);
800 oic_options_ptr = oic_options;
803 icd_ioty_csdk_lock();
804 ret = OCCancel(handle, OC_HIGH_QOS, oic_options_ptr, options_size);
805 icd_ioty_csdk_unlock();
806 if (OC_STACK_OK != ret) {
807 ERR("OCCancel() Fail(%d)", ret);
808 return icd_ioty_convert_error(ret);
811 return IOTCON_ERROR_NONE;
815 int icd_ioty_register_device_info(GVariant *value)
817 OCStackResult result;
818 OCDeviceInfo device_info = {0};
820 g_variant_get(value, "(&s)", &device_info.deviceName);
822 icd_ioty_csdk_lock();
823 result = OCSetDeviceInfo(device_info);
824 icd_ioty_csdk_unlock();
826 if (OC_STACK_OK != result) {
827 ERR("OCSetDeviceInfo() Fail(%d)", result);
828 return icd_ioty_convert_error(result);
831 return IOTCON_ERROR_NONE;
835 int icd_ioty_register_platform_info(GVariant *value)
837 OCStackResult result;
838 OCPlatformInfo platform_info = {0};
840 g_variant_get(value, "(&s&s&s&s&s&s&s&s&s&s&s)",
841 &platform_info.platformID,
842 &platform_info.manufacturerName,
843 &platform_info.manufacturerUrl,
844 &platform_info.modelNumber,
845 &platform_info.dateOfManufacture,
846 &platform_info.platformVersion,
847 &platform_info.operatingSystemVersion,
848 &platform_info.hardwareVersion,
849 &platform_info.firmwareVersion,
850 &platform_info.supportUrl,
851 &platform_info.systemTime);
853 icd_ioty_csdk_lock();
854 result = OCSetPlatformInfo(platform_info);
855 icd_ioty_csdk_unlock();
857 if (OC_STACK_OK != result) {
858 ERR("OCSetPlatformInfo() Fail(%d)", result);
859 return icd_ioty_convert_error(result);
862 return IOTCON_ERROR_NONE;
866 int icd_ioty_get_info(int type, const char *host_address, unsigned int signal_number,
867 const char *bus_name)
869 OCStackResult result;
870 icd_sig_ctx_s *context;
871 OCCallbackData cbdata = {0};
872 char uri[PATH_MAX] = {0};
873 char *uri_path = NULL;
874 iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
875 OCConnectivityType oic_conn_type;
877 if (ICD_DEVICE_INFO == type)
878 uri_path = OC_RSRVD_DEVICE_URI;
879 else if (ICD_PLATFORM_INFO == type)
880 uri_path = OC_RSRVD_PLATFORM_URI;
882 return IOTCON_ERROR_INVALID_PARAMETER;
884 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address))
885 snprintf(uri, sizeof(uri), "%s", uri_path);
887 snprintf(uri, sizeof(uri), "%s%s", host_address, uri_path);
889 context = calloc(1, sizeof(icd_sig_ctx_s));
890 if (NULL == context) {
891 ERR("calloc() Fail(%d)", errno);
892 return IOTCON_ERROR_OUT_OF_MEMORY;
894 context->bus_name = ic_utils_strdup(bus_name);
895 context->signum = signal_number;
897 cbdata.context = context;
898 cbdata.cb = icd_ioty_ocprocess_info_cb;
899 cbdata.cd = _ioty_free_signal_context;
901 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
903 icd_ioty_csdk_lock();
904 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
905 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
906 OC_LOW_QOS, &cbdata, NULL, 0);
907 icd_ioty_csdk_unlock();
909 if (OC_STACK_OK != result) {
910 ERR("OCDoResource() Fail(%d)", result);
911 free(context->bus_name);
913 return icd_ioty_convert_error(result);
916 return IOTCON_ERROR_NONE;
920 OCDoHandle icd_ioty_subscribe_presence(const char *host_address,
921 const char *resource_type, unsigned int signal_number, const char *bus_name)
925 OCStackResult result;
926 char uri[PATH_MAX] = {0};
927 OCCallbackData cbdata = {0};
928 icd_sig_ctx_s *context;
930 len = snprintf(uri, sizeof(uri), "%s%s", host_address, OC_RSRVD_PRESENCE_URI);
931 if (len <= 0 || sizeof(uri) <= len) {
932 ERR("snprintf() Fail(%d)", len);
936 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
937 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
939 context = calloc(1, sizeof(icd_sig_ctx_s));
940 if (NULL == context) {
941 ERR("calloc() Fail(%d)", errno);
944 context->bus_name = ic_utils_strdup(bus_name);
945 context->signum = signal_number;
947 cbdata.context = context;
948 cbdata.cb = icd_ioty_ocprocess_presence_cb;
949 cbdata.cd = _ioty_free_signal_context;
951 /* In case of IPV4 or IPV6, connectivity type is CT_ADAPTER_IP in iotivity 0.9.2 */
952 icd_ioty_csdk_lock();
953 result = OCDoResource(&handle, OC_REST_PRESENCE, uri, NULL, NULL, CT_ADAPTER_IP,
954 OC_LOW_QOS, &cbdata, NULL, 0);
955 icd_ioty_csdk_unlock();
957 if (OC_STACK_OK != result) {
958 ERR("OCDoResource() Fail(%d)", result);
959 free(context->bus_name);
967 int icd_ioty_unsubscribe_presence(OCDoHandle handle)
971 icd_ioty_csdk_lock();
972 ret = OCCancel(handle, OC_LOW_QOS, NULL, 0);
973 icd_ioty_csdk_unlock();
974 if (OC_STACK_OK != ret) {
975 ERR("OCCancel() Fail(%d)", ret);
976 return icd_ioty_convert_error(ret);
979 return IOTCON_ERROR_NONE;
983 int icd_ioty_start_presence(unsigned int time_to_live)
987 icd_ioty_csdk_lock();
988 ret = OCStartPresence(time_to_live);
989 icd_ioty_csdk_unlock();
990 if (OC_STACK_OK != ret) {
991 ERR("OCStartPresence() Fail(%d)", ret);
992 return icd_ioty_convert_error(ret);
995 return IOTCON_ERROR_NONE;
999 int icd_ioty_stop_presence()
1003 icd_ioty_csdk_lock();
1004 ret = OCStopPresence();
1005 icd_ioty_csdk_unlock();
1006 if (OC_STACK_OK != ret) {
1007 ERR("OCStopPresence() Fail(%d)", ret);
1008 return icd_ioty_convert_error(ret);
1011 return IOTCON_ERROR_NONE;