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.
24 #include "iotcon-internal.h"
27 #include "icl-resource-types.h"
30 #define ICL_PRESENCE_TTL_SECONDS_MAX (60 * 60 * 24) /* 60 sec/min * 60 min/hr * 24 hr/day */
32 typedef struct icl_presence {
34 iotcon_connectivity_type_e connectivity_type;
36 iotcon_presence_cb cb;
43 typedef struct icl_presence_response {
45 iotcon_connectivity_type_e connectivity_type;
47 iotcon_presence_result_e result;
48 iotcon_presence_trigger_e trigger;
49 } icl_presence_response_s;
52 API int iotcon_start_presence(unsigned int time_to_live)
58 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
59 RETV_IF(ICL_PRESENCE_TTL_SECONDS_MAX < time_to_live, IOTCON_ERROR_INVALID_PARAMETER);
61 ic_dbus_call_start_presence_sync(icl_dbus_get_object(), time_to_live, &ret, NULL,
64 ERR("ic_dbus_call_start_presence_sync() Fail(%s)", error->message);
65 ret = icl_dbus_convert_dbus_error(error->code);
70 if (IOTCON_ERROR_NONE != ret) {
71 ERR("iotcon-daemon Fail(%d)", ret);
72 return icl_dbus_convert_daemon_error(ret);
75 return IOTCON_ERROR_NONE;
79 API int iotcon_stop_presence(void)
85 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
87 ic_dbus_call_stop_presence_sync(icl_dbus_get_object(), &ret, NULL, &error);
89 ERR("ic_dbus_call_stop_presence_sync() Fail(%s)", error->message);
90 ret = icl_dbus_convert_dbus_error(error->code);
95 if (IOTCON_ERROR_NONE != ret) {
96 ERR("iotcon-daemon Fail(%d)", ret);
97 return icl_dbus_convert_daemon_error(ret);
100 return IOTCON_ERROR_NONE;
104 static void _icl_presence_cb(GDBusConnection *connection,
105 const gchar *sender_name,
106 const gchar *object_path,
107 const gchar *interface_name,
108 const gchar *signal_name,
109 GVariant *parameters,
114 char *host_address, *resource_type;
115 int res, connectivity_type, trigger;
116 icl_presence_s *presence = user_data;
117 iotcon_presence_cb cb = presence->cb;
118 icl_presence_response_s response = {0};
120 g_variant_get(parameters, "(iu&sii&s)", &res, &nonce, &host_address,
121 &connectivity_type, &trigger, &resource_type);
123 if (res < IOTCON_ERROR_NONE && cb)
124 cb(presence, icl_dbus_convert_daemon_error(res), NULL, presence->user_data);
126 DBG("presence nonce : %d", nonce);
128 response.host_address = host_address;
129 response.connectivity_type = connectivity_type;
130 response.resource_type = ic_utils_dbus_decode_str(resource_type);
131 response.result = res;
132 response.trigger = trigger;
135 cb(presence, IOTCON_ERROR_NONE, &response, presence->user_data);
139 static void _icl_presence_conn_cleanup(icl_presence_s *presence)
141 presence->sub_id = 0;
143 if (presence->handle) {
144 presence->handle = 0;
148 free(presence->resource_type);
149 free(presence->host_address);
154 /* The length of resource_type should be less than or equal to 61. */
155 API int iotcon_add_presence_cb(const char *host_address,
156 iotcon_connectivity_type_e connectivity_type,
157 const char *resource_type,
158 iotcon_presence_cb cb,
160 iotcon_presence_h *presence_handle)
163 GError *error = NULL;
165 int signal_number, ret;
166 char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
167 icl_presence_s *presence;
169 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_INVALID_PARAMETER);
170 RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
171 RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
173 if (resource_type && (ICL_RESOURCE_TYPE_LENGTH_MAX < strlen(resource_type))) {
174 ERR("The length of resource_type(%s) is invalid", resource_type);
175 return IOTCON_ERROR_INVALID_PARAMETER;
178 signal_number = icl_dbus_generate_signal_number();
180 presence = calloc(1, sizeof(icl_presence_s));
181 if (NULL == presence) {
182 ERR("calloc() Fail(%d)", errno);
183 return IOTCON_ERROR_OUT_OF_MEMORY;
186 resource_type = ic_utils_dbus_encode_str(resource_type);
188 ic_dbus_call_subscribe_presence_sync(icl_dbus_get_object(),
197 ERR("ic_dbus_call_subscribe_presence_sync() Fail(%s)", error->message);
198 ret = icl_dbus_convert_dbus_error(error->code);
204 if (0 == presence->handle) {
205 ERR("iotcon-daemon Fail");
207 return IOTCON_ERROR_IOTIVITY;
210 snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_PRESENCE,
214 presence->user_data = user_data;
216 presence->host_address = ic_utils_strdup(host_address);
217 presence->connectivity_type = connectivity_type;
219 presence->resource_type = strdup(resource_type);
221 sub_id = icl_dbus_subscribe_signal(signal_name, presence,
222 _icl_presence_conn_cleanup, _icl_presence_cb);
224 ERR("icl_dbus_subscribe_signal() Fail");
225 free(presence->resource_type);
226 free(presence->host_address);
228 return IOTCON_ERROR_DBUS;
231 presence->sub_id = sub_id;
233 *presence_handle = presence;
235 return IOTCON_ERROR_NONE;
239 API int iotcon_remove_presence_cb(iotcon_presence_h presence)
243 GError *error = NULL;
245 RETV_IF(NULL == presence, IOTCON_ERROR_INVALID_PARAMETER);
247 if (0 == presence->sub_id) { /* disconnected iotcon dbus */
248 WARN("Invalid Presence handle");
249 free(presence->resource_type);
250 free(presence->host_address);
252 return IOTCON_ERROR_NONE;
255 if (NULL == icl_dbus_get_object()) {
256 ERR("icl_dbus_get_object() return NULL");
257 return IOTCON_ERROR_DBUS;
260 ic_dbus_call_unsubscribe_presence_sync(icl_dbus_get_object(), presence->handle,
263 ERR("ic_dbus_call_unsubscribe_presence_sync() Fail(%s)", error->message);
264 ret = icl_dbus_convert_dbus_error(error->code);
269 if (IOTCON_ERROR_NONE != ret) {
270 ERR("iotcon-daemon Fail(%d)", ret);
271 return icl_dbus_convert_daemon_error(ret);
273 presence->handle = 0;
275 icl_dbus_unsubscribe_signal(presence->sub_id);
277 return IOTCON_ERROR_NONE;
281 API int iotcon_presence_get_host_address(iotcon_presence_h presence, char **host_address)
283 RETV_IF(NULL == presence, IOTCON_ERROR_INVALID_PARAMETER);
284 RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
286 *host_address = presence->host_address;
288 return IOTCON_ERROR_NONE;
292 API int iotcon_presence_get_connectivity_type(iotcon_presence_h presence,
293 int *connectivity_type)
295 RETV_IF(NULL == presence, IOTCON_ERROR_INVALID_PARAMETER);
296 RETV_IF(NULL == connectivity_type, IOTCON_ERROR_INVALID_PARAMETER);
298 *connectivity_type = presence->connectivity_type;
300 return IOTCON_ERROR_NONE;
304 API int iotcon_presence_get_resource_type(iotcon_presence_h presence,
305 char **resource_type)
307 RETV_IF(NULL == presence, IOTCON_ERROR_INVALID_PARAMETER);
308 RETV_IF(NULL == resource_type, IOTCON_ERROR_INVALID_PARAMETER);
310 *resource_type = presence->resource_type;
312 return IOTCON_ERROR_NONE;
316 API int iotcon_presence_response_get_host_address(iotcon_presence_response_h response,
319 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
320 RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
322 *host_address = response->host_address;
324 return IOTCON_ERROR_NONE;
328 API int iotcon_presence_response_get_connectivity_type(
329 iotcon_presence_response_h response, int *connectivity_type)
331 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
332 RETV_IF(NULL == connectivity_type, IOTCON_ERROR_INVALID_PARAMETER);
334 *connectivity_type = response->connectivity_type;
336 return IOTCON_ERROR_NONE;
340 API int iotcon_presence_response_get_resource_type(iotcon_presence_response_h response,
341 char **resource_type)
343 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
344 RETV_IF(NULL == resource_type, IOTCON_ERROR_INVALID_PARAMETER);
346 *resource_type = response->resource_type;
348 return IOTCON_ERROR_NONE;
352 API int iotcon_presence_response_get_result(iotcon_presence_response_h response,
355 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
356 RETV_IF(NULL == result, IOTCON_ERROR_INVALID_PARAMETER);
358 *result = response->result;
360 return IOTCON_ERROR_NONE;
364 API int iotcon_presence_response_get_trigger(iotcon_presence_response_h response,
367 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
368 RETV_IF(NULL == trigger, IOTCON_ERROR_INVALID_PARAMETER);
370 if (IOTCON_PRESENCE_OK != response->result) {
371 ERR("trigger is valid if IOTCON_PRESENCE_OK");
372 return IOTCON_ERROR_INVALID_PARAMETER;
375 *trigger = response->trigger;
377 return IOTCON_ERROR_NONE;