2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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>
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
14 * http://floralicense.org/license/
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.
24 #include <curl/curl.h>
26 #include <json-glib/json-glib.h>
30 #define URI_PATH_LEN 64
31 #define REQ_CON_TIMEOUT 5L
32 #define REQ_TIMEOUT 7L
34 typedef struct _wu_json_handle {
40 static wu_json_handle Json_h = {NULL, false, false};
42 static size_t _post_response_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
46 res_size = size*nmemb;
49 _I("POST response : %s", ptr);
50 /* What should we do here, if response body has negative message? */
55 static size_t _get_response_write_callback(void *ptr, size_t size, size_t nmemb, void *data)
58 char **received = (char **)data;
60 res_size = size*nmemb;
62 if (received && res_size > 0)
63 *received = strndup((char *)ptr, size*nmemb);
65 _E("fail to get response [res size : %d]", res_size);
70 static int __curl_debug(CURL *handle, curl_infotype type,
71 char *data, size_t size, void *userptr)
73 const char *prefix = NULL;
80 _D("== text Info: %s", data);
82 case CURLINFO_HEADER_OUT:
83 prefix = "=> Send header:";
85 case CURLINFO_DATA_OUT:
86 prefix = "=> Send data:";
88 case CURLINFO_SSL_DATA_OUT:
89 prefix = "=> Send SSL data:";
91 case CURLINFO_HEADER_IN:
92 prefix = "<= Recv header:";
94 case CURLINFO_DATA_IN:
95 prefix = "<= Recv data:";
97 case CURLINFO_SSL_DATA_IN:
98 prefix = "<= Recv SSL data:";
101 message = g_strndup(data, size);
102 _D("%s %s", prefix, message);
107 static const char *_get_time_str(void)
111 static char res_time[40] = {0, };
113 gettimeofday(&val, NULL);
114 ptm = localtime(&val.tv_sec);
116 // format : YY-MM-DD_hh:mm:ss:uuuuuu
117 snprintf(res_time, sizeof(res_time), "%04d-%02d-%02d_%02d:%02d:%02d:%06ld"
118 , ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday
119 , ptm->tm_hour, ptm->tm_min, ptm->tm_sec
122 return (const char *)res_time;
126 int web_util_noti_init(void)
130 result = curl_global_init(CURL_GLOBAL_DEFAULT);
131 if (result != CURLE_OK) {
132 _E("curl_global_init() failed: %s",
133 curl_easy_strerror(result));
139 void web_util_noti_fini(void)
141 curl_global_cleanup();
145 int web_util_noti_post_image_data(const char *url, const char *device_id,
146 const void *image_data, unsigned int image_size)
150 CURLcode response = CURLE_OK;
151 struct curl_httppost *formpost = NULL;
152 struct curl_httppost *lastptr = NULL;
153 char *filename = NULL;
154 char *post_url = NULL;
156 retv_if(url == NULL, -1);
157 retv_if(device_id == NULL, -1);
158 retv_if(image_data == NULL, -1);
159 retv_if(image_size == 0, -1);
161 curl = curl_easy_init();
164 _E("fail to init curl");
168 filename = g_strdup_printf("%s_%s.jpg", device_id, _get_time_str());
169 post_url = g_strdup_printf("%s?id=%s", url, device_id);
170 _D("FileName: [%s], PostUrl: [%s]", filename, post_url);
172 curl_formadd(&formpost, &lastptr,
173 CURLFORM_COPYNAME, "content-type:",
174 CURLFORM_COPYCONTENTS, "multipart/form-data",
177 curl_formadd(&formpost, &lastptr,
178 CURLFORM_COPYNAME, "imageFile",
179 CURLFORM_BUFFER, filename,
180 CURLFORM_BUFFERPTR, image_data,
181 CURLFORM_BUFFERLENGTH, image_size,
184 curl_easy_setopt(curl, CURLOPT_URL, post_url);
185 curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
187 /* if CURLOPT_VERBOSE is enabled, __curl_debug() function will be called */
188 // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
189 curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, __curl_debug);
191 // curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, REQ_CON_TIMEOUT);
192 // curl_easy_setopt(curl, CURLOPT_TIMEOUT, REQ_TIMEOUT);
194 response = curl_easy_perform(curl);
196 if (response != CURLE_OK) {
197 _E("curl_easy_perform() failed: %s",
198 curl_easy_strerror(response));
202 curl_easy_cleanup(curl);
203 curl_formfree(formpost);
210 int web_util_noti_post(const char *resource, const char *json_data)
214 CURLcode response = CURLE_OK;
215 struct curl_slist *headers = NULL;
217 retv_if(resource == NULL, -1);
218 retv_if(json_data == NULL, -1);
220 _I("server : %s", resource);
221 _I("json_data : %s", json_data);
223 curl = curl_easy_init();
226 _E("fail to init curl");
230 headers = curl_slist_append(headers, "Accept: application/json");
231 headers = curl_slist_append(headers, "Content-Type: application/json");
233 curl_easy_setopt(curl, CURLOPT_URL, resource);
234 curl_easy_setopt(curl, CURLOPT_POST, 1L);
235 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
236 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);
237 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _post_response_write_callback);
238 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, REQ_CON_TIMEOUT);
239 curl_easy_setopt(curl, CURLOPT_TIMEOUT, REQ_TIMEOUT);
241 response = curl_easy_perform(curl);
243 if (response != CURLE_OK) {
244 _E("curl_easy_perform() failed: %s",
245 curl_easy_strerror(response));
246 /* What should we do here, if response is kind of errors? */
250 curl_slist_free_all(headers);
251 curl_easy_cleanup(curl);
256 int web_util_noti_get(const char *resource, char **res)
260 CURLcode response = CURLE_OK;
262 retv_if(resource == NULL, -1);
264 _I("GET to [%s]", resource);
266 curl = curl_easy_init();
269 _E("fail to init curl");
273 curl_easy_setopt(curl, CURLOPT_URL, resource);
274 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _get_response_write_callback);
275 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)res);
276 curl_easy_setopt(curl, CURLOPT_USERAGENT, "tizen-iot-agent/1.0");
277 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, REQ_CON_TIMEOUT);
279 response = curl_easy_perform(curl);
281 if (response != CURLE_OK) {
282 _E("curl_easy_perform() failed: %s",
283 curl_easy_strerror(response));
284 /* What should we do here, if response is kind of errors? */
288 curl_easy_cleanup(curl);
293 int web_util_json_init(void)
296 g_object_unref(Json_h.builder);
298 Json_h.is_begin = false;
299 Json_h.is_end = false;
300 Json_h.builder = json_builder_new();
301 retv_if(Json_h.builder == NULL, -1);
306 int web_util_json_fini(void)
309 if (Json_h.builder) {
310 g_object_unref(Json_h.builder);
311 Json_h.builder = NULL;
314 Json_h.is_begin = false;
315 Json_h.is_end = false;
320 int web_util_json_begin(void)
322 retv_if(Json_h.builder == NULL, -1);
323 retv_if(Json_h.is_begin == true, -1);
324 retv_if(Json_h.is_end == true, -1);
326 Json_h.is_begin = true;
328 json_builder_begin_object(Json_h.builder);
333 int web_util_json_end(void)
335 retv_if(Json_h.builder == NULL, -1);
336 retv_if(Json_h.is_begin == false, -1);
337 retv_if(Json_h.is_end == true, -1);
339 json_builder_end_object(Json_h.builder);
340 Json_h.is_end = true;
345 int web_util_json_add_int(const char* key, long long int value)
349 if (Json_h.builder == NULL) {
350 _E("Handle for json is not initialized, call web_util_json_init() first");
354 if (Json_h.is_begin == false) {
355 _E("json object has not begun, call web_util_json_begin() first");
359 if (Json_h.is_end == true) {
360 _E("json object has already ended, call web_util_json_begin() first");
364 json_builder_set_member_name(Json_h.builder, key);
365 json_builder_add_int_value(Json_h.builder, value);
370 int web_util_json_add_double(const char* key, double value)
374 if (Json_h.builder == NULL) {
375 _E("Handle for json is not initialized, call web_util_json_init() first");
379 if (Json_h.is_begin == false) {
380 _E("json object has not begun, call web_util_json_begin() first");
384 if (Json_h.is_end == true) {
385 _E("json object has already ended, call web_util_json_begin() first");
389 json_builder_set_member_name(Json_h.builder, key);
390 json_builder_add_double_value(Json_h.builder, value);
395 int web_util_json_add_boolean(const char* key, bool value)
399 if (Json_h.builder == NULL) {
400 _E("Handle for json is not initialized, call web_util_json_init() first");
404 if (Json_h.is_begin == false) {
405 _E("json object has not begun, call web_util_json_begin() first");
409 if (Json_h.is_end == true) {
410 _E("json object has already ended, call web_util_json_begin() first");
414 json_builder_set_member_name(Json_h.builder, key);
415 json_builder_add_boolean_value(Json_h.builder, value);
420 int web_util_json_add_string(const char* key, const char *value)
424 if (Json_h.builder == NULL) {
425 _E("Handle for json is not initialized, call web_util_json_init() first");
429 if (Json_h.is_begin == false) {
430 _E("json object has not begun, call web_util_json_begin() first");
434 if (Json_h.is_end == true) {
435 _E("json object has already ended, call web_util_json_begin() first");
439 json_builder_set_member_name(Json_h.builder, key);
440 json_builder_add_string_value(Json_h.builder, value);
445 int web_util_json_data_array_begin(void)
448 retv_if(Json_h.builder == NULL, -1);
450 ret = web_util_json_begin();
453 json_builder_set_member_name(Json_h.builder, "SensorDataList");
454 json_builder_begin_array(Json_h.builder);
459 int web_util_json_data_array_end(void)
461 retv_if(Json_h.builder == NULL, -1);
462 retv_if(Json_h.is_begin == false, -1);
463 retv_if(Json_h.is_end == true, -1);
465 json_builder_end_array(Json_h.builder);
471 int web_util_json_add_sensor_data(const char* sensorpi_id, web_util_sensor_data_s *sensor_data)
473 const char n_id[] = "SensorPiID";
474 const char n_motion[] = "Motion";
475 const char n_flame[] = "Flame";
476 const char n_hum[] = "Humidity";
477 const char n_temp[] = "Temperature";
478 const char n_vib[] = "Vibration";
479 const char n_co2[] = "CO2";
480 const char n_sound[] = "SoundLevel";
481 const char n_tilt[] = "Tilt";
482 const char n_light[] = "Light";
483 const char n_collision[] = "Collision";
484 const char n_obstacle[] = "Obstacle";
485 const char n_distance[] = "Distance";
486 const char n_rain[] = "Rain";
487 const char n_touch[] = "Touch";
488 const char n_gas[] = "Gas";
489 const char n_e_sensor[] = "SensorEnabled";
490 const char n_hash[] = "Hash";
491 const char n_ip[] = "SensorPiIP";
493 retv_if(!sensorpi_id, -1);
494 retv_if(Json_h.builder == NULL, -1);
495 retv_if(Json_h.is_begin == false, -1);
496 retv_if(Json_h.is_end == true, -1);
497 retv_if(sensor_data == NULL, -1);
518 SensorEnabled: [Motion, ],
523 json_builder_begin_object(Json_h.builder);
525 json_builder_set_member_name(Json_h.builder, n_id);
526 json_builder_add_string_value(Json_h.builder, sensorpi_id);
528 if (sensor_data->ip_addr) {
529 json_builder_set_member_name(Json_h.builder, n_ip);
530 json_builder_add_string_value(Json_h.builder, sensor_data->ip_addr);
533 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION) {
534 json_builder_set_member_name(Json_h.builder, n_motion);
535 json_builder_add_int_value(Json_h.builder, sensor_data->motion);
538 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME) {
539 json_builder_set_member_name(Json_h.builder, n_flame);
540 json_builder_add_int_value(Json_h.builder, sensor_data->flame);
543 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY) {
544 json_builder_set_member_name(Json_h.builder, n_hum);
545 json_builder_add_double_value(Json_h.builder, sensor_data->humidity);
548 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE) {
549 json_builder_set_member_name(Json_h.builder, n_temp);
550 json_builder_add_double_value(Json_h.builder, sensor_data->temperature);
553 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB) {
554 json_builder_set_member_name(Json_h.builder, n_vib);
555 json_builder_add_int_value(Json_h.builder, sensor_data->virbration);
558 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2) {
559 json_builder_set_member_name(Json_h.builder, n_co2);
560 json_builder_add_double_value(Json_h.builder, sensor_data->co2);
563 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND) {
564 json_builder_set_member_name(Json_h.builder, n_sound);
565 json_builder_add_int_value(Json_h.builder, sensor_data->soundlevel);
568 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TILT) {
569 json_builder_set_member_name(Json_h.builder, n_tilt);
570 json_builder_add_int_value(Json_h.builder, sensor_data->tilt);
573 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_LIGHT) {
574 json_builder_set_member_name(Json_h.builder, n_light);
575 json_builder_add_int_value(Json_h.builder, sensor_data->light);
578 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_COLLISION) {
579 json_builder_set_member_name(Json_h.builder, n_collision);
580 json_builder_add_int_value(Json_h.builder, sensor_data->collision);
583 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_OBSTACLE) {
584 json_builder_set_member_name(Json_h.builder, n_obstacle);
585 json_builder_add_int_value(Json_h.builder, sensor_data->obstacle);
588 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_ULTRASONIC_DISTANCE) {
589 json_builder_set_member_name(Json_h.builder, n_distance);
590 json_builder_add_double_value(Json_h.builder, sensor_data->distance);
593 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_RAIN) {
594 json_builder_set_member_name(Json_h.builder, n_rain);
595 json_builder_add_int_value(Json_h.builder, sensor_data->rain);
598 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TOUCH) {
599 json_builder_set_member_name(Json_h.builder, n_touch);
600 json_builder_add_int_value(Json_h.builder, sensor_data->touch);
603 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_GAS) {
604 json_builder_set_member_name(Json_h.builder, n_gas);
605 json_builder_add_int_value(Json_h.builder, sensor_data->gas);
608 json_builder_set_member_name(Json_h.builder, n_e_sensor);
609 json_builder_begin_array(Json_h.builder);
611 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_MOTION)
612 json_builder_add_string_value(Json_h.builder, n_motion);
614 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_FLAME)
615 json_builder_add_string_value(Json_h.builder, n_flame);
617 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_HUMIDITY)
618 json_builder_add_string_value(Json_h.builder, n_hum);
620 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TEMPERATURE)
621 json_builder_add_string_value(Json_h.builder, n_temp);
623 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_VIB)
624 json_builder_add_string_value(Json_h.builder, n_vib);
626 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_CO2)
627 json_builder_add_string_value(Json_h.builder, n_co2);
629 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_SOUND)
630 json_builder_add_string_value(Json_h.builder, n_sound);
632 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TILT)
633 json_builder_add_string_value(Json_h.builder, n_tilt);
635 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_LIGHT)
636 json_builder_add_string_value(Json_h.builder, n_light);
638 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_COLLISION)
639 json_builder_add_string_value(Json_h.builder, n_collision);
641 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_OBSTACLE)
642 json_builder_add_string_value(Json_h.builder, n_obstacle);
644 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_ULTRASONIC_DISTANCE)
645 json_builder_add_string_value(Json_h.builder, n_distance);
647 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_RAIN)
648 json_builder_add_string_value(Json_h.builder, n_rain);
650 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_TOUCH)
651 json_builder_add_string_value(Json_h.builder, n_touch);
653 if (sensor_data->enabled_sensor & WEB_UTIL_SENSOR_GAS)
654 json_builder_add_string_value(Json_h.builder, n_gas);
656 json_builder_end_array(Json_h.builder);
658 if (sensor_data->hash) {
659 json_builder_set_member_name(Json_h.builder, n_hash);
660 json_builder_add_string_value(Json_h.builder, sensor_data->hash);
663 json_builder_end_object(Json_h.builder);
668 char *web_util_get_json_string(void)
670 JsonGenerator *gen = NULL;
671 JsonNode *root = NULL;
674 retv_if(Json_h.builder == NULL, NULL);
675 retv_if(Json_h.is_begin == false, NULL);
676 retv_if(Json_h.is_end == false, NULL);
678 root = json_builder_get_root(Json_h.builder);
679 retv_if(root == NULL, NULL);
681 gen = json_generator_new();
682 goto_if(gen == NULL, error_release_all);
683 json_generator_set_root(gen, root);
685 str = json_generator_to_data(gen, NULL);
691 json_node_free(root);