Sync between position-finder-server & bangbang-sensor-pi
[apps/native/position-finder-server.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
123         Json_h.is_begin = false;
124         Json_h.is_end = false;
125         Json_h.builder = json_builder_new();
126         retv_if(Json_h.builder == NULL, -1);
127
128         return 0;
129 }
130
131 int web_util_json_fini(void)
132 {
133
134         if(Json_h.builder) {
135                 g_object_unref(Json_h.builder);
136                 Json_h.builder = NULL;
137         }
138
139         Json_h.is_begin = false;
140         Json_h.is_end = false;
141
142         return 0;
143 }
144
145 int web_util_json_data_array_begin(void)
146 {
147         retv_if(Json_h.builder == NULL, -1);
148         retv_if(Json_h.is_begin == true, -1);
149         retv_if(Json_h.is_end == true, -1);
150
151         Json_h.is_begin = true;
152
153         /*
154         {
155                 SensorsDataList : [ SensorData ]
156         }
157         */
158
159         json_builder_begin_object(Json_h.builder);
160         json_builder_set_member_name(Json_h.builder,"SensorDataList");
161         json_builder_begin_array(Json_h.builder);
162
163         return 0;
164 }
165
166 int web_util_json_data_array_end(void)
167 {
168         retv_if(Json_h.builder == NULL, -1);
169         retv_if(Json_h.is_begin == false, -1);
170         retv_if(Json_h.is_end == true, -1);
171
172         json_builder_end_array(Json_h.builder);
173         json_builder_end_object(Json_h.builder);
174         Json_h.is_end = true;
175
176         return 0;
177 }
178
179 static int _get_default_path_in_conf(char *buf, int size)
180 {
181         FILE *in = NULL;
182         size_t nread = 0;
183
184         in = fopen(CONF_FILE, "r");
185         retv_if(!in, -1);
186
187         nread = fread(buf, 1, size, in);
188         if (nread <= 0) {
189                 _I("No contents in the conf.");
190                 return -1;
191         }
192
193         if (buf[nread - 1] == '\n')
194                 buf[nread - 1] = '\0';
195
196         fclose(in);
197
198         return 0;
199 }
200
201 int web_util_json_add_sensor_data(const char* sensorpi_id, web_util_sensor_data_s *sensor_data)
202 {
203         const char n_id[] = "SensorPiID";
204         const char n_motion[] = "Motion";
205         const char n_flame[] = "Flame";
206         const char n_hum[] = "Humidity";
207         const char n_temp[] = "Temperature";
208         const char n_vib[] = "Vibration";
209         const char n_co2[] = "CO2";
210         const char n_sound[] = "SoundLevel";
211         const char n_tilt[] = "Tilt";
212         const char n_light[] = "Light";
213         const char n_collision[] = "Collision";
214         const char n_obstacle[] = "Obstacle";
215         const char n_distance[] = "Distance";
216         const char n_rain[] = "Rain";
217         const char n_touch[] = "Touch";
218         const char n_gas[] = "Gas";
219         const char n_e_sensor[] = "SensorEnabled";
220         const char n_hash[] = "Hash";
221         const char *path = NULL;
222         char default_path[URI_PATH_LEN] = { 0, };
223         int ret = -1;
224
225         retv_if(Json_h.builder == NULL, -1);
226         retv_if(Json_h.is_begin == false, -1);
227         retv_if(Json_h.is_end == true, -1);
228         retv_if(sensor_data == NULL, -1);
229
230         /* JSON structure :
231         {
232                 SensorPiID: string,
233                 Motion: boolean,
234                 Flame: boolean,
235                 Humidity: double,
236                 Temperature: double,
237                 Vibration: boolean,
238                 CO2: double,
239                 SoundLevel: int,
240                 Tilt: int,
241                 Light: int,
242                 Collision: int,
243                 Obstacle: int,
244                 Distance: double,
245                 Rain: int,
246                 Touch: int,
247                 Gas: int,
248                 SensorEnabled: [Motion, ],
249                 Hash: string,
250         }
251         */
252
253         if (sensorpi_id) {
254                 path = sensorpi_id;
255         } else {
256                 ret = _get_default_path_in_conf(default_path, URI_PATH_LEN);
257                 retv_if(ret < 0, -1);
258                 path = default_path;
259         }
260         retv_if(!path, -1);
261         retv_if(0 == strlen(path), -1);
262
263         json_builder_begin_object(Json_h.builder);
264
265         json_builder_set_member_name(Json_h.builder, n_id);
266         json_builder_add_string_value(Json_h.builder, path);
267
268         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION) {
269                 json_builder_set_member_name(Json_h.builder, n_motion);
270                 json_builder_add_int_value(Json_h.builder, sensor_data->motion);
271         }
272
273         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME) {
274                 json_builder_set_member_name(Json_h.builder, n_flame);
275                 json_builder_add_int_value(Json_h.builder, sensor_data->flame);
276         }
277
278         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY) {
279                 json_builder_set_member_name(Json_h.builder, n_hum);
280                 json_builder_add_double_value(Json_h.builder, sensor_data->humidity);
281         }
282
283         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE) {
284                 json_builder_set_member_name(Json_h.builder, n_temp);
285                 json_builder_add_double_value(Json_h.builder, sensor_data->temperature);
286         }
287
288         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB) {
289                 json_builder_set_member_name(Json_h.builder, n_vib);
290                 json_builder_add_int_value(Json_h.builder, sensor_data->virbration);
291         }
292
293         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2) {
294                 json_builder_set_member_name(Json_h.builder, n_co2);
295                 json_builder_add_double_value(Json_h.builder, sensor_data->co2);
296         }
297
298         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND) {
299                 json_builder_set_member_name(Json_h.builder, n_sound);
300                 json_builder_add_int_value(Json_h.builder, sensor_data->soundlevel);
301         }
302
303         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TILT) {
304                 json_builder_set_member_name(Json_h.builder, n_tilt);
305                 json_builder_add_int_value(Json_h.builder, sensor_data->tilt);
306         }
307
308         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_LIGHT) {
309                 json_builder_set_member_name(Json_h.builder, n_light);
310                 json_builder_add_int_value(Json_h.builder, sensor_data->light);
311         }
312
313         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_COLLISION) {
314                 json_builder_set_member_name(Json_h.builder, n_collision);
315                 json_builder_add_int_value(Json_h.builder, sensor_data->collision);
316         }
317
318         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_OBSTACLE) {
319                 json_builder_set_member_name(Json_h.builder, n_obstacle);
320                 json_builder_add_int_value(Json_h.builder, sensor_data->obstacle);
321         }
322
323         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_ULTRASONIC_DISTANCE) {
324                 json_builder_set_member_name(Json_h.builder, n_distance);
325                 json_builder_add_double_value(Json_h.builder, sensor_data->distance);
326         }
327
328         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_RAIN) {
329                 json_builder_set_member_name(Json_h.builder, n_rain);
330                 json_builder_add_int_value(Json_h.builder, sensor_data->rain);
331         }
332
333         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TOUCH) {
334                 json_builder_set_member_name(Json_h.builder, n_touch);
335                 json_builder_add_int_value(Json_h.builder, sensor_data->touch);
336         }
337
338         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_GAS) {
339                 json_builder_set_member_name(Json_h.builder, n_gas);
340                 json_builder_add_int_value(Json_h.builder, sensor_data->gas);
341         }
342
343         json_builder_set_member_name(Json_h.builder, n_e_sensor);
344         json_builder_begin_array(Json_h.builder);
345
346         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION)
347                 json_builder_add_string_value(Json_h.builder, n_motion);
348
349         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME)
350                 json_builder_add_string_value(Json_h.builder, n_flame);
351
352         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY)
353                 json_builder_add_string_value(Json_h.builder, n_hum);
354
355         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE)
356                 json_builder_add_string_value(Json_h.builder, n_temp);
357
358         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB)
359                 json_builder_add_string_value(Json_h.builder, n_vib);
360
361         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2)
362                 json_builder_add_string_value(Json_h.builder, n_co2);
363
364         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND)
365                 json_builder_add_string_value(Json_h.builder, n_sound);
366
367         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TILT)
368                 json_builder_add_string_value(Json_h.builder, n_tilt);
369
370         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_LIGHT)
371                 json_builder_add_string_value(Json_h.builder, n_light);
372
373         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_COLLISION)
374                 json_builder_add_string_value(Json_h.builder, n_collision);
375
376         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_OBSTACLE)
377                 json_builder_add_string_value(Json_h.builder, n_obstacle);
378
379         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_ULTRASONIC_DISTANCE)
380                 json_builder_add_string_value(Json_h.builder, n_distance);
381
382         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_RAIN)
383                 json_builder_add_string_value(Json_h.builder, n_rain);
384
385         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TOUCH)
386                 json_builder_add_string_value(Json_h.builder, n_touch);
387
388         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_GAS)
389                 json_builder_add_string_value(Json_h.builder, n_gas);
390
391         json_builder_end_array(Json_h.builder);
392
393         if(sensor_data->hash) {
394                 json_builder_set_member_name(Json_h.builder, n_hash);
395                 json_builder_add_string_value(Json_h.builder, sensor_data->hash);
396         }
397
398         json_builder_end_object(Json_h.builder);
399
400         return 0;
401 }
402
403 char *web_util_get_json_string(void)
404 {
405         JsonGenerator *gen = NULL;
406         JsonNode *root = NULL;
407         char *str = NULL;
408
409         retv_if(Json_h.builder == NULL, NULL);
410         retv_if(Json_h.is_begin == false, NULL);
411         retv_if(Json_h.is_end == false, NULL);
412
413         root = json_builder_get_root(Json_h.builder);
414         retv_if(root == NULL, NULL);
415
416         gen = json_generator_new();
417         goto_if(gen == NULL, error_release_all);
418         json_generator_set_root(gen, root);
419
420         str = json_generator_to_data(gen, NULL);
421
422         return str;
423
424 error_release_all:
425         if(root)
426                 json_node_free(root);
427
428         if(gen)
429                 g_object_unref(gen);
430
431         return NULL;
432 }
433