revise
[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
29 /**
30  * @brief The maximum length which can be held in a manufacturer name.
31  *
32  * @since_tizen 3.0
33  */
34 #define ICL_MANUFACTURER_NAME_LENGTH_MAX 15
35
36 /**
37  * @brief The maximum length which can be held in a manufacturer url.
38  *
39  * @since_tizen 3.0
40  */
41 #define ICL_MANUFACTURER_URL_LENGTH_MAX 32
42
43
44 typedef struct {
45         iotcon_device_info_cb cb;
46         void *user_data;
47         unsigned int id;
48 } icl_device_info_s;
49
50 typedef struct {
51         iotcon_platform_info_cb cb;
52         void *user_data;
53         unsigned int id;
54 } icl_platform_info_s;
55
56
57 API int iotcon_register_device_info(const char *device_name)
58 {
59         int ret;
60         GError *error = NULL;
61         GVariant *arg_info;
62
63         RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
64         RETV_IF(NULL == device_name, IOTCON_ERROR_INVALID_PARAMETER);
65
66         arg_info = icl_dbus_device_info_to_gvariant(device_name);
67         ic_dbus_call_register_device_info_sync(icl_dbus_get_object(), arg_info, &ret,
68                         NULL, &error);
69         if (error) {
70                 ERR("ic_dbus_call_register_device_info_sync() Fail(%s)", error->message);
71                 ret = icl_dbus_convert_dbus_error(error->code);
72                 g_error_free(error);
73                 g_variant_unref(arg_info);
74                 return ret;
75         }
76
77         if (IOTCON_ERROR_NONE != ret) {
78                 ERR("iotcon-daemon Fail(%d)", ret);
79                 return icl_dbus_convert_daemon_error(ret);
80         }
81
82         return ret;
83 }
84
85
86 static void _icl_device_info_cb(GDBusConnection *connection,
87                 const gchar *sender_name,
88                 const gchar *object_path,
89                 const gchar *interface_name,
90                 const gchar *signal_name,
91                 GVariant *parameters,
92                 gpointer user_data)
93 {
94         icl_device_info_s *cb_container = user_data;
95         iotcon_device_info_cb cb = cb_container->cb;
96         char *device_name, *sid, *spec_version, *data_model_version;
97
98         g_variant_get(parameters, "(&s&s&s&s)", &device_name, &sid, &spec_version,
99                         &data_model_version);
100
101         if (cb)
102                 cb(device_name, sid, spec_version, data_model_version, cb_container->user_data);
103 }
104
105
106 API int iotcon_get_device_info(const char *host_address, iotcon_device_info_cb cb,
107                 void *user_data)
108 {
109         GError *error = NULL;
110         unsigned int sub_id;
111         int ret, signal_number;
112         char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
113         icl_device_info_s *cb_container;
114
115         RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
116         RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
117         RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
118
119         signal_number = icl_dbus_generate_signal_number();
120
121         ic_dbus_call_get_device_info_sync(icl_dbus_get_object(), host_address,
122                         signal_number, &ret, NULL, &error);
123         if (error) {
124                 ERR("ic_dbus_call_get_device_info_sync() Fail(%s)", error->message);
125                 ret = icl_dbus_convert_dbus_error(error->code);
126                 g_error_free(error);
127                 return ret;
128         }
129
130         if (IOTCON_ERROR_NONE != ret) {
131                 ERR("iotcon-daemon Fail(%d)", ret);
132                 return icl_dbus_convert_daemon_error(ret);
133         }
134
135         snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_DEVICE,
136                         signal_number);
137
138         cb_container = calloc(1, sizeof(icl_device_info_s));
139         if (NULL == cb_container) {
140                 ERR("calloc() Fail(%d)", errno);
141                 return IOTCON_ERROR_OUT_OF_MEMORY;
142         }
143
144         cb_container->cb = cb;
145         cb_container->user_data = user_data;
146
147         sub_id = icl_dbus_subscribe_signal(signal_name, cb_container, free,
148                         _icl_device_info_cb);
149         if (0 == sub_id) {
150                 ERR("icl_dbus_subscribe_signal() Fail");
151                 free(cb_container);
152                 return IOTCON_ERROR_DBUS;
153         }
154
155         cb_container->id = sub_id;
156
157         return ret;
158 }
159
160
161 /* The length of manufacturer_name should be less than and equal to 16.
162  * The length of manufacturer_url should be less than and equal to 32. */
163 API int iotcon_register_platform_info(iotcon_platform_info_s *platform_info)
164 {
165         int ret;
166         GError *error = NULL;
167         GVariant *arg_info;
168
169         RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
170
171         if (NULL == platform_info->platform_id
172                         || NULL == platform_info->manuf_name
173                         || NULL == platform_info->manuf_url
174                         || NULL == platform_info->model_number
175                         || NULL == platform_info->date_of_manufacture
176                         || NULL == platform_info->platform_ver
177                         || NULL == platform_info->os_ver
178                         || NULL == platform_info->hardware_ver
179                         || NULL == platform_info->firmware_ver
180                         || NULL == platform_info->support_url
181                         || NULL == platform_info->system_time) {
182                 ERR("one of parameter is NULL");
183                 return IOTCON_ERROR_INVALID_PARAMETER;
184         }
185
186         if (platform_info->manuf_name
187                         && (ICL_MANUFACTURER_NAME_LENGTH_MAX < strlen(platform_info->manuf_name))) {
188                 ERR("The length of manufacturer_name(%s) is invalid.", platform_info->manuf_name);
189                 return IOTCON_ERROR_INVALID_PARAMETER;
190         }
191
192         if (platform_info->manuf_url
193                         && (ICL_MANUFACTURER_URL_LENGTH_MAX < strlen(platform_info->manuf_url))) {
194                 ERR("The length of manufacturer_url(%s) is invalid.", platform_info->manuf_url);
195                 return IOTCON_ERROR_INVALID_PARAMETER;
196         }
197
198         arg_info = icl_dbus_platform_info_to_gvariant(platform_info);
199         ic_dbus_call_register_platform_info_sync(icl_dbus_get_object(), arg_info, &ret,
200                         NULL, &error);
201         if (error) {
202                 ERR("ic_dbus_call_register_platform_info_sync() Fail(%s)", error->message);
203                 ret = icl_dbus_convert_dbus_error(error->code);
204                 g_error_free(error);
205                 g_variant_unref(arg_info);
206                 return ret;
207         }
208
209         if (IOTCON_ERROR_NONE != ret) {
210                 ERR("iotcon-daemon Fail(%d)", ret);
211                 return icl_dbus_convert_daemon_error(ret);
212         }
213
214         return ret;
215 }
216
217
218 static void _icl_platform_info_cb(GDBusConnection *connection,
219                 const gchar *sender_name,
220                 const gchar *object_path,
221                 const gchar *interface_name,
222                 const gchar *signal_name,
223                 GVariant *parameters,
224                 gpointer user_data)
225 {
226         char *uri_path;
227         iotcon_platform_info_s *info;
228         icl_platform_info_s *cb_container = user_data;
229         iotcon_platform_info_cb cb = cb_container->cb;
230
231         info = calloc(1, sizeof(iotcon_platform_info_s));
232         if (NULL == info) {
233                 ERR("calloc(client) Fail(%d)", errno);
234                 return;
235         }
236
237         g_variant_get(parameters, "(&s&s&s&s&s&s&s&s&s&s&s&s)",
238                         &uri_path,
239                         &info->platform_id,
240                         &info->manuf_name,
241                         &info->manuf_url,
242                         &info->model_number,
243                         &info->date_of_manufacture,
244                         &info->platform_ver,
245                         &info->os_ver,
246                         &info->hardware_ver,
247                         &info->firmware_ver,
248                         &info->support_url,
249                         &info->system_time);
250
251         /* From iotivity, we can get uri_path. But, the value is always "/oic/p". */
252
253         if (cb)
254                 cb(info, cb_container->user_data);
255
256         free(info);
257 }
258
259
260 API int iotcon_get_platform_info(const char *host_address, iotcon_platform_info_cb cb,
261                 void *user_data)
262 {
263         GError *error = NULL;
264         unsigned int sub_id;
265         int ret, signal_number;
266         char signal_name[IC_DBUS_SIGNAL_LENGTH] = {0};
267         icl_platform_info_s *cb_container;
268
269         RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
270         RETV_IF(NULL == host_address, IOTCON_ERROR_INVALID_PARAMETER);
271         RETV_IF(NULL == cb, IOTCON_ERROR_INVALID_PARAMETER);
272
273         signal_number = icl_dbus_generate_signal_number();
274
275         ic_dbus_call_get_platform_info_sync(icl_dbus_get_object(), host_address,
276                         signal_number, &ret, NULL, &error);
277         if (error) {
278                 ERR("ic_dbus_call_get_platform_info_sync() Fail(%s)", error->message);
279                 ret = icl_dbus_convert_dbus_error(error->code);
280                 g_error_free(error);
281                 return ret;
282         }
283
284         if (IOTCON_ERROR_NONE != ret) {
285                 ERR("iotcon-daemon Fail(%d)", ret);
286                 return icl_dbus_convert_daemon_error(ret);
287         }
288
289         snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_PLATFORM,
290                         signal_number);
291
292         cb_container = calloc(1, sizeof(icl_platform_info_s));
293         if (NULL == cb_container) {
294                 ERR("calloc() Fail(%d)", errno);
295                 return IOTCON_ERROR_OUT_OF_MEMORY;
296         }
297
298         cb_container->cb = cb;
299         cb_container->user_data = user_data;
300
301         sub_id = icl_dbus_subscribe_signal(signal_name, cb_container, free,
302                         _icl_platform_info_cb);
303         if (0 == sub_id) {
304                 ERR("icl_dbus_subscribe_signal() Fail");
305                 free(cb_container);
306                 return IOTCON_ERROR_DBUS;
307         }
308
309         cb_container->id = sub_id;
310
311         return ret;
312 }
313