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();
151 if (OC_STACK_OK != ret) {
152 ERR("OCDeleteResource() Fail(%d)", ret);
153 return IOTCON_ERROR_IOTIVITY;
156 return IOTCON_ERROR_NONE;
160 int icd_ioty_bind_interface(OCResourceHandle handle, iotcon_interface_e iface)
163 OCStackResult result;
164 char *resource_interface;
166 ret = ic_utils_convert_interface_flag(iface, &resource_interface);
167 if (IOTCON_ERROR_NONE != ret) {
168 ERR("ic_utils_convert_interface_flag(%d) Fail(%d)", iface, ret);
172 icd_ioty_csdk_lock();
173 result = OCBindResourceInterfaceToResource(handle, resource_interface);
174 icd_ioty_csdk_unlock();
175 if (OC_STACK_OK != result) {
176 ERR("OCBindResourceInterfaceToResource() Fail(%d)", result);
177 return IOTCON_ERROR_IOTIVITY;
180 return IOTCON_ERROR_NONE;
184 int icd_ioty_bind_type(OCResourceHandle handle, const char *resource_type)
188 icd_ioty_csdk_lock();
189 ret = OCBindResourceTypeToResource(handle, resource_type);
190 icd_ioty_csdk_unlock();
191 if (OC_STACK_OK != ret) {
192 ERR("OCBindResourceTypeToResource() Fail(%d)", ret);
193 return IOTCON_ERROR_IOTIVITY;
196 return IOTCON_ERROR_NONE;
200 int icd_ioty_bind_resource(OCResourceHandle parent, OCResourceHandle child)
204 icd_ioty_csdk_lock();
205 ret = OCBindResource(parent, child);
206 icd_ioty_csdk_unlock();
207 if (OC_STACK_OK != ret) {
208 ERR("OCBindResource() Fail(%d)", ret);
209 return IOTCON_ERROR_IOTIVITY;
212 return IOTCON_ERROR_NONE;
216 int icd_ioty_unbind_resource(OCResourceHandle parent, OCResourceHandle child)
220 icd_ioty_csdk_lock();
221 ret = OCUnBindResource(parent, child);
222 icd_ioty_csdk_unlock();
223 if (OC_STACK_OK != ret) {
224 ERR("OCUnBindResource() Fail(%d)", ret);
225 return IOTCON_ERROR_IOTIVITY;
228 return IOTCON_ERROR_NONE;
232 int icd_ioty_notify_list_of_observers(OCResourceHandle handle, GVariant *msg,
235 int i, error_code, obs_length;
237 GVariantIter obs_iter, msg_iter;
239 OCRepPayload *payload;
241 g_variant_iter_init(&obs_iter, observers);
242 obs_length = g_variant_iter_n_children(&obs_iter);
244 /* Variable-length Array */
245 OCObservationId obs_ids[obs_length];
247 for (i = 0; i < obs_length; i++)
248 g_variant_iter_loop(&obs_iter, "i", &obs_ids[i]);
250 g_variant_iter_init(&msg_iter, msg);
251 g_variant_iter_loop(&msg_iter, "(iv)", &error_code, &repr_gvar);
252 /* TODO : How to use error_code. */
254 payload = icd_payload_representation_from_gvariant(repr_gvar);
256 icd_ioty_csdk_lock();
257 /* TODO : QoS is come from lib. */
258 ret = OCNotifyListOfObservers(handle, obs_ids, obs_length, payload, OC_LOW_QOS);
259 icd_ioty_csdk_unlock();
261 if (OC_STACK_NO_OBSERVERS == ret) {
262 WARN("No Observers. Stop Notifying");
263 return IOTCON_ERROR_NONE;
264 } else if (OC_STACK_OK != ret) {
265 ERR("OCNotifyListOfObservers() Fail(%d)", ret);
266 return IOTCON_ERROR_IOTIVITY;
269 return IOTCON_ERROR_NONE;
273 int icd_ioty_notify_all(OCResourceHandle handle)
277 icd_ioty_csdk_lock();
278 /* TODO : QoS is come from lib. */
279 ret = OCNotifyAllObservers(handle, OC_LOW_QOS);
280 icd_ioty_csdk_unlock();
282 if (OC_STACK_NO_OBSERVERS == ret) {
283 WARN("No Observers. Stop Notifying");
284 return IOTCON_ERROR_NONE;
285 } else if (OC_STACK_OK != ret) {
286 ERR("OCNotifyAllObservers() Fail(%d)", ret);
287 return IOTCON_ERROR_IOTIVITY;
290 return IOTCON_ERROR_NONE;
294 static int _ioty_get_header_options(GVariantIter *src, int src_size,
295 OCHeaderOption dest[], int dest_size)
299 unsigned short option_id;
301 RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
303 if (dest_size < src_size) {
304 ERR("Exceed Size(%d)", src_size);
305 return IOTCON_ERROR_INVALID_PARAMETER;
308 while (g_variant_iter_loop(src, "(q&s)", &option_id, &option_data)) {
309 dest[i].protocolID = OC_COAP_ID;
310 dest[i].optionID = option_id;
311 dest[i].optionLength = strlen(option_data) + 1;
312 memcpy(dest[i].optionData, option_data, dest[i].optionLength);
316 return IOTCON_ERROR_NONE;
320 int icd_ioty_send_response(GVariant *resp)
324 GVariantIter *options;
326 OCEntityHandlerResponse response = {0};
327 int result, error_code, options_size;
328 int64_t request_handle, resource_handle;
330 g_variant_get(resp, "(&sia(qs)ivxx)",
339 response.requestHandle = ICD_INT64_TO_POINTER(request_handle);
340 response.resourceHandle = ICD_INT64_TO_POINTER(resource_handle);
341 response.ehResult = (OCEntityHandlerResult)result;
343 if (OC_EH_RESOURCE_CREATED == response.ehResult)
344 snprintf(response.resourceUri, sizeof(response.resourceUri), "%s", new_uri_path);
346 options_size = g_variant_iter_n_children(options);
347 response.numSendVendorSpecificHeaderOptions = options_size;
349 if (0 != options_size) {
350 int ret= _ioty_get_header_options(options,
351 response.numSendVendorSpecificHeaderOptions,
352 response.sendVendorSpecificHeaderOptions,
353 sizeof(response.sendVendorSpecificHeaderOptions)
354 / sizeof(response.sendVendorSpecificHeaderOptions[0]));
356 if (IOTCON_ERROR_NONE != ret)
357 ERR("_ioty_get_header_options() Fail(%d)", ret);
359 g_variant_iter_free(options);
361 response.payload = (OCPayload*)icd_payload_representation_from_gvariant(repr_gvar);
363 /* related to block transfer */
364 response.persistentBufferFlag = 0;
366 icd_ioty_csdk_lock();
367 ret = OCDoResponse(&response);
368 icd_ioty_csdk_unlock();
370 if (OC_STACK_OK != ret) {
371 ERR("OCDoResponse() Fail(%d)", ret);
372 return IOTCON_ERROR_IOTIVITY;
375 return IOTCON_ERROR_NONE;
379 static void _ioty_free_signal_context(void *data)
381 icd_sig_ctx_s *context = data;
382 free(context->bus_name);
387 int icd_ioty_find_resource(const char *host_address, const char *resource_type,
388 unsigned int signum, const char *bus_name)
391 OCStackResult result;
392 icd_sig_ctx_s *context;
393 char uri[PATH_MAX] = {0};
394 OCCallbackData cbdata = {0};
395 OCConnectivityType oic_conn_type;
396 iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
398 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address)) {
399 len = snprintf(uri, sizeof(uri), "%s", OC_RSRVD_WELL_KNOWN_URI);
401 len = snprintf(uri, sizeof(uri), ICD_IOTY_COAP"%s%s", host_address,
402 OC_RSRVD_WELL_KNOWN_URI);
404 if (len <= 0 || sizeof(uri) <= len) {
405 ERR("snprintf() Fail(%d)", len);
406 return IOTCON_ERROR_IO_ERROR;
409 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
410 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
412 context = calloc(1, sizeof(icd_sig_ctx_s));
413 if (NULL == context) {
414 ERR("calloc() Fail(%d)", errno);
415 return IOTCON_ERROR_OUT_OF_MEMORY;
418 context->bus_name = ic_utils_strdup(bus_name);
419 context->signum = signum;
421 cbdata.context = context;
422 cbdata.cb = icd_ioty_ocprocess_find_cb;
423 cbdata.cd = _ioty_free_signal_context;
425 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
427 icd_ioty_csdk_lock();
428 /* TODO : QoS is come from lib. */
429 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
430 OC_LOW_QOS, &cbdata, NULL, 0);
431 icd_ioty_csdk_unlock();
433 if (OC_STACK_OK != result) {
434 ERR("OCDoResource() Fail(%d)", result);
435 free(context->bus_name);
437 return IOTCON_ERROR_IOTIVITY;
440 return IOTCON_ERROR_NONE;
445 * returned string SHOULD be released by you
447 static char* _icd_ioty_resource_generate_uri(char *uri_path, GVariant *query)
450 bool loop_first = true;
452 GVariantIter query_iter;
453 char uri_buf[PATH_MAX] = {0};
455 len = snprintf(uri_buf, sizeof(uri_buf), "%s", uri_path);
457 /* remove suffix '/' */
458 if ('/' == uri_buf[strlen(uri_buf) - 1]) {
459 uri_buf[strlen(uri_buf) - 1] = '\0';
463 g_variant_iter_init(&query_iter, query);
465 while (g_variant_iter_loop(&query_iter, "(&s&s)", &key, &value)) {
468 DBG("query exist. key(%s), value(%s)", key, value);
470 if (true == loop_first) {
471 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "?%s=%s", key, value);
474 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "&%s=%s", key, value);
480 return strdup(uri_buf);
484 void icd_ioty_complete(int type, GDBusMethodInvocation *invocation, GVariant *value)
488 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
491 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
494 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
496 case ICD_CRUD_DELETE:
497 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
503 void icd_ioty_complete_error(int type, GDBusMethodInvocation *invocation, int ret_val)
509 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
510 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
513 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
514 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
517 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
518 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
520 case ICD_CRUD_DELETE:
521 value = g_variant_new("(a(qs)i)", NULL, ret_val);
522 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
528 static gboolean _icd_ioty_crud(int type, icDbus *object, GDBusMethodInvocation *invocation,
529 GVariant *resource, GVariant *query, GVariant *repr)
533 OCStackResult result;
534 GVariantIter *options;
535 OCCallbackData cbdata = {0};
536 int conn_type, options_size;
537 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
538 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
539 OCHeaderOption *oic_options_ptr = NULL;
540 OCPayload *payload = NULL;
541 OCConnectivityType oic_conn_type;
542 OCDevAddr dev_addr = {0};
546 cbdata.cb = icd_ioty_ocprocess_get_cb;
547 rest_type = OC_REST_GET;
550 cbdata.cb = icd_ioty_ocprocess_put_cb;
551 rest_type = OC_REST_PUT;
554 cbdata.cb = icd_ioty_ocprocess_post_cb;
555 rest_type = OC_REST_POST;
557 case ICD_CRUD_DELETE:
558 cbdata.cb = icd_ioty_ocprocess_delete_cb;
559 rest_type = OC_REST_DELETE;
562 ERR("Invalid CRUD Type(%d)", type);
566 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
573 uri = _icd_ioty_resource_generate_uri(uri_path, query);
575 ERR("_icd_ioty_resource_generate_uri() Fail");
576 g_variant_iter_free(options);
577 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_INVALID_PARAMETER);
581 case ICD_CRUD_DELETE:
582 uri = strdup(uri_path);
586 cbdata.context = invocation;
588 options_size = g_variant_iter_n_children(options);
589 if (0 != options_size) {
590 int ret = _ioty_get_header_options(options, options_size, oic_options,
591 sizeof(oic_options) / sizeof(oic_options[0]));
592 if (IOTCON_ERROR_NONE != ret) {
593 ERR("_ioty_get_header_options() Fail(%d)", ret);
595 g_variant_iter_free(options);
596 icd_ioty_complete_error(type, invocation, ret);
599 oic_options_ptr = oic_options;
601 g_variant_iter_free(options);
604 payload = (OCPayload*)icd_payload_representation_from_gvariant(repr);
606 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
608 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
612 case IOTCON_CONNECTIVITY_IPV4:
613 dev_host = strtok_r(host, ":", &ptr);
614 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
615 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
617 case IOTCON_CONNECTIVITY_IPV6:
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));
623 ERR("Invalid Connectivitiy Type");
624 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_IOTIVITY);
629 icd_ioty_csdk_lock();
630 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
631 result = OCDoResource(NULL, rest_type, uri, &dev_addr, payload, oic_conn_type,
632 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
633 icd_ioty_csdk_unlock();
637 if (OC_STACK_OK != result) {
638 ERR("OCDoResource() Fail(%d)", result);
639 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_IOTIVITY);
646 gboolean icd_ioty_get(icDbus *object, GDBusMethodInvocation *invocation,
647 GVariant *resource, GVariant *query)
649 return _icd_ioty_crud(ICD_CRUD_GET, object, invocation, resource, query, NULL);
653 gboolean icd_ioty_put(icDbus *object, GDBusMethodInvocation *invocation,
654 GVariant *resource, GVariant *repr, GVariant *query)
656 return _icd_ioty_crud(ICD_CRUD_PUT, object, invocation, resource, query, repr);
660 gboolean icd_ioty_post(icDbus *object, GDBusMethodInvocation *invocation,
661 GVariant *resource, GVariant *repr, GVariant *query)
663 return _icd_ioty_crud(ICD_CRUD_POST, object, invocation, resource, query, repr);
667 gboolean icd_ioty_delete(icDbus *object, GDBusMethodInvocation *invocation,
670 return _icd_ioty_crud(ICD_CRUD_DELETE, object, invocation, resource, NULL, NULL);
674 OCDoHandle icd_ioty_observer_start(GVariant *resource, int observe_type, GVariant *query,
675 unsigned int signal_number, const char *bus_name)
680 OCStackResult result;
681 GVariantIter *options;
682 icd_sig_ctx_s *context;
683 OCCallbackData cbdata = {0};
684 int conn_type, options_size;
685 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
686 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
687 OCHeaderOption *oic_options_ptr = NULL;
688 OCConnectivityType oic_conn_type;
689 OCDevAddr dev_addr = {0};
691 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
694 uri = _icd_ioty_resource_generate_uri(uri_path, query);
696 ERR("_icd_ioty_resource_generate_uri() Fail");
697 g_variant_iter_free(options);
701 if (IOTCON_OBSERVE == observe_type)
702 method = OC_REST_OBSERVE;
703 else if (IOTCON_OBSERVE_ALL == observe_type)
704 method = OC_REST_OBSERVE_ALL;
706 method = OC_REST_OBSERVE_ALL;
708 context = calloc(1, sizeof(icd_sig_ctx_s));
709 if (NULL == context) {
710 ERR("calloc() Fail(%d)", errno);
713 context->bus_name = ic_utils_strdup(bus_name);
714 context->signum = signal_number;
716 cbdata.context = context;
717 cbdata.cb = icd_ioty_ocprocess_observe_cb;
718 cbdata.cd = _ioty_free_signal_context;
720 options_size = g_variant_iter_n_children(options);
721 if (0 != options_size) {
722 int ret = _ioty_get_header_options(options, options_size, oic_options,
723 sizeof(oic_options) / sizeof(oic_options[0]));
724 if (IOTCON_ERROR_NONE != ret) {
725 ERR("_ioty_get_header_options() Fail(%d)", ret);
726 free(context->bus_name);
729 g_variant_iter_free(options);
732 oic_options_ptr = oic_options;
734 g_variant_iter_free(options);
736 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
738 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
742 case IOTCON_CONNECTIVITY_IPV4:
743 dev_host = strtok_r(host, ":", &ptr);
744 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
745 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
747 case IOTCON_CONNECTIVITY_IPV6:
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));
753 ERR("Invalid Connectivitiy Type");
754 free(context->bus_name);
760 icd_ioty_csdk_lock();
761 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
762 result = OCDoResource(&handle, method, uri, &dev_addr, NULL, oic_conn_type,
763 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
764 icd_ioty_csdk_unlock();
766 if (OC_STACK_OK != result) {
767 ERR("OCDoResource() Fail(%d)", result);
768 free(context->bus_name);
777 int icd_ioty_observer_stop(OCDoHandle handle, GVariant *options)
781 GVariantIter options_iter;
782 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
783 OCHeaderOption *oic_options_ptr = NULL;
785 g_variant_iter_init(&options_iter, options);
787 options_size = g_variant_iter_n_children(&options_iter);
788 if (0 != options_size) {
789 int ret = _ioty_get_header_options(&options_iter, options_size, oic_options,
790 sizeof(oic_options) / sizeof(oic_options[0]));
791 if (IOTCON_ERROR_NONE != ret) {
792 ERR("_ioty_get_header_options() Fail(%d)", ret);
795 oic_options_ptr = oic_options;
798 icd_ioty_csdk_lock();
799 ret = OCCancel(handle, OC_HIGH_QOS, oic_options_ptr, options_size);
800 icd_ioty_csdk_unlock();
801 if (OC_STACK_OK != ret) {
802 ERR("OCCancel() Fail(%d)", ret);
803 return IOTCON_ERROR_IOTIVITY;
806 return IOTCON_ERROR_NONE;
810 int icd_ioty_register_device_info(GVariant *value)
812 OCStackResult result;
813 OCDeviceInfo device_info = {0};
815 g_variant_get(value, "(&s)", &device_info.deviceName);
817 icd_ioty_csdk_lock();
818 result = OCSetDeviceInfo(device_info);
819 icd_ioty_csdk_unlock();
821 if (OC_STACK_OK != result) {
822 ERR("OCSetDeviceInfo() Fail(%d)", result);
823 return IOTCON_ERROR_IOTIVITY;
826 return IOTCON_ERROR_NONE;
830 int icd_ioty_register_platform_info(GVariant *value)
832 OCStackResult result;
833 OCPlatformInfo platform_info = {0};
835 g_variant_get(value, "(&s&s&s&s&s&s&s&s&s&s&s)",
836 &platform_info.platformID,
837 &platform_info.manufacturerName,
838 &platform_info.manufacturerUrl,
839 &platform_info.modelNumber,
840 &platform_info.dateOfManufacture,
841 &platform_info.platformVersion,
842 &platform_info.operatingSystemVersion,
843 &platform_info.hardwareVersion,
844 &platform_info.firmwareVersion,
845 &platform_info.supportUrl,
846 &platform_info.systemTime);
848 icd_ioty_csdk_lock();
849 result = OCSetPlatformInfo(platform_info);
850 icd_ioty_csdk_unlock();
852 if (OC_STACK_OK != result) {
853 ERR("OCSetPlatformInfo() Fail(%d)", result);
854 return IOTCON_ERROR_IOTIVITY;
857 return IOTCON_ERROR_NONE;
861 int icd_ioty_get_info(int type, const char *host_address, unsigned int signal_number,
862 const char *bus_name)
864 OCStackResult result;
865 icd_sig_ctx_s *context;
866 OCCallbackData cbdata = {0};
867 char uri[PATH_MAX] = {0};
868 char *uri_path = NULL;
869 iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
870 OCConnectivityType oic_conn_type;
872 if (ICD_DEVICE_INFO == type)
873 uri_path = OC_RSRVD_DEVICE_URI;
874 else if (ICD_PLATFORM_INFO == type)
875 uri_path = OC_RSRVD_PLATFORM_URI;
877 return IOTCON_ERROR_INVALID_PARAMETER;
879 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address))
880 snprintf(uri, sizeof(uri), "%s", uri_path);
882 snprintf(uri, sizeof(uri), "%s%s", host_address, uri_path);
884 context = calloc(1, sizeof(icd_sig_ctx_s));
885 if (NULL == context) {
886 ERR("calloc() Fail(%d)", errno);
887 return IOTCON_ERROR_OUT_OF_MEMORY;
889 context->bus_name = ic_utils_strdup(bus_name);
890 context->signum = signal_number;
892 cbdata.context = context;
893 cbdata.cb = icd_ioty_ocprocess_info_cb;
894 cbdata.cd = _ioty_free_signal_context;
896 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
898 icd_ioty_csdk_lock();
899 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
900 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
901 OC_LOW_QOS, &cbdata, NULL, 0);
902 icd_ioty_csdk_unlock();
904 if (OC_STACK_OK != result) {
905 ERR("OCDoResource() Fail(%d)", result);
906 free(context->bus_name);
908 return IOTCON_ERROR_IOTIVITY;
911 return IOTCON_ERROR_NONE;
915 OCDoHandle icd_ioty_subscribe_presence(const char *host_address,
916 const char *resource_type, unsigned int signal_number, const char *bus_name)
920 OCStackResult result;
921 char uri[PATH_MAX] = {0};
922 OCCallbackData cbdata = {0};
923 icd_sig_ctx_s *context;
925 len = snprintf(uri, sizeof(uri), "%s%s", host_address, OC_RSRVD_PRESENCE_URI);
926 if (len <= 0 || sizeof(uri) <= len) {
927 ERR("snprintf() Fail(%d)", len);
931 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
932 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
934 context = calloc(1, sizeof(icd_sig_ctx_s));
935 if (NULL == context) {
936 ERR("calloc() Fail(%d)", errno);
939 context->bus_name = ic_utils_strdup(bus_name);
940 context->signum = signal_number;
942 cbdata.context = context;
943 cbdata.cb = icd_ioty_ocprocess_presence_cb;
944 cbdata.cd = _ioty_free_signal_context;
946 /* In case of IPV4 or IPV6, connectivity type is CT_ADAPTER_IP in iotivity 0.9.2 */
947 icd_ioty_csdk_lock();
948 result = OCDoResource(&handle, OC_REST_PRESENCE, uri, NULL, NULL, CT_ADAPTER_IP,
949 OC_LOW_QOS, &cbdata, NULL, 0);
950 icd_ioty_csdk_unlock();
952 if (OC_STACK_OK != result) {
953 ERR("OCDoResource() Fail(%d)", result);
954 free(context->bus_name);
962 int icd_ioty_unsubscribe_presence(OCDoHandle handle)
966 icd_ioty_csdk_lock();
967 ret = OCCancel(handle, OC_LOW_QOS, NULL, 0);
968 icd_ioty_csdk_unlock();
969 if (OC_STACK_OK != ret) {
970 ERR("OCCancel() Fail(%d)", ret);
971 return IOTCON_ERROR_IOTIVITY;
974 return IOTCON_ERROR_NONE;
978 int icd_ioty_start_presence(unsigned int time_to_live)
982 icd_ioty_csdk_lock();
983 ret = OCStartPresence(time_to_live);
984 icd_ioty_csdk_unlock();
985 if (OC_STACK_OK != ret) {
986 ERR("OCStartPresence() Fail(%d)", ret);
987 return IOTCON_ERROR_IOTIVITY;
990 return IOTCON_ERROR_NONE;
994 int icd_ioty_stop_presence()
998 icd_ioty_csdk_lock();
999 ret = OCStopPresence();
1000 icd_ioty_csdk_unlock();
1001 if (OC_STACK_OK != ret) {
1002 ERR("OCStopPresence() Fail(%d)", ret);
1003 return IOTCON_ERROR_IOTIVITY;
1006 return IOTCON_ERROR_NONE;