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 */
22 #include <tizen_type.h>
23 #include <system_info.h>
24 #include <system_settings.h>
33 #include "icd-payload.h"
36 #include "icd-ioty-type.h"
37 #include "icd-ioty-ocprocess.h"
39 #define ICD_UUID_LENGTH 37
41 static const char *ICD_SYSTEM_INFO_TIZEN_ID = "http://tizen.org/system/tizenid";
42 static const char *ICD_SYSTEM_INFO_PLATFORM_NAME = "http://tizen.org/system/platform.name";
43 static const char *ICD_SYSTEM_INFO_PLATFORM_VERSION = "http://tizen.org/feature/platform.version";
44 static const char *ICD_SYSTEM_INFO_MANUF_NAME = "http://tizen.org/system/manufacturer";
45 static const char *ICD_SYSTEM_INFO_MODEL_NAME = "http://tizen.org/system/model_name";
46 static const char *ICD_SYSTEM_INFO_BUILD_STRING = "http://tizen.org/system/build.string";
50 char *tizen_device_id;
53 static icd_tizen_info_s icd_tizen_info = {0};
55 static GMutex icd_csdk_mutex;
57 void icd_ioty_csdk_lock()
59 g_mutex_lock(&icd_csdk_mutex);
63 void icd_ioty_csdk_unlock()
65 g_mutex_unlock(&icd_csdk_mutex);
69 GThread* icd_ioty_init(const char *addr, unsigned short port)
75 OCStackResult result = OCInit(addr, port, OC_CLIENT_SERVER);
76 if (OC_STACK_OK != result) {
77 ERR("OCInit() Fail(%d)", result);
81 DBG("OCInit() Success");
83 thread = g_thread_try_new("packet_receive_thread", icd_ioty_ocprocess_thread,
86 ERR("g_thread_try_new() Fail(%s)", error->message);
95 void icd_ioty_deinit(GThread *thread)
99 icd_ioty_ocprocess_stop();
100 g_thread_join(thread);
103 if (OC_STACK_OK != result)
104 ERR("OCStop() Fail(%d)", result);
107 static int _ioty_properties_to_oic_properties(int properties)
109 int prop = OC_RES_PROP_NONE;
111 if (IOTCON_DISCOVERABLE & properties)
112 prop |= OC_DISCOVERABLE;
114 if (IOTCON_OBSERVABLE & properties)
115 prop |= OC_OBSERVABLE;
117 if (IOTCON_ACTIVE & properties)
120 if (IOTCON_SLOW & properties)
123 if (IOTCON_SECURE & properties)
126 if (IOTCON_EXPLICIT_DISCOVERABLE & properties)
127 prop |= OC_EXPLICIT_DISCOVERABLE;
129 /* TODO: Secure option is not supported yet. */
130 properties = (properties & OC_SECURE)? (properties ^ OC_SECURE):properties;
135 OCResourceHandle icd_ioty_register_resource(const char *uri_path,
136 const char* const* res_types, int ifaces, int properties)
141 OCResourceHandle handle;
142 const char *res_iface = NULL;
144 if (IOTCON_INTERFACE_DEFAULT & ifaces) {
145 res_iface = IC_INTERFACE_DEFAULT;
146 ifaces ^= IOTCON_INTERFACE_DEFAULT;
147 } else if (IOTCON_INTERFACE_LINK & ifaces) {
148 res_iface = IC_INTERFACE_LINK;
149 ifaces ^= IOTCON_INTERFACE_LINK;
150 } else if (IOTCON_INTERFACE_BATCH & ifaces) {
151 res_iface = IC_INTERFACE_BATCH;
152 ifaces ^= IOTCON_INTERFACE_BATCH;
153 } else if (IOTCON_INTERFACE_GROUP & ifaces) {
154 res_iface = IC_INTERFACE_GROUP;
155 ifaces ^= IOTCON_INTERFACE_GROUP;
157 ERR("Invalid interface type(%d)", ifaces);
161 properties = _ioty_properties_to_oic_properties(properties);
163 icd_ioty_csdk_lock();
164 ret = OCCreateResource(&handle, res_types[0], res_iface, uri_path,
165 icd_ioty_ocprocess_req_handler, NULL, properties);
166 icd_ioty_csdk_unlock();
167 if (OC_STACK_OK != ret) {
168 ERR("OCCreateResource() Fail(%d)", ret);
172 for (i = 1; res_types[i]; i++)
173 icd_ioty_bind_type(handle, res_types[i]);
175 if (IOTCON_INTERFACE_DEFAULT & ifaces)
176 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_DEFAULT);
177 if (IOTCON_INTERFACE_LINK & ifaces)
178 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_LINK);
179 if (IOTCON_INTERFACE_BATCH & ifaces)
180 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_BATCH);
181 if (IOTCON_INTERFACE_GROUP & ifaces)
182 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_GROUP);
188 int icd_ioty_unregister_resource(OCResourceHandle handle)
192 icd_ioty_csdk_lock();
193 ret = OCDeleteResource(handle);
194 icd_ioty_csdk_unlock();
196 if (OC_STACK_OK != ret) {
197 ERR("OCDeleteResource() Fail(%d)", ret);
198 return icd_ioty_convert_error(ret);
201 return IOTCON_ERROR_NONE;
205 int icd_ioty_bind_interface(OCResourceHandle handle, iotcon_interface_e iface)
208 OCStackResult result;
209 char *resource_interface;
211 ret = ic_utils_convert_interface_flag(iface, &resource_interface);
212 if (IOTCON_ERROR_NONE != ret) {
213 ERR("ic_utils_convert_interface_flag(%d) Fail(%d)", iface, ret);
217 icd_ioty_csdk_lock();
218 result = OCBindResourceInterfaceToResource(handle, resource_interface);
219 icd_ioty_csdk_unlock();
221 if (OC_STACK_OK != result) {
222 ERR("OCBindResourceInterfaceToResource() Fail(%d)", result);
223 return icd_ioty_convert_error(result);
226 return IOTCON_ERROR_NONE;
230 int icd_ioty_bind_type(OCResourceHandle handle, const char *resource_type)
234 icd_ioty_csdk_lock();
235 ret = OCBindResourceTypeToResource(handle, resource_type);
236 icd_ioty_csdk_unlock();
238 if (OC_STACK_OK != ret) {
239 ERR("OCBindResourceTypeToResource() Fail(%d)", ret);
240 return icd_ioty_convert_error(ret);
243 return IOTCON_ERROR_NONE;
247 int icd_ioty_bind_resource(OCResourceHandle parent, OCResourceHandle child)
251 icd_ioty_csdk_lock();
252 ret = OCBindResource(parent, child);
253 icd_ioty_csdk_unlock();
255 if (OC_STACK_OK != ret) {
256 ERR("OCBindResource() Fail(%d)", ret);
257 return icd_ioty_convert_error(ret);
260 return IOTCON_ERROR_NONE;
264 int icd_ioty_unbind_resource(OCResourceHandle parent, OCResourceHandle child)
268 icd_ioty_csdk_lock();
269 ret = OCUnBindResource(parent, child);
270 icd_ioty_csdk_unlock();
272 if (OC_STACK_OK != ret) {
273 ERR("OCUnBindResource() Fail(%d)", ret);
274 return icd_ioty_convert_error(ret);
277 return IOTCON_ERROR_NONE;
280 int icd_ioty_notify(OCResourceHandle handle, GVariant *msg, GVariant *observers)
282 int i, obs_length, msg_length;
284 GVariantIter obs_iter, msg_iter;
286 OCRepPayload *payload;
288 g_variant_iter_init(&obs_iter, observers);
289 obs_length = g_variant_iter_n_children(&obs_iter);
291 /* Variable-length Array */
292 OCObservationId obs_ids[obs_length];
294 for (i = 0; i < obs_length; i++)
295 g_variant_iter_loop(&obs_iter, "i", &obs_ids[i]);
297 g_variant_iter_init(&msg_iter, msg);
298 msg_length = g_variant_iter_n_children(&msg_iter);
300 g_variant_iter_loop(&msg_iter, "v", &repr_gvar);
301 /* TODO : How to use error_code. */
302 payload = icd_payload_representation_from_gvariant(repr_gvar);
305 icd_ioty_csdk_lock();
306 /* TODO : QoS is come from lib. */
308 ret = OCNotifyListOfObservers(handle, obs_ids, obs_length, payload, OC_LOW_QOS);
310 ret = OCNotifyAllObservers(handle, OC_LOW_QOS);
312 icd_ioty_csdk_unlock();
314 if (OC_STACK_NO_OBSERVERS == ret) {
315 WARN("No Observers. Stop Notifying");
316 return IOTCON_ERROR_NONE;
317 } else if (OC_STACK_OK != ret) {
318 ERR("OCNotifyListOfObservers() Fail(%d)", ret);
319 return icd_ioty_convert_error(ret);
322 return IOTCON_ERROR_NONE;
326 static int _ioty_get_header_options(GVariantIter *src, int src_size,
327 OCHeaderOption dest[], int dest_size)
331 unsigned short option_id;
333 RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
335 if (dest_size < src_size) {
336 ERR("Exceed Size(%d)", src_size);
337 return IOTCON_ERROR_INVALID_PARAMETER;
340 while (g_variant_iter_loop(src, "(q&s)", &option_id, &option_data)) {
341 dest[i].protocolID = OC_COAP_ID;
342 dest[i].optionID = option_id;
343 dest[i].optionLength = strlen(option_data) + 1;
344 memcpy(dest[i].optionData, option_data, dest[i].optionLength);
348 return IOTCON_ERROR_NONE;
352 int icd_ioty_send_response(GVariant *resp)
355 GVariantIter *options;
357 OCEntityHandlerResponse response = {0};
358 int result, options_size;
359 int64_t request_handle, resource_handle;
361 g_variant_get(resp, "(a(qs)ivxx)",
368 response.requestHandle = ICD_INT64_TO_POINTER(request_handle);
369 response.resourceHandle = ICD_INT64_TO_POINTER(resource_handle);
370 response.ehResult = (OCEntityHandlerResult)result;
372 options_size = g_variant_iter_n_children(options);
373 response.numSendVendorSpecificHeaderOptions = options_size;
375 if (0 != options_size) {
376 int ret= _ioty_get_header_options(options,
377 response.numSendVendorSpecificHeaderOptions,
378 response.sendVendorSpecificHeaderOptions,
379 sizeof(response.sendVendorSpecificHeaderOptions)
380 / sizeof(response.sendVendorSpecificHeaderOptions[0]));
382 if (IOTCON_ERROR_NONE != ret)
383 ERR("_ioty_get_header_options() Fail(%d)", ret);
385 g_variant_iter_free(options);
387 response.payload = (OCPayload*)icd_payload_representation_from_gvariant(repr_gvar);
389 /* related to block transfer */
390 response.persistentBufferFlag = 0;
392 icd_ioty_csdk_lock();
393 ret = OCDoResponse(&response);
394 icd_ioty_csdk_unlock();
396 if (OC_STACK_OK != ret) {
397 ERR("OCDoResponse() Fail(%d)", ret);
398 return icd_ioty_convert_error(ret);
401 return IOTCON_ERROR_NONE;
405 static void _ioty_free_signal_context(void *data)
407 icd_sig_ctx_s *context = data;
408 free(context->bus_name);
413 int icd_ioty_find_resource(const char *host_address, int conn_type,
414 const char *resource_type, unsigned int signal_number, const char *bus_name)
417 OCStackResult result;
418 icd_sig_ctx_s *context;
419 char uri[PATH_MAX] = {0};
420 OCCallbackData cbdata = {0};
421 OCConnectivityType oic_conn_type;
423 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address)) {
424 len = snprintf(uri, sizeof(uri), "%s", OC_RSRVD_WELL_KNOWN_URI);
426 len = snprintf(uri, sizeof(uri), ICD_IOTY_COAP"%s%s", host_address,
427 OC_RSRVD_WELL_KNOWN_URI);
429 if (len <= 0 || sizeof(uri) <= len) {
430 ERR("snprintf() Fail(%d)", len);
431 return IOTCON_ERROR_IO_ERROR;
434 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
435 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
437 context = calloc(1, sizeof(icd_sig_ctx_s));
438 if (NULL == context) {
439 ERR("calloc() Fail(%d)", errno);
440 return IOTCON_ERROR_OUT_OF_MEMORY;
443 context->bus_name = ic_utils_strdup(bus_name);
444 context->signal_number = signal_number;
446 cbdata.context = context;
447 cbdata.cb = icd_ioty_ocprocess_find_cb;
448 cbdata.cd = _ioty_free_signal_context;
450 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
452 icd_ioty_csdk_lock();
453 /* TODO : QoS is come from lib. */
454 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
455 OC_LOW_QOS, &cbdata, NULL, 0);
456 icd_ioty_csdk_unlock();
458 if (OC_STACK_OK != result) {
459 ERR("OCDoResource() Fail(%d)", result);
460 free(context->bus_name);
462 return icd_ioty_convert_error(result);
465 return IOTCON_ERROR_NONE;
470 * returned string SHOULD be released by you
472 static char* _icd_ioty_resource_generate_uri(char *uri_path, GVariant *query)
475 bool loop_first = true;
477 GVariantIter query_iter;
478 char uri_buf[PATH_MAX] = {0};
480 len = snprintf(uri_buf, sizeof(uri_buf), "%s", uri_path);
482 /* remove suffix '/' */
483 if ('/' == uri_buf[strlen(uri_buf) - 1]) {
484 uri_buf[strlen(uri_buf) - 1] = '\0';
488 g_variant_iter_init(&query_iter, query);
490 while (g_variant_iter_loop(&query_iter, "(&s&s)", &key, &value)) {
493 DBG("query exist. key(%s), value(%s)", key, value);
495 if (true == loop_first) {
496 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "?%s=%s", key, value);
499 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "&%s=%s", key, value);
505 return strdup(uri_buf);
509 void icd_ioty_complete(int type, GDBusMethodInvocation *invocation, GVariant *value)
513 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
516 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
519 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
521 case ICD_CRUD_DELETE:
522 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
525 ic_dbus_complete_get_tizen_info(icd_dbus_get_object(), invocation, value);
528 INFO("Invalid type(%d)", type);
533 void icd_ioty_complete_error(int type, GDBusMethodInvocation *invocation, int ret_val)
537 GVariantBuilder options;
541 g_variant_builder_init(&options, G_VARIANT_TYPE("a(qs)"));
542 payload = icd_payload_representation_empty_gvariant();
543 value = g_variant_new("(a(qs)vi)", &options, payload, ret_val);
544 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
547 g_variant_builder_init(&options, G_VARIANT_TYPE("a(qs)"));
548 payload = icd_payload_representation_empty_gvariant();
549 value = g_variant_new("(a(qs)vi)", &options, payload, ret_val);
550 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
553 g_variant_builder_init(&options, G_VARIANT_TYPE("a(qs)"));
554 payload = icd_payload_representation_empty_gvariant();
555 value = g_variant_new("(a(qs)vi)", &options, payload, ret_val);
556 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
558 case ICD_CRUD_DELETE:
559 g_variant_builder_init(&options, G_VARIANT_TYPE("a(qs)"));
560 value = g_variant_new("(a(qs)i)", &options, ret_val);
561 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
564 value = g_variant_new("(ssi)", IC_STR_NULL, IC_STR_NULL, ret_val);
565 ic_dbus_complete_get_tizen_info(icd_dbus_get_object(), invocation, value);
572 static gboolean _icd_ioty_crud(int type,
574 GDBusMethodInvocation *invocation,
581 OCStackResult result;
582 GVariantIter *options;
583 OCCallbackData cbdata = {0};
584 int conn_type, options_size;
585 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
586 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
587 OCHeaderOption *oic_options_ptr = NULL;
588 OCPayload *payload = NULL;
589 OCConnectivityType oic_conn_type;
590 OCDevAddr dev_addr = {0};
594 cbdata.cb = icd_ioty_ocprocess_get_cb;
595 rest_type = OC_REST_GET;
598 cbdata.cb = icd_ioty_ocprocess_put_cb;
599 rest_type = OC_REST_PUT;
602 cbdata.cb = icd_ioty_ocprocess_post_cb;
603 rest_type = OC_REST_POST;
605 case ICD_CRUD_DELETE:
606 cbdata.cb = icd_ioty_ocprocess_delete_cb;
607 rest_type = OC_REST_DELETE;
610 ERR("Invalid CRUD Type(%d)", type);
614 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
621 uri = _icd_ioty_resource_generate_uri(uri_path, query);
623 ERR("_icd_ioty_resource_generate_uri() Fail");
624 g_variant_iter_free(options);
625 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_INVALID_PARAMETER);
629 case ICD_CRUD_DELETE:
630 uri = strdup(uri_path);
634 cbdata.context = invocation;
636 options_size = g_variant_iter_n_children(options);
637 if (0 != options_size) {
638 int ret = _ioty_get_header_options(options, options_size, oic_options,
639 sizeof(oic_options) / sizeof(oic_options[0]));
640 if (IOTCON_ERROR_NONE != ret) {
641 ERR("_ioty_get_header_options() Fail(%d)", ret);
643 g_variant_iter_free(options);
644 icd_ioty_complete_error(type, invocation, ret);
647 oic_options_ptr = oic_options;
649 g_variant_iter_free(options);
652 payload = (OCPayload*)icd_payload_representation_from_gvariant(repr);
654 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
656 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
660 case IOTCON_CONNECTIVITY_IPV4:
661 dev_host = strtok_r(host, ":", &ptr);
662 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
663 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
665 case IOTCON_CONNECTIVITY_IPV6:
666 dev_host = strtok_r(host, "]", &ptr);
667 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
668 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
671 ERR("Invalid Connectivitiy Type");
672 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_IOTIVITY);
677 icd_ioty_csdk_lock();
678 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
679 result = OCDoResource(NULL, rest_type, uri, &dev_addr, payload, oic_conn_type,
680 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
681 icd_ioty_csdk_unlock();
685 if (OC_STACK_OK != result) {
686 ERR("OCDoResource() Fail(%d)", result);
687 icd_ioty_complete_error(type, invocation, icd_ioty_convert_error(result));
694 gboolean icd_ioty_get(icDbus *object, GDBusMethodInvocation *invocation,
695 GVariant *resource, GVariant *query)
697 return _icd_ioty_crud(ICD_CRUD_GET, object, invocation, resource, query, NULL);
701 gboolean icd_ioty_put(icDbus *object, GDBusMethodInvocation *invocation,
702 GVariant *resource, GVariant *repr, GVariant *query)
704 return _icd_ioty_crud(ICD_CRUD_PUT, object, invocation, resource, query, repr);
708 gboolean icd_ioty_post(icDbus *object, GDBusMethodInvocation *invocation,
709 GVariant *resource, GVariant *repr, GVariant *query)
711 return _icd_ioty_crud(ICD_CRUD_POST, object, invocation, resource, query, repr);
715 gboolean icd_ioty_delete(icDbus *object, GDBusMethodInvocation *invocation,
718 return _icd_ioty_crud(ICD_CRUD_DELETE, object, invocation, resource, NULL, NULL);
722 OCDoHandle icd_ioty_observer_start(GVariant *resource, int observe_type,
723 GVariant *query, unsigned int signal_number, const char *bus_name)
728 OCStackResult result;
729 GVariantIter *options;
730 icd_sig_ctx_s *context;
731 OCCallbackData cbdata = {0};
732 int conn_type, options_size;
733 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
734 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
735 OCHeaderOption *oic_options_ptr = NULL;
736 OCConnectivityType oic_conn_type;
737 OCDevAddr dev_addr = {0};
739 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
742 uri = _icd_ioty_resource_generate_uri(uri_path, query);
744 ERR("_icd_ioty_resource_generate_uri() Fail");
745 g_variant_iter_free(options);
749 if (IOTCON_OBSERVE == observe_type)
750 method = OC_REST_OBSERVE;
751 else if (IOTCON_OBSERVE_ALL == observe_type)
752 method = OC_REST_OBSERVE_ALL;
754 method = OC_REST_OBSERVE_ALL;
756 context = calloc(1, sizeof(icd_sig_ctx_s));
757 if (NULL == context) {
758 ERR("calloc() Fail(%d)", errno);
761 context->bus_name = ic_utils_strdup(bus_name);
762 context->signal_number = signal_number;
764 cbdata.context = context;
765 cbdata.cb = icd_ioty_ocprocess_observe_cb;
766 cbdata.cd = _ioty_free_signal_context;
768 options_size = g_variant_iter_n_children(options);
769 if (0 != options_size) {
770 int ret = _ioty_get_header_options(options, options_size, oic_options,
771 sizeof(oic_options) / sizeof(oic_options[0]));
772 if (IOTCON_ERROR_NONE != ret) {
773 ERR("_ioty_get_header_options() Fail(%d)", ret);
774 free(context->bus_name);
777 g_variant_iter_free(options);
780 oic_options_ptr = oic_options;
782 g_variant_iter_free(options);
784 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
786 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
790 case IOTCON_CONNECTIVITY_IPV4:
791 dev_host = strtok_r(host, ":", &ptr);
792 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
793 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
795 case IOTCON_CONNECTIVITY_IPV6:
796 dev_host = strtok_r(host, "]", &ptr);
797 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
798 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
801 ERR("Invalid Connectivitiy Type");
802 free(context->bus_name);
808 icd_ioty_csdk_lock();
809 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
810 result = OCDoResource(&handle, method, uri, &dev_addr, NULL, oic_conn_type,
811 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
812 icd_ioty_csdk_unlock();
814 if (OC_STACK_OK != result) {
815 ERR("OCDoResource() Fail(%d)", result);
816 free(context->bus_name);
825 int icd_ioty_observer_stop(OCDoHandle handle, GVariant *options)
829 GVariantIter options_iter;
830 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
831 OCHeaderOption *oic_options_ptr = NULL;
833 g_variant_iter_init(&options_iter, options);
835 options_size = g_variant_iter_n_children(&options_iter);
836 if (0 != options_size) {
837 int ret = _ioty_get_header_options(&options_iter, options_size, oic_options,
838 sizeof(oic_options) / sizeof(oic_options[0]));
839 if (IOTCON_ERROR_NONE != ret) {
840 ERR("_ioty_get_header_options() Fail(%d)", ret);
843 oic_options_ptr = oic_options;
846 icd_ioty_csdk_lock();
847 ret = OCCancel(handle, OC_HIGH_QOS, oic_options_ptr, options_size);
848 icd_ioty_csdk_unlock();
849 if (OC_STACK_OK != ret) {
850 ERR("OCCancel() Fail(%d)", ret);
851 return icd_ioty_convert_error(ret);
854 return IOTCON_ERROR_NONE;
857 int icd_ioty_get_info(int type, const char *host_address, int conn_type,
858 unsigned int signal_number, const char *bus_name)
860 OCStackResult result;
861 icd_sig_ctx_s *context;
862 OCCallbackData cbdata = {0};
863 char uri[PATH_MAX] = {0};
864 char *uri_path = NULL;
865 OCConnectivityType oic_conn_type;
867 if (ICD_DEVICE_INFO == type)
868 uri_path = OC_RSRVD_DEVICE_URI;
869 else if (ICD_PLATFORM_INFO == type)
870 uri_path = OC_RSRVD_PLATFORM_URI;
872 return IOTCON_ERROR_INVALID_PARAMETER;
874 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address))
875 snprintf(uri, sizeof(uri), "%s", uri_path);
877 snprintf(uri, sizeof(uri), "%s%s", host_address, uri_path);
879 context = calloc(1, sizeof(icd_sig_ctx_s));
880 if (NULL == context) {
881 ERR("calloc() Fail(%d)", errno);
882 return IOTCON_ERROR_OUT_OF_MEMORY;
884 context->bus_name = ic_utils_strdup(bus_name);
885 context->signal_number = signal_number;
887 cbdata.context = context;
888 cbdata.cb = icd_ioty_ocprocess_info_cb;
889 cbdata.cd = _ioty_free_signal_context;
891 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
893 icd_ioty_csdk_lock();
894 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
895 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
896 OC_LOW_QOS, &cbdata, NULL, 0);
897 icd_ioty_csdk_unlock();
899 if (OC_STACK_OK != result) {
900 ERR("OCDoResource() Fail(%d)", result);
901 free(context->bus_name);
903 return icd_ioty_convert_error(result);
906 return IOTCON_ERROR_NONE;
909 static int _icd_ioty_get_tizen_id(char **tizen_device_id)
912 char *tizen_id = NULL;
914 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_TIZEN_ID, &tizen_id);
915 if (SYSTEM_INFO_ERROR_NONE != ret) {
916 ERR("system_info_get_platform_string() Fail(%d)", ret);
917 return IOTCON_ERROR_SYSTEM;
919 *tizen_device_id = tizen_id;
921 return IOTCON_ERROR_NONE;
924 static int _ioty_set_device_info()
927 char *device_name = NULL;
928 OCDeviceInfo device_info = {0};
930 ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_DEVICE_NAME, &device_name);
931 if (SYSTEM_SETTINGS_ERROR_NONE != ret) {
932 ERR("system_settings_get_value_string() Fail(%d)", ret);
933 return IOTCON_ERROR_SYSTEM;
936 device_info.deviceName = device_name;
938 icd_ioty_csdk_lock();
939 ret = OCSetDeviceInfo(device_info);
940 icd_ioty_csdk_unlock();
942 if (OC_STACK_OK != ret) {
943 ERR("OCSetDeviceInfo() Fail(%d)", ret);
945 return icd_ioty_convert_error(ret);
948 free(icd_tizen_info.device_name);
949 icd_tizen_info.device_name = device_name;
951 return IOTCON_ERROR_NONE;
954 static void _icd_ioty_on_device_name_changed_cb(system_settings_key_e key,
960 ret = _ioty_set_device_info();
961 if (IOTCON_ERROR_NONE != ret) {
962 ERR("_ioty_set_device_info() Fail(%d)", ret);
967 int icd_ioty_set_device_info()
971 ret = system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_DEVICE_NAME,
972 _icd_ioty_on_device_name_changed_cb, NULL);
973 if (SYSTEM_SETTINGS_ERROR_NONE != ret) {
974 ERR("system_settings_set_changed_cb() Fail(%d)", ret);
975 return IOTCON_ERROR_SYSTEM;
978 ret = _ioty_set_device_info();
979 if (IOTCON_ERROR_NONE != ret) {
980 ERR("_ioty_set_device_info() Fail(%d)", ret);
984 return IOTCON_ERROR_NONE;
987 static void _ioty_free_platform_info(OCPlatformInfo platform_info)
989 free(platform_info.manufacturerName);
990 free(platform_info.manufacturerUrl);
991 free(platform_info.modelNumber);
992 free(platform_info.dateOfManufacture);
993 free(platform_info.platformVersion);
994 free(platform_info.operatingSystemVersion);
995 free(platform_info.hardwareVersion);
996 free(platform_info.firmwareVersion);
997 free(platform_info.supportUrl);
998 free(platform_info.systemTime);
1001 int icd_ioty_set_platform_info()
1004 OCPlatformInfo platform_info = {0};
1006 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_PLATFORM_NAME,
1007 &platform_info.platformID);
1008 if (SYSTEM_INFO_ERROR_NONE != ret) {
1009 ERR("system_info_get_platform_string() Fail(%d)", ret);
1010 _ioty_free_platform_info(platform_info);
1011 return IOTCON_ERROR_SYSTEM;
1014 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_MANUF_NAME,
1015 &platform_info.manufacturerName);
1016 if (SYSTEM_INFO_ERROR_NONE != ret) {
1017 ERR("system_info_get_platform_string() Fail(%d)", ret);
1018 _ioty_free_platform_info(platform_info);
1019 return IOTCON_ERROR_SYSTEM;
1022 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_MODEL_NAME,
1023 &platform_info.modelNumber);
1024 if (SYSTEM_INFO_ERROR_NONE != ret) {
1025 ERR("system_info_get_platform_string() Fail(%d)", ret);
1026 _ioty_free_platform_info(platform_info);
1027 return IOTCON_ERROR_SYSTEM;
1030 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_PLATFORM_VERSION,
1031 &platform_info.platformVersion);
1032 if (SYSTEM_INFO_ERROR_NONE != ret) {
1033 ERR("system_info_get_platform_string() Fail(%d)", ret);
1034 _ioty_free_platform_info(platform_info);
1035 return IOTCON_ERROR_SYSTEM;
1038 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_BUILD_STRING,
1039 &platform_info.firmwareVersion);
1040 if (SYSTEM_INFO_ERROR_NONE != ret) {
1041 ERR("system_info_get_platform_string() Fail(%d)", ret);
1042 _ioty_free_platform_info(platform_info);
1043 return IOTCON_ERROR_SYSTEM;
1046 /* platform_info.manufacturerUrl */
1047 /* platform_info.dateOfManufacture */
1048 /* platform_info.operatingSystemVersion */
1049 /* platform_info.hardwareVersion */
1050 /* platform_info.supportUrl */
1051 /* platform_info.systemTime */
1053 icd_ioty_csdk_lock();
1054 ret = OCSetPlatformInfo(platform_info);
1055 icd_ioty_csdk_unlock();
1057 if (OC_STACK_OK != ret) {
1058 ERR("OCSetPlatformInfo() Fail(%d)", ret);
1059 _ioty_free_platform_info(platform_info);
1060 return icd_ioty_convert_error(ret);
1062 _ioty_free_platform_info(platform_info);
1064 return IOTCON_ERROR_NONE;
1067 int icd_ioty_set_tizen_info()
1071 OCResourceHandle handle;
1072 char *tizen_device_id = NULL;
1074 result = _icd_ioty_get_tizen_id(&tizen_device_id);
1075 if (IOTCON_ERROR_NONE != result) {
1076 ERR("_icd_ioty_get_tizen_id() Fail(%d)", result);
1080 icd_tizen_info.tizen_device_id = tizen_device_id;
1081 DBG("tizen_device_id : %s", icd_tizen_info.tizen_device_id);
1083 icd_ioty_csdk_lock();
1084 ret = OCCreateResource(&handle,
1085 ICD_IOTY_TIZEN_INFO_TYPE,
1086 IC_INTERFACE_DEFAULT,
1087 ICD_IOTY_TIZEN_INFO_URI,
1088 icd_ioty_ocprocess_tizen_info_handler,
1090 OC_EXPLICIT_DISCOVERABLE);
1091 icd_ioty_csdk_unlock();
1092 if (OC_STACK_OK != ret) {
1093 ERR("OCCreateResource() Fail(%d)", ret);
1094 return icd_ioty_convert_error(ret);
1097 return IOTCON_ERROR_NONE;
1101 gboolean icd_ioty_get_tizen_info(icDbus *object, GDBusMethodInvocation *invocation,
1102 const gchar *host_address, int conn_type)
1104 OCStackResult result;
1105 OCDevAddr dev_addr = {0};
1106 OCCallbackData cbdata = {0};
1107 OCConnectivityType oic_conn_type;
1108 char host[PATH_MAX] = {0};
1109 char *dev_host, *ptr = NULL;
1111 snprintf(host, sizeof(host), "%s", host_address);
1113 cbdata.cb = icd_ioty_ocprocess_get_tizen_info_cb;
1114 cbdata.context = invocation;
1116 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
1117 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
1120 switch (conn_type) {
1121 case IOTCON_CONNECTIVITY_IPV4:
1122 dev_host = strtok_r(host, ":", &ptr);
1123 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
1124 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
1126 case IOTCON_CONNECTIVITY_IPV6:
1127 dev_host = strtok_r(host, "]", &ptr);
1128 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
1129 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
1132 ERR("Invalid Connectivitiy Type");
1133 icd_ioty_complete_error(ICD_TIZEN_INFO, invocation, IOTCON_ERROR_IOTIVITY);
1137 icd_ioty_csdk_lock();
1138 result = OCDoResource(NULL, OC_REST_GET, ICD_IOTY_TIZEN_INFO_URI, &dev_addr, NULL,
1139 oic_conn_type, OC_LOW_QOS, &cbdata, NULL, 0);
1140 icd_ioty_csdk_unlock();
1142 if (OC_STACK_OK != result) {
1143 ERR("OCDoResource() Fail(%d)", result);
1144 icd_ioty_complete_error(ICD_TIZEN_INFO, invocation, icd_ioty_convert_error(result));
1152 int icd_ioty_tizen_info_get_property(char **device_name, char **tizen_device_id)
1154 RETV_IF(NULL == device_name, IOTCON_ERROR_INVALID_PARAMETER);
1155 RETV_IF(NULL == tizen_device_id, IOTCON_ERROR_INVALID_PARAMETER);
1157 *device_name = icd_tizen_info.device_name;
1158 *tizen_device_id = icd_tizen_info.tizen_device_id;
1160 return IOTCON_ERROR_NONE;
1164 OCDoHandle icd_ioty_subscribe_presence(const char *host_address, int conn_type,
1165 const char *resource_type, unsigned int signal_number, const char *bus_name)
1169 OCStackResult result;
1170 icd_sig_ctx_s *context;
1171 char uri[PATH_MAX] = {0};
1172 OCCallbackData cbdata = {0};
1173 OCConnectivityType oic_conn_type;
1175 len = snprintf(uri, sizeof(uri), "%s%s", host_address, OC_RSRVD_PRESENCE_URI);
1176 if (len <= 0 || sizeof(uri) <= len) {
1177 ERR("snprintf() Fail(%d)", len);
1181 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
1182 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
1184 context = calloc(1, sizeof(icd_sig_ctx_s));
1185 if (NULL == context) {
1186 ERR("calloc() Fail(%d)", errno);
1189 context->bus_name = ic_utils_strdup(bus_name);
1190 context->signal_number = signal_number;
1192 cbdata.context = context;
1193 cbdata.cb = icd_ioty_ocprocess_presence_cb;
1194 cbdata.cd = _ioty_free_signal_context;
1196 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
1198 icd_ioty_csdk_lock();
1199 result = OCDoResource(&handle, OC_REST_PRESENCE, uri, NULL, NULL, oic_conn_type,
1200 OC_LOW_QOS, &cbdata, NULL, 0);
1201 icd_ioty_csdk_unlock();
1203 if (OC_STACK_OK != result) {
1204 ERR("OCDoResource() Fail(%d)", result);
1205 free(context->bus_name);
1213 int icd_ioty_unsubscribe_presence(OCDoHandle handle)
1217 icd_ioty_csdk_lock();
1218 ret = OCCancel(handle, OC_LOW_QOS, NULL, 0);
1219 icd_ioty_csdk_unlock();
1220 if (OC_STACK_OK != ret) {
1221 ERR("OCCancel() Fail(%d)", ret);
1222 return icd_ioty_convert_error(ret);
1225 return IOTCON_ERROR_NONE;
1229 int icd_ioty_start_presence(unsigned int time_to_live)
1233 icd_ioty_csdk_lock();
1234 ret = OCStartPresence(time_to_live);
1235 icd_ioty_csdk_unlock();
1236 if (OC_STACK_OK != ret) {
1237 ERR("OCStartPresence() Fail(%d)", ret);
1238 return icd_ioty_convert_error(ret);
1241 return IOTCON_ERROR_NONE;
1245 int icd_ioty_stop_presence()
1249 icd_ioty_csdk_lock();
1250 ret = OCStopPresence();
1251 icd_ioty_csdk_unlock();
1252 if (OC_STACK_OK != ret) {
1253 ERR("OCStopPresence() Fail(%d)", ret);
1254 return icd_ioty_convert_error(ret);
1257 return IOTCON_ERROR_NONE;