add new functions for json strings
[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
32 typedef struct _wu_json_handle {
33         JsonBuilder *builder;
34         bool is_begin;
35         bool is_end;
36 } wu_json_handle;
37
38 static wu_json_handle Json_h = {NULL, false, false};
39
40 static size_t _response_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
41 {
42         size_t res_size = 0;
43
44         res_size = size*nmemb;
45
46         if (res_size > 0)
47                 _I("POST response : %s", ptr);
48         /* What should we do here, if response body has negative message? */
49
50         return res_size;
51 }
52
53 int web_util_noti_init(void)
54 {
55         int ret = 0;
56         CURLcode result;
57         result = curl_global_init(CURL_GLOBAL_DEFAULT);
58         if (result != CURLE_OK) {
59                 _E("curl_global_init() failed: %s",
60                         curl_easy_strerror(result));
61                 ret = -1;
62         }
63         return ret;
64 }
65
66 void web_util_noti_fini(void)
67 {
68         curl_global_cleanup();
69         return;
70 }
71
72 int web_util_noti_post(const char *resource, const char *json_data)
73 {
74         int ret = 0;
75         CURL *curl = NULL;
76         CURLcode response = CURLE_OK;
77         struct curl_slist *headers = NULL;
78
79         retv_if(resource == NULL, -1);
80         retv_if(json_data == NULL, -1);
81
82         _I("server : %s", resource);
83         _I("json_data : %s", json_data);
84
85         curl = curl_easy_init();
86
87         if (!curl) {
88                 _E("fail to init curl");
89                 return -1;
90         }
91
92         headers = curl_slist_append(headers, "Accept: application/json");
93         headers = curl_slist_append(headers, "Content-Type: application/json");
94
95         curl_easy_setopt(curl, CURLOPT_URL, resource);
96         curl_easy_setopt(curl, CURLOPT_POST, 1L);
97         curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
98         curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
99         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _response_write_callback);
100
101         response = curl_easy_perform(curl);
102
103         if (response != CURLE_OK) {
104                 _E("curl_easy_perform() failed: %s",
105                         curl_easy_strerror(response));
106                 /* What should we do here, if response is kind of errors? */
107                 ret = -1;
108         }
109
110         curl_slist_free_all(headers);
111         curl_easy_cleanup(curl);
112
113         return ret;
114 }
115
116
117 int web_util_json_init(void)
118 {
119         if (Json_h.builder)
120                 g_object_unref(Json_h.builder);
121
122         Json_h.is_begin = false;
123         Json_h.is_end = false;
124         Json_h.builder = json_builder_new();
125         retv_if(Json_h.builder == NULL, -1);
126
127         return 0;
128 }
129
130 int web_util_json_fini(void)
131 {
132
133         if (Json_h.builder) {
134                 g_object_unref(Json_h.builder);
135                 Json_h.builder = NULL;
136         }
137
138         Json_h.is_begin = false;
139         Json_h.is_end = false;
140
141         return 0;
142 }
143
144 int web_util_json_begin(void)
145 {
146         retv_if(Json_h.builder == NULL, -1);
147         retv_if(Json_h.is_begin == true, -1);
148         retv_if(Json_h.is_end == true, -1);
149
150         Json_h.is_begin = true;
151
152         json_builder_begin_object(Json_h.builder);
153
154         return 0;
155 }
156
157 int web_util_json_end(void)
158 {
159         retv_if(Json_h.builder == NULL, -1);
160         retv_if(Json_h.is_begin == false, -1);
161         retv_if(Json_h.is_end == true, -1);
162
163         json_builder_end_object(Json_h.builder);
164         Json_h.is_end = true;
165
166         return 0;
167 }
168
169 int web_util_json_add_int(const char* key, long long int value)
170 {
171         retv_if(!key, -1);
172
173         if (Json_h.builder == NULL) {
174                 _E("Handle for json is not initialized, call web_util_json_init() first");
175                 return -1;
176         }
177
178         if (Json_h.is_begin == false) {
179                 _E("json object has not begun, call web_util_json_begin() first");
180                 return -1;
181         }
182
183         if (Json_h.is_end == true) {
184                 _E("json object has already ended, call web_util_json_begin() first");
185                 return -1;
186         }
187
188         json_builder_set_member_name(Json_h.builder, key);
189         json_builder_add_int_value(Json_h.builder, value);
190
191         return 0;
192 }
193
194 int web_util_json_add_double(const char* key, double value)
195 {
196         retv_if(!key, -1);
197
198         if (Json_h.builder == NULL) {
199                 _E("Handle for json is not initialized, call web_util_json_init() first");
200                 return -1;
201         }
202
203         if (Json_h.is_begin == false) {
204                 _E("json object has not begun, call web_util_json_begin() first");
205                 return -1;
206         }
207
208         if (Json_h.is_end == true) {
209                 _E("json object has already ended, call web_util_json_begin() first");
210                 return -1;
211         }
212
213         json_builder_set_member_name(Json_h.builder, key);
214         json_builder_add_double_value(Json_h.builder, value);
215
216         return 0;
217 }
218
219 int web_util_json_add_boolean(const char* key, bool value)
220 {
221         retv_if(!key, -1);
222
223         if (Json_h.builder == NULL) {
224                 _E("Handle for json is not initialized, call web_util_json_init() first");
225                 return -1;
226         }
227
228         if (Json_h.is_begin == false) {
229                 _E("json object has not begun, call web_util_json_begin() first");
230                 return -1;
231         }
232
233         if (Json_h.is_end == true) {
234                 _E("json object has already ended, call web_util_json_begin() first");
235                 return -1;
236         }
237
238         json_builder_set_member_name(Json_h.builder, key);
239         json_builder_add_boolean_value(Json_h.builder, value);
240
241         return 0;
242 }
243
244 int web_util_json_add_string(const char* key, const char *value)
245 {
246         retv_if(!key, -1);
247
248         if (Json_h.builder == NULL) {
249                 _E("Handle for json is not initialized, call web_util_json_init() first");
250                 return -1;
251         }
252
253         if (Json_h.is_begin == false) {
254                 _E("json object has not begun, call web_util_json_begin() first");
255                 return -1;
256         }
257
258         if (Json_h.is_end == true) {
259                 _E("json object has already ended, call web_util_json_begin() first");
260                 return -1;
261         }
262
263         json_builder_set_member_name(Json_h.builder, key);
264         json_builder_add_string_value(Json_h.builder, value);
265
266         return 0;
267 }
268
269 int web_util_json_data_array_begin(void)
270 {
271         int ret = 0;
272         retv_if(Json_h.builder == NULL, -1);
273
274         ret = web_util_json_begin();
275         retv_if(ret, -1);
276
277         json_builder_set_member_name(Json_h.builder, "SensorDataList");
278         json_builder_begin_array(Json_h.builder);
279
280         return 0;
281 }
282
283 int web_util_json_data_array_end(void)
284 {
285         retv_if(Json_h.builder == NULL, -1);
286         retv_if(Json_h.is_begin == false, -1);
287         retv_if(Json_h.is_end == true, -1);
288
289         json_builder_end_array(Json_h.builder);
290         web_util_json_end();
291
292         return 0;
293 }
294
295 int web_util_json_add_sensor_data(const char* sensorpi_id, web_util_sensor_data_s *sensor_data)
296 {
297         const char n_id[] = "SensorPiID";
298         const char n_motion[] = "Motion";
299         const char n_flame[] = "Flame";
300         const char n_hum[] = "Humidity";
301         const char n_temp[] = "Temperature";
302         const char n_vib[] = "Vibration";
303         const char n_co2[] = "CO2";
304         const char n_sound[] = "SoundLevel";
305         const char n_tilt[] = "Tilt";
306         const char n_light[] = "Light";
307         const char n_collision[] = "Collision";
308         const char n_obstacle[] = "Obstacle";
309         const char n_distance[] = "Distance";
310         const char n_rain[] = "Rain";
311         const char n_touch[] = "Touch";
312         const char n_gas[] = "Gas";
313         const char n_e_sensor[] = "SensorEnabled";
314         const char n_hash[] = "Hash";
315
316         retv_if(!sensorpi_id, -1);
317         retv_if(Json_h.builder == NULL, -1);
318         retv_if(Json_h.is_begin == false, -1);
319         retv_if(Json_h.is_end == true, -1);
320         retv_if(sensor_data == NULL, -1);
321
322         /* JSON structure :
323         {
324                 SensorPiID: string,
325                 Motion: boolean,
326                 Flame: boolean,
327                 Humidity: double,
328                 Temperature: double,
329                 Vibration: boolean,
330                 CO2: double,
331                 SoundLevel: int,
332                 Tilt: int,
333                 Light: int,
334                 Collision: int,
335                 Obstacle: int,
336                 Distance: double,
337                 Rain: int,
338                 Touch: int,
339                 Gas: int,
340                 SensorEnabled: [Motion, ],
341                 Hash: string,
342         }
343         */
344
345
346         json_builder_begin_object(Json_h.builder);
347
348         json_builder_set_member_name(Json_h.builder, n_id);
349         json_builder_add_string_value(Json_h.builder, sensorpi_id);
350
351         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION) {
352                 json_builder_set_member_name(Json_h.builder, n_motion);
353                 json_builder_add_int_value(Json_h.builder, sensor_data->motion);
354         }
355
356         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME) {
357                 json_builder_set_member_name(Json_h.builder, n_flame);
358                 json_builder_add_int_value(Json_h.builder, sensor_data->flame);
359         }
360
361         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY) {
362                 json_builder_set_member_name(Json_h.builder, n_hum);
363                 json_builder_add_double_value(Json_h.builder, sensor_data->humidity);
364         }
365
366         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE) {
367                 json_builder_set_member_name(Json_h.builder, n_temp);
368                 json_builder_add_double_value(Json_h.builder, sensor_data->temperature);
369         }
370
371         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB) {
372                 json_builder_set_member_name(Json_h.builder, n_vib);
373                 json_builder_add_int_value(Json_h.builder, sensor_data->virbration);
374         }
375
376         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2) {
377                 json_builder_set_member_name(Json_h.builder, n_co2);
378                 json_builder_add_double_value(Json_h.builder, sensor_data->co2);
379         }
380
381         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND) {
382                 json_builder_set_member_name(Json_h.builder, n_sound);
383                 json_builder_add_int_value(Json_h.builder, sensor_data->soundlevel);
384         }
385
386         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TILT) {
387                 json_builder_set_member_name(Json_h.builder, n_tilt);
388                 json_builder_add_int_value(Json_h.builder, sensor_data->tilt);
389         }
390
391         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_LIGHT) {
392                 json_builder_set_member_name(Json_h.builder, n_light);
393                 json_builder_add_int_value(Json_h.builder, sensor_data->light);
394         }
395
396         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_COLLISION) {
397                 json_builder_set_member_name(Json_h.builder, n_collision);
398                 json_builder_add_int_value(Json_h.builder, sensor_data->collision);
399         }
400
401         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_OBSTACLE) {
402                 json_builder_set_member_name(Json_h.builder, n_obstacle);
403                 json_builder_add_int_value(Json_h.builder, sensor_data->obstacle);
404         }
405
406         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_ULTRASONIC_DISTANCE) {
407                 json_builder_set_member_name(Json_h.builder, n_distance);
408                 json_builder_add_double_value(Json_h.builder, sensor_data->distance);
409         }
410
411         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_RAIN) {
412                 json_builder_set_member_name(Json_h.builder, n_rain);
413                 json_builder_add_int_value(Json_h.builder, sensor_data->rain);
414         }
415
416         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TOUCH) {
417                 json_builder_set_member_name(Json_h.builder, n_touch);
418                 json_builder_add_int_value(Json_h.builder, sensor_data->touch);
419         }
420
421         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_GAS) {
422                 json_builder_set_member_name(Json_h.builder, n_gas);
423                 json_builder_add_int_value(Json_h.builder, sensor_data->gas);
424         }
425
426         json_builder_set_member_name(Json_h.builder, n_e_sensor);
427         json_builder_begin_array(Json_h.builder);
428
429         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION)
430                 json_builder_add_string_value(Json_h.builder, n_motion);
431
432         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME)
433                 json_builder_add_string_value(Json_h.builder, n_flame);
434
435         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY)
436                 json_builder_add_string_value(Json_h.builder, n_hum);
437
438         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE)
439                 json_builder_add_string_value(Json_h.builder, n_temp);
440
441         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB)
442                 json_builder_add_string_value(Json_h.builder, n_vib);
443
444         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2)
445                 json_builder_add_string_value(Json_h.builder, n_co2);
446
447         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND)
448                 json_builder_add_string_value(Json_h.builder, n_sound);
449
450         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TILT)
451                 json_builder_add_string_value(Json_h.builder, n_tilt);
452
453         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_LIGHT)
454                 json_builder_add_string_value(Json_h.builder, n_light);
455
456         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_COLLISION)
457                 json_builder_add_string_value(Json_h.builder, n_collision);
458
459         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_OBSTACLE)
460                 json_builder_add_string_value(Json_h.builder, n_obstacle);
461
462         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_ULTRASONIC_DISTANCE)
463                 json_builder_add_string_value(Json_h.builder, n_distance);
464
465         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_RAIN)
466                 json_builder_add_string_value(Json_h.builder, n_rain);
467
468         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TOUCH)
469                 json_builder_add_string_value(Json_h.builder, n_touch);
470
471         if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_GAS)
472                 json_builder_add_string_value(Json_h.builder, n_gas);
473
474         json_builder_end_array(Json_h.builder);
475
476         if (sensor_data->hash) {
477                 json_builder_set_member_name(Json_h.builder, n_hash);
478                 json_builder_add_string_value(Json_h.builder, sensor_data->hash);
479         }
480
481         json_builder_end_object(Json_h.builder);
482
483         return 0;
484 }
485
486 char *web_util_get_json_string(void)
487 {
488         JsonGenerator *gen = NULL;
489         JsonNode *root = NULL;
490         char *str = NULL;
491
492         retv_if(Json_h.builder == NULL, NULL);
493         retv_if(Json_h.is_begin == false, NULL);
494         retv_if(Json_h.is_end == false, NULL);
495
496         root = json_builder_get_root(Json_h.builder);
497         retv_if(root == NULL, NULL);
498
499         gen = json_generator_new();
500         goto_if(gen == NULL, error_release_all);
501         json_generator_set_root(gen, root);
502
503         str = json_generator_to_data(gen, NULL);
504
505         return str;
506
507 error_release_all:
508         if (root)
509                 json_node_free(root);
510
511         if (gen)
512                 g_object_unref(gen);
513
514         return NULL;
515 }
516