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.
23 #include "iotcon-types.h"
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(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
59 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
60 RETV_IF(ICL_PRESENCE_TTL_SECONDS_MAX < time_to_live, IOTCON_ERROR_INVALID_PARAMETER);
62 ic_dbus_call_start_presence_sync(icl_dbus_get_object(), time_to_live, &ret, NULL,
65 ERR("ic_dbus_call_start_presence_sync() Fail(%s)", error->message);
66 ret = icl_dbus_convert_dbus_error(error->code);
71 if (IOTCON_ERROR_NONE != ret) {
72 ERR("iotcon-daemon Fail(%d)", ret);
73 return icl_dbus_convert_daemon_error(ret);
76 return IOTCON_ERROR_NONE;
80 API int iotcon_stop_presence(void)
86 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
87 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
89 ic_dbus_call_stop_presence_sync(icl_dbus_get_object(), &ret, NULL, &error);
91 ERR("ic_dbus_call_stop_presence_sync() Fail(%s)", error->message);
92 ret = icl_dbus_convert_dbus_error(error->code);
97 if (IOTCON_ERROR_NONE != ret) {
98 ERR("iotcon-daemon Fail(%d)", ret);
99 return icl_dbus_convert_daemon_error(ret);
102 return IOTCON_ERROR_NONE;
106 static void _icl_presence_cb(GDBusConnection *connection,
107 const gchar *sender_name,
108 const gchar *object_path,
109 const gchar *interface_name,
110 const gchar *signal_name,
111 GVariant *parameters,
116 char *host_address, *resource_type;
117 int res, connectivity_type, trigger;
118 icl_presence_s *presence = user_data;
119 iotcon_presence_cb cb = presence->cb;
120 icl_presence_response_s response = {0};
122 g_variant_get(parameters, "(iu&sii&s)", &res, &nonce, &host_address,
123 &connectivity_type, &trigger, &resource_type);
125 response.resource_type = ic_utils_dbus_decode_str(resource_type);
127 if (response.resource_type && presence->resource_type) {
128 if (IC_STR_EQUAL != strcmp(response.resource_type, presence->resource_type))
132 if (res < IOTCON_ERROR_NONE && cb)
133 cb(presence, icl_dbus_convert_daemon_error(res), NULL, presence->user_data);
135 DBG("presence nonce : %u", nonce);
137 response.host_address = host_address;
138 response.connectivity_type = connectivity_type;
139 response.result = res;
140 response.trigger = trigger;
143 cb(presence, IOTCON_ERROR_NONE, &response, presence->user_data);
147 static void _icl_presence_conn_cleanup(icl_presence_s *presence)
149 presence->sub_id = 0;
151 if (presence->handle) {
152 presence->handle = 0;
156 free(presence->resource_type);
157 free(presence->host_address);
162 /* The length of resource_type should be less than or equal to 61. */
163 API int iotcon_add_presence_cb(const char *host_address,
164 iotcon_connectivity_type_e connectivity_type,
165 const char *resource_type,
166 iotcon_presence_cb cb,
168 iotcon_presence_h *presence_handle)
173 GError *error = NULL;
174 icl_presence_s *presence;
175 char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
177 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
178 RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_INVALID_PARAMETER);
179 RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
180 RETV_IF(NULL == presence_handle, IOTCON_ERROR_INVALID_PARAMETER);
182 if (resource_type && (ICL_RESOURCE_TYPE_LENGTH_MAX < strlen(resource_type))) {
183 ERR("The length of resource_type(%s) is invalid", resource_type);
184 return IOTCON_ERROR_INVALID_PARAMETER;
187 if ((IOTCON_MULTICAST_ADDRESS == host_address || '\0' == host_address[0])
188 && (IOTCON_CONNECTIVITY_IPV4 != connectivity_type
189 && IOTCON_CONNECTIVITY_ALL != connectivity_type)) {
190 ERR("Multicast is available only if IPV4");
191 return IOTCON_ERROR_INVALID_PARAMETER;
194 presence = calloc(1, sizeof(icl_presence_s));
195 if (NULL == presence) {
196 ERR("calloc() Fail(%d)", errno);
197 return IOTCON_ERROR_OUT_OF_MEMORY;
200 ic_dbus_call_subscribe_presence_sync(icl_dbus_get_object(),
201 ic_utils_dbus_encode_str(host_address),
203 ic_utils_dbus_encode_str(resource_type),
208 ERR("ic_dbus_call_subscribe_presence_sync() Fail(%s)", error->message);
209 ret = icl_dbus_convert_dbus_error(error->code);
215 if (0 == presence->handle) {
216 ERR("iotcon-daemon Fail");
218 return IOTCON_ERROR_IOTIVITY;
221 snprintf(signal_name, sizeof(signal_name), "%s_%llx", IC_DBUS_SIGNAL_PRESENCE,
225 presence->user_data = user_data;
228 presence->host_address = strdup(host_address);
229 presence->connectivity_type = connectivity_type;
231 presence->resource_type = strdup(resource_type);
233 sub_id = icl_dbus_subscribe_signal(signal_name, presence,
234 _icl_presence_conn_cleanup, _icl_presence_cb);
236 ERR("icl_dbus_subscribe_signal() Fail");
237 free(presence->resource_type);
238 free(presence->host_address);
240 return IOTCON_ERROR_DBUS;
243 presence->sub_id = sub_id;
245 *presence_handle = presence;
247 return IOTCON_ERROR_NONE;
251 API int iotcon_remove_presence_cb(iotcon_presence_h presence)
255 GError *error = NULL;
257 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
258 RETV_IF(NULL == presence, IOTCON_ERROR_INVALID_PARAMETER);
260 if (0 == presence->sub_id) { /* disconnected iotcon dbus */
261 WARN("Invalid Presence handle");
262 free(presence->resource_type);
263 free(presence->host_address);
265 return IOTCON_ERROR_NONE;
268 if (NULL == icl_dbus_get_object()) {
269 ERR("icl_dbus_get_object() return NULL");
270 return IOTCON_ERROR_DBUS;
273 ic_dbus_call_unsubscribe_presence_sync(icl_dbus_get_object(), presence->handle,
274 presence->host_address, &ret, NULL, &error);
276 ERR("ic_dbus_call_unsubscribe_presence_sync() Fail(%s)", error->message);
277 ret = icl_dbus_convert_dbus_error(error->code);
282 if (IOTCON_ERROR_NONE != ret) {
283 ERR("iotcon-daemon Fail(%d)", ret);
284 return icl_dbus_convert_daemon_error(ret);
286 presence->handle = 0;
288 icl_dbus_unsubscribe_signal(presence->sub_id);
289 presence->sub_id = 0;
291 return IOTCON_ERROR_NONE;
295 API int iotcon_presence_get_host_address(iotcon_presence_h presence, char **host_address)
297 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
298 RETV_IF(NULL == presence, IOTCON_ERROR_INVALID_PARAMETER);
299 RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
301 *host_address = presence->host_address;
303 return IOTCON_ERROR_NONE;
307 API int iotcon_presence_get_connectivity_type(iotcon_presence_h presence,
308 iotcon_connectivity_type_e *connectivity_type)
310 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
311 RETV_IF(NULL == presence, IOTCON_ERROR_INVALID_PARAMETER);
312 RETV_IF(NULL == connectivity_type, IOTCON_ERROR_INVALID_PARAMETER);
314 *connectivity_type = presence->connectivity_type;
316 return IOTCON_ERROR_NONE;
320 API int iotcon_presence_get_resource_type(iotcon_presence_h presence,
321 char **resource_type)
323 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
324 RETV_IF(NULL == presence, IOTCON_ERROR_INVALID_PARAMETER);
325 RETV_IF(NULL == resource_type, IOTCON_ERROR_INVALID_PARAMETER);
327 *resource_type = presence->resource_type;
329 return IOTCON_ERROR_NONE;
333 API int iotcon_presence_response_get_host_address(iotcon_presence_response_h response,
336 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
337 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
338 RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
340 *host_address = response->host_address;
342 return IOTCON_ERROR_NONE;
346 API int iotcon_presence_response_get_connectivity_type(
347 iotcon_presence_response_h response, iotcon_connectivity_type_e *connectivity_type)
349 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
350 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
351 RETV_IF(NULL == connectivity_type, IOTCON_ERROR_INVALID_PARAMETER);
353 *connectivity_type = response->connectivity_type;
355 return IOTCON_ERROR_NONE;
359 API int iotcon_presence_response_get_resource_type(iotcon_presence_response_h response,
360 char **resource_type)
362 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
363 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
364 RETV_IF(NULL == resource_type, IOTCON_ERROR_INVALID_PARAMETER);
366 *resource_type = response->resource_type;
368 return IOTCON_ERROR_NONE;
372 API int iotcon_presence_response_get_result(iotcon_presence_response_h response,
373 iotcon_presence_result_e *result)
375 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
376 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
377 RETV_IF(NULL == result, IOTCON_ERROR_INVALID_PARAMETER);
379 *result = response->result;
381 return IOTCON_ERROR_NONE;
385 API int iotcon_presence_response_get_trigger(iotcon_presence_response_h response,
386 iotcon_presence_trigger_e *trigger)
388 RETV_IF(false == ic_utils_check_oic_feature_supported(), IOTCON_ERROR_NOT_SUPPORTED);
389 RETV_IF(NULL == response, IOTCON_ERROR_INVALID_PARAMETER);
390 RETV_IF(NULL == trigger, IOTCON_ERROR_INVALID_PARAMETER);
392 if (IOTCON_PRESENCE_OK != response->result) {
393 ERR("trigger is valid if IOTCON_PRESENCE_OK");
394 return IOTCON_ERROR_INVALID_PARAMETER;
397 *trigger = response->trigger;
399 return IOTCON_ERROR_NONE;