Iotcon documentation
[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 IOTCON_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 IOTCON_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                 g_error_free(error);
72                 g_variant_unref(arg_info);
73                 return IOTCON_ERROR_DBUS;
74         }
75
76         if (IOTCON_ERROR_NONE != ret) {
77                 ERR("iotcon-daemon Fail(%d)", ret);
78                 return icl_dbus_convert_daemon_error(ret);
79         }
80
81         return ret;
82 }
83
84
85 static void _icl_device_info_cb(GDBusConnection *connection,
86                 const gchar *sender_name,
87                 const gchar *object_path,
88                 const gchar *interface_name,
89                 const gchar *signal_name,
90                 GVariant *parameters,
91                 gpointer user_data)
92 {
93         icl_device_info_s *cb_container = user_data;
94         iotcon_device_info_cb cb = cb_container->cb;
95         char *device_name, *sid, *spec_version, *data_model_version;
96
97         g_variant_get(parameters, "(&s&s&s&s)", &device_name, &sid, &spec_version,
98                         &data_model_version);
99
100         if (cb)
101                 cb(device_name, sid, spec_version, data_model_version, cb_container->user_data);
102 }
103
104
105 API int iotcon_get_device_info(const char *host_address, iotcon_device_info_cb cb,
106                 void *user_data)
107 {
108         int ret;
109         GError *error = NULL;
110         unsigned int sub_id;
111         int 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                 g_error_free(error);
126                 return IOTCON_ERROR_DBUS;
127         }
128
129         if (IOTCON_ERROR_NONE != ret) {
130                 ERR("iotcon-daemon Fail(%d)", ret);
131                 return icl_dbus_convert_daemon_error(ret);
132         }
133
134         snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_DEVICE,
135                         signal_number);
136
137         cb_container = calloc(1, sizeof(icl_device_info_s));
138         if (NULL == cb_container) {
139                 ERR("calloc() Fail(%d)", errno);
140                 return IOTCON_ERROR_OUT_OF_MEMORY;
141         }
142
143         cb_container->cb = cb;
144         cb_container->user_data = user_data;
145
146         sub_id = icl_dbus_subscribe_signal(signal_name, cb_container, free,
147                         _icl_device_info_cb);
148         if (0 == sub_id) {
149                 ERR("icl_dbus_subscribe_signal() Fail");
150                 return IOTCON_ERROR_DBUS;
151         }
152
153         cb_container->id = sub_id;
154
155         return ret;
156 }
157
158
159 /* The length of manufacturer_name should be less than and equal to 16.
160  * The length of manufacturer_url should be less than and equal to 32. */
161 API int iotcon_register_platform_info(iotcon_platform_info_s platform_info)
162 {
163         int ret;
164         GError *error = NULL;
165         GVariant *arg_info;
166
167         RETV_IF(NULL == icl_dbus_get_object(), IOTCON_ERROR_DBUS);
168
169         if (NULL == platform_info.platform_id
170                         || NULL == platform_info.manuf_name
171                         || NULL == platform_info.manuf_url
172                         || NULL == platform_info.model_number
173                         || NULL == platform_info.date_of_manufacture
174                         || NULL == platform_info.platform_ver
175                         || NULL == platform_info.os_ver
176                         || NULL == platform_info.hardware_ver
177                         || NULL == platform_info.firmware_ver
178                         || NULL == platform_info.support_url
179                         || NULL == platform_info.system_time) {
180                 ERR("one of parameter is NULL");
181                 return IOTCON_ERROR_INVALID_PARAMETER;
182         }
183
184         if (platform_info.manuf_name
185                         && (IOTCON_MANUFACTURER_NAME_LENGTH_MAX < strlen(platform_info.manuf_name))) {
186                 ERR("The length of manufacturer_name(%s) is invalid.", platform_info.manuf_name);
187                 return IOTCON_ERROR_INVALID_PARAMETER;
188         }
189
190         if (platform_info.manuf_url
191                         && (IOTCON_MANUFACTURER_URL_LENGTH_MAX < strlen(platform_info.manuf_url))) {
192                 ERR("The length of manufacturer_url(%s) is invalid.", platform_info.manuf_url);
193                 return IOTCON_ERROR_INVALID_PARAMETER;
194         }
195
196         arg_info = icl_dbus_platform_info_to_gvariant(&platform_info);
197         ic_dbus_call_register_platform_info_sync(icl_dbus_get_object(), arg_info, &ret,
198                         NULL, &error);
199         if (error) {
200                 ERR("ic_dbus_call_register_platform_info_sync() Fail(%s)", error->message);
201                 g_error_free(error);
202                 g_variant_unref(arg_info);
203                 return IOTCON_ERROR_DBUS;
204         }
205
206         if (IOTCON_ERROR_NONE != ret) {
207                 ERR("iotcon-daemon Fail(%d)", ret);
208                 return icl_dbus_convert_daemon_error(ret);
209         }
210
211         return ret;
212 }
213
214
215 static void _icl_platform_info_cb(GDBusConnection *connection,
216                 const gchar *sender_name,
217                 const gchar *object_path,
218                 const gchar *interface_name,
219                 const gchar *signal_name,
220                 GVariant *parameters,
221                 gpointer user_data)
222 {
223         char *uri_path;
224         iotcon_platform_info_s info = {0};
225         icl_platform_info_s *cb_container = user_data;
226         iotcon_platform_info_cb cb = cb_container->cb;
227
228         g_variant_get(parameters, "(&s&s&s&s&s&s&s&s&s&s&s&s)",
229                         &uri_path,
230                         &info.platform_id,
231                         &info.manuf_name,
232                         &info.manuf_url,
233                         &info.model_number,
234                         &info.date_of_manufacture,
235                         &info.platform_ver,
236                         &info.os_ver,
237                         &info.hardware_ver,
238                         &info.firmware_ver,
239                         &info.support_url,
240                         &info.system_time);
241
242         /* From iotivity, we can get uri_path. But, the value is always "/oic/p". */
243
244         if (cb)
245                 cb(info, cb_container->user_data);
246 }
247
248
249 API int iotcon_get_platform_info(const char *host_address, iotcon_platform_info_cb cb,
250                 void *user_data)
251 {
252         int ret;
253         GError *error = NULL;
254         unsigned int sub_id;
255         int 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                 g_error_free(error);
270                 return IOTCON_ERROR_DBUS;
271         }
272
273         if (IOTCON_ERROR_NONE != ret) {
274                 ERR("iotcon-daemon Fail(%d)", ret);
275                 return icl_dbus_convert_daemon_error(ret);
276         }
277
278         snprintf(signal_name, sizeof(signal_name), "%s_%u", IC_DBUS_SIGNAL_PLATFORM,
279                         signal_number);
280
281         cb_container = calloc(1, sizeof(icl_platform_info_s));
282         if (NULL == cb_container) {
283                 ERR("calloc() Fail(%d)", errno);
284                 return IOTCON_ERROR_OUT_OF_MEMORY;
285         }
286
287         cb_container->cb = cb;
288         cb_container->user_data = user_data;
289
290         sub_id = icl_dbus_subscribe_signal(signal_name, cb_container, free,
291                         _icl_platform_info_cb);
292         if (0 == sub_id) {
293                 ERR("icl_dbus_subscribe_signal() Fail");
294                 return IOTCON_ERROR_DBUS;
295         }
296
297         cb_container->id = sub_id;
298
299         return ret;
300 }