apply put,post,delete functions
[platform/core/iot/iotcon.git] / daemon / icd-ioty.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <stdint.h> /* for uint8_t etc */
20 #include <stdbool.h>
21 #include <errno.h>
22 #include <glib.h>
23 #include <json-glib/json-glib.h>
24
25 #include <octypes.h>
26 #include <ocstack.h>
27
28 #include "iotcon.h"
29 #include "ic-dbus.h"
30 #include "ic-utils.h"
31 #include "icd.h"
32 #include "icd-dbus.h"
33 #include "icd-ioty.h"
34 #include "icd-ioty-ocprocess.h"
35
36 static GMutex icd_csdk_mutex;
37
38 void icd_ioty_csdk_lock()
39 {
40         g_mutex_lock(&icd_csdk_mutex);
41 }
42
43
44 void icd_ioty_csdk_unlock()
45 {
46         g_mutex_unlock(&icd_csdk_mutex);
47 }
48
49
50 GThread* icd_ioty_init(const char *addr, unsigned short port)
51 {
52         FN_CALL;
53         GError *error;
54         GThread *thread;
55
56         OCStackResult result = OCInit(addr, port, OC_CLIENT_SERVER);
57         if (OC_STACK_OK != result) {
58                 ERR("OCInit() Fail(%d)", result);
59                 return NULL;
60         }
61
62         DBG("OCInit() Success");
63
64         thread = g_thread_try_new("packet_receive_thread", icd_ioty_ocprocess_thread,
65                         NULL, &error);
66         if (NULL == thread) {
67                 ERR("g_thread_try_new() Fail(%s)", error->message);
68                 g_error_free(error);
69                 return NULL;
70         }
71
72         return thread;
73 }
74
75
76 void icd_ioty_deinit(GThread *thread)
77 {
78         OCStackResult result;
79
80         icd_ioty_ocprocess_stop();
81         g_thread_join(thread);
82
83         result = OCStop();
84         if (OC_STACK_OK != result)
85                 ERR("OCStop() Fail(%d)", result);
86 }
87
88
89 OCResourceHandle icd_ioty_register_resource(const char *uri_path,
90                 const char* const* res_types, int ifaces, uint8_t properties)
91 {
92         FN_CALL;
93         int i;
94         OCStackResult ret;
95         OCResourceHandle handle;
96         const char *resInterface = NULL;
97
98         if (IOTCON_INTERFACE_DEFAULT & ifaces) {
99                 resInterface = IC_INTERFACE_DEFAULT;
100                 ifaces ^= IOTCON_INTERFACE_DEFAULT;
101         } else if (IOTCON_INTERFACE_LINK & ifaces) {
102                 resInterface = IC_INTERFACE_LINK;
103                 ifaces ^= IOTCON_INTERFACE_LINK;
104         } else if (IOTCON_INTERFACE_BATCH & ifaces) {
105                 resInterface = IC_INTERFACE_BATCH;
106                 ifaces ^= IOTCON_INTERFACE_BATCH;
107         } else if (IOTCON_INTERFACE_GROUP & ifaces) {
108                 resInterface = IC_INTERFACE_GROUP;
109                 ifaces ^= IOTCON_INTERFACE_GROUP;
110         } else {
111                 ERR("Invalid interface type(%d)", ifaces);
112                 return NULL;
113         }
114
115         icd_ioty_csdk_lock();
116         ret = OCCreateResource(&handle, res_types[0], resInterface, uri_path,
117                         icd_ioty_ocprocess_req_handler, properties);
118         icd_ioty_csdk_unlock();
119         if (OC_STACK_OK != ret) {
120                 ERR("OCCreateResource() Fail(%d)", ret);
121                 return NULL;
122         }
123
124         for (i = 1; res_types[i]; i++)
125                 icd_ioty_bind_type(handle, res_types[i]);
126
127         if (IOTCON_INTERFACE_DEFAULT & ifaces)
128                 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_DEFAULT);
129         if (IOTCON_INTERFACE_LINK & ifaces)
130                 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_LINK);
131         if (IOTCON_INTERFACE_BATCH & ifaces)
132                 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_BATCH);
133         if (IOTCON_INTERFACE_GROUP & ifaces)
134                 icd_ioty_bind_interface(handle, IOTCON_INTERFACE_GROUP);
135
136         return handle;
137 }
138
139
140 int icd_ioty_unregister_resource(OCResourceHandle resource_handle)
141 {
142         OCStackResult ret;
143
144         icd_ioty_csdk_lock();
145         ret = OCDeleteResource(resource_handle);
146         icd_ioty_csdk_unlock();
147         if (OC_STACK_OK != ret) {
148                 ERR("OCDeleteResource() Fail(%d)", ret);
149                 return IOTCON_ERROR_IOTIVITY;
150         }
151
152         return IOTCON_ERROR_NONE;
153 }
154
155
156 int icd_ioty_bind_interface(OCResourceHandle resourceHandle, iotcon_interface_e iface)
157 {
158         int ret;
159         OCStackResult result;
160         char *resource_interface;
161
162         ret = ic_utils_convert_interface_flag(iface, &resource_interface);
163         if (IOTCON_ERROR_NONE != ret) {
164                 ERR("ic_utils_convert_interface_flag(%d) Fail(%d)", iface, ret);
165                 return ret;
166         }
167
168         icd_ioty_csdk_lock();
169         result = OCBindResourceInterfaceToResource(resourceHandle, resource_interface);
170         icd_ioty_csdk_unlock();
171         if (OC_STACK_OK != result) {
172                 ERR("OCBindResourceInterfaceToResource() Fail(%d)", result);
173                 return IOTCON_ERROR_IOTIVITY;
174         }
175
176         return IOTCON_ERROR_NONE;
177 }
178
179
180 int icd_ioty_bind_type(OCResourceHandle resource_handle, const char *resource_type)
181 {
182         OCStackResult ret;
183
184         icd_ioty_csdk_lock();
185         ret = OCBindResourceTypeToResource(resource_handle, resource_type);
186         icd_ioty_csdk_unlock();
187         if (OC_STACK_OK != ret) {
188                 ERR("OCBindResourceTypeToResource() Fail(%d)", ret);
189                 return IOTCON_ERROR_IOTIVITY;
190         }
191
192         return IOTCON_ERROR_NONE;
193 }
194
195
196 int icd_ioty_bind_resource(OCResourceHandle parent, OCResourceHandle child)
197 {
198         OCStackResult ret;
199
200         icd_ioty_csdk_lock();
201         ret = OCBindResource(parent, child);
202         icd_ioty_csdk_unlock();
203         if (OC_STACK_OK != ret) {
204                 ERR("OCBindResource() Fail(%d)", ret);
205                 return IOTCON_ERROR_IOTIVITY;
206         }
207
208         return IOTCON_ERROR_NONE;
209 }
210
211
212 int icd_ioty_unbind_resource(OCResourceHandle parent, OCResourceHandle child)
213 {
214         OCStackResult ret;
215
216         icd_ioty_csdk_lock();
217         ret = OCUnBindResource(parent, child);
218         icd_ioty_csdk_unlock();
219         if (OC_STACK_OK != ret) {
220                 ERR("OCUnBindResource() Fail(%d)", ret);
221                 return IOTCON_ERROR_IOTIVITY;
222         }
223
224         return IOTCON_ERROR_NONE;
225 }
226
227
228 int icd_ioty_notify_list_of_observers(void *handle, GVariant *msg, GVariant *observers)
229 {
230         int i, error_code, obs_length;
231         char *repr_json = NULL;
232         GVariantIter obs_iter, msg_iter;
233         OCStackResult ret;
234
235         g_variant_iter_init(&obs_iter, observers);
236         obs_length = g_variant_iter_n_children(&obs_iter);
237
238         /* Variable-length Array */
239         OCObservationId obs_ids[obs_length];
240
241         for (i = 0; i < obs_length; i++)
242                 g_variant_iter_loop(&obs_iter, "i", &obs_ids[i]);
243
244         g_variant_iter_init(&msg_iter, msg);
245         g_variant_iter_loop(&msg_iter, "(i&s)", &error_code, &repr_json);
246         /* TODO : How to use error_code. */
247
248         icd_ioty_csdk_lock();
249         /* TODO : QoS is come from lib. And user can set QoS to client structure.  */
250         ret = OCNotifyListOfObservers(handle, obs_ids, obs_length, repr_json, OC_HIGH_QOS);
251         icd_ioty_csdk_unlock();
252
253         if (OC_STACK_NO_OBSERVERS == ret) {
254                 WARN("No Observers. Stop Notifying");
255                 return IOTCON_ERROR_NONE;
256         } else if (OC_STACK_OK != ret) {
257                 ERR("OCNotifyListOfObservers() Fail(%d)", ret);
258                 return IOTCON_ERROR_IOTIVITY;
259         }
260
261         return IOTCON_ERROR_NONE;
262 }
263
264
265 int icd_ioty_notify_all(void *handle)
266 {
267         OCStackResult ret;
268
269         icd_ioty_csdk_lock();
270         /* TODO : QoS is come from lib. And user can set QoS to client structure.  */
271         ret = OCNotifyAllObservers(handle, OC_HIGH_QOS);
272         icd_ioty_csdk_unlock();
273
274         if (OC_STACK_NO_OBSERVERS == ret) {
275                 WARN("No Observers. Stop Notifying");
276                 return IOTCON_ERROR_NONE;
277         } else if (OC_STACK_OK != ret) {
278                 ERR("OCNotifyAllObservers() Fail(%d)", ret);
279                 return IOTCON_ERROR_IOTIVITY;
280         }
281
282         return IOTCON_ERROR_NONE;
283 }
284
285
286 static int _ioty_get_header_options(GVariantIter *src, int src_size,
287                 OCHeaderOption dest[], int dest_size)
288 {
289         int i = 0;
290         char *option_data;
291         unsigned short option_id;
292
293         RETV_IF(NULL == dest, IOTCON_ERROR_INVALID_PARAMETER);
294
295         if (dest_size < src_size) {
296                 ERR("Exceed Size(%d)", src_size);
297                 return IOTCON_ERROR_INVALID_PARAMETER;
298         }
299
300         while (g_variant_iter_loop(src, "(q&s)", &option_id, &option_data)) {
301                 dest[i].protocolID = OC_COAP_ID;
302                 dest[i].optionID = option_id;
303                 dest[i].optionLength = strlen(option_data) + 1;
304                 memcpy(dest[i].optionData, option_data, dest[i].optionLength);
305                 i++;
306         }
307
308         return IOTCON_ERROR_NONE;
309 }
310
311
312 int icd_ioty_send_response(GVariant *resp)
313 {
314         int result, error_code, options_size;
315         int request_handle, resource_handle;
316         char *new_uri_path, *repr_json;
317         GVariantIter *options;
318         OCStackResult ret;
319         OCEntityHandlerResponse response = {0};
320
321         g_variant_get(resp, "(&sia(qs)i&sii)",
322                         &new_uri_path,
323                         &error_code,
324                         &options,
325                         &result,
326                         &repr_json,
327                         &request_handle,
328                         &resource_handle);
329
330         response.requestHandle = GINT_TO_POINTER(request_handle);
331         response.resourceHandle = GINT_TO_POINTER(resource_handle);
332         response.ehResult = (OCEntityHandlerResult)result;
333
334         if (OC_EH_RESOURCE_CREATED == response.ehResult)
335                 snprintf(response.resourceUri, sizeof(response.resourceUri), "%s", new_uri_path);
336
337         options_size = g_variant_iter_n_children(options);
338         response.numSendVendorSpecificHeaderOptions = options_size;
339
340         if (0 != options_size) {
341                 int ret= _ioty_get_header_options(options,
342                                 response.numSendVendorSpecificHeaderOptions,
343                                 response.sendVendorSpecificHeaderOptions,
344                                 sizeof(response.sendVendorSpecificHeaderOptions)
345                                 / sizeof(response.sendVendorSpecificHeaderOptions[0]));
346
347                 if (IOTCON_ERROR_NONE != ret)
348                         ERR("_ioty_get_header_options() Fail(%d)", ret);
349         }
350         g_variant_iter_free(options);
351
352         response.payload = repr_json;
353         response.payloadSize = strlen(response.payload) + 1;
354
355         /* related to block transfer */
356         response.persistentBufferFlag = 0;
357
358         icd_ioty_csdk_lock();
359         ret = OCDoResponse(&response);
360         icd_ioty_csdk_unlock();
361
362         if (OC_STACK_OK != ret) {
363                 ERR("OCDoResponse() Fail(%d)", ret);
364                 return IOTCON_ERROR_IOTIVITY;
365         }
366
367         return IOTCON_ERROR_NONE;
368 }
369
370
371 static void _ioty_free_signal_context(void *data)
372 {
373         icd_sig_ctx_s *context = data;
374         free(context->bus_name);
375         free(context);
376 }
377
378 int icd_ioty_find_resource(const char *host_address, const char *resource_type,
379                 unsigned int signum, const char *bus_name)
380 {
381         int len;
382         OCStackResult result;
383         OCCallbackData cbdata = {0};
384         icd_sig_ctx_s *context;
385         char uri[PATH_MAX] = {0};
386         iotcon_connectivity_type_e conn_type = IOTCON_CONNECTIVITY_IPV4;
387
388         if (IC_STR_EQUAL == strcmp(IOTCON_MULTICAST_ADDRESS, host_address)) {
389                 len = snprintf(uri, sizeof(uri), "%s", OC_MULTICAST_DISCOVERY_URI);
390                 conn_type = IOTCON_CONNECTIVITY_ALL;
391         } else {
392                 len = snprintf(uri, sizeof(uri), ICD_IOTY_COAP"%s%s", host_address,
393                                 OC_MULTICAST_DISCOVERY_URI);
394         }
395         if (len <= 0 || sizeof(uri) <= len) {
396                 ERR("snprintf() Fail(%d)", len);
397                 return IOTCON_ERROR_UNKNOWN;
398         }
399
400         if (IC_STR_EQUAL != strcmp(IC_STR_NULL, resource_type))
401                 snprintf(uri + len, sizeof(uri), "?rt=%s", resource_type);
402
403         context = calloc(1, sizeof(icd_sig_ctx_s));
404         if (NULL == context) {
405                 ERR("calloc() Fail(%d)", errno);
406                 return IOTCON_ERROR_OUT_OF_MEMORY;
407         }
408
409         context->bus_name = ic_utils_strdup(bus_name);
410         context->signum = signum;
411
412         cbdata.context = context;
413         cbdata.cb = icd_ioty_ocprocess_find_cb;
414         cbdata.cd = _ioty_free_signal_context;
415
416         icd_ioty_csdk_lock();
417         result = OCDoResource(NULL, OC_REST_GET, uri, NULL, NULL, conn_type, OC_LOW_QOS,
418                         &cbdata, NULL, 0);
419         icd_ioty_csdk_unlock();
420
421         if (OC_STACK_OK != result) {
422                 ERR("OCDoResource() Fail(%d)", result);
423                 free(context->bus_name);
424                 free(context);
425                 return IOTCON_ERROR_IOTIVITY;
426         }
427
428         return IOTCON_ERROR_NONE;
429 }
430
431
432 /*
433  * returned string SHOULD be released by you
434  */
435 static char* _icd_ioty_resource_generate_uri(char *host, char *uri_path, GVariant *query)
436 {
437         int len;
438         bool loop_first = true;
439         char *key, *value;
440         GVariantIter query_iter;
441         char uri_buf[PATH_MAX] = {0};
442
443         len = snprintf(uri_buf, sizeof(uri_buf), "%s%s", host, uri_path);
444
445         /* remove suffix '/' */
446         if ('/' == uri_buf[strlen(uri_buf) - 1]) {
447                 uri_buf[strlen(uri_buf) - 1] = '\0';
448                 len--;
449         }
450
451         g_variant_iter_init(&query_iter, query);
452
453         while (g_variant_iter_loop(&query_iter, "(&s&s)", &key, &value)) {
454                 int query_len;
455
456                 DBG("query exist. key(%s), value(%s)", key, value);
457
458                 if (true == loop_first) {
459                         query_len = snprintf(uri_buf + len, sizeof(uri_buf), "?%s=%s", key, value);
460                         loop_first = false;
461                 } else {
462                         query_len = snprintf(uri_buf + len, sizeof(uri_buf), "&%s=%s", key, value);
463                 }
464
465                 len += query_len;
466         }
467
468         return strdup(uri_buf);
469 }
470
471
472 void icd_ioty_complete(int type, GDBusMethodInvocation *invocation, GVariant *value)
473 {
474         switch(type) {
475         case ICD_CRUD_GET:
476                 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
477                 break;
478         case ICD_CRUD_PUT:
479                 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
480                 break;
481         case ICD_CRUD_POST:
482                 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
483                 break;
484         case ICD_CRUD_DELETE:
485                 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
486                 break;
487         }
488 }
489
490
491 void icd_ioty_complete_error(int type, GDBusMethodInvocation *invocation, int ret_val)
492 {
493         GVariant *value;
494
495         switch (type) {
496         case ICD_CRUD_GET:
497                 value = g_variant_new("(a(qs)si)", NULL, IC_STR_NULL, ret_val);
498                 ic_dbus_complete_get(icd_dbus_get_object(), invocation, value);
499                 break;
500         case ICD_CRUD_PUT:
501                 value = g_variant_new("(a(qs)si)", NULL, IC_STR_NULL, ret_val);
502                 ic_dbus_complete_put(icd_dbus_get_object(), invocation, value);
503                 break;
504         case ICD_CRUD_POST:
505                 value = g_variant_new("(a(qs)si)", NULL, IC_STR_NULL, ret_val);
506                 ic_dbus_complete_post(icd_dbus_get_object(), invocation, value);
507                 break;
508         case ICD_CRUD_DELETE:
509                 value = g_variant_new("(a(qs)i)", NULL, ret_val);
510                 ic_dbus_complete_delete(icd_dbus_get_object(), invocation, value);
511                 break;
512         }
513 }
514
515
516 static gboolean _icd_ioty_crud(int type, icDbus *object, GDBusMethodInvocation *invocation,
517                 GVariant *resource, GVariant *query, const char *repr)
518 {
519         OCMethod rest_type;
520         OCStackResult result;
521         GVariantIter *options;
522         OCCallbackData cbdata = {0};
523         int conn_type, options_size;
524         char *uri_path, *host, *uri;
525         char uri_buf[PATH_MAX] = {0};
526         OCHeaderOption oic_options[MAX_HEADER_OPTIONS];
527         OCHeaderOption *oic_options_ptr = NULL;
528
529         switch (type) {
530         case ICD_CRUD_GET:
531                 cbdata.cb = icd_ioty_ocprocess_get_cb;
532                 rest_type = OC_REST_GET;
533                 break;
534         case ICD_CRUD_PUT:
535                 cbdata.cb = icd_ioty_ocprocess_put_cb;
536                 rest_type = OC_REST_PUT;
537                 break;
538         case ICD_CRUD_POST:
539                 cbdata.cb = icd_ioty_ocprocess_post_cb;
540                 rest_type = OC_REST_POST;
541                 break;
542         case ICD_CRUD_DELETE:
543                 cbdata.cb = icd_ioty_ocprocess_delete_cb;
544                 rest_type = OC_REST_DELETE;
545                 break;
546         default:
547                 ERR("Invalid CRUD Type(%d)", type);
548                 return FALSE;
549         }
550
551         g_variant_get(resource, "(&s&sa(qs)i)", &uri_path, &host, &options, &conn_type);
552
553         switch (type) {
554         case ICD_CRUD_GET:
555         case ICD_CRUD_PUT:
556         case ICD_CRUD_POST:
557                 uri = _icd_ioty_resource_generate_uri(host, uri_path, query);
558                 if (NULL == uri) {
559                         ERR("_icd_ioty_resource_generate_uri() Fail");
560                         g_variant_iter_free(options);
561                         icd_ioty_complete_error(type, invocation, IOTCON_ERROR_INVALID_PARAMETER);
562                         return TRUE;
563                 }
564                 break;
565         case ICD_CRUD_DELETE:
566                 snprintf(uri_buf, sizeof(uri_buf), "%s%s", host, uri_path);
567                 uri = strdup(uri_buf);
568                 break;
569         }
570
571         cbdata.context = invocation;
572
573         options_size = g_variant_iter_n_children(options);
574         if (0 != options_size) {
575                 int ret = _ioty_get_header_options(options, options_size, oic_options,
576                                 sizeof(oic_options) / sizeof(oic_options[0]));
577                 if (IOTCON_ERROR_NONE != ret) {
578                         ERR("_ioty_get_header_options() Fail(%d)", ret);
579                         free(uri);
580                         g_variant_iter_free(options);
581                         icd_ioty_complete_error(type, invocation, ret);
582                         return TRUE;
583                 }
584                 oic_options_ptr = oic_options;
585         }
586         g_variant_iter_free(options);
587
588         icd_ioty_csdk_lock();
589         /* TODO : QoS is come from lib. And user can set QoS to client structure.  */
590         result = OCDoResource(NULL, rest_type, uri, NULL, repr, conn_type, OC_HIGH_QOS,
591                         &cbdata, oic_options_ptr, options_size);
592         icd_ioty_csdk_unlock();
593
594         free(uri);
595
596         if (OC_STACK_OK != result) {
597                 ERR("OCDoResource() Fail(%d)", result);
598                 icd_ioty_complete_error(type, invocation, IOTCON_ERROR_IOTIVITY);
599                 return TRUE;
600         }
601
602         return TRUE;
603 }
604
605 gboolean icd_ioty_get(icDbus *object, GDBusMethodInvocation *invocation,
606                 GVariant *resource, GVariant *query)
607 {
608         FN_CALL;
609         return _icd_ioty_crud(ICD_CRUD_GET, object, invocation, resource, query, NULL);
610 }
611
612
613 gboolean icd_ioty_put(icDbus *object, GDBusMethodInvocation *invocation,
614                 GVariant *resource, const char *repr, GVariant *query)
615 {
616         FN_CALL;
617         return _icd_ioty_crud(ICD_CRUD_PUT, object, invocation, resource, query, repr);
618 }
619
620
621 gboolean icd_ioty_post(icDbus *object, GDBusMethodInvocation *invocation,
622                 GVariant *resource, const char *repr, GVariant *query)
623 {
624         FN_CALL;
625         return _icd_ioty_crud(ICD_CRUD_POST, object, invocation, resource, query, repr);
626 }
627
628
629 gboolean icd_ioty_delete(icDbus *object, GDBusMethodInvocation *invocation,
630                 GVariant *resource)
631 {
632         FN_CALL;
633         return _icd_ioty_crud(ICD_CRUD_DELETE, object, invocation, resource, NULL, NULL);
634 }
635
636
637 int icd_ioty_observer_start(GVariant *resource, int observe_type,
638                 GVariant *query, unsigned int signal_number, const char *bus_name, int *observe_h)
639 {
640         // TODO : To be implemented
641         return IOTCON_ERROR_NONE;
642 }
643
644
645 int icd_ioty_observer_stop(void *observe_h)
646 {
647         // TODO : To be implemented
648         return IOTCON_ERROR_NONE;
649 }
650
651
652 #ifdef DEVICE_INFO_IMPL /* not implemented in iotivity 0.9.1 */
653 int icd_ioty_register_device_info(GVariant *value)
654 {
655         // TODO : To be implemented
656         return IOTCON_ERROR_NONE;
657 }
658
659
660 int icd_ioty_get_device_info(const char *host_address,
661                 unsigned int signal_number, const char *bus_name)
662 {
663         // TODO : To be implemented
664         return IOTCON_ERROR_NONE;
665 }
666 #endif
667
668
669 int icd_ioty_register_platform_info(GVariant *value)
670 {
671         // TODO : To be implemented
672         return IOTCON_ERROR_NONE;
673 }
674
675
676 int icd_ioty_get_platform_info(const char *host_address, unsigned int signal_number,
677                 const char *bus_name)
678 {
679         // TODO : To be implemented
680         return IOTCON_ERROR_NONE;
681 }
682
683
684 OCDoHandle icd_ioty_subscribe_presence(const char *host_address,
685                 const char *resource_type, unsigned int signal_number, const char *bus_name)
686 {
687         // TODO : To be implemented
688         return NULL;
689 }
690
691
692 int icd_ioty_unsubscribe_presence(OCDoHandle presence_handle)
693 {
694         // TODO : To be implemented
695         return IOTCON_ERROR_NONE;
696 }
697
698
699 int icd_ioty_start_presence(unsigned int time_to_live)
700 {
701         // TODO : To be implemented
702         return IOTCON_ERROR_NONE;
703 }
704
705
706 int icd_ioty_stop_presence()
707 {
708         // TODO : To be implemented
709         return IOTCON_ERROR_NONE;
710 }