Release Tizen2.0 beta
[framework/location/libdecarta.git] / decarta / decarta_route.c
1 /*
2  * libdecarta
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #include <glib.h>
23 #include <stdbool.h>
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 #include "decarta_log.h"
28 #include "decarta_config.h"
29 #include "http_wrapper.h"
30 #include "decarta_xml.h"
31 #include "decarta_route.h"
32
33 typedef struct {
34         DecartaRouteCB callback;
35         void *userdata;
36         guint request_id; /**< used to remove from table after success */
37 } DecartaRouteCBData;
38
39 static GHashTable *http_reqid_hash = NULL;
40 static bool is_found = false;
41
42 static gboolean
43 __route_del_table_node_cb(gpointer key,
44         gpointer value,
45         gpointer user_data)
46 {
47         if (!user_data || !key || !value) {
48                 return false;
49         }
50         HttpHandle http_async = NULL;
51
52         http_async = (HttpHandle)value;
53         char *user_key = (char *)user_data;
54         char *table_key = (char *)key;
55
56         if (!g_strcmp0(user_key, table_key)) {
57                 DECARTA_LOGD("req_id [%s] http_async [%d] closed!", table_key, http_async);
58                 g_free(table_key);
59                 http_close(http_async);
60                 is_found = true;
61                 return true;
62         }
63         DECARTA_LOGD("req_id [%s] http_async [%d] not close", table_key, http_async);
64         return false;
65 }
66
67 static void
68 search_route_cb (gboolean success,
69         char *recv_data,
70         void *user_data)
71 {
72         DECARTA_LOGD("search_route_cb");
73         DecartaRouteCBData* cb_data = (DecartaRouteCBData*)user_data;
74         DecartaError err = DECARTA_ERROR_NONE;
75         DecartaRoute *route = NULL;
76         gchar *req_id_str = NULL;
77         gchar *error_code = NULL;
78         gchar *error_msg = NULL;
79         if (success != TRUE) err = DECARTA_ERROR_HTTP;
80         else if (!xml_route_parse(recv_data, &route, &req_id_str, &error_code, &error_msg)) err = DECARTA_ERROR_XML;
81
82         if (cb_data && cb_data->callback) cb_data->callback (err, req_id_str, route, error_code, error_msg, cb_data->userdata);
83         DECARTA_LOGD("search_route_cb callback called");
84
85         /** remove the success request id from hash table */
86         char *request_id_str = g_strdup_printf("%u", cb_data->request_id);
87         if (http_reqid_hash) {
88                 DECARTA_LOGD("remove the http async after success!");
89                 g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__route_del_table_node_cb, (gpointer)request_id_str);
90                 if (!g_hash_table_size(http_reqid_hash)) {
91                         g_hash_table_destroy(http_reqid_hash);
92                         http_reqid_hash = NULL;
93                 }
94         }
95         if (request_id_str) {
96                 g_free(request_id_str);
97         }
98
99         if (recv_data) {
100                 g_free(recv_data);
101         }
102         if (route) {
103                 decarta_route_free (route);
104         }
105         if (req_id_str) {
106                 g_free(req_id_str);
107         }
108         if (error_code) {
109                 g_free(error_code);
110         }
111         if (error_msg) {
112                 g_free(error_msg);
113         }
114         if (cb_data) {
115                 g_free(cb_data);
116         }
117 }
118
119 EXPORT_API int
120 decarta_search_route (const DecartaRouteRequest *request,
121          DecartaRoute **route)
122 {
123         DECARTA_LOGD("decarta_search_route");
124         if (!request || !route)   return DECARTA_ERROR_PARAMETER;
125         if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE;
126
127         int err = DECARTA_ERROR_NONE;
128         char *req = NULL;
129         char *resp = NULL;
130         unsigned int size = 0;
131         gchar *req_id_str = NULL;
132         gchar *error_code = NULL;
133         gchar *error_msg = NULL;
134         if (!xml_route_request_get(request, &req, &size)) return DECARTA_ERROR_PARAMETER;
135         HttpHandle http = http_open(HTTP_TYPE_SYNC);
136         if (http_send(http, req, get_host(), &resp, NULL, NULL)) {
137                 if (!xml_route_parse(resp, route, &req_id_str, &error_code, &error_msg)) err = DECARTA_ERROR_XML;
138         } else err = DECARTA_ERROR_HTTP;
139         if (req) {
140                 g_free (req);
141         }
142         if (resp) {
143                 g_free (resp);
144         }
145         if (req_id_str) {
146                 g_free(req_id_str);
147         }
148         if (error_code) {
149                 g_free(error_code);
150         }
151         if (error_msg) {
152                 g_free(error_msg);
153         }
154         http_close(http);
155         return err;
156 }
157
158 EXPORT_API int
159 decarta_search_route_async (const DecartaRouteRequest *request,
160         DecartaRouteCB callback,
161         void *userdata)
162 {
163         DECARTA_LOGD("decarta_search_route_async");
164         if (!request || !callback) return DECARTA_ERROR_PARAMETER;
165         if (!load_config()) return DECARTA_ERROR_CONFIGURATION_FILE;
166
167         char* req = NULL;
168         unsigned int size = 0;
169         DecartaRouteCBData* cb_data = g_new0(DecartaRouteCBData, 1);
170         cb_data->callback = callback;
171         cb_data->userdata = userdata;
172         cb_data->request_id = request->request_id;
173
174         if (!xml_route_request_get(request, &req, &size)) {
175                 if (cb_data) {
176                         g_free(cb_data);
177                         cb_data = NULL;
178                 }
179                 if (req) {
180                         g_free(req);
181                 }
182                 return DECARTA_ERROR_PARAMETER;
183         }
184
185         char *request_id_str = g_strdup_printf("%u", request->request_id);
186         if (request_id_str == NULL) {
187                 if (cb_data) {
188                         g_free(cb_data);
189                         cb_data = NULL;
190                 }
191                 if (req) {
192                         g_free(req);
193                 }
194                 return DECARTA_ERROR_PARAMETER;
195         }
196
197         HttpHandle http_async = http_open(HTTP_TYPE_ASYNC);
198         DECARTA_LOGD("decarta_search_route_async: http %d, req_id %d", http_async, request->request_id);
199
200         if (!http_reqid_hash) {
201                 http_reqid_hash = g_hash_table_new(g_str_hash, g_str_equal);
202                 if (http_reqid_hash == NULL) {
203                         if (request_id_str) {
204                                 g_free(request_id_str);
205                         }
206                         if (cb_data) {
207                                 g_free(cb_data);
208                                 cb_data = NULL;
209                         }
210                         if (req) {
211                                 g_free(req);
212                         }
213                         http_close(http_async);
214                         return DECARTA_ERROR_HTTP;
215                 }
216                 g_hash_table_insert(http_reqid_hash, (gpointer)request_id_str, (gpointer)http_async);
217                 DECARTA_LOGD("first insert http [0x%x], req_id [%d]", http_async, request->request_id);
218         } else {
219                 g_hash_table_insert(http_reqid_hash, (gpointer)request_id_str, (gpointer)http_async);
220                 DECARTA_LOGD("Not the first insert http [0x%x], req_id [%d]", http_async, request->request_id);
221         }
222
223         if(!http_send(http_async, req, get_host(), NULL, (HttpCallback)search_route_cb, cb_data)){
224                 g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__route_del_table_node_cb, (gpointer)request_id_str);
225                 if (!g_hash_table_size(http_reqid_hash)) {
226                         g_hash_table_destroy(http_reqid_hash);
227                         http_reqid_hash = NULL;
228                 }
229
230                 if (cb_data) {
231                         g_free(cb_data);
232                         cb_data = NULL;
233                 }
234                 if (req) {
235                         g_free(req);
236                 }
237                 return DECARTA_ERROR_HTTP;
238         }
239
240         // cb_data will be freed in callback
241         if (req) {
242                 g_free(req);
243         }
244         return DECARTA_ERROR_NONE;
245 }
246
247 EXPORT_API int
248 decarta_search_route_async_cancel (guint request_id)
249 {
250         DECARTA_LOGD("decarta_search_route_async_cancel: req_id %d called", request_id);
251
252         if (http_reqid_hash) {
253                 char *request_id_str = g_strdup_printf("%u", request_id);
254                 if (request_id_str == NULL) {
255                         return DECARTA_ERROR_NOT_FOUND;
256                 }
257
258                 /** cancel the request_id http async request*/
259                 is_found = false;
260                 g_hash_table_foreach_remove(http_reqid_hash, (GHRFunc)__route_del_table_node_cb, (gpointer)request_id_str);
261                 g_free(request_id_str);
262                 if (is_found == false) {
263                         return DECARTA_ERROR_NOT_FOUND;
264                 }
265         } else {
266                 DECARTA_LOGD("decarta_search_route_async_cancel: req_id %d http_reqid_hash NOT exist!", request_id);
267                 return DECARTA_ERROR_NOT_FOUND;
268         }
269
270         return DECARTA_ERROR_NONE;
271 }