add get function for web module
[apps/native/rcc.git] / src / webutil.c
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
4  * Contact: Jin Yoon <jinny.yoon@samsung.com>
5  *          Geunsun Lee <gs86.lee@samsung.com>
6  *          Eunyoung Lee <ey928.lee@samsung.com>
7  *          Junkyu Han <junkyu.han@samsung.com>
8  *          Jeonghoon Park <jh1979.park@samsung.com>
9  *
10  * Licensed under the Flora License, Version 1.1 (the License);
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://floralicense.org/license/
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an AS IS BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */
22
23 #include <stdbool.h>
24 #include <curl/curl.h>
25 #include <glib-object.h>
26 #include <json-glib/json-glib.h>
27 #include "log.h"
28 #include "webutil.h"
29
30 #define URI_PATH_LEN 64
31 #define REQ_CON_TIMEOUT 5L
32
33 typedef struct _wu_json_handle {
34         JsonBuilder *builder;
35         bool is_begin;
36         bool is_end;
37 } wu_json_handle;
38
39 static wu_json_handle Json_h = {NULL, false, false};
40
41 static size_t _post_response_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
42 {
43         size_t res_size = 0;
44
45         res_size = size*nmemb;
46
47         if (res_size > 0)
48                 _I("POST response : %s", ptr);
49         /* What should we do here, if response body has negative message? */
50
51         return res_size;
52 }
53
54 static size_t _get_response_write_callback(void *ptr, size_t size, size_t nmemb, void *data)
55 {
56         size_t res_size = 0;
57         char **received = (char **)data;
58
59         res_size = size*nmemb;
60
61         if (received && res_size > 0)
62                 *received = strndup((char *)ptr, size*nmemb);
63         else
64                 _E("fail to get response [res size : %d]", res_size);
65
66         return res_size;
67 }
68
69 int web_util_noti_init(void)
70 {
71         int ret = 0;
72         CURLcode result;
73         result = curl_global_init(CURL_GLOBAL_DEFAULT);
74         if (result != CURLE_OK) {
75                 _E("curl_global_init() failed: %s",
76                         curl_easy_strerror(result));
77                 ret = -1;
78         }
79         return ret;
80 }
81
82 void web_util_noti_fini(void)
83 {
84         curl_global_cleanup();
85         return;
86 }
87
88 int web_util_noti_post(const char *resource, const char *json_data)
89 {
90         int ret = 0;
91         CURL *curl = NULL;
92         CURLcode response = CURLE_OK;
93         struct curl_slist *headers = NULL;
94
95         retv_if(resource == NULL, -1);
96         retv_if(json_data == NULL, -1);
97
98         _I("server : %s", resource);
99         _I("json_data : %s", json_data);
100
101         curl = curl_easy_init();
102
103         if (!curl) {
104                 _E("fail to init curl");
105                 return -1;
106         }
107
108         headers = curl_slist_append(headers, "Accept: application/json");
109         headers = curl_slist_append(headers, "Content-Type: application/json");
110
111         curl_easy_setopt(curl, CURLOPT_URL, resource);
112         curl_easy_setopt(curl, CURLOPT_POST, 1L);
113         curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
114         curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
115         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _post_response_write_callback);
116         curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, REQ_CON_TIMEOUT);
117
118         response = curl_easy_perform(curl);
119
120         if (response != CURLE_OK) {
121                 _E("curl_easy_perform() failed: %s",
122                         curl_easy_strerror(response));
123                 /* What should we do here, if response is kind of errors? */
124                 ret = -1;
125         }
126
127         curl_slist_free_all(headers);
128         curl_easy_cleanup(curl);
129
130         return ret;
131 }
132
133 int web_util_noti_get(const char *resource, char **res)
134 {
135         int ret = 0;
136         CURL *curl = NULL;
137         CURLcode response = CURLE_OK;
138
139         retv_if(resource == NULL, -1);
140
141         _I("GET to [%s]", resource);
142
143         curl = curl_easy_init();
144
145         if (!curl) {
146                 _E("fail to init curl");
147                 return -1;
148         }
149
150         curl_easy_setopt(curl, CURLOPT_URL, resource);
151         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _get_response_write_callback);
152         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)res);
153         curl_easy_setopt(curl, CURLOPT_USERAGENT, "tizen-iot-agent/1.0");
154         curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, REQ_CON_TIMEOUT);
155
156         response = curl_easy_perform(curl);
157
158         if (response != CURLE_OK) {
159                 _E("curl_easy_perform() failed: %s",
160                 curl_easy_strerror(response));
161                 /* What should we do here, if response is kind of errors? */
162                 ret = -1;
163         }
164
165         curl_easy_cleanup(curl);
166
167         return ret;
168 }
169
170 int web_util_json_init(void)
171 {
172         if (Json_h.builder)
173                 g_object_unref(Json_h.builder);
174
175         Json_h.is_begin = false;
176         Json_h.is_end = false;
177         Json_h.builder = json_builder_new();
178         retv_if(Json_h.builder == NULL, -1);
179
180         return 0;
181 }
182
183 int web_util_json_fini(void)
184 {
185
186         if (Json_h.builder) {
187                 g_object_unref(Json_h.builder);
188                 Json_h.builder = NULL;
189         }
190
191         Json_h.is_begin = false;
192         Json_h.is_end = false;
193
194         return 0;
195 }
196
197 int web_util_json_begin(void)
198 {
199         retv_if(Json_h.builder == NULL, -1);
200         retv_if(Json_h.is_begin == true, -1);
201         retv_if(Json_h.is_end == true, -1);
202
203         Json_h.is_begin = true;
204
205         json_builder_begin_object(Json_h.builder);
206
207         return 0;
208 }
209
210 int web_util_json_end(void)
211 {
212         retv_if(Json_h.builder == NULL, -1);
213         retv_if(Json_h.is_begin == false, -1);
214         retv_if(Json_h.is_end == true, -1);
215
216         json_builder_end_object(Json_h.builder);
217         Json_h.is_end = true;
218
219         return 0;
220 }
221
222 int web_util_json_add_int(const char* key, long long int value)
223 {
224         retv_if(!key, -1);
225
226         if (Json_h.builder == NULL) {
227                 _E("Handle for json is not initialized, call web_util_json_init() first");
228                 return -1;
229         }
230
231         if (Json_h.is_begin == false) {
232                 _E("json object has not begun, call web_util_json_begin() first");
233                 return -1;
234         }
235
236         if (Json_h.is_end == true) {
237                 _E("json object has already ended, call web_util_json_begin() first");
238                 return -1;
239         }
240
241         json_builder_set_member_name(Json_h.builder, key);
242         json_builder_add_int_value(Json_h.builder, value);
243
244         return 0;
245 }
246
247 int web_util_json_add_double(const char* key, double value)
248 {
249         retv_if(!key, -1);
250
251         if (Json_h.builder == NULL) {
252                 _E("Handle for json is not initialized, call web_util_json_init() first");
253                 return -1;
254         }
255
256         if (Json_h.is_begin == false) {
257                 _E("json object has not begun, call web_util_json_begin() first");
258                 return -1;
259         }
260
261         if (Json_h.is_end == true) {
262                 _E("json object has already ended, call web_util_json_begin() first");
263                 return -1;
264         }
265
266         json_builder_set_member_name(Json_h.builder, key);
267         json_builder_add_double_value(Json_h.builder, value);
268
269         return 0;
270 }
271
272 int web_util_json_add_boolean(const char* key, bool value)
273 {
274         retv_if(!key, -1);
275
276         if (Json_h.builder == NULL) {
277                 _E("Handle for json is not initialized, call web_util_json_init() first");
278                 return -1;
279         }
280
281         if (Json_h.is_begin == false) {
282                 _E("json object has not begun, call web_util_json_begin() first");
283                 return -1;
284         }
285
286         if (Json_h.is_end == true) {
287                 _E("json object has already ended, call web_util_json_begin() first");
288                 return -1;
289         }
290
291         json_builder_set_member_name(Json_h.builder, key);
292         json_builder_add_boolean_value(Json_h.builder, value);
293
294         return 0;
295 }
296
297 int web_util_json_add_string(const char* key, const char *value)
298 {
299         retv_if(!key, -1);
300
301         if (Json_h.builder == NULL) {
302                 _E("Handle for json is not initialized, call web_util_json_init() first");
303                 return -1;
304         }
305
306         if (Json_h.is_begin == false) {
307                 _E("json object has not begun, call web_util_json_begin() first");
308                 return -1;
309         }
310
311         if (Json_h.is_end == true) {
312                 _E("json object has already ended, call web_util_json_begin() first");
313                 return -1;
314         }
315
316         json_builder_set_member_name(Json_h.builder, key);
317         json_builder_add_string_value(Json_h.builder, value);
318
319         return 0;
320 }
321
322 int web_util_json_data_array_begin(void)
323 {
324         int ret = 0;
325         retv_if(Json_h.builder == NULL, -1);
326
327         ret = web_util_json_begin();
328         retv_if(ret, -1);
329
330         json_builder_set_member_name(Json_h.builder, "SensorDataList");
331         json_builder_begin_array(Json_h.builder);
332
333         return 0;
334 }
335
336 int web_util_json_data_array_end(void)
337 {
338         retv_if(Json_h.builder == NULL, -1);
339         retv_if(Json_h.is_begin == false, -1);
340         retv_if(Json_h.is_end == true, -1);
341
342         json_builder_end_array(Json_h.builder);
343         web_util_json_end();
344
345         return 0;
346 }
347
348 int web_util_json_add_sensor_data(const char* sensorpi_id, web_util_sensor_data_s *sensor_data)
349 {
350         const char n_id[] = "SensorPiID";
351         const char n_motion[] = "Motion";
352         const char n_flame[] = "Flame";
353         const char n_hum[] = "Humidity";
354         const char n_temp[] = "Temperature";
355         const char n_vib[] = "Vibration";
356         const char n_co2[] = "CO2";
357         const char n_sound[] = "SoundLevel";
358         const char n_tilt[] = "Tilt";
359         const char n_light[] = "Light";
360         const char n_collision[] = "Collision";
361         const char n_obstacle[] = "Obstacle";
362         const char n_distance[] = "Distance";
363         const char n_rain[] = "Rain";
364         const char n_touch[] = "Touch";
365         const char n_gas[] = "Gas";
366         const char n_e_sensor[] = "SensorEnabled";
367         const char n_hash[] = "Hash";
368
369         retv_if(!sensorpi_id, -1);
370         retv_if(Json_h.builder == NULL, -1);
371         retv_if(Json_h.is_begin == false, -1);
372         retv_if(Json_h.is_end == true, -1);
373         retv_if(sensor_data == NULL, -1);
374
375         /* JSON structure :
376         {
377                 SensorPiID: string,
378                 Motion: boolean,
379                 Flame: boolean,
380                 Humidity: double,
381                 Temperature: double,
382                 Vibration: boolean,
383                 CO2: double,
384                 SoundLevel: int,
385                 Tilt: int,
386                 Light: int,
387                 Collision: int,
388                 Obstacle: int,
389                 Distance: double,
390                 Rain: int,
391                 Touch: int,
392                 Gas: int,
393                 SensorEnabled: [Motion, ],
394                 Hash: string,
395         }
396         */
397
398
399         json_builder_begin_object(Json_h.builder);
400
401         json_builder_set_member_name(Json_h.builder, n_id);
402         json_builder_add_string_value(Json_h.builder, sensorpi_id);
403
404         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION) {
405                 json_builder_set_member_name(Json_h.builder, n_motion);
406                 json_builder_add_int_value(Json_h.builder, sensor_data->motion);
407         }
408
409         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME) {
410                 json_builder_set_member_name(Json_h.builder, n_flame);
411                 json_builder_add_int_value(Json_h.builder, sensor_data->flame);
412         }
413
414         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY) {
415                 json_builder_set_member_name(Json_h.builder, n_hum);
416                 json_builder_add_double_value(Json_h.builder, sensor_data->humidity);
417         }
418
419         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE) {
420                 json_builder_set_member_name(Json_h.builder, n_temp);
421                 json_builder_add_double_value(Json_h.builder, sensor_data->temperature);
422         }
423
424         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB) {
425                 json_builder_set_member_name(Json_h.builder, n_vib);
426                 json_builder_add_int_value(Json_h.builder, sensor_data->virbration);
427         }
428
429         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2) {
430                 json_builder_set_member_name(Json_h.builder, n_co2);
431                 json_builder_add_double_value(Json_h.builder, sensor_data->co2);
432         }
433
434         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND) {
435                 json_builder_set_member_name(Json_h.builder, n_sound);
436                 json_builder_add_int_value(Json_h.builder, sensor_data->soundlevel);
437         }
438
439         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TILT) {
440                 json_builder_set_member_name(Json_h.builder, n_tilt);
441                 json_builder_add_int_value(Json_h.builder, sensor_data->tilt);
442         }
443
444         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_LIGHT) {
445                 json_builder_set_member_name(Json_h.builder, n_light);
446                 json_builder_add_int_value(Json_h.builder, sensor_data->light);
447         }
448
449         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_COLLISION) {
450                 json_builder_set_member_name(Json_h.builder, n_collision);
451                 json_builder_add_int_value(Json_h.builder, sensor_data->collision);
452         }
453
454         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_OBSTACLE) {
455                 json_builder_set_member_name(Json_h.builder, n_obstacle);
456                 json_builder_add_int_value(Json_h.builder, sensor_data->obstacle);
457         }
458
459         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_ULTRASONIC_DISTANCE) {
460                 json_builder_set_member_name(Json_h.builder, n_distance);
461                 json_builder_add_double_value(Json_h.builder, sensor_data->distance);
462         }
463
464         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_RAIN) {
465                 json_builder_set_member_name(Json_h.builder, n_rain);
466                 json_builder_add_int_value(Json_h.builder, sensor_data->rain);
467         }
468
469         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TOUCH) {
470                 json_builder_set_member_name(Json_h.builder, n_touch);
471                 json_builder_add_int_value(Json_h.builder, sensor_data->touch);
472         }
473
474         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_GAS) {
475                 json_builder_set_member_name(Json_h.builder, n_gas);
476                 json_builder_add_int_value(Json_h.builder, sensor_data->gas);
477         }
478
479         json_builder_set_member_name(Json_h.builder, n_e_sensor);
480         json_builder_begin_array(Json_h.builder);
481
482         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION)
483                 json_builder_add_string_value(Json_h.builder, n_motion);
484
485         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME)
486                 json_builder_add_string_value(Json_h.builder, n_flame);
487
488         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY)
489                 json_builder_add_string_value(Json_h.builder, n_hum);
490
491         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE)
492                 json_builder_add_string_value(Json_h.builder, n_temp);
493
494         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB)
495                 json_builder_add_string_value(Json_h.builder, n_vib);
496
497         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2)
498                 json_builder_add_string_value(Json_h.builder, n_co2);
499
500         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND)
501                 json_builder_add_string_value(Json_h.builder, n_sound);
502
503         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TILT)
504                 json_builder_add_string_value(Json_h.builder, n_tilt);
505
506         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_LIGHT)
507                 json_builder_add_string_value(Json_h.builder, n_light);
508
509         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_COLLISION)
510                 json_builder_add_string_value(Json_h.builder, n_collision);
511
512         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_OBSTACLE)
513                 json_builder_add_string_value(Json_h.builder, n_obstacle);
514
515         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_ULTRASONIC_DISTANCE)
516                 json_builder_add_string_value(Json_h.builder, n_distance);
517
518         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_RAIN)
519                 json_builder_add_string_value(Json_h.builder, n_rain);
520
521         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TOUCH)
522                 json_builder_add_string_value(Json_h.builder, n_touch);
523
524         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_GAS)
525                 json_builder_add_string_value(Json_h.builder, n_gas);
526
527         json_builder_end_array(Json_h.builder);
528
529         if (sensor_data->hash) {
530                 json_builder_set_member_name(Json_h.builder, n_hash);
531                 json_builder_add_string_value(Json_h.builder, sensor_data->hash);
532         }
533
534         json_builder_end_object(Json_h.builder);
535
536         return 0;
537 }
538
539 char *web_util_get_json_string(void)
540 {
541         JsonGenerator *gen = NULL;
542         JsonNode *root = NULL;
543         char *str = NULL;
544
545         retv_if(Json_h.builder == NULL, NULL);
546         retv_if(Json_h.is_begin == false, NULL);
547         retv_if(Json_h.is_end == false, NULL);
548
549         root = json_builder_get_root(Json_h.builder);
550         retv_if(root == NULL, NULL);
551
552         gen = json_generator_new();
553         goto_if(gen == NULL, error_release_all);
554         json_generator_set_root(gen, root);
555
556         str = json_generator_to_data(gen, NULL);
557
558         return str;
559
560 error_release_all:
561         if (root)
562                 json_node_free(root);
563
564         if (gen)
565                 g_object_unref(gen);
566
567         return NULL;
568 }
569