(ACR) remove set_device/platform_info API, hide start/stop_presence API
[platform/core/iot/iotcon.git] / lib / icl-device.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 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <glib.h>
21
22 #include "iotcon.h"
23 #include "ic-utils.h"
24 #include "icl.h"
25 #include "icl-repr.h"
26 #include "icl-dbus.h"
27 #include "icl-dbus-type.h"
28 #include "icl-device.h"
29
30 /**
31  * @brief The maximum length which can be held in a manufacturer name.
32  *
33  * @since_tizen 3.0
34  */
35 #define ICL_MANUFACTURER_NAME_LENGTH_MAX 15
36
37 /**
38  * @brief The maximum length which can be held in a manufacturer url.
39  *
40  * @since_tizen 3.0
41  */
42 #define ICL_MANUFACTURER_URL_LENGTH_MAX 32
43
44
45 typedef struct {
46         iotcon_device_info_cb cb;
47         void *user_data;
48         unsigned int id;
49 } icl_device_info_s;
50
51 typedef struct {
52         iotcon_platform_info_cb cb;
53         void *user_data;
54         unsigned int id;
55 } icl_platform_info_s;
56
57 typedef struct {
58         iotcon_tizen_info_cb cb;
59         void *user_data;
60 } icl_tizen_info_s;
61
62
63 API int iotcon_device_info_get_property(iotcon_device_info_h device_info,
64                 iotcon_device_info_e property, char **value)
65 {
66         RETV_IF(NULL == device_info, IOTCON_ERROR_INVALID_PARAMETER);
67         RETV_IF(NULL == value, IOTCON_ERROR_INVALID_PARAMETER);
68
69         switch (property) {
70         case IOTCON_DEVICE_INFO_NAME:
71                 *value = device_info->device_name;
72                 break;
73         case IOTCON_DEVICE_INFO_SPEC_VER:
74                 *value = device_info->spec_ver;
75                 break;
76         case IOTCON_DEVICE_INFO_ID:
77                 *value = device_info->device_id;
78                 break;
79         case IOTCON_DEVICE_INFO_DATA_MODEL_VER:
80                 *value = device_info->data_model_ver;
81                 break;
82         default:
83                 ERR("Invalid property(%d)", property);
84                 return IOTCON_ERROR_INVALID_PARAMETER;
85         }
86
87         return IOTCON_ERROR_NONE;
88 }
89
90 static void _icl_device_info_cb(GDBusConnection *connection,
91                 const gchar *sender_name,
92                 const gchar *object_path,
93                 const gchar *interface_name,
94                 const gchar *signal_name,
95                 GVariant *parameters,
96                 gpointer user_data)
97 {
98         char *uri_path;
99         struct icl_device_info info = {0};
100         icl_device_info_s *cb_container = user_data;
101         iotcon_device_info_cb cb = cb_container->cb;
102
103         g_variant_get(parameters, "(&s&s&s&s&s)", &uri_path, &info.device_name,
104                         &info.spec_ver, &info.device_id, &info.data_model_ver);
105
106         /* From iotivity, we can get uri_path. But, the value is always "/oic/d". */
107
108         if (cb)
109                 cb(&info, cb_container->user_data);
110 }
111
112
113 API int iotcon_get_device_info(const char *host_address, iotcon_device_info_cb cb,
114                 void *user_data)
115 {
116         GError *error = NULL;
117         unsigned int sub_id;
118         int ret, signal_number;
119         char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
120         icl_device_info_s *cb_container;
121
122         RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
123         RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
124         RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
125
126         signal_number = icl_dbus_generate_signal_number();
127
128         ic_dbus_call_get_device_info_sync(icl_dbus_get_object(), host_address,
129                         signal_number, &ret, NULL, &error);
130         if (error) {
131                 ERR("ic_dbus_call_get_device_info_sync() Fail(%s)", error->message);
132                 ret = icl_dbus_convert_dbus_error(error->code);
133                 g_error_free(error);
134                 return ret;
135         }
136
137         if (IOTCON_ERROR_NONE != ret) {
138                 ERR("iotcon-daemon Fail(%d)", ret);
139                 return icl_dbus_convert_daemon_error(ret);
140         }
141
142         snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_DEVICE,
143                         signal_number);
144
145         cb_container = calloc(1, sizeof(icl_device_info_s));
146         if (NULL == cb_container) {
147                 ERR("calloc() Fail(%d)", errno);
148                 return IOTCON_ERROR_OUT_OF_MEMORY;
149         }
150
151         cb_container->cb = cb;
152         cb_container->user_data = user_data;
153
154         sub_id = icl_dbus_subscribe_signal(signal_name, cb_container, free,
155                         _icl_device_info_cb);
156         if (0 == sub_id) {
157                 ERR("icl_dbus_subscribe_signal() Fail");
158                 free(cb_container);
159                 return IOTCON_ERROR_DBUS;
160         }
161
162         cb_container->id = sub_id;
163
164         return ret;
165 }
166
167 API int iotcon_platform_info_get_property(iotcon_platform_info_h platform_info,
168                 iotcon_platform_info_e property, char **value)
169 {
170         RETV_IF(NULL == platform_info, IOTCON_ERROR_INVALID_PARAMETER);
171         RETV_IF(NULL == value, IOTCON_ERROR_INVALID_PARAMETER);
172
173         switch (property) {
174         case IOTCON_PLATFORM_INFO_ID:
175                 *value = platform_info->platform_id;
176                 break;
177         case IOTCON_PLATFORM_INFO_MANUF_NAME:
178                 *value = platform_info->manuf_name;
179                 break;
180         case IOTCON_PLATFORM_INFO_MANUF_URL:
181                 *value = platform_info->manuf_url;
182                 break;
183         case IOTCON_PLATFORM_INFO_MODEL_NUMBER:
184                 *value = platform_info->model_number;
185                 break;
186         case IOTCON_PLATFORM_INFO_DATE_OF_MANUF:
187                 *value = platform_info->date_of_manuf;
188                 break;
189         case IOTCON_PLATFORM_INFO_PLATFORM_VER:
190                 *value = platform_info->platform_ver;
191                 break;
192         case IOTCON_PLATFORM_INFO_OS_VER:
193                 *value = platform_info->os_ver;
194                 break;
195         case IOTCON_PLATFORM_INFO_HARDWARE_VER:
196                 *value = platform_info->hardware_ver;
197                 break;
198         case IOTCON_PLATFORM_INFO_FIRMWARE_VER:
199                 *value = platform_info->firmware_ver;
200                 break;
201         case IOTCON_PLATFORM_INFO_SUPPORT_URL:
202                 *value = platform_info->support_url;
203                 break;
204         case IOTCON_PLATFORM_INFO_SYSTEM_TIME:
205                 *value = platform_info->system_time;
206                 break;
207         default:
208                 ERR("Invalid property(%d)", property);
209                 return IOTCON_ERROR_INVALID_PARAMETER;
210         }
211
212         return IOTCON_ERROR_NONE;
213 }
214
215
216 static void _icl_platform_info_cb(GDBusConnection *connection,
217                 const gchar *sender_name,
218                 const gchar *object_path,
219                 const gchar *interface_name,
220                 const gchar *signal_name,
221                 GVariant *parameters,
222                 gpointer user_data)
223 {
224         char *uri_path;
225         struct icl_platform_info info = {0};
226         icl_platform_info_s *cb_container = user_data;
227         iotcon_platform_info_cb cb = cb_container->cb;
228
229         g_variant_get(parameters, "(&s&s&s&s&s&s&s&s&s&s&s&s)",
230                         &uri_path,
231                         &info.platform_id,
232                         &info.manuf_name,
233                         &info.manuf_url,
234                         &info.model_number,
235                         &info.date_of_manuf,
236                         &info.platform_ver,
237                         &info.os_ver,
238                         &info.hardware_ver,
239                         &info.firmware_ver,
240                         &info.support_url,
241                         &info.system_time);
242
243         /* From iotivity, we can get uri_path. But, the value is always "/oic/p". */
244
245         if (cb)
246                 cb(&info, cb_container->user_data);
247 }
248
249
250 API int iotcon_get_platform_info(const char *host_address, iotcon_platform_info_cb cb,
251                 void *user_data)
252 {
253         GError *error = NULL;
254         unsigned int sub_id;
255         int ret, signal_number;
256         char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
257         icl_platform_info_s *cb_container;
258
259         RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
260         RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
261         RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
262
263         signal_number = icl_dbus_generate_signal_number();
264
265         ic_dbus_call_get_platform_info_sync(icl_dbus_get_object(), host_address,
266                         signal_number, &ret, NULL, &error);
267         if (error) {
268                 ERR("ic_dbus_call_get_platform_info_sync() Fail(%s)", error->message);
269                 ret = icl_dbus_convert_dbus_error(error->code);
270                 g_error_free(error);
271                 return ret;
272         }
273
274         if (IOTCON_ERROR_NONE != ret) {
275                 ERR("iotcon-daemon Fail(%d)", ret);
276                 return icl_dbus_convert_daemon_error(ret);
277         }
278
279         snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_PLATFORM,
280                         signal_number);
281
282         cb_container = calloc(1, sizeof(icl_platform_info_s));
283         if (NULL == cb_container) {
284                 ERR("calloc() Fail(%d)", errno);
285                 return IOTCON_ERROR_OUT_OF_MEMORY;
286         }
287
288         cb_container->cb = cb;
289         cb_container->user_data = user_data;
290
291         sub_id = icl_dbus_subscribe_signal(signal_name, cb_container, free,
292                         _icl_platform_info_cb);
293         if (0 == sub_id) {
294                 ERR("icl_dbus_subscribe_signal() Fail");
295                 free(cb_container);
296                 return IOTCON_ERROR_DBUS;
297         }
298
299         cb_container->id = sub_id;
300
301         return ret;
302 }
303
304
305 static void _icl_tizen_info_cb(GObject *object, GAsyncResult *g_async_res,
306                 gpointer user_data)
307 {
308         int res;
309         GVariant *result;
310         char *device_name;
311         char *tizen_device_id;
312         GError *error = NULL;
313         struct icl_tizen_info info = {0};
314         icl_tizen_info_s *cb_container = user_data;
315         iotcon_tizen_info_cb cb = cb_container->cb;
316
317         ic_dbus_call_get_tizen_info_finish(IC_DBUS(object), &result, g_async_res, &error);
318         if (error) {
319                 ERR("ic_dbus_call_get_tizen_info_finish() Fail(%s)", error->message);
320                 g_error_free(error);
321                 cb(&info, IOTCON_ERROR_DBUS, cb_container->user_data);
322                 /* TODO contain time out error */
323                 free(cb_container);
324                 return;
325         }
326
327         g_variant_get(result, "(&s&si)", &device_name, &tizen_device_id, &res);
328
329         if (IOTCON_ERROR_NONE == res && NULL != ic_utils_dbus_decode_str(tizen_device_id)) {
330                 info.device_name = ic_utils_dbus_decode_str(device_name);
331                 info.tizen_device_id = tizen_device_id;
332         }
333
334         if (cb)
335                 cb(&info, res, cb_container->user_data);
336
337         free(cb_container);
338 }
339
340
341 API int iotcon_get_tizen_info(const char *host_address, iotcon_tizen_info_cb cb,
342                 void *user_data)
343 {
344         icl_tizen_info_s *cb_container;
345
346         RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
347         RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
348         RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
349
350         cb_container = calloc(1, sizeof(icl_tizen_info_s));
351         if (NULL == cb_container) {
352                 ERR("calloc() Fail(%d)", errno);
353                 return IOTCON_ERROR_OUT_OF_MEMORY;
354         }
355
356         cb_container->cb = cb;
357         cb_container->user_data = user_data;
358
359         ic_dbus_call_get_tizen_info(icl_dbus_get_object(), host_address, NULL,
360                         _icl_tizen_info_cb, cb_container);
361
362         return IOTCON_ERROR_NONE;
363 }
364
365
366 API int iotcon_tizen_info_get_property(iotcon_tizen_info_h tizen_info,
367                 iotcon_tizen_info_e property, char **value)
368 {
369         RETV_IF(NULL == tizen_info, IOTCON_ERROR_INVALID_PARAMETER);
370         RETV_IF(NULL == value, IOTCON_ERROR_INVALID_PARAMETER);
371
372         switch (property) {
373         case IOTCON_TIZEN_INFO_DEVICE_NAME:
374                 *value = tizen_info->device_name;
375                 break;
376         case IOTCON_TIZEN_INFO_TIZEN_DEVICE_ID:
377                 *value = tizen_info->tizen_device_id;
378                 break;
379         default:
380                 ERR("Invalid property(%d)", property);
381                 return IOTCON_ERROR_INVALID_PARAMETER;
382         }
383
384         return IOTCON_ERROR_NONE;
385 }