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.
27 #include "icl-options.h"
29 #include "icl-dbus-type.h"
30 #include "icl-representation.h"
31 #include "icl-response.h"
32 #include "icl-remote-resource.h"
33 #include "icl-payload.h"
36 iotcon_remote_resource_response_cb cb;
38 iotcon_remote_resource_h resource;
41 static GList *icl_crud_cb_list = NULL;
43 void icl_remote_resource_crud_stop(iotcon_remote_resource_h resource)
46 for (c = icl_crud_cb_list; c; c = c->next) {
47 icl_on_response_s *cb_container = c->data;
48 if (NULL == cb_container) {
49 ERR("cb_container is NULL");
52 if (cb_container->resource == resource)
53 cb_container->cb = NULL;
57 static int _icl_parse_crud_gvariant(iotcon_request_type_e request_type,
58 GVariant *gvar, iotcon_response_h *response)
63 GVariantIter *options_iter = NULL;
64 GVariant *repr_gvar = NULL;
65 iotcon_response_h resp = NULL;
66 iotcon_options_h options = NULL;
67 iotcon_representation_h repr = NULL;
69 if (IOTCON_REQUEST_OBSERVE == request_type)
70 g_variant_get(gvar, "(a(qs)vii)", &options_iter, &repr_gvar, &res, &seq_number);
71 else if (IOTCON_REQUEST_DELETE == request_type)
72 g_variant_get(gvar, "(a(qs)i)", &options_iter, &res);
74 g_variant_get(gvar, "(a(qs)vi)", &options_iter, &repr_gvar, &res);
77 if (g_variant_iter_n_children(options_iter)) {
78 unsigned short option_id;
81 ret = iotcon_options_create(&options);
82 if (IOTCON_ERROR_NONE != ret) {
83 ERR("iotcon_options_create() Fail(%d)", ret);
86 while (g_variant_iter_loop(options_iter, "(q&s)", &option_id, &option_data))
87 iotcon_options_add(options, option_id, option_data);
89 g_variant_iter_free(options_iter);
93 repr = icl_representation_from_gvariant(repr_gvar);
95 ERR("icl_representation_from_gvariant() Fail");
97 iotcon_options_destroy(options);
98 return IOTCON_ERROR_SYSTEM;
102 res = icl_dbus_convert_daemon_error(res);
104 resp = calloc(1, sizeof(struct icl_resource_response));
106 ERR("calloc() Fail(%d)", errno);
108 iotcon_representation_destroy(repr);
110 iotcon_options_destroy(options);
111 return IOTCON_ERROR_OUT_OF_MEMORY;
115 resp->header_options = options;
116 resp->seq_number = seq_number;
120 return IOTCON_ERROR_NONE;
123 static void _icl_on_crud_cb(iotcon_request_type_e request_type,
124 GObject *object, GAsyncResult *g_async_res, icl_on_response_s *cb_container)
127 iotcon_response_h response = NULL;
129 GError *error = NULL;
131 RET_IF(NULL == cb_container);
133 icl_crud_cb_list = g_list_remove(icl_crud_cb_list, cb_container);
135 switch (request_type) {
136 case IOTCON_REQUEST_GET:
137 ic_dbus_call_get_finish(IC_DBUS(object), &result, g_async_res, &error);
139 case IOTCON_REQUEST_PUT:
140 ic_dbus_call_put_finish(IC_DBUS(object), &result, g_async_res, &error);
142 case IOTCON_REQUEST_POST:
143 ic_dbus_call_post_finish(IC_DBUS(object), &result, g_async_res, &error);
145 case IOTCON_REQUEST_DELETE:
146 ic_dbus_call_delete_finish(IC_DBUS(object), &result, g_async_res, &error);
149 ERR("Invalid type(%d)", request_type);
154 ERR("ic_dbus_call_finish() Fail(%d, %s)", request_type, error->message);
155 if (cb_container->cb) {
156 int ret = icl_dbus_convert_dbus_error(error->code);
157 cb_container->cb(cb_container->resource, ret, request_type, NULL,
158 cb_container->user_data);
165 ret = _icl_parse_crud_gvariant(request_type, result, &response);
166 if (IOTCON_ERROR_NONE != ret) {
167 ERR("_icl_parse_crud_gvariant() Fail(%s)", ret);
168 if (cb_container->cb) {
169 cb_container->cb(cb_container->resource, ret, request_type, NULL,
170 cb_container->user_data);
175 if (cb_container->cb)
176 cb_container->cb(cb_container->resource, IOTCON_ERROR_NONE, request_type,
177 response, cb_container->user_data);
180 iotcon_response_destroy(response);
186 static void _icl_on_get_cb(GObject *object, GAsyncResult *g_async_res,
189 _icl_on_crud_cb(IOTCON_REQUEST_GET, object, g_async_res, user_data);
193 static void _icl_on_put_cb(GObject *object, GAsyncResult *g_async_res,
196 _icl_on_crud_cb(IOTCON_REQUEST_PUT, object, g_async_res, user_data);
200 static void _icl_on_post_cb(GObject *object, GAsyncResult *g_async_res,
203 _icl_on_crud_cb(IOTCON_REQUEST_POST, object, g_async_res, user_data);
207 API int iotcon_remote_resource_get(iotcon_remote_resource_h resource,
208 iotcon_query_h query, iotcon_remote_resource_response_cb cb, void *user_data)
211 GVariant *arg_remote_resource;
212 icl_on_response_s *cb_container;
214 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
215 RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
216 RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
218 cb_container = calloc(1, sizeof(icl_on_response_s));
219 if (NULL == cb_container) {
220 ERR("calloc() Fail(%d)", errno);
221 return IOTCON_ERROR_OUT_OF_MEMORY;
224 cb_container->resource = resource;
225 cb_container->cb = cb;
226 cb_container->user_data = user_data;
228 arg_remote_resource = icl_dbus_remote_resource_to_gvariant(resource);
229 arg_query = icl_dbus_query_to_gvariant(query);
231 ic_dbus_call_get(icl_dbus_get_object(), arg_remote_resource, arg_query, NULL,
232 _icl_on_get_cb, cb_container);
234 icl_crud_cb_list = g_list_append(icl_crud_cb_list, cb_container);
236 return IOTCON_ERROR_NONE;
240 API int iotcon_remote_resource_put(iotcon_remote_resource_h resource,
241 iotcon_representation_h repr,
242 iotcon_query_h query,
243 iotcon_remote_resource_response_cb cb,
247 GVariant *arg_remote_resource;
249 icl_on_response_s *cb_container;
251 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
252 RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
253 RETV_IF(NULL == repr, IOTCON_ERROR_INVALID_PARAMETER);
254 RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
256 cb_container = calloc(1, sizeof(icl_on_response_s));
257 if (NULL == cb_container) {
258 ERR("calloc() Fail(%d)", errno);
259 return IOTCON_ERROR_OUT_OF_MEMORY;
262 cb_container->resource = resource;
263 cb_container->cb = cb;
264 cb_container->user_data = user_data;
266 arg_repr = icl_representation_to_gvariant(repr);
267 if (NULL == arg_repr) {
268 ERR("icl_representation_to_gvariant() Fail");
270 return IOTCON_ERROR_REPRESENTATION;
273 arg_remote_resource = icl_dbus_remote_resource_to_gvariant(resource);
274 arg_query = icl_dbus_query_to_gvariant(query);
276 ic_dbus_call_put(icl_dbus_get_object(), arg_remote_resource, arg_repr, arg_query,
277 NULL, _icl_on_put_cb, cb_container);
279 icl_crud_cb_list = g_list_append(icl_crud_cb_list, cb_container);
281 return IOTCON_ERROR_NONE;
285 API int iotcon_remote_resource_post(iotcon_remote_resource_h resource,
286 iotcon_representation_h repr,
287 iotcon_query_h query,
288 iotcon_remote_resource_response_cb cb,
293 GVariant *arg_remote_resource;
294 icl_on_response_s *cb_container;
296 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
297 RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
298 RETV_IF(NULL == repr, IOTCON_ERROR_INVALID_PARAMETER);
299 RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
301 cb_container = calloc(1, sizeof(icl_on_response_s));
302 if (NULL == cb_container) {
303 ERR("calloc() Fail(%d)", errno);
304 return IOTCON_ERROR_OUT_OF_MEMORY;
307 cb_container->resource = resource;
308 cb_container->cb = cb;
309 cb_container->user_data = user_data;
311 arg_repr = icl_representation_to_gvariant(repr);
312 if (NULL == arg_repr) {
313 ERR("icl_representation_to_gvariant() Fail");
315 return IOTCON_ERROR_REPRESENTATION;
318 arg_remote_resource = icl_dbus_remote_resource_to_gvariant(resource);
319 arg_query = icl_dbus_query_to_gvariant(query);
321 ic_dbus_call_post(icl_dbus_get_object(), arg_remote_resource, arg_repr, arg_query,
322 NULL, _icl_on_post_cb, cb_container);
324 icl_crud_cb_list = g_list_append(icl_crud_cb_list, cb_container);
326 return IOTCON_ERROR_NONE;
330 static void _icl_on_delete_cb(GObject *object, GAsyncResult *g_async_res,
333 _icl_on_crud_cb(IOTCON_REQUEST_DELETE, object, g_async_res, user_data);
337 API int iotcon_remote_resource_delete(iotcon_remote_resource_h resource,
338 iotcon_remote_resource_response_cb cb, void *user_data)
340 GVariant *arg_remote_resource;
341 icl_on_response_s *cb_container;
343 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
344 RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
345 RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
347 cb_container = calloc(1, sizeof(icl_on_response_s));
348 if (NULL == cb_container) {
349 ERR("calloc() Fail(%d)", errno);
350 return IOTCON_ERROR_OUT_OF_MEMORY;
353 cb_container->resource = resource;
354 cb_container->cb = cb;
355 cb_container->user_data = user_data;
357 arg_remote_resource = icl_dbus_remote_resource_to_gvariant(resource);
359 ic_dbus_call_delete(icl_dbus_get_object(), arg_remote_resource, NULL,
360 _icl_on_delete_cb, cb_container);
362 icl_crud_cb_list = g_list_append(icl_crud_cb_list, cb_container);
364 return IOTCON_ERROR_NONE;
367 static void _icl_on_observe_cb(GDBusConnection *connection,
368 const gchar *sender_name,
369 const gchar *object_path,
370 const gchar *interface_name,
371 const gchar *signal_name,
372 GVariant *parameters,
376 iotcon_response_h response = NULL;
377 icl_on_response_s *cb_container = user_data;
379 RET_IF(NULL == cb_container);
381 ret = _icl_parse_crud_gvariant(IOTCON_REQUEST_OBSERVE, parameters, &response);
382 if (IOTCON_ERROR_NONE != ret) {
383 ERR("_icl_parse_crud_gvariant() Fail(%d)", ret);
384 if (cb_container->cb) {
385 cb_container->cb(cb_container->resource, ret, IOTCON_REQUEST_OBSERVE, NULL,
386 cb_container->user_data);
391 if (cb_container->cb)
392 cb_container->cb(cb_container->resource, IOTCON_ERROR_NONE, IOTCON_REQUEST_OBSERVE,
393 response, cb_container->user_data);
396 iotcon_response_destroy(response);
400 static void _icl_observe_conn_cleanup(icl_on_response_s *cb_container)
402 cb_container->resource->observe_handle = 0;
403 cb_container->resource->observe_sub_id = 0;
408 int icl_remote_resource_observer_start(iotcon_remote_resource_h resource,
409 iotcon_observe_type_e observe_type,
410 iotcon_query_h query,
411 GDBusSignalCallback sig_handler,
414 unsigned int *sub_id,
415 int64_t *observe_handle)
418 GError *error = NULL;
419 unsigned int signal_number;
420 GVariant *arg_query, *arg_remote_resource;
421 char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
423 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
425 signal_number = icl_dbus_generate_signal_number();
427 arg_remote_resource = icl_dbus_remote_resource_to_gvariant(resource);
428 arg_query = icl_dbus_query_to_gvariant(query);
430 ic_dbus_call_observer_start_sync(icl_dbus_get_object(), arg_remote_resource,
431 observe_type, arg_query, signal_number, observe_handle, NULL, &error);
433 ERR("ic_dbus_call_observer_start_sync() Fail(%s)", error->message);
434 ret = icl_dbus_convert_dbus_error(error->code);
436 g_variant_unref(arg_query);
437 g_variant_unref(arg_remote_resource);
441 if (0 == *observe_handle) {
442 ERR("iotcon-daemon Fail");
443 return IOTCON_ERROR_IOTIVITY;
446 snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_OBSERVE,
449 *sub_id = icl_dbus_subscribe_signal(signal_name, cb_container, cb_free, sig_handler);
451 ERR("icl_dbus_subscribe_signal() Fail");
452 return IOTCON_ERROR_DBUS;
455 return IOTCON_ERROR_NONE;
459 API int iotcon_remote_resource_start_observing(iotcon_remote_resource_h resource,
460 iotcon_observe_type_e observe_type,
461 iotcon_query_h query,
462 iotcon_remote_resource_response_cb cb,
467 int64_t observe_handle;
468 icl_on_response_s *cb_container;
470 RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
471 RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
472 RETV_IF(resource->observe_handle || resource->observe_sub_id, IOTCON_ERROR_ALREADY);
474 cb_container = calloc(1, sizeof(icl_on_response_s));
475 if (NULL == cb_container) {
476 ERR("calloc() Fail(%d)", errno);
477 return IOTCON_ERROR_OUT_OF_MEMORY;
480 cb_container->resource = resource;
481 cb_container->cb = cb;
482 cb_container->user_data = user_data;
484 ret = icl_remote_resource_observer_start(resource,
489 _icl_observe_conn_cleanup,
492 if (IOTCON_ERROR_NONE != ret) {
493 ERR("icl_remote_resource_observer_start() Fail(%d)", ret);
498 resource->observe_sub_id = sub_id;
499 resource->observe_handle = observe_handle;
501 return IOTCON_ERROR_NONE;
505 int icl_remote_resource_stop_observing(iotcon_remote_resource_h resource,
506 iotcon_options_h options, int64_t handle, unsigned int sub_id)
509 GError *error = NULL;
510 GVariant *arg_options;
512 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
514 arg_options = icl_dbus_options_to_gvariant(options);
516 ic_dbus_call_observer_stop_sync(icl_dbus_get_object(), handle, arg_options,
519 ERR("ic_dbus_call_observer_stop_sync() Fail(%s)", error->message);
520 ret = icl_dbus_convert_dbus_error(error->code);
524 if (IOTCON_ERROR_NONE != ret) {
525 ERR("iotcon-daemon Fail(%d)", ret);
526 return icl_dbus_convert_daemon_error(ret);
529 icl_dbus_unsubscribe_signal(resource->observe_sub_id);
531 return IOTCON_ERROR_NONE;
535 API int iotcon_remote_resource_stop_observing(iotcon_remote_resource_h resource)
539 RETV_IF(NULL == resource, IOTCON_ERROR_INVALID_PARAMETER);
540 if (0 == resource->observe_handle) {
541 ERR("It doesn't have a observe_handle");
542 return IOTCON_ERROR_INVALID_PARAMETER;
545 ret = icl_remote_resource_stop_observing(resource, resource->header_options,
546 resource->observe_handle, resource->observe_sub_id);
547 if (IOTCON_ERROR_NONE != ret) {
548 ERR("icl_remote_resource_stop_observing() Fail(%d)", ret);
552 return IOTCON_ERROR_NONE;