2 * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <stdint.h> /* for uint8_t etc */
23 #include <system_info.h>
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);
108 OCResourceHandle icd_ioty_register_resource(const char *uri_path,
109 const char* const* res_types, int ifaces, int properties)
114 OCResourceHandle handle;
115 const char *res_iface = NULL;
117 if (IOTCON_INTERFACE_DEFAULT & ifaces) {
118 res_iface = IC_INTERFACE_DEFAULT;
119 ifaces ^= IOTCON_INTERFACE_DEFAULT;
120 } else if (IOTCON_INTERFACE_LINK & ifaces) {
121 res_iface = IC_INTERFACE_LINK;
122 ifaces ^= IOTCON_INTERFACE_LINK;
123 } else if (IOTCON_INTERFACE_BATCH & ifaces) {
124 res_iface = IC_INTERFACE_BATCH;
125 ifaces ^= IOTCON_INTERFACE_BATCH;
126 } else if (IOTCON_INTERFACE_GROUP & ifaces) {
127 res_iface = IC_INTERFACE_GROUP;
128 ifaces ^= IOTCON_INTERFACE_GROUP;
130 ERR("Invalid interface type(%d)", ifaces);
134 /* Secure option is not supported yet. */
135 properties = (properties & OC_SECURE)? (properties ^ OC_SECURE):properties;
137 icd_ioty_csdk_lock();
138 ret = OCCreateResource(&handle, res_types[0], res_iface, uri_path,
139 icd_ioty_ocprocess_req_handler, NULL, properties);
140 icd_ioty_csdk_unlock();
141 if (OC_STACK_OK != ret) {
142 ERR("OCCreateResource() Fail(%d)", ret);
146 for (i = 1; res_types[i]; i++)
147 icd_ioty_bind_type(handle, res_types[i]);
149 if (IOTCON_INTERFACE_DEFAULT & ifaces)
150 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_DEFAULT);
151 if (IOTCON_INTERFACE_LINK & ifaces)
152 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_LINK);
153 if (IOTCON_INTERFACE_BATCH & ifaces)
154 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_BATCH);
155 if (IOTCON_INTERFACE_GROUP & ifaces)
156 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_GROUP);
162 int icd_ioty_unregister_resource(OCResourceHandle handle)
166 icd_ioty_csdk_lock();
167 ret = OCDeleteResource(handle);
168 icd_ioty_csdk_unlock();
170 if (OC_STACK_OK != ret) {
171 ERR("OCDeleteResource() Fail(%d)", ret);
172 return icd_ioty_convert_error(ret);
175 return IOTCON_ERROR_NONE;
179 int icd_ioty_bind_interface(OCResourceHandle handle, iotcon_interface_e iface)
182 OCStackResult result;
183 char *resource_interface;
185 ret = ic_utils_convert_interface_flag(iface, &resource_interface);
186 if (IOTCON_ERROR_NONE != ret) {
187 ERR("ic_utils_convert_interface_flag(%d) Fail(%d)", iface, ret);
191 icd_ioty_csdk_lock();
192 result = OCBindResourceInterfaceToResource(handle, resource_interface);
193 icd_ioty_csdk_unlock();
195 if (OC_STACK_OK != result) {
196 ERR("OCBindResourceInterfaceToResource() Fail(%d)", result);
197 return icd_ioty_convert_error(result);
200 return IOTCON_ERROR_NONE;
204 int icd_ioty_bind_type(OCResourceHandle handle, const char *resource_type)
208 icd_ioty_csdk_lock();
209 ret = OCBindResourceTypeToResource(handle, resource_type);
210 icd_ioty_csdk_unlock();
212 if (OC_STACK_OK != ret) {
213 ERR("OCBindResourceTypeToResource() Fail(%d)", ret);
214 return icd_ioty_convert_error(ret);
217 return IOTCON_ERROR_NONE;
221 int icd_ioty_bind_resource(OCResourceHandle parent, OCResourceHandle child)
225 icd_ioty_csdk_lock();
226 ret = OCBindResource(parent, child);
227 icd_ioty_csdk_unlock();
229 if (OC_STACK_OK != ret) {
230 ERR("OCBindResource() Fail(%d)", ret);
231 return icd_ioty_convert_error(ret);
234 return IOTCON_ERROR_NONE;
238 int icd_ioty_unbind_resource(OCResourceHandle parent, OCResourceHandle child)
242 icd_ioty_csdk_lock();
243 ret = OCUnBindResource(parent, child);
244 icd_ioty_csdk_unlock();
246 if (OC_STACK_OK != ret) {
247 ERR("OCUnBindResource() Fail(%d)", ret);
248 return icd_ioty_convert_error(ret);
251 return IOTCON_ERROR_NONE;
255 int icd_ioty_notify(OCResourceHandle handle, GVariant *msg, GVariant *observers)
257 int i, error_code, obs_length, msg_length;
259 GVariantIter obs_iter, msg_iter;
261 OCRepPayload *payload;
263 g_variant_iter_init(&obs_iter, observers);
264 obs_length = g_variant_iter_n_children(&obs_iter);
266 /* Variable-length Array */
267 OCObservationId obs_ids[obs_length];
269 for (i = 0; i < obs_length; i++)
270 g_variant_iter_loop(&obs_iter, "i", &obs_ids[i]);
272 g_variant_iter_init(&msg_iter, msg);
273 msg_length = g_variant_iter_n_children(&msg_iter);
275 g_variant_iter_loop(&msg_iter, "(iv)", &error_code, &repr_gvar);
276 /* TODO : How to use error_code. */
277 payload = icd_payload_representation_from_gvariant(repr_gvar);
280 icd_ioty_csdk_lock();
281 /* TODO : QoS is come from lib. */
283 ret = OCNotifyListOfObservers(handle, obs_ids, obs_length, payload, OC_LOW_QOS);
285 ret = OCNotifyAllObservers(handle, OC_LOW_QOS);
287 icd_ioty_csdk_unlock();
289 if (OC_STACK_NO_OBSERVERS == ret) {
290 WARN("No Observers. Stop Notifying");
291 return IOTCON_ERROR_NONE;
292 } else if (OC_STACK_OK != ret) {
293 ERR("OCNotifyListOfObservers() Fail(%d)", ret);
294 return icd_ioty_convert_error(ret);
297 return IOTCON_ERROR_NONE;
301 static int _ioty_get_header_options(GVariantIter *src, int src_size,
302 OCHeaderOption dest[], int dest_size)
306 unsigned short option_id;
308 RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
310 if (dest_size < src_size) {
311 ERR("Exceed Size(%d)", src_size);
312 return IOTCON_ERROR_INVALID_PARAMETER;
315 while (g_variant_iter_loop(src, "(q&s)", &option_id, &option_data)) {
316 dest[i].protocolID = OC_COAP_ID;
317 dest[i].optionID = option_id;
318 dest[i].optionLength = strlen(option_data) + 1;
319 memcpy(dest[i].optionData, option_data, dest[i].optionLength);
323 return IOTCON_ERROR_NONE;
327 int icd_ioty_send_response(GVariant *resp)
331 GVariantIter *options;
333 OCEntityHandlerResponse response = {0};
334 int result, error_code, options_size;
335 int64_t request_handle, resource_handle;
337 g_variant_get(resp, "(&sia(qs)ivxx)",
346 response.requestHandle = ICD_INT64_TO_POINTER(request_handle);
347 response.resourceHandle = ICD_INT64_TO_POINTER(resource_handle);
348 response.ehResult = (OCEntityHandlerResult)result;
350 if (OC_EH_RESOURCE_CREATED == response.ehResult)
351 snprintf(response.resourceUri, sizeof(response.resourceUri), "%s", new_uri_path);
353 options_size = g_variant_iter_n_children(options);
354 response.numSendVendorSpecificHeaderOptions = options_size;
356 if (0 != options_size) {
357 int ret= _ioty_get_header_options(options,
358 response.numSendVendorSpecificHeaderOptions,
359 response.sendVendorSpecificHeaderOptions,
360 sizeof(response.sendVendorSpecificHeaderOptions)
361 / sizeof(response.sendVendorSpecificHeaderOptions[0]));
363 if (IOTCON_ERROR_NONE != ret)
364 ERR("_ioty_get_header_options() Fail(%d)", ret);
366 g_variant_iter_free(options);
368 response.payload = (OCPayload*)icd_payload_representation_from_gvariant(repr_gvar);
370 /* related to block transfer */
371 response.persistentBufferFlag = 0;
373 icd_ioty_csdk_lock();
374 ret = OCDoResponse(&response);
375 icd_ioty_csdk_unlock();
377 if (OC_STACK_OK != ret) {
378 ERR("OCDoResponse() Fail(%d)", ret);
379 return icd_ioty_convert_error(ret);
382 return IOTCON_ERROR_NONE;
386 static void _ioty_free_signal_context(void *data)
388 icd_sig_ctx_s *context = data;
389 free(context->bus_name);
394 int icd_ioty_find_resource(const char *host_address, int conn_type,
395 const char *resource_type, unsigned int signum, const char *bus_name)
398 OCStackResult result;
399 icd_sig_ctx_s *context;
400 char uri[PATH_MAX] = {0};
401 OCCallbackData cbdata = {0};
402 OCConnectivityType oic_conn_type;
404 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address)) {
405 len = snprintf(uri, sizeof(uri), "%s", OC_RSRVD_WELL_KNOWN_URI);
407 len = snprintf(uri, sizeof(uri), ICD_IOTY_COAP"%s%s", host_address,
408 OC_RSRVD_WELL_KNOWN_URI);
410 if (len <= 0 || sizeof(uri) <= len) {
411 ERR("snprintf() Fail(%d)", len);
412 return IOTCON_ERROR_IO_ERROR;
415 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
416 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
418 context = calloc(1, sizeof(icd_sig_ctx_s));
419 if (NULL == context) {
420 ERR("calloc() Fail(%d)", errno);
421 return IOTCON_ERROR_OUT_OF_MEMORY;
424 context->bus_name = ic_utils_strdup(bus_name);
425 context->signum = signum;
427 cbdata.context = context;
428 cbdata.cb = icd_ioty_ocprocess_find_cb;
429 cbdata.cd = _ioty_free_signal_context;
431 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
433 icd_ioty_csdk_lock();
434 /* TODO : QoS is come from lib. */
435 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
436 OC_LOW_QOS, &cbdata, NULL, 0);
437 icd_ioty_csdk_unlock();
439 if (OC_STACK_OK != result) {
440 ERR("OCDoResource() Fail(%d)", result);
441 free(context->bus_name);
443 return icd_ioty_convert_error(result);
446 return IOTCON_ERROR_NONE;
451 * returned string SHOULD be released by you
453 static char* _icd_ioty_resource_generate_uri(char *uri_path, GVariant *query)
456 bool loop_first = true;
458 GVariantIter query_iter;
459 char uri_buf[PATH_MAX] = {0};
461 len = snprintf(uri_buf, sizeof(uri_buf), "%s", uri_path);
463 /* remove suffix '/' */
464 if ('/' == uri_buf[strlen(uri_buf) - 1]) {
465 uri_buf[strlen(uri_buf) - 1] = '\0';
469 g_variant_iter_init(&query_iter, query);
471 while (g_variant_iter_loop(&query_iter, "(&s&s)", &key, &value)) {
474 DBG("query exist. key(%s), value(%s)", key, value);
476 if (true == loop_first) {
477 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "?%s=%s", key, value);
480 query_len = snprintf(uri_buf + len, sizeof(uri_buf) - len, "&%s=%s", key, value);
486 return strdup(uri_buf);
490 void icd_ioty_complete(int type, GDBusMethodInvocation *invocation, GVariant *value)
494 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
497 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
500 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
502 case ICD_CRUD_DELETE:
503 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
506 ic_dbus_complete_get_tizen_info(icd_dbus_get_object(), invocation, value);
512 void icd_ioty_complete_error(int type, GDBusMethodInvocation *invocation, int ret_val)
516 GVariantBuilder options;
520 g_variant_builder_init(&options, G_VARIANT_TYPE("a(qs)"));
521 payload = icd_payload_representation_empty_gvariant();
522 value = g_variant_new("(a(qs)vi)", &options, payload, ret_val);
523 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
526 g_variant_builder_init(&options, G_VARIANT_TYPE("a(qs)"));
527 payload = icd_payload_representation_empty_gvariant();
528 value = g_variant_new("(a(qs)vi)", &options, payload, ret_val);
529 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
532 g_variant_builder_init(&options, G_VARIANT_TYPE("a(qs)"));
533 payload = icd_payload_representation_empty_gvariant();
534 value = g_variant_new("(a(qs)vi)", &options, payload, ret_val);
535 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
537 case ICD_CRUD_DELETE:
538 g_variant_builder_init(&options, G_VARIANT_TYPE("a(qs)"));
539 value = g_variant_new("(a(qs)i)", &options, ret_val);
540 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
543 value = g_variant_new("(ssi)", IC_STR_NULL, IC_STR_NULL, ret_val);
544 ic_dbus_complete_get_tizen_info(icd_dbus_get_object(), invocation, value);
551 static gboolean _icd_ioty_crud(int type, icDbus *object, GDBusMethodInvocation *invocation,
552 GVariant *resource, GVariant *query, GVariant *repr)
556 OCStackResult result;
557 GVariantIter *options;
558 OCCallbackData cbdata = {0};
559 int conn_type, options_size;
560 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
561 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
562 OCHeaderOption *oic_options_ptr = NULL;
563 OCPayload *payload = NULL;
564 OCConnectivityType oic_conn_type;
565 OCDevAddr dev_addr = {0};
569 cbdata.cb = icd_ioty_ocprocess_get_cb;
570 rest_type = OC_REST_GET;
573 cbdata.cb = icd_ioty_ocprocess_put_cb;
574 rest_type = OC_REST_PUT;
577 cbdata.cb = icd_ioty_ocprocess_post_cb;
578 rest_type = OC_REST_POST;
580 case ICD_CRUD_DELETE:
581 cbdata.cb = icd_ioty_ocprocess_delete_cb;
582 rest_type = OC_REST_DELETE;
585 ERR("Invalid CRUD Type(%d)", type);
589 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
596 uri = _icd_ioty_resource_generate_uri(uri_path, query);
598 ERR("_icd_ioty_resource_generate_uri() Fail");
599 g_variant_iter_free(options);
600 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_INVALID_PARAMETER);
604 case ICD_CRUD_DELETE:
605 uri = strdup(uri_path);
609 cbdata.context = invocation;
611 options_size = g_variant_iter_n_children(options);
612 if (0 != options_size) {
613 int ret = _ioty_get_header_options(options, options_size, oic_options,
614 sizeof(oic_options) / sizeof(oic_options[0]));
615 if (IOTCON_ERROR_NONE != ret) {
616 ERR("_ioty_get_header_options() Fail(%d)", ret);
618 g_variant_iter_free(options);
619 icd_ioty_complete_error(type, invocation, ret);
622 oic_options_ptr = oic_options;
624 g_variant_iter_free(options);
627 payload = (OCPayload*)icd_payload_representation_from_gvariant(repr);
629 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
631 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
635 case IOTCON_CONNECTIVITY_IPV4:
636 dev_host = strtok_r(host, ":", &ptr);
637 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
638 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
640 case IOTCON_CONNECTIVITY_IPV6:
641 dev_host = strtok_r(host, "]", &ptr);
642 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
643 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
646 ERR("Invalid Connectivitiy Type");
647 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_IOTIVITY);
652 icd_ioty_csdk_lock();
653 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
654 result = OCDoResource(NULL, rest_type, uri, &dev_addr, payload, oic_conn_type,
655 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
656 icd_ioty_csdk_unlock();
660 if (OC_STACK_OK != result) {
661 ERR("OCDoResource() Fail(%d)", result);
662 icd_ioty_complete_error(type, invocation, icd_ioty_convert_error(result));
669 gboolean icd_ioty_get(icDbus *object, GDBusMethodInvocation *invocation,
670 GVariant *resource, GVariant *query)
672 return _icd_ioty_crud(ICD_CRUD_GET, object, invocation, resource, query, NULL);
676 gboolean icd_ioty_put(icDbus *object, GDBusMethodInvocation *invocation,
677 GVariant *resource, GVariant *repr, GVariant *query)
679 return _icd_ioty_crud(ICD_CRUD_PUT, object, invocation, resource, query, repr);
683 gboolean icd_ioty_post(icDbus *object, GDBusMethodInvocation *invocation,
684 GVariant *resource, GVariant *repr, GVariant *query)
686 return _icd_ioty_crud(ICD_CRUD_POST, object, invocation, resource, query, repr);
690 gboolean icd_ioty_delete(icDbus *object, GDBusMethodInvocation *invocation,
693 return _icd_ioty_crud(ICD_CRUD_DELETE, object, invocation, resource, NULL, NULL);
697 OCDoHandle icd_ioty_observer_start(GVariant *resource, int observe_type, GVariant *query,
698 unsigned int signal_number, const char *bus_name)
703 OCStackResult result;
704 GVariantIter *options;
705 icd_sig_ctx_s *context;
706 OCCallbackData cbdata = {0};
707 int conn_type, options_size;
708 char *uri_path, *host, *uri, *dev_host, *ptr = NULL;
709 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
710 OCHeaderOption *oic_options_ptr = NULL;
711 OCConnectivityType oic_conn_type;
712 OCDevAddr dev_addr = {0};
714 g_variant_get(resource, "(&s&sba(qs)i)", &uri_path, &host, &is_secure, &options,
717 uri = _icd_ioty_resource_generate_uri(uri_path, query);
719 ERR("_icd_ioty_resource_generate_uri() Fail");
720 g_variant_iter_free(options);
724 if (IOTCON_OBSERVE == observe_type)
725 method = OC_REST_OBSERVE;
726 else if (IOTCON_OBSERVE_ALL == observe_type)
727 method = OC_REST_OBSERVE_ALL;
729 method = OC_REST_OBSERVE_ALL;
731 context = calloc(1, sizeof(icd_sig_ctx_s));
732 if (NULL == context) {
733 ERR("calloc() Fail(%d)", errno);
736 context->bus_name = ic_utils_strdup(bus_name);
737 context->signum = signal_number;
739 cbdata.context = context;
740 cbdata.cb = icd_ioty_ocprocess_observe_cb;
741 cbdata.cd = _ioty_free_signal_context;
743 options_size = g_variant_iter_n_children(options);
744 if (0 != options_size) {
745 int ret = _ioty_get_header_options(options, options_size, oic_options,
746 sizeof(oic_options) / sizeof(oic_options[0]));
747 if (IOTCON_ERROR_NONE != ret) {
748 ERR("_ioty_get_header_options() Fail(%d)", ret);
749 free(context->bus_name);
752 g_variant_iter_free(options);
755 oic_options_ptr = oic_options;
757 g_variant_iter_free(options);
759 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
761 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
765 case IOTCON_CONNECTIVITY_IPV4:
766 dev_host = strtok_r(host, ":", &ptr);
767 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
768 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
770 case IOTCON_CONNECTIVITY_IPV6:
771 dev_host = strtok_r(host, "]", &ptr);
772 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
773 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
776 ERR("Invalid Connectivitiy Type");
777 free(context->bus_name);
783 icd_ioty_csdk_lock();
784 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
785 result = OCDoResource(&handle, method, uri, &dev_addr, NULL, oic_conn_type,
786 OC_LOW_QOS, &cbdata, oic_options_ptr, options_size);
787 icd_ioty_csdk_unlock();
789 if (OC_STACK_OK != result) {
790 ERR("OCDoResource() Fail(%d)", result);
791 free(context->bus_name);
800 int icd_ioty_observer_stop(OCDoHandle handle, GVariant *options)
804 GVariantIter options_iter;
805 OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
806 OCHeaderOption *oic_options_ptr = NULL;
808 g_variant_iter_init(&options_iter, options);
810 options_size = g_variant_iter_n_children(&options_iter);
811 if (0 != options_size) {
812 int ret = _ioty_get_header_options(&options_iter, options_size, oic_options,
813 sizeof(oic_options) / sizeof(oic_options[0]));
814 if (IOTCON_ERROR_NONE != ret) {
815 ERR("_ioty_get_header_options() Fail(%d)", ret);
818 oic_options_ptr = oic_options;
821 icd_ioty_csdk_lock();
822 ret = OCCancel(handle, OC_HIGH_QOS, oic_options_ptr, options_size);
823 icd_ioty_csdk_unlock();
824 if (OC_STACK_OK != ret) {
825 ERR("OCCancel() Fail(%d)", ret);
826 return icd_ioty_convert_error(ret);
829 return IOTCON_ERROR_NONE;
832 int icd_ioty_get_info(int type, const char *host_address, int conn_type,
833 unsigned int signal_number, const char *bus_name)
835 OCStackResult result;
836 icd_sig_ctx_s *context;
837 OCCallbackData cbdata = {0};
838 char uri[PATH_MAX] = {0};
839 char *uri_path = NULL;
840 OCConnectivityType oic_conn_type;
842 if (ICD_DEVICE_INFO == type)
843 uri_path = OC_RSRVD_DEVICE_URI;
844 else if (ICD_PLATFORM_INFO == type)
845 uri_path = OC_RSRVD_PLATFORM_URI;
847 return IOTCON_ERROR_INVALID_PARAMETER;
849 if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address))
850 snprintf(uri, sizeof(uri), "%s", uri_path);
852 snprintf(uri, sizeof(uri), "%s%s", host_address, uri_path);
854 context = calloc(1, sizeof(icd_sig_ctx_s));
855 if (NULL == context) {
856 ERR("calloc() Fail(%d)", errno);
857 return IOTCON_ERROR_OUT_OF_MEMORY;
859 context->bus_name = ic_utils_strdup(bus_name);
860 context->signum = signal_number;
862 cbdata.context = context;
863 cbdata.cb = icd_ioty_ocprocess_info_cb;
864 cbdata.cd = _ioty_free_signal_context;
866 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
868 icd_ioty_csdk_lock();
869 /* TODO : QoS is come from lib. And user can set QoS to client structure. */
870 result = OCDoResource(NULL, OC_REST_DISCOVER, uri, NULL, NULL, oic_conn_type,
871 OC_LOW_QOS, &cbdata, NULL, 0);
872 icd_ioty_csdk_unlock();
874 if (OC_STACK_OK != result) {
875 ERR("OCDoResource() Fail(%d)", result);
876 free(context->bus_name);
878 return icd_ioty_convert_error(result);
881 return IOTCON_ERROR_NONE;
884 static int _icd_ioty_get_tizen_id(char **tizen_device_id)
887 char *tizen_id = NULL;
889 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_TIZEN_ID, &tizen_id);
890 if (SYSTEM_INFO_ERROR_NONE != ret) {
891 ERR("system_info_get_platform_string() Fail(%d)", ret);
892 return IOTCON_ERROR_SYSTEM;
894 *tizen_device_id = tizen_id;
896 return IOTCON_ERROR_NONE;
899 static int _ioty_set_device_info()
902 char *device_name = NULL;
903 OCDeviceInfo device_info = {0};
905 ret = system_settings_get_value_string(SYSTEM_SETTINGS_KEY_DEVICE_NAME, &device_name);
906 if (SYSTEM_SETTINGS_ERROR_NONE != ret) {
907 ERR("system_settings_get_value_string() Fail(%d)", ret);
908 return IOTCON_ERROR_SYSTEM;
911 device_info.deviceName = device_name;
913 icd_ioty_csdk_lock();
914 ret = OCSetDeviceInfo(device_info);
915 icd_ioty_csdk_unlock();
917 if (OC_STACK_OK != ret) {
918 ERR("OCSetDeviceInfo() Fail(%d)", ret);
920 return icd_ioty_convert_error(ret);
923 free(icd_tizen_info.device_name);
924 icd_tizen_info.device_name = device_name;
926 return IOTCON_ERROR_NONE;
929 static void _icd_ioty_on_device_name_changed_cb(system_settings_key_e key,
935 ret = _ioty_set_device_info();
936 if (IOTCON_ERROR_NONE != ret) {
937 ERR("_ioty_set_device_info() Fail(%d)", ret);
942 int icd_ioty_set_device_info()
946 ret = system_settings_set_changed_cb(SYSTEM_SETTINGS_KEY_DEVICE_NAME,
947 _icd_ioty_on_device_name_changed_cb, NULL);
948 if (SYSTEM_SETTINGS_ERROR_NONE != ret) {
949 ERR("system_settings_set_changed_cb() Fail(%d)", ret);
950 return IOTCON_ERROR_SYSTEM;
953 ret = _ioty_set_device_info();
954 if (IOTCON_ERROR_NONE != ret) {
955 ERR("_ioty_set_device_info() Fail(%d)", ret);
959 return IOTCON_ERROR_NONE;
962 static void _ioty_free_platform_info(OCPlatformInfo platform_info)
964 free(platform_info.manufacturerName);
965 free(platform_info.manufacturerUrl);
966 free(platform_info.modelNumber);
967 free(platform_info.dateOfManufacture);
968 free(platform_info.platformVersion);
969 free(platform_info.operatingSystemVersion);
970 free(platform_info.hardwareVersion);
971 free(platform_info.firmwareVersion);
972 free(platform_info.supportUrl);
973 free(platform_info.systemTime);
976 int icd_ioty_set_platform_info()
979 OCPlatformInfo platform_info = {0};
981 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_PLATFORM_NAME,
982 &platform_info.platformID);
983 if (SYSTEM_INFO_ERROR_NONE != ret) {
984 ERR("system_info_get_platform_string() Fail(%d)", ret);
985 _ioty_free_platform_info(platform_info);
986 return IOTCON_ERROR_SYSTEM;
989 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_MANUF_NAME,
990 &platform_info.manufacturerName);
991 if (SYSTEM_INFO_ERROR_NONE != ret) {
992 ERR("system_info_get_platform_string() Fail(%d)", ret);
993 _ioty_free_platform_info(platform_info);
994 return IOTCON_ERROR_SYSTEM;
997 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_MODEL_NAME,
998 &platform_info.modelNumber);
999 if (SYSTEM_INFO_ERROR_NONE != ret) {
1000 ERR("system_info_get_platform_string() Fail(%d)", ret);
1001 _ioty_free_platform_info(platform_info);
1002 return IOTCON_ERROR_SYSTEM;
1005 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_PLATFORM_VERSION,
1006 &platform_info.platformVersion);
1007 if (SYSTEM_INFO_ERROR_NONE != ret) {
1008 ERR("system_info_get_platform_string() Fail(%d)", ret);
1009 _ioty_free_platform_info(platform_info);
1010 return IOTCON_ERROR_SYSTEM;
1013 ret = system_info_get_platform_string(ICD_SYSTEM_INFO_BUILD_STRING,
1014 &platform_info.firmwareVersion);
1015 if (SYSTEM_INFO_ERROR_NONE != ret) {
1016 ERR("system_info_get_platform_string() Fail(%d)", ret);
1017 _ioty_free_platform_info(platform_info);
1018 return IOTCON_ERROR_SYSTEM;
1021 /* platform_info.manufacturerUrl */
1022 /* platform_info.dateOfManufacture */
1023 /* platform_info.operatingSystemVersion */
1024 /* platform_info.hardwareVersion */
1025 /* platform_info.supportUrl */
1026 /* platform_info.systemTime */
1028 icd_ioty_csdk_lock();
1029 ret = OCSetPlatformInfo(platform_info);
1030 icd_ioty_csdk_unlock();
1032 if (OC_STACK_OK != ret) {
1033 ERR("OCSetPlatformInfo() Fail(%d)", ret);
1034 _ioty_free_platform_info(platform_info);
1035 return icd_ioty_convert_error(ret);
1037 _ioty_free_platform_info(platform_info);
1039 return IOTCON_ERROR_NONE;
1042 int icd_ioty_set_tizen_info()
1046 OCResourceHandle handle;
1047 char *tizen_device_id = NULL;
1049 result = _icd_ioty_get_tizen_id(&tizen_device_id);
1050 if (IOTCON_ERROR_NONE != result) {
1051 ERR("_icd_ioty_get_tizen_id() Fail(%d)", result);
1055 icd_tizen_info.tizen_device_id = tizen_device_id;
1056 DBG("tizen_device_id : %s", icd_tizen_info.tizen_device_id);
1058 icd_ioty_csdk_lock();
1059 ret = OCCreateResource(&handle,
1060 ICD_IOTY_TIZEN_INFO_TYPE,
1061 IC_INTERFACE_DEFAULT,
1062 ICD_IOTY_TIZEN_INFO_URI,
1063 icd_ioty_ocprocess_tizen_info_handler,
1066 icd_ioty_csdk_unlock();
1067 if (OC_STACK_OK != ret) {
1068 ERR("OCCreateResource() Fail(%d)", ret);
1069 return icd_ioty_convert_error(ret);
1072 return IOTCON_ERROR_NONE;
1076 gboolean icd_ioty_get_tizen_info(icDbus *object, GDBusMethodInvocation *invocation,
1077 const gchar *host_address, int conn_type)
1079 OCStackResult result;
1080 OCDevAddr dev_addr = {0};
1081 OCCallbackData cbdata = {0};
1082 OCConnectivityType oic_conn_type;
1083 char host[PATH_MAX] = {0};
1084 char *dev_host, *ptr = NULL;
1086 snprintf(host, sizeof(host), "%s", host_address);
1088 cbdata.cb = icd_ioty_ocprocess_get_tizen_info_cb;
1089 cbdata.context = invocation;
1091 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
1092 icd_ioty_conn_type_to_oic_transport_type(conn_type, &dev_addr.adapter,
1095 switch (conn_type) {
1096 case IOTCON_CONNECTIVITY_IPV4:
1097 dev_host = strtok_r(host, ":", &ptr);
1098 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
1099 dev_addr.port = atoi(strtok_r(NULL, ":", &ptr));
1101 case IOTCON_CONNECTIVITY_IPV6:
1102 dev_host = strtok_r(host, "]", &ptr);
1103 snprintf(dev_addr.addr, sizeof(dev_addr.addr), "%s", dev_host);
1104 dev_addr.port = atoi(strtok_r(NULL, "]", &ptr));
1107 ERR("Invalid Connectivitiy Type");
1108 icd_ioty_complete_error(ICD_TIZEN_INFO, invocation, IOTCON_ERROR_IOTIVITY);
1112 icd_ioty_csdk_lock();
1113 result = OCDoResource(NULL, OC_REST_GET, ICD_IOTY_TIZEN_INFO_URI, &dev_addr, NULL,
1114 oic_conn_type, OC_LOW_QOS, &cbdata, NULL, 0);
1115 icd_ioty_csdk_unlock();
1117 if (OC_STACK_OK != result) {
1118 ERR("OCDoResource() Fail(%d)", result);
1119 icd_ioty_complete_error(ICD_TIZEN_INFO, invocation, icd_ioty_convert_error(result));
1127 int icd_ioty_tizen_info_get_property(char **device_name, char **tizen_device_id)
1129 RETV_IF(NULL == device_name, IOTCON_ERROR_INVALID_PARAMETER);
1130 RETV_IF(NULL == tizen_device_id, IOTCON_ERROR_INVALID_PARAMETER);
1132 *device_name = icd_tizen_info.device_name;
1133 *tizen_device_id = icd_tizen_info.tizen_device_id;
1135 return IOTCON_ERROR_NONE;
1139 OCDoHandle icd_ioty_subscribe_presence(const char *host_address, int conn_type,
1140 const char *resource_type, unsigned int signal_number, const char *bus_name)
1144 OCStackResult result;
1145 icd_sig_ctx_s *context;
1146 char uri[PATH_MAX] = {0};
1147 OCCallbackData cbdata = {0};
1148 OCConnectivityType oic_conn_type;
1150 len = snprintf(uri, sizeof(uri), "%s%s", host_address, OC_RSRVD_PRESENCE_URI);
1151 if (len <= 0 || sizeof(uri) <= len) {
1152 ERR("snprintf() Fail(%d)", len);
1156 if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
1157 snprintf(uri + len, sizeof(uri) - len, "?rt=%s", resource_type);
1159 context = calloc(1, sizeof(icd_sig_ctx_s));
1160 if (NULL == context) {
1161 ERR("calloc() Fail(%d)", errno);
1164 context->bus_name = ic_utils_strdup(bus_name);
1165 context->signum = signal_number;
1167 cbdata.context = context;
1168 cbdata.cb = icd_ioty_ocprocess_presence_cb;
1169 cbdata.cd = _ioty_free_signal_context;
1171 oic_conn_type = icd_ioty_conn_type_to_oic_conn_type(conn_type);
1173 /* In case of IPV4 or IPV6, connectivity type is CT_ADAPTER_IP in iotivity 0.9.2 */
1174 if (CT_IP_USE_V4 == oic_conn_type && CT_IP_USE_V6 == oic_conn_type)
1175 oic_conn_type = CT_ADAPTER_IP;
1177 icd_ioty_csdk_lock();
1178 result = OCDoResource(&handle, OC_REST_PRESENCE, uri, NULL, NULL, CT_ADAPTER_IP,
1179 OC_LOW_QOS, &cbdata, NULL, 0);
1180 icd_ioty_csdk_unlock();
1182 if (OC_STACK_OK != result) {
1183 ERR("OCDoResource() Fail(%d)", result);
1184 free(context->bus_name);
1192 int icd_ioty_unsubscribe_presence(OCDoHandle handle)
1196 icd_ioty_csdk_lock();
1197 ret = OCCancel(handle, OC_LOW_QOS, NULL, 0);
1198 icd_ioty_csdk_unlock();
1199 if (OC_STACK_OK != ret) {
1200 ERR("OCCancel() Fail(%d)", ret);
1201 return icd_ioty_convert_error(ret);
1204 return IOTCON_ERROR_NONE;
1208 int icd_ioty_start_presence(unsigned int time_to_live)
1212 icd_ioty_csdk_lock();
1213 ret = OCStartPresence(time_to_live);
1214 icd_ioty_csdk_unlock();
1215 if (OC_STACK_OK != ret) {
1216 ERR("OCStartPresence() Fail(%d)", ret);
1217 return icd_ioty_convert_error(ret);
1220 return IOTCON_ERROR_NONE;
1224 int icd_ioty_stop_presence()
1228 icd_ioty_csdk_lock();
1229 ret = OCStopPresence();
1230 icd_ioty_csdk_unlock();
1231 if (OC_STACK_OK != ret) {
1232 ERR("OCStopPresence() Fail(%d)", ret);
1233 return icd_ioty_convert_error(ret);
1236 return IOTCON_ERROR_NONE;