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(OCResourceHandle handle, GVariant *msg, GVariant *observers)
239 int i, error_code, obs_length, msg_length;
241 GVariantIter obs_iter, msg_iter;
243 OCRepPayload *payload;
245 g_variant_iter_init(&obs_iter, observers);
246 obs_length = g_variant_iter_n_children(&obs_iter);
248 /* Variable-length Array */
249 OCObservationId obs_ids[obs_length];
251 for (i = 0; i < obs_length; i++)
252 g_variant_iter_loop(&obs_iter, "i", &obs_ids[i]);
254 g_variant_iter_init(&msg_iter, msg);
255 msg_length = g_variant_iter_n_children(&msg_iter);
257 g_variant_iter_loop(&msg_iter, "(iv)", &error_code, &repr_gvar);
258 /* TODO : How to use error_code. */
259 payload = icd_payload_representation_from_gvariant(repr_gvar);
262 icd_ioty_csdk_lock();
263 /* TODO : QoS is come from lib. */
265 ret = OCNotifyListOfObservers(handle, obs_ids, obs_length, payload, OC_LOW_QOS);
267 ret = OCNotifyAllObservers(handle, OC_LOW_QOS);
269 icd_ioty_csdk_unlock();
271 if (OC_STACK_NO_OBSERVERS == ret) {
272 WARN("No Observers. Stop Notifying");
273 return IOTCON_ERROR_NONE;
274 } else if (OC_STACK_OK != ret) {
275 ERR("OCNotifyListOfObservers() Fail(%d)", ret);
276 return icd_ioty_convert_error(ret);
279 return IOTCON_ERROR_NONE;
283 static int _ioty_get_header_options(GVariantIter *src, int src_size,
284 OCHeaderOption dest[], int dest_size)
288 unsigned short option_id;
290 RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
292 if (dest_size < src_size) {
293 ERR("Exceed Size(%d)", src_size);
294 return IOTCON_ERROR_INVALID_PARAMETER;
297 while (g_variant_iter_loop(src, "(q&s)", &option_id, &option_data)) {
298 dest[i].protocolID = OC_COAP_ID;
299 dest[i].optionID = option_id;
300 dest[i].optionLength = strlen(option_data) + 1;
301 memcpy(dest[i].optionData, option_data, dest[i].optionLength);
305 return IOTCON_ERROR_NONE;
309 int icd_ioty_send_response(GVariant *resp)
313 GVariantIter *options;
315 OCEntityHandlerResponse response = {0};
316 int result, error_code, options_size;
317 int64_t request_handle, resource_handle;
319 g_variant_get(resp, "(&sia(qs)ivxx)",
328 response.requestHandle = ICD_INT64_TO_POINTER(request_handle);
329 response.resourceHandle = ICD_INT64_TO_POINTER(resource_handle);
330 response.ehResult = (OCEntityHandlerResult)result;
332 if (OC_EH_RESOURCE_CREATED == response.ehResult)
333 snprintf(response.resourceUri, sizeof(response.resourceUri), "%s", new_uri_path);
335 options_size = g_variant_iter_n_children(options);
336 response.numSendVendorSpecificHeaderOptions = options_size;
338 if (0 != options_size) {
339 int ret= _ioty_get_header_options(options,
340 response.numSendVendorSpecificHeaderOptions,
341 response.sendVendorSpecificHeaderOptions,
342 sizeof(response.sendVendorSpecificHeaderOptions)
343 / sizeof(response.sendVendorSpecificHeaderOptions[0]));
345 if (IOTCON_ERROR_NONE != ret)
346 ERR("_ioty_get_header_options() Fail(%d)", ret);
348 g_variant_iter_free(options);
350 response.payload = (OCPayload*)icd_payload_representation_from_gvariant(repr_gvar);
352 /* related to block transfer */
353 response.persistentBufferFlag = 0;
355 icd_ioty_csdk_lock();
356 ret = OCDoResponse(&response);
357 icd_ioty_csdk_unlock();
359 if (OC_STACK_OK != ret) {
360 ERR("OCDoResponse() Fail(%d)", ret);
361 return icd_ioty_convert_error(ret);
364 return IOTCON_ERROR_NONE;
368 static void _ioty_free_signal_context(void *data)
370 icd_sig_ctx_s *context = data;
371 free(context->bus_name);
376 int icd_ioty_find_resource(const char *host_address, const char *resource_type,
377 unsigned int signum, const char *bus_name)
380 OCStackResult result;
381 icd_sig_ctx_s *context;
382 char uri[PATH_MAX] = {0};
383 OCCallbackData cbdata = {0};
384 OCConnectivityType oic_conn_type;
385 iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
387 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address)) {
388 len = snprintf(uri, sizeof(uri), "%s", OC_RSRVD_WELL_KNOWN_URI);
390 len = snprintf(uri, sizeof(uri), ICD_IOTY_COAP"%s%s", host_address,
391 OC_RSRVD_WELL_KNOWN_URI);
393 if (len <= 0 || sizeof(uri) <= len) {
394 ERR("snprintf() Fail(%d)", len);
395 return IOTCON_ERROR_IO_ERROR;
398 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
399 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
401 context = calloc(1, sizeof(icd_sig_ctx_s));
402 if (NULL == context) {
403 ERR("calloc() Fail(%d)", errno);
404 return IOTCON_ERROR_OUT_OF_MEMORY;
407 context->bus_name = ic_utils_strdup(bus_name);
408 context->signum = signum;
410 cbdata.context = context;
411 cbdata.cb = icd_ioty_ocprocess_find_cb;
412 cbdata.cd = _ioty_free_signal_context;
414 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
416 icd_ioty_csdk_lock();
417 /* TODO : QoS is come from lib. */
418 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
419 OC_LOW_QOS, &cbdata, NULL, 0);
420 icd_ioty_csdk_unlock();
422 if (OC_STACK_OK != result) {
423 ERR("OCDoResource() Fail(%d)", result);
424 free(context->bus_name);
426 return icd_ioty_convert_error(result);
429 return IOTCON_ERROR_NONE;
434 * returned string SHOULD be released by you
436 static char* _icd_ioty_resource_generate_uri(char *uri_path, GVariant *query)
439 bool loop_first = true;
441 GVariantIter query_iter;
442 char uri_buf[PATH_MAX] = {0};
444 len = snprintf(uri_buf, sizeof(uri_buf), "%s", uri_path);
446 /* remove suffix '/' */
447 if ('/' == uri_buf[strlen(uri_buf) - 1]) {
448 uri_buf[strlen(uri_buf) - 1] = '\0';
452 g_variant_iter_init(&query_iter, query);
454 while (g_variant_iter_loop(&query_iter, "(&s&s)", &key, &value)) {
457 DBG("query exist. key(%s), value(%s)", key, value);
459 if (true == loop_first) {
460 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "?%s=%s", key, value);
463 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "&%s=%s", key, value);
469 return strdup(uri_buf);
473 void icd_ioty_complete(int type, GDBusMethodInvocation *invocation, GVariant *value)
477 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
480 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
483 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
485 case ICD_CRUD_DELETE:
486 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
492 void icd_ioty_complete_error(int type, GDBusMethodInvocation *invocation, int ret_val)
498 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
499 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
502 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
503 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
506 value = g_variant_new("(a(qs)vi)", NULL, NULL, ret_val);
507 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
509 case ICD_CRUD_DELETE:
510 value = g_variant_new("(a(qs)i)", NULL, ret_val);
511 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
517 static gboolean _icd_ioty_crud(int type, icDbus *object, GDBusMethodInvocation *invocation,
518 GVariant *resource, GVariant *query, GVariant *repr)
522 OCStackResult result;
523 GVariantIter *options;
524 OCCallbackData cbdata = {0};
525 int conn_type, options_size;
526 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
527 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
528 OCHeaderOption *oic_options_ptr = NULL;
529 OCPayload *payload = NULL;
530 OCConnectivityType oic_conn_type;
531 OCDevAddr dev_addr = {0};
535 cbdata.cb = icd_ioty_ocprocess_get_cb;
536 rest_type = OC_REST_GET;
539 cbdata.cb = icd_ioty_ocprocess_put_cb;
540 rest_type = OC_REST_PUT;
543 cbdata.cb = icd_ioty_ocprocess_post_cb;
544 rest_type = OC_REST_POST;
546 case ICD_CRUD_DELETE:
547 cbdata.cb = icd_ioty_ocprocess_delete_cb;
548 rest_type = OC_REST_DELETE;
551 ERR("Invalid CRUD Type(%d)", type);
555 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
562 uri = _icd_ioty_resource_generate_uri(uri_path, query);
564 ERR("_icd_ioty_resource_generate_uri() Fail");
565 g_variant_iter_free(options);
566 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_INVALID_PARAMETER);
570 case ICD_CRUD_DELETE:
571 uri = strdup(uri_path);
575 cbdata.context = invocation;
577 options_size = g_variant_iter_n_children(options);
578 if (0 != options_size) {
579 int ret = _ioty_get_header_options(options, options_size, oic_options,
580 sizeof(oic_options) / sizeof(oic_options[0]));
581 if (IOTCON_ERROR_NONE != ret) {
582 ERR("_ioty_get_header_options() Fail(%d)", ret);
584 g_variant_iter_free(options);
585 icd_ioty_complete_error(type, invocation, ret);
588 oic_options_ptr = oic_options;
590 g_variant_iter_free(options);
593 payload = (OCPayload*)icd_payload_representation_from_gvariant(repr);
595 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
597 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
601 case IOTCON_CONNECTIVITY_IPV4:
602 dev_host = strtok_r(host, ":", &ptr);
603 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
604 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
606 case IOTCON_CONNECTIVITY_IPV6:
607 dev_host = strtok_r(host, "]", &ptr);
608 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
609 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
612 ERR("Invalid Connectivitiy Type");
613 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_IOTIVITY);
618 icd_ioty_csdk_lock();
619 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
620 result = OCDoResource(NULL, rest_type, uri, &dev_addr, payload, oic_conn_type,
621 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
622 icd_ioty_csdk_unlock();
626 if (OC_STACK_OK != result) {
627 ERR("OCDoResource() Fail(%d)", result);
628 return icd_ioty_convert_error(result);
635 gboolean icd_ioty_get(icDbus *object, GDBusMethodInvocation *invocation,
636 GVariant *resource, GVariant *query)
638 return _icd_ioty_crud(ICD_CRUD_GET, object, invocation, resource, query, NULL);
642 gboolean icd_ioty_put(icDbus *object, GDBusMethodInvocation *invocation,
643 GVariant *resource, GVariant *repr, GVariant *query)
645 return _icd_ioty_crud(ICD_CRUD_PUT, object, invocation, resource, query, repr);
649 gboolean icd_ioty_post(icDbus *object, GDBusMethodInvocation *invocation,
650 GVariant *resource, GVariant *repr, GVariant *query)
652 return _icd_ioty_crud(ICD_CRUD_POST, object, invocation, resource, query, repr);
656 gboolean icd_ioty_delete(icDbus *object, GDBusMethodInvocation *invocation,
659 return _icd_ioty_crud(ICD_CRUD_DELETE, object, invocation, resource, NULL, NULL);
663 OCDoHandle icd_ioty_observer_start(GVariant *resource, int observe_type, GVariant *query,
664 unsigned int signal_number, const char *bus_name)
669 OCStackResult result;
670 GVariantIter *options;
671 icd_sig_ctx_s *context;
672 OCCallbackData cbdata = {0};
673 int conn_type, options_size;
674 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
675 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
676 OCHeaderOption *oic_options_ptr = NULL;
677 OCConnectivityType oic_conn_type;
678 OCDevAddr dev_addr = {0};
680 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
683 uri = _icd_ioty_resource_generate_uri(uri_path, query);
685 ERR("_icd_ioty_resource_generate_uri() Fail");
686 g_variant_iter_free(options);
690 if (IOTCON_OBSERVE == observe_type)
691 method = OC_REST_OBSERVE;
692 else if (IOTCON_OBSERVE_ALL == observe_type)
693 method = OC_REST_OBSERVE_ALL;
695 method = OC_REST_OBSERVE_ALL;
697 context = calloc(1, sizeof(icd_sig_ctx_s));
698 if (NULL == context) {
699 ERR("calloc() Fail(%d)", errno);
702 context->bus_name = ic_utils_strdup(bus_name);
703 context->signum = signal_number;
705 cbdata.context = context;
706 cbdata.cb = icd_ioty_ocprocess_observe_cb;
707 cbdata.cd = _ioty_free_signal_context;
709 options_size = g_variant_iter_n_children(options);
710 if (0 != options_size) {
711 int ret = _ioty_get_header_options(options, options_size, oic_options,
712 sizeof(oic_options) / sizeof(oic_options[0]));
713 if (IOTCON_ERROR_NONE != ret) {
714 ERR("_ioty_get_header_options() Fail(%d)", ret);
715 free(context->bus_name);
718 g_variant_iter_free(options);
721 oic_options_ptr = oic_options;
723 g_variant_iter_free(options);
725 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
727 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
731 case IOTCON_CONNECTIVITY_IPV4:
732 dev_host = strtok_r(host, ":", &ptr);
733 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
734 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
736 case IOTCON_CONNECTIVITY_IPV6:
737 dev_host = strtok_r(host, "]", &ptr);
738 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
739 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
742 ERR("Invalid Connectivitiy Type");
743 free(context->bus_name);
749 icd_ioty_csdk_lock();
750 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
751 result = OCDoResource(&handle, method, uri, &dev_addr, NULL, oic_conn_type,
752 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
753 icd_ioty_csdk_unlock();
755 if (OC_STACK_OK != result) {
756 ERR("OCDoResource() Fail(%d)", result);
757 free(context->bus_name);
766 int icd_ioty_observer_stop(OCDoHandle handle, GVariant *options)
770 GVariantIter options_iter;
771 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
772 OCHeaderOption *oic_options_ptr = NULL;
774 g_variant_iter_init(&options_iter, options);
776 options_size = g_variant_iter_n_children(&options_iter);
777 if (0 != options_size) {
778 int ret = _ioty_get_header_options(&options_iter, options_size, oic_options,
779 sizeof(oic_options) / sizeof(oic_options[0]));
780 if (IOTCON_ERROR_NONE != ret) {
781 ERR("_ioty_get_header_options() Fail(%d)", ret);
784 oic_options_ptr = oic_options;
787 icd_ioty_csdk_lock();
788 ret = OCCancel(handle, OC_HIGH_QOS, oic_options_ptr, options_size);
789 icd_ioty_csdk_unlock();
790 if (OC_STACK_OK != ret) {
791 ERR("OCCancel() Fail(%d)", ret);
792 return icd_ioty_convert_error(ret);
795 return IOTCON_ERROR_NONE;
799 int icd_ioty_register_device_info(GVariant *value)
801 OCStackResult result;
802 OCDeviceInfo device_info = {0};
804 g_variant_get(value, "(&s)", &device_info.deviceName);
806 icd_ioty_csdk_lock();
807 result = OCSetDeviceInfo(device_info);
808 icd_ioty_csdk_unlock();
810 if (OC_STACK_OK != result) {
811 ERR("OCSetDeviceInfo() Fail(%d)", result);
812 return icd_ioty_convert_error(result);
815 return IOTCON_ERROR_NONE;
819 int icd_ioty_register_platform_info(GVariant *value)
821 OCStackResult result;
822 OCPlatformInfo platform_info = {0};
824 g_variant_get(value, "(&s&s&s&s&s&s&s&s&s&s&s)",
825 &platform_info.platformID,
826 &platform_info.manufacturerName,
827 &platform_info.manufacturerUrl,
828 &platform_info.modelNumber,
829 &platform_info.dateOfManufacture,
830 &platform_info.platformVersion,
831 &platform_info.operatingSystemVersion,
832 &platform_info.hardwareVersion,
833 &platform_info.firmwareVersion,
834 &platform_info.supportUrl,
835 &platform_info.systemTime);
837 icd_ioty_csdk_lock();
838 result = OCSetPlatformInfo(platform_info);
839 icd_ioty_csdk_unlock();
841 if (OC_STACK_OK != result) {
842 ERR("OCSetPlatformInfo() Fail(%d)", result);
843 return icd_ioty_convert_error(result);
846 return IOTCON_ERROR_NONE;
850 int icd_ioty_get_info(int type, const char *host_address, unsigned int signal_number,
851 const char *bus_name)
853 OCStackResult result;
854 icd_sig_ctx_s *context;
855 OCCallbackData cbdata = {0};
856 char uri[PATH_MAX] = {0};
857 char *uri_path = NULL;
858 iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
859 OCConnectivityType oic_conn_type;
861 if (ICD_DEVICE_INFO == type)
862 uri_path = OC_RSRVD_DEVICE_URI;
863 else if (ICD_PLATFORM_INFO == type)
864 uri_path = OC_RSRVD_PLATFORM_URI;
866 return IOTCON_ERROR_INVALID_PARAMETER;
868 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address))
869 snprintf(uri, sizeof(uri), "%s", uri_path);
871 snprintf(uri, sizeof(uri), "%s%s", host_address, uri_path);
873 context = calloc(1, sizeof(icd_sig_ctx_s));
874 if (NULL == context) {
875 ERR("calloc() Fail(%d)", errno);
876 return IOTCON_ERROR_OUT_OF_MEMORY;
878 context->bus_name = ic_utils_strdup(bus_name);
879 context->signum = signal_number;
881 cbdata.context = context;
882 cbdata.cb = icd_ioty_ocprocess_info_cb;
883 cbdata.cd = _ioty_free_signal_context;
885 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
887 icd_ioty_csdk_lock();
888 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
889 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
890 OC_LOW_QOS, &cbdata, NULL, 0);
891 icd_ioty_csdk_unlock();
893 if (OC_STACK_OK != result) {
894 ERR("OCDoResource() Fail(%d)", result);
895 free(context->bus_name);
897 return icd_ioty_convert_error(result);
900 return IOTCON_ERROR_NONE;
904 OCDoHandle icd_ioty_subscribe_presence(const char *host_address,
905 const char *resource_type, unsigned int signal_number, const char *bus_name)
909 OCStackResult result;
910 char uri[PATH_MAX] = {0};
911 OCCallbackData cbdata = {0};
912 icd_sig_ctx_s *context;
914 len = snprintf(uri, sizeof(uri), "%s%s", host_address, OC_RSRVD_PRESENCE_URI);
915 if (len <= 0 || sizeof(uri) <= len) {
916 ERR("snprintf() Fail(%d)", len);
920 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
921 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
923 context = calloc(1, sizeof(icd_sig_ctx_s));
924 if (NULL == context) {
925 ERR("calloc() Fail(%d)", errno);
928 context->bus_name = ic_utils_strdup(bus_name);
929 context->signum = signal_number;
931 cbdata.context = context;
932 cbdata.cb = icd_ioty_ocprocess_presence_cb;
933 cbdata.cd = _ioty_free_signal_context;
935 /* In case of IPV4 or IPV6, connectivity type is CT_ADAPTER_IP in iotivity 0.9.2 */
936 icd_ioty_csdk_lock();
937 result = OCDoResource(&handle, OC_REST_PRESENCE, uri, NULL, NULL, CT_ADAPTER_IP,
938 OC_LOW_QOS, &cbdata, NULL, 0);
939 icd_ioty_csdk_unlock();
941 if (OC_STACK_OK != result) {
942 ERR("OCDoResource() Fail(%d)", result);
943 free(context->bus_name);
951 int icd_ioty_unsubscribe_presence(OCDoHandle handle)
955 icd_ioty_csdk_lock();
956 ret = OCCancel(handle, OC_LOW_QOS, NULL, 0);
957 icd_ioty_csdk_unlock();
958 if (OC_STACK_OK != ret) {
959 ERR("OCCancel() Fail(%d)", ret);
960 return icd_ioty_convert_error(ret);
963 return IOTCON_ERROR_NONE;
967 int icd_ioty_start_presence(unsigned int time_to_live)
971 icd_ioty_csdk_lock();
972 ret = OCStartPresence(time_to_live);
973 icd_ioty_csdk_unlock();
974 if (OC_STACK_OK != ret) {
975 ERR("OCStartPresence() Fail(%d)", ret);
976 return icd_ioty_convert_error(ret);
979 return IOTCON_ERROR_NONE;
983 int icd_ioty_stop_presence()
987 icd_ioty_csdk_lock();
988 ret = OCStopPresence();
989 icd_ioty_csdk_unlock();
990 if (OC_STACK_OK != ret) {
991 ERR("OCStopPresence() Fail(%d)", ret);
992 return icd_ioty_convert_error(ret);
995 return IOTCON_ERROR_NONE;