Config added for the cloud comunication
[apps/native/gear-racing-car.git] / src / cloud / cloud_lap_request.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "cloud/cloud_lap_request.h"
18 #include "cloud/http_request.h"
19 #include "cloud/lap_info_serializer.h"
20 #include "cloud/lap_info.h"
21 #include <glib.h>
22 #include <gio/gio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include "log.h"
26
27 #define PATH_API_LAP "/api/lap"
28 #define CONFIG_LAP_API_KEY "lap"
29
30 typedef struct {
31         char *ap_mac;
32         cloud_request_lap_list_data_cb cb;
33         void *user_data;
34 } lap_api_get_request_context_t;
35
36 typedef struct {
37         lap_info_t *lap;
38         cloud_request_lap_post_finish_cb cb;
39         void *user_data;
40 } lap_api_post_request_context_t;
41
42 typedef struct {
43         long response_code;
44         char *response_msg;
45 } lap_api_post_request_response_t;
46
47 typedef struct {
48         long response_code;
49         lap_info_t **laps;
50         int size;
51 } lap_api_get_request_response_t;
52
53 static void lap_api_post_task_thread_cb(GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable);
54 static void lap_api_post_task_ready_cb(GObject *source_object, GAsyncResult *res, gpointer user_data);
55 static void lap_api_post_task_context_free(lap_api_post_request_context_t *context);
56 static void lap_api_post_request_response_free(lap_api_post_request_response_t *response);
57
58 static void lap_api_get_task_context_free(lap_api_get_request_context_t *context);
59 static void lap_api_get_request_response_free(lap_api_get_request_response_t *response);
60 static void lap_api_get_task_thread_cb(GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable);
61 static void lap_api_get_task_ready_cb(GObject *source_object, GAsyncResult *res, gpointer user_data);
62
63 #define G_ERROR_DOMAIN g_quark_from_static_string("cloud_lap_request")
64
65 GCancellable *cloud_lap_request_api_racing_get(const char *ap_mac, cloud_request_lap_list_data_cb cb, void *user_data)
66 {
67         GCancellable *cancellable = g_cancellable_new();
68
69         GTask *task = g_task_new(NULL, cancellable, lap_api_get_task_ready_cb, NULL);
70         g_task_set_source_tag(task, cloud_lap_request_api_racing_get);
71         g_task_set_return_on_cancel(task, FALSE);
72
73         lap_api_get_request_context_t *context = g_new0(lap_api_get_request_context_t, 1);
74         context->ap_mac = strndup(ap_mac, strlen(ap_mac));
75         context->cb = cb;
76         context->user_data = user_data;
77
78         g_task_set_task_data(task, context, (GDestroyNotify)lap_api_get_task_context_free);
79         g_task_run_in_thread(task, lap_api_get_task_thread_cb);
80
81         g_object_unref(task);
82
83         return cancellable;
84 }
85
86 GCancellable *cloud_lap_request_api_racing_post(const lap_info_t *lap_info, cloud_request_lap_post_finish_cb cb, void *user_data)
87 {
88         GCancellable *cancellable = g_cancellable_new();
89
90         GTask *task = g_task_new(NULL, cancellable, lap_api_post_task_ready_cb, NULL);
91         g_task_set_source_tag(task, cloud_lap_request_api_racing_post);
92         g_task_set_return_on_cancel(task, FALSE);
93
94         lap_api_post_request_context_t *context = g_new0(lap_api_post_request_context_t, 1);
95         context->lap = lap_info_copy(lap_info);
96         context->cb = cb;
97         context->user_data = user_data;
98
99         g_task_set_task_data(task, context, (GDestroyNotify)lap_api_post_task_context_free);
100         g_task_run_in_thread(task, lap_api_post_task_thread_cb);
101
102         g_object_unref(task);
103
104         return cancellable;
105 }
106
107 static void lap_api_post_task_context_free(lap_api_post_request_context_t *context)
108 {
109         ret_if(!context);
110
111         lap_info_destroy(context->lap);
112         g_free(context);
113 }
114
115 static void lap_api_post_request_response_free(lap_api_post_request_response_t *response)
116 {
117         ret_if(!response);
118
119         g_free(response->response_msg);
120         g_free(response);
121 }
122
123 static void lap_api_post_task_thread_cb(GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable)
124 {
125         lap_api_post_request_context_t *context = (lap_api_post_request_context_t *)task_data;
126
127         if (g_task_return_error_if_cancelled(task)) {
128                 return;
129         }
130
131         lap_api_post_request_response_t *response = g_new0(lap_api_post_request_response_t, 1);
132
133         char *json = lap_info_serializer_serialize(context->lap);
134
135         char *url = http_request_get_url(PATH_API_LAP, CONFIG_LAP_API_KEY);
136
137         int retval = http_request_post(url, json, &(response->response_msg), &(response->response_code));
138
139         _D("URL FROM CONFIG (LAP POST): %s", url);
140         free(url);
141         g_free(json);
142
143         if (retval != 0) {
144                 GError *err = g_error_new(G_ERROR_DOMAIN, retval, "http_request_post failed!");
145                 g_task_return_error(task, err);
146         }
147
148         g_task_return_pointer(task, response, (GDestroyNotify)lap_api_post_request_response_free);
149 }
150
151 static void lap_api_post_task_ready_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
152 {
153         GTask *task = G_TASK(res);
154         GError *error = NULL;
155
156         //If no error occurred g_task_propagate_pointer transfers ownership, so later response have to be freed.
157         lap_api_post_request_response_t *response = g_task_propagate_pointer(task, &error);
158         if (error != NULL) {
159                 _E("POST async task failed with msg: %s", error->message);
160                 g_error_free(error);
161                 return;
162         }
163         lap_api_post_request_context_t *context = g_task_get_task_data(task);
164
165         bool result = (response->response_code == 200 && (strncmp(response->response_msg, "Success", strlen("Success")) == 0)) ?
166                 true :
167                 false;
168
169         if (context->cb) {
170                 context->cb(result, context->user_data);
171         }
172
173         lap_api_post_request_response_free(response);
174 }
175
176 static void lap_api_get_task_context_free(lap_api_get_request_context_t *context)
177 {
178         ret_if(!context);
179
180         g_free(context->ap_mac);
181         g_free(context);
182 }
183
184 static void lap_api_get_request_response_free(lap_api_get_request_response_t *response)
185 {
186         ret_if(!response);
187         ret_if(response->size <= 0);
188
189         for (int i = 0; i < response->size; i++)
190         {
191                 lap_info_destroy(response->laps[i]);
192         }
193         g_free(response->laps);
194         g_free(response);
195 }
196
197 static void lap_api_get_task_thread_cb(GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable)
198 {
199         lap_api_get_request_context_t *context = (lap_api_get_request_context_t *)task_data;
200
201         if (g_task_return_error_if_cancelled(task)) {
202                 return;
203         }
204
205         lap_api_get_request_response_t *response = g_new0(lap_api_get_request_response_t, 1);
206         char *response_json = NULL;
207         char *url_with_api = http_request_get_url(PATH_API_LAP, CONFIG_LAP_API_KEY);
208
209         GString *url = g_string_new(url_with_api);
210         g_string_append(url, "?apMac=");
211         g_string_append(url, context->ap_mac);
212
213         free(url_with_api);
214         _D("URL FROM CONFIG (LAP GET): %s", url);
215
216         int retval = http_request_get(url->str, &response_json, &(response->response_code));
217         g_string_free(url, TRUE);
218
219         if (retval != 0) {
220                 GError *err = g_error_new(G_ERROR_DOMAIN, retval, "http_request_get failed!");
221                 g_task_return_error(task, err);
222         }
223         else {
224                 response->laps = lap_info_serializer_deserialize_array(response_json, &(response->size));
225         }
226
227         g_free(response_json);
228         g_task_return_pointer(task, response, (GDestroyNotify)lap_api_get_request_response_free);
229 }
230
231 static void lap_api_get_task_ready_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
232 {
233         GTask *task = G_TASK(res);
234         GError *error = NULL;
235
236         //If no error occurred g_task_propagate_pointer transfers ownership, so later response have to be freed.
237         lap_api_get_request_response_t *response = g_task_propagate_pointer(task, &error);
238         if (error != NULL) {
239                 _E("GET async task failed with msg: %s", error->message);
240                 g_error_free(error);
241                 return;
242         }
243         lap_api_get_request_context_t *context = g_task_get_task_data(task);
244
245         bool result = (response->response_code == 200) ? true : false;
246
247         if (context->cb) {
248                 context->cb(result, response->laps, response->size, context->user_data);
249         }
250
251         lap_api_get_request_response_free(response);
252 }