Add the 'webutil' feature into the Server
[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 typedef struct _wu_json_handle {
31         JsonBuilder *builder;
32         bool is_begin;
33         bool is_end;
34 } wu_json_handle;
35
36 static wu_json_handle Json_h = {NULL, false, false};
37
38 static size_t _response_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
39 {
40         size_t res_size = 0;
41
42         res_size = size*nmemb;
43
44         if(res_size > 0)
45                 _I("POST response : %s", ptr);
46         /* What should we do here, if response body has negative message? */
47
48         return res_size;
49 }
50
51 int web_util_noti_init(void)
52 {
53         int ret = 0;
54         CURLcode result;
55         result = curl_global_init(CURL_GLOBAL_DEFAULT);
56         if(result != CURLE_OK) {
57                 _E("curl_global_init() failed: %s",
58                         curl_easy_strerror(result));
59                 ret = -1;
60         }
61         return ret;
62 }
63
64 void web_util_noti_fini(void)
65 {
66         curl_global_cleanup();
67         return;
68 }
69
70 int web_util_noti_post(const char *resource, const char *json_data)
71 {
72         int ret = 0;
73         CURL *curl = NULL;
74         CURLcode response = CURLE_OK;
75         struct curl_slist *headers = NULL;
76
77         retv_if(resource == NULL,-1);
78         retv_if(json_data == NULL,-1);
79
80         _I("server : %s", resource);
81         _I("json_data : %s", json_data);
82
83         curl = curl_easy_init();
84
85         if(!curl) {
86                 _E("fail to init curl");
87                 return -1;
88         }
89
90         headers = curl_slist_append(headers, "Accept: application/json");
91         headers = curl_slist_append(headers, "Content-Type: application/json");
92
93         curl_easy_setopt(curl, CURLOPT_URL, resource);
94         curl_easy_setopt(curl, CURLOPT_POST, 1L);
95         curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
96         curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
97         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _response_write_callback);
98
99         response = curl_easy_perform(curl);
100
101         if(response != CURLE_OK) {
102                 _E("curl_easy_perform() failed: %s",
103                         curl_easy_strerror(response));
104                 /* What should we do here, if response is kind of errors? */
105                 ret = -1;
106         }
107
108         curl_slist_free_all(headers);
109         curl_easy_cleanup(curl);
110
111         return ret;
112 }
113
114
115 int web_util_json_init(void)
116 {
117         if(Json_h.builder) {
118                 g_object_unref(Json_h.builder);
119         }
120
121         Json_h.is_begin = false;
122         Json_h.is_end = false;
123         Json_h.builder = json_builder_new();
124         retv_if(Json_h.builder == NULL, -1);
125
126         return 0;
127 }
128
129 int web_util_json_fini(void)
130 {
131
132         if(Json_h.builder) {
133                 g_object_unref(Json_h.builder);
134                 Json_h.builder = NULL;
135         }
136
137         Json_h.is_begin = false;
138         Json_h.is_end = false;
139
140         return 0;
141 }
142
143 int web_util_json_data_array_begin(void)
144 {
145         retv_if(Json_h.builder == NULL, -1);
146         retv_if(Json_h.is_begin == true, -1);
147         retv_if(Json_h.is_end == true, -1);
148
149         Json_h.is_begin = true;
150
151         /*
152         {
153                 SensorsDataList : [ SensorData ]
154         }
155         */
156
157         json_builder_begin_object(Json_h.builder);
158         json_builder_set_member_name(Json_h.builder,"SensorDataList");
159         json_builder_begin_array(Json_h.builder);
160
161         return 0;
162 }
163
164 int web_util_json_data_array_end(void)
165 {
166         retv_if(Json_h.builder == NULL, -1);
167         retv_if(Json_h.is_begin == false, -1);
168         retv_if(Json_h.is_end == true, -1);
169
170         json_builder_end_array(Json_h.builder);
171         json_builder_end_object(Json_h.builder);
172         Json_h.is_end = true;
173
174         return 0;
175 }
176
177 int web_util_json_add_sensor_data(const char* sensorpi_id, web_util_sensor_data_s *sensor_data)
178 {
179         const char n_id[] = "SensorPiID";
180         const char n_motion[] = "Motion";
181         const char n_flame[] = "Flame";
182         const char n_hum[] = "Humidity";
183         const char n_temp[] = "Temperature";
184         const char n_vib[] = "Vibration";
185         const char n_co2[] = "CO2";
186         const char n_sound[] = "SoundLevel";
187         const char n_e_sensor[] = "SensorEnabled";
188         const char n_hash[] = "Hash";
189
190         retv_if(Json_h.builder == NULL, -1);
191         retv_if(Json_h.is_begin == false, -1);
192         retv_if(Json_h.is_end == true, -1);
193         retv_if(sensorpi_id == NULL, -1);
194         retv_if(sensor_data == NULL, -1);
195
196         /* JSON structure :
197         {
198                 SensorPiID: string,
199                 Motion: boolean,
200                 Flame: boolean,
201                 Humidity: double,
202                 Temperature: double,
203                 Vibration: boolean,
204                 CO2: double,
205                 SoundLevel: int,
206                 SensorEnabled: [Motion, ],
207                 Hash: string,
208         }
209         */
210
211         json_builder_begin_object(Json_h.builder);
212
213         json_builder_set_member_name(Json_h.builder, n_id);
214         json_builder_add_string_value(Json_h.builder, sensorpi_id);
215
216         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION) {
217                 json_builder_set_member_name(Json_h.builder, n_motion);
218                 json_builder_add_int_value(Json_h.builder, sensor_data->motion);
219         }
220
221         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME) {
222                 json_builder_set_member_name(Json_h.builder, n_flame);
223                 json_builder_add_int_value(Json_h.builder, sensor_data->flame);
224         }
225
226         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY) {
227                 json_builder_set_member_name(Json_h.builder, n_hum);
228                 json_builder_add_double_value(Json_h.builder, sensor_data->humidity);
229         }
230
231         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE) {
232                 json_builder_set_member_name(Json_h.builder, n_temp);
233                 json_builder_add_double_value(Json_h.builder, sensor_data->temperature);
234         }
235
236         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB) {
237                 json_builder_set_member_name(Json_h.builder, n_vib);
238                 json_builder_add_int_value(Json_h.builder, sensor_data->virbration);
239         }
240
241         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2) {
242                 json_builder_set_member_name(Json_h.builder, n_co2);
243                 json_builder_add_double_value(Json_h.builder, sensor_data->co2);
244         }
245
246         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND) {
247                 json_builder_set_member_name(Json_h.builder, n_sound);
248                 json_builder_add_int_value(Json_h.builder, sensor_data->soundlevel);
249         }
250
251         json_builder_set_member_name(Json_h.builder, n_e_sensor);
252         json_builder_begin_array(Json_h.builder);
253
254         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION)
255                 json_builder_add_string_value(Json_h.builder, n_motion);
256
257         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME)
258                 json_builder_add_string_value(Json_h.builder, n_flame);
259
260         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY)
261                 json_builder_add_string_value(Json_h.builder, n_hum);
262
263         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE)
264                 json_builder_add_string_value(Json_h.builder, n_temp);
265
266         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB)
267                 json_builder_add_string_value(Json_h.builder, n_vib);
268
269         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2)
270                 json_builder_add_string_value(Json_h.builder, n_co2);
271
272         if(sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND)
273                 json_builder_add_string_value(Json_h.builder, n_sound);
274
275         json_builder_end_array(Json_h.builder);
276
277         if(sensor_data->hash) {
278                 json_builder_set_member_name(Json_h.builder, n_hash);
279                 json_builder_add_string_value(Json_h.builder, sensor_data->hash);
280         }
281
282         json_builder_end_object(Json_h.builder);
283
284         return 0;
285 }
286
287 char *web_util_get_json_string(void)
288 {
289         JsonGenerator *gen = NULL;
290         JsonNode *root = NULL;
291         char *str = NULL;
292
293         retv_if(Json_h.builder == NULL, NULL);
294         retv_if(Json_h.is_begin == false, NULL);
295         retv_if(Json_h.is_end == false, NULL);
296
297         root = json_builder_get_root(Json_h.builder);
298         retv_if(root == NULL, NULL);
299
300         gen = json_generator_new();
301         goto_if(gen == NULL, error_release_all);
302         json_generator_set_root(gen, root);
303
304         str = json_generator_to_data(gen, NULL);
305
306         return str;
307
308 error_release_all:
309         if(root)
310                 json_node_free(root);
311
312         if(gen)
313                 g_object_unref(gen);
314
315         return NULL;
316 }
317