Mapquest Initial codes 46/47546/1 tizen_3.0.m1_mobile tizen_3.0.m1_tv accepted/tizen/ivi/20160218.024009 accepted/tizen/mobile/20150908.232152 accepted/tizen/tv/20150908.232220 accepted/tizen/wearable/20150908.232204 submit/tizen/20150908.104309 submit/tizen_common/20151023.083358 submit/tizen_common/20151026.085049 submit/tizen_ivi/20160217.000000 submit/tizen_ivi/20160217.000003 tizen_3.0.m1_mobile_release tizen_3.0.m1_tv_release tizen_3.0.m2.a1_mobile_release tizen_3.0.m2.a1_tv_release
authorkj7.sung <kj7.sung@samsung.com>
Fri, 4 Sep 2015 11:08:56 +0000 (20:08 +0900)
committerkj7.sung <kj7.sung@samsung.com>
Fri, 4 Sep 2015 11:08:56 +0000 (20:08 +0900)
Change-Id: I9b4bb0dc2821a75bf829dc67300d83c332572b9c
Signed-off-by: kj7.sung <kj7.sung@samsung.com>
29 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
capi-maps-plugin-mapquest.manifest [new file with mode: 0644]
include/mapquest_plugin.h [new file with mode: 0644]
include/mapquest_plugin_internal.h [new file with mode: 0644]
maps-plugin-mapquest.pc.in [new file with mode: 0644]
packaging/maps-plugin-mapquest.spec [new file with mode: 0644]
src/mapquest/mapquest_api.c [new file with mode: 0644]
src/mapquest/mapquest_api.h [new file with mode: 0644]
src/mapquest/mapquest_debug.h [new file with mode: 0644]
src/mapquest/mapquest_geocode.c [new file with mode: 0644]
src/mapquest/mapquest_geocode.h [new file with mode: 0644]
src/mapquest/mapquest_jsonparser.c [new file with mode: 0644]
src/mapquest/mapquest_jsonparser.h [new file with mode: 0644]
src/mapquest/mapquest_place.c [new file with mode: 0644]
src/mapquest/mapquest_place.h [new file with mode: 0644]
src/mapquest/mapquest_queue.c [new file with mode: 0644]
src/mapquest/mapquest_queue.h [new file with mode: 0644]
src/mapquest/mapquest_restcurl.c [new file with mode: 0644]
src/mapquest/mapquest_restcurl.h [new file with mode: 0644]
src/mapquest/mapquest_revgeocode.c [new file with mode: 0644]
src/mapquest/mapquest_revgeocode.h [new file with mode: 0644]
src/mapquest/mapquest_route.c [new file with mode: 0644]
src/mapquest/mapquest_route.h [new file with mode: 0644]
src/mapquest/mapquest_server_private.h [new file with mode: 0644]
src/mapquest/mapquest_types.h [new file with mode: 0644]
src/mapquest/mapquest_util.c [new file with mode: 0644]
src/mapquest/mapquest_util.h [new file with mode: 0644]
src/mapquest_plugin.c [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9263e8e
--- /dev/null
@@ -0,0 +1,117 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_name "maps-plugin-mapquest")
+PROJECT(${fw_name} C CXX)
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+# Dependencies
+SET(dependents "glib-2.0 gmodule-2.0 dlog libcurl capi-network-connection json-glib-1.0 capi-maps-service")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED ${dependents})
+FOREACH(flag ${pkgs_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+    SET(EXTRA_CXXFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+
+# Build
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fvisibility=hidden -fPIC -Wall -Werror")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpie ${EXTRA_CFLAGS} -Wall -g -fPIC -std=c++0x -fvisibility=hidden")
+
+IF("${ARCH}" STREQUAL "arm")
+    ADD_DEFINITIONS("-DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DEXPORT_API=__attribute__((visibility(\"default\")))")
+ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=/usr/lib")
+
+
+# Include files
+# Maps Service Includes
+SET(INC_DIR
+       include
+)
+
+# Maps Service Implementation
+SET(INTERNAL_INC_DIR
+       src
+)
+
+# Mapquest Engine Implementation
+SET(ENGINE_INC_DIR
+       src/mapquest
+)
+INCLUDE_DIRECTORIES(
+${INC_DIR} ${INTERNAL_INC_DIR} ${ENGINE_INC_DIR}
+)
+
+#This file must be corrected
+
+# Source Lists
+SET(SRCS
+       # Maps API
+       src/mapquest_plugin.c
+
+       # Mapquest Engine
+       src/mapquest/mapquest_api.c
+       src/mapquest/mapquest_geocode.c
+       src/mapquest/mapquest_revgeocode.c
+       src/mapquest/mapquest_route.c
+       src/mapquest/mapquest_place.c
+       src/mapquest/mapquest_restcurl.c
+       src/mapquest/mapquest_jsonparser.c
+       src/mapquest/mapquest_queue.c
+       src/mapquest/mapquest_util.c
+)
+
+ADD_LIBRARY(${fw_name} SHARED ${SRCS})
+
+SET_TARGET_PROPERTIES(${fw_name}
+       PROPERTIES
+    VERSION ${FULLVER}
+    SOVERSION ${MAJORVER}
+    CLEAN_DIRECT_OUTPUT 1
+)
+
+TARGET_LINK_LIBRARIES(${fw_name} ${pkgs_LDFLAGS})
+
+SET(PC_NAME ${fw_name})
+SET(PC_DESCRIPTION "Tizen mpaquest plugin Library")
+SET(PC_LDFLAGS -l${fw_name})
+SET(PC_INCLUDE /usr/include/maps)
+
+CONFIGURE_FILE(
+       ${fw_name}.pc.in
+       ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc
+       @ONLY
+)
+
+# Install
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig)
+INSTALL(TARGETS ${fw_name} DESTINATION lib/maps/plugins)
+
+#INCLUDE(FindPkgConfig)
+#pkg_check_modules(lib_pkgs REQUIRED
+#              capi-maps-service
+#)
+
+SET(LIB_APP_ASSIST capi-maps-service)
+INSTALL(
+       DIRECTORY ${INC_DIR}/ DESTINATION include/mapquest-plugin
+    FILES_MATCHING
+    PATTERN "*_internal.h" EXCLUDE
+    PATTERN "${INC_DIR}/mapquest_*.h"
+)
+
+# Test Suite
+#IF("${BINTYPE}" STREQUAL "eng")
+#ENDIF("${BINTYPE}" STREQUAL "eng")
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..1da314d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/capi-maps-plugin-mapquest.manifest b/capi-maps-plugin-mapquest.manifest
new file mode 100644 (file)
index 0000000..97e8c31
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_"/>
+       </request>
+</manifest>
diff --git a/include/mapquest_plugin.h b/include/mapquest_plugin.h
new file mode 100644 (file)
index 0000000..9c4f18c
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_PLUGIN_H_
+#define _MAPQUEST_PLUGIN_H_
+
+#include <maps_plugin.h>
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct callback_geocode {
+       maps_service_geocode_cb callback;
+       void *data;
+       int reqID;
+} callback_info_geocode;
+
+typedef struct callback_reverse_geocode {
+       maps_service_reverse_geocode_cb callback;
+       void *data;
+       int reqID;
+} callback_info_reverse_geocode;
+
+typedef struct callback_route {
+       maps_service_search_route_cb callback;
+       void *data;
+       int reqID;
+} callback_info_route;
+
+typedef struct callback_place {
+       maps_service_search_place_cb callback;
+       void *data;
+       int reqID;
+} callback_info_place;
+
+int maps_plugin_init(maps_plugin_h *plugin);
+
+int maps_plugin_shutdown(maps_plugin_h plugin);
+
+int maps_plugin_is_service_supported(maps_service_e service, bool *supported);
+
+int maps_plugin_is_data_supported(maps_service_data_e data, bool *supported);
+
+int maps_plugin_get_info(maps_plugin_info_h *info);
+
+int maps_plugin_set_provider_key(const char *provider_key);
+
+int maps_plugin_get_provider_key(char **provider_key);
+
+int maps_plugin_set_preference(maps_item_hashtable_h preference);
+
+int maps_plugin_get_preference(maps_item_hashtable_h *preference);
+
+/* Geocode */
+int maps_plugin_geocode(const char *address, const maps_preference_h preference, maps_service_geocode_cb callback, void *user_data, int *request_id);
+
+/* Geocode inside area */
+int maps_plugin_geocode_inside_area(const char *address, const maps_area_h bounds, const maps_preference_h preference, maps_service_geocode_cb callback, void *user_data, int *request_id);
+
+/* Geocode by structured address */
+int maps_plugin_geocode_by_structured_address(const maps_address_h address, const maps_preference_h preference, maps_service_geocode_cb callback, void *user_data, int *request_id);
+
+/* Rev Geocode */
+int maps_plugin_reverse_geocode(double latitude, double longitude, const maps_preference_h preference, maps_service_reverse_geocode_cb callback, void *user_data, int *request_id);
+
+/* Route search */
+int maps_plugin_search_route(const maps_coordinates_h origin, const maps_coordinates_h destination, maps_preference_h preference, maps_service_search_route_cb callback, void *user_data, int *request_id);
+
+/* Route search waypoints */
+int maps_plugin_search_route_waypoints(const maps_coordinates_h *waypoint_list, int waypoint_num, maps_preference_h preference, maps_service_search_route_cb callback, void *user_data, int *request_id);
+
+/* Place search */
+int maps_plugin_search_place(const maps_coordinates_h position, int distance, const maps_place_filter_h filter, maps_preference_h preference, maps_service_search_place_cb callback, void *user_data, int *request_id);
+
+/* Place search by area */
+int maps_plugin_search_place_by_area(const maps_area_h boundary, const maps_place_filter_h filter, maps_preference_h preference, maps_service_search_place_cb callback, void *user_data, int *request_id);
+
+/* Place search by address */
+int maps_plugin_search_place_by_address(const char *address, const maps_area_h boundary, const maps_place_filter_h filter, maps_preference_h preference, maps_service_search_place_cb callback, void *user_data, int *request_id);
+
+/* Cancel Request */
+int maps_plugin_cancel_request(int request_id);
+
+#ifdef __cplusplus
+}
+#endif
+#endif                         /* _MAPQUEST_PLUGIN_H_ */
diff --git a/include/mapquest_plugin_internal.h b/include/mapquest_plugin_internal.h
new file mode 100644 (file)
index 0000000..c9f1fa9
--- /dev/null
@@ -0,0 +1,61 @@
+/* Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __MAPQUEST_PLUGIN_INTERNAL_H__
+#define __MAPQUEST_PLUGIN_INTERNAL_H__
+
+#include <dlog.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "MAPQUEST_PLUGIN"
+
+/*
+ * Internal Macros
+ */
+#define MAPS_LOGD(fmt, args...)  LOGD(fmt, ##args)
+#define MAPS_LOGW(fmt, args...)  LOGW(fmt, ##args)
+#define MAPS_LOGI(fmt, args...)  LOGI(fmt, ##args)
+#define MAPS_LOGE(fmt, args...)  LOGE(fmt, ##args)
+#define MAPS_SECLOG(fmt, args...)  SECURE_LOGD(fmt, ##args)
+
+#define MAPS_CHECK_CONDITION(condition, error, msg)    \
+       do { \
+               if (condition) { \
+               } else { \
+                       MAPS_LOGE("%s(0x%08x)", msg, error); \
+                       return error; \
+               } \
+       } while (0)
+
+#define MAPS_NULL_ARG_CHECK_RETURN_FALSE(arg)\
+       do { \
+               if (arg != NULL) { \
+               } else  { \
+                       MAPS_LOGE("MAPS_ERROR_INVALID_PARAMETER");  \
+                       return false; };        \
+       } while (0)
+
+#define MAPS_NULL_ARG_CHECK(arg)       \
+       MAPS_CHECK_CONDITION(arg != NULL, MAPS_ERROR_INVALID_PARAMETER, "MAPS_ERROR_INVALID_PARAMETER")
+
+#define MAPS_PRINT_ERROR_CODE_RETURN(code) \
+       do { \
+               MAPS_LOGE("%s(0x%08x)", #code, code); \
+               return code;    \
+       } while (0)
+
+#endif /* __MAPQUEST_PLUGIN_INTERNAL_H__ */
diff --git a/maps-plugin-mapquest.pc.in b/maps-plugin-mapquest.pc.in
new file mode 100644 (file)
index 0000000..599cd78
--- /dev/null
@@ -0,0 +1,14 @@
+#Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=/usr/lib
+includedir=@PC_INCLUDE@
+
+Name: @PC_NAME@
+Description: @PC_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
+
diff --git a/packaging/maps-plugin-mapquest.spec b/packaging/maps-plugin-mapquest.spec
new file mode 100644 (file)
index 0000000..0a48ec8
--- /dev/null
@@ -0,0 +1,95 @@
+Name:       maps-plugin-mapquest
+Summary:    Tizen MapQuest Maps Plug-in Library
+Version:    0.0.3
+Release:    1
+Group:      Location/Libraries
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+
+#Requires(post): eglibc
+#Requires(postun): eglibc
+
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(gmodule-2.0)
+BuildRequires:  pkgconfig(dlog)
+BuildRequires: pkgconfig(libcurl)
+BuildRequires:  pkgconfig(capi-network-connection)
+BuildRequires: pkgconfig(capi-maps-service)
+BuildRequires:  capi-maps-service-plugin-devel
+BuildRequires:  pkgconfig(json-glib-1.0)
+Requires(post):  /sbin/ldconfig
+Requires(postun):  /sbin/ldconfig
+
+%ifarch %{arm}
+%define ARCH arm
+%else
+%define ARCH i586
+%endif
+
+%description
+This packages provides Plugin APIs capsulating MapQuest Maps Open APIs for Maps Service Library.
+
+%prep
+%setup -q
+
+%build
+%if 0%{?tizen_build_binary_release_type_eng}
+export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE -g"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_ENGINEER_MODE -g"
+export FFLAGS="$FFLAGS -DTIZEN_ENGINEER_MODE"
+%endif
+
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DMAJORVER=${MAJORVER} -DFULLVER=%{version}
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}/usr/share/license
+cp LICENSE %{buildroot}/usr/share/license/%{name}
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
+
+%files
+%manifest capi-maps-plugin-mapquest.manifest
+%defattr(-,root,root,-)
+%{_prefix}/lib/maps/plugins/libmaps-plugin-mapquest.so
+%{_prefix}/lib/maps/plugins/libmaps-plugin-mapquest.so.*
+%{_prefix}/lib/pkgconfig/maps-plugin-mapquest.pc
+/usr/share/license/maps-plugin-mapquest
+
+%package devel
+Summary:    Tizen MapsQuest Maps Plug-in Library (Development)
+Group:      Framework/maps
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+This packages provides Plugin APIs capsulating MapQuest Maps Open APIs for Maps Service Library. (Development)
+
+%post devel
+/sbin/ldconfig
+
+%postun devel
+/sbin/ldconfig
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/mapquest-plugin/*.h
+%{_prefix}/lib/pkgconfig/maps-plugin-mapquest.pc
+%{_prefix}/lib/maps/plugins/libmaps-plugin-mapquest.so
+
+%package test
+Summary:    Tizen MapQuest Maps Plug-in Library (Internal Dev)
+Group:      Framework/maps
+Requires:   capi-maps-service = %{version}-%{release}
+
+%description test
+This packages provides Plugin APIs capsulating MapQuest Maps Open APIs for Maps Service Library. (Internal Dev)
+
diff --git a/src/mapquest/mapquest_api.c b/src/mapquest/mapquest_api.c
new file mode 100644 (file)
index 0000000..88f1da9
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "mapquest_api.h"
+#include "mapquest_server_private.h"
+#include "mapquest_queue.h"
+#include "mapquest_debug.h"
+
+EXPORT_API int mapquest_init()
+{
+       int ret = mapquest_init_queue();
+
+       return ret;
+}
+
+EXPORT_API int mapquest_shutdown()
+{
+       int ret = mapquest_deinit_queue();
+
+       return ret;
+}
+
+EXPORT_API int mapquest_geocode(mapquest_geocode_req_s *req_details, mapquest_geocode_cb callback, int request_id, void *user_data)
+{
+       int ret = MAPQUEST_ERROR_NONE;
+       ret = start_geocode_service(req_details, callback, request_id, user_data);
+
+       return ret;
+}
+
+EXPORT_API int mapquest_cancel_request(int request_id)
+{
+       int ret = remove_from_request_list(request_id);
+
+       return ret;
+}
+
+EXPORT_API int mapquest_reverse_geocode(mapquest_revgeocode_req_s *req_details, mapquest_reverse_geocode_cb callback, int request_id, void *user_data)
+{
+       int ret = MAPQUEST_ERROR_NONE;
+       ret = start_reversegeocode_service(req_details, callback, request_id, user_data);
+
+       return ret;
+}
+
+EXPORT_API int mapquest_search_place(mapquest_search_req_s *req_details, mapquest_place_search_cb callback, int request_id, void *user_data)
+{
+       int ret = MAPQUEST_ERROR_NONE;
+       ret = start_places_service(req_details, callback, request_id, user_data);
+
+       return ret;
+}
+
+EXPORT_API int mapquest_start_route(mapquest_route_req_s *req_details, mapquest_route_cb callback, int request_id, void *user_data)
+{
+       int ret = MAPQUEST_ERROR_NONE;
+       ret = start_route_service(req_details, callback, request_id, user_data);
+
+       return ret;
+}
diff --git a/src/mapquest/mapquest_api.h b/src/mapquest/mapquest_api.h
new file mode 100644 (file)
index 0000000..479e306
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_API_H_
+#define _MAPQUEST_API_H_
+
+#include "mapquest_types.h"
+#include <tizen_type.h>
+
+/**
+ * @ingroup    MAPQUEST_ENGINE_MODULE
+ * @defgroup   MAPQUEST_ENGINE_API_MODULE
+ *
+ * @file mapquest_api.h
+ * @brief This file contains the MapQuest engine API's that should be called by the plugin
+ *
+ * @addtogroup MAPQUEST_ENGINE_MODULE
+ * @{
+ * @brief This provides APIs related to MapQuest engine.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  /* Callbacks */
+typedef void (*mapquest_geocode_cb) (mapquest_error_e result, int request_id, GList *co_ordinates, void *user_data);
+
+typedef void (*mapquest_reverse_geocode_cb) (mapquest_error_e result, int request_id, mapquest_address_resp_s *address, void *user_data);
+
+typedef void (*mapquest_place_search_cb) (mapquest_error_e result, int request_id, GList *places, void *user_data);
+
+typedef void (*mapquest_route_cb) (mapquest_error_e result, int request_id, mapquest_route_resp_s *route_info, void *user_data);
+
+typedef void (*mapquest_maptile_cb) (mapquest_error_e result, int request_id, char *buffer, void *user_data);
+
+int mapquest_init();
+
+int mapquest_shutdown();
+
+int mapquest_geocode(mapquest_geocode_req_s *req_details, mapquest_geocode_cb callback, int request_id, void *user_data);
+
+int mapquest_cancel_request(int request_id);
+
+int mapquest_reverse_geocode(mapquest_revgeocode_req_s *req_details, mapquest_reverse_geocode_cb callback, int request_id, void *user_data);
+
+int mapquest_search_place(mapquest_search_req_s *req_details, mapquest_place_search_cb callback, int request_id, void *user_data);
+
+int mapquest_start_route(mapquest_route_req_s *req_details, mapquest_route_cb callback, int request_id, void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif                         /* _MAPQUEST_API_H_ */
diff --git a/src/mapquest/mapquest_debug.h b/src/mapquest/mapquest_debug.h
new file mode 100644 (file)
index 0000000..8bdec35
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#ifndef _MAPQUEST_DEBUG_H_
+#define _MAPQUEST_DEBUG_H_
+
+#include <dlog.h>
+#include <string.h>
+#include <assert.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define EXPORT_API __attribute__((visibility("default")))
+
+#define LOG_TAG "MAPQUEST_ENGINE"
+
+/* normal log */
+#define MAP_DEBUG(fmt, args...) LOGD(fmt, ##args)
+#define MAP_ENTER() LOGD(WCOLOR_GREEN "BEGIN >>>>" WCOLOR_END)
+#define MAP_LEAVE() LOGD(WCOLOR_GREEN "END <<<<" WCOLOR_END)
+
+#endif /* _MAPQUEST_DEBUG_H_ */
diff --git a/src/mapquest/mapquest_geocode.c b/src/mapquest/mapquest_geocode.c
new file mode 100644 (file)
index 0000000..553dce2
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include <pthread.h>
+#include "mapquest_geocode.h"
+#include "mapquest_types.h"
+#include "mapquest_server_private.h"
+#include "mapquest_debug.h"
+#include "mapquest_queue.h"
+#include "mapquest_restcurl.h"
+
+#define GEOCODE_URL    "https://open.mapquestapi.com/geocoding/v1/address?key=%s&inFormat=kvp&outFormat=json"
+
+int query_geocode_within_bounds(gchar *maps_key, char *address, coords_s top_left, coords_s bottom_right, int num_results, gpointer user_data)
+{
+       char url[1024];
+       char tmpStr[512];
+
+       if (maps_key != NULL)
+               snprintf(tmpStr, sizeof(tmpStr), GEOCODE_URL, maps_key);
+       else
+               snprintf(tmpStr, sizeof(tmpStr), GEOCODE_URL, "null");
+
+       strcpy(url, tmpStr);
+
+       snprintf(tmpStr, sizeof(tmpStr), "&boundingBox=%f,%f,%f,%f", top_left.latitude, top_left.longitude, bottom_right.latitude, bottom_right.longitude);
+       strcat(url, tmpStr);
+
+       snprintf(tmpStr, sizeof(tmpStr), "&maxResults=%d", num_results);
+       strcat(url, tmpStr);
+
+       snprintf(tmpStr, sizeof(tmpStr), "&location=%s", address);
+       strcat(url, tmpStr);
+
+       add_handle(url, REQ_TYPE_GEOCODE, user_data);
+
+       return 0;
+}
+
+int query_geocode(gchar *maps_key, char *address, int num_results, gpointer user_data)
+{
+       MAP_DEBUG("geocode address : %s", address);
+       char url[1024];
+       char tmpStr[512];
+
+       if (maps_key != NULL)
+               snprintf(tmpStr, sizeof(tmpStr), GEOCODE_URL, maps_key);
+       else
+               snprintf(tmpStr, sizeof(tmpStr), GEOCODE_URL, "null");
+
+       strcpy(url, tmpStr);
+
+       snprintf(tmpStr, sizeof(tmpStr), "&maxResults=%d", num_results);
+       strcat(url, tmpStr);
+
+       snprintf(tmpStr, sizeof(tmpStr), "&location=%s", address);
+       strcat(url, tmpStr);
+
+       add_handle(url, REQ_TYPE_GEOCODE, user_data);
+
+       return 0;
+}
diff --git a/src/mapquest/mapquest_geocode.h b/src/mapquest/mapquest_geocode.h
new file mode 100644 (file)
index 0000000..85c689e
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_GEOCODE_H_
+#define _MAPQUEST_GEOCODE_H_
+
+#include "mapquest_api.h"
+#include "mapquest_types.h"
+
+int query_geocode(gchar *maps_key, char *address, int num_results, gpointer user_data);
+int query_geocode_within_bounds(gchar *maps_key, char *address, coords_s top_left, coords_s bottom_right, int num_results, gpointer user_data);
+
+#endif /* MAPQUEST_GEOCODE_H_ */
diff --git a/src/mapquest/mapquest_jsonparser.c b/src/mapquest/mapquest_jsonparser.c
new file mode 100644 (file)
index 0000000..e549a5c
--- /dev/null
@@ -0,0 +1,1124 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <json-glib/json-glib.h>
+#include "mapquest_jsonparser.h"
+#include "mapquest_queue.h"
+#include "mapquest_debug.h"
+
+#define ROUTE_UNIT_CONVERSION_MILE_TO_M(x)     (1609.34 * (x))
+#define ROUTE_UNIT_CONVERSION_MILE_TO_KM(x)    (1.60934 * (x))
+#define ROUTE_UNIT_CONVERSION_MILE_TO_FT(x)    (5280 * (x))
+#define ROUTE_UNIT_CONVERSION_MILE_TO_YD(x)    (1760 * (x))
+
+static route_unit __route_unit = ROUTE_UNIT_M;
+static int __maneuver_index = 0;
+static coords_s __destination_point;
+
+static mapquest_error_e __convert_status(int status)
+{
+       mapquest_error_e error = MAPQUEST_ERROR_UNKNOWN;
+       switch (status) {
+       case 0:
+               {
+                       /* Successful Geocode call */
+                       error = MAPQUEST_ERROR_NONE;
+                       break;
+               }
+       case 400:
+               {
+                       /* Error with input - Illegal argument from request */
+                       error = MAPQUEST_ERROR_INVALID_PARAMETER;
+                       break;
+               }
+       case 403:
+               {
+                       /* Key related error - Invalid key */
+                       error = MAPQUEST_ERROR_KEY_NOT_AVAILABLE;
+                       break;
+               }
+       case 500:
+               {
+                       /* Unknown error */
+                       error = MAPQUEST_ERROR_UNKNOWN;
+                       break;
+               }
+       case -1:
+               {
+                       /* Network error */
+                       error = MAPQUEST_ERROR_NETWORK_UNREACHABLE;
+                       break;
+               }
+       }
+
+       return error;
+}
+
+/************ GEOCODE ***************/
+
+static void __parse_lat_lng(JsonNode *node, GList **coordsList)
+{
+       if (!node || !coordsList) return;
+
+       gdouble latitude = 0.0;
+       gdouble longitude = 0.0;
+       JsonObject *resultObj = json_node_get_object(node);
+
+       if (resultObj) {
+               JsonNode *latNode = json_object_get_member(resultObj, "lat");
+
+               if (latNode) {
+                       latitude = json_node_get_double(latNode);
+                       MAP_DEBUG("Latitude :: >>> %f", latitude);
+               }
+
+               JsonNode *lngNode = json_object_get_member(resultObj, "lng");
+
+               if (lngNode) {
+                       longitude = json_node_get_double(lngNode);
+                       MAP_DEBUG("Longitude :: >>> %f", longitude);
+               }
+
+               coords_s *coords = (coords_s *)g_malloc0(sizeof(coords_s));
+               if (coords != NULL) {
+                       MAP_DEBUG("Storing the latitude and longitude data..");
+                       coords->latitude = latitude;
+                       coords->longitude = longitude;
+               }
+
+               if (*coordsList == NULL)
+                       *coordsList = g_list_append(*coordsList, coords);
+               else
+                       *coordsList = g_list_insert_before(*coordsList, NULL, coords);
+       }
+}
+
+static void __parse_locations(JsonNode *node, GList **coordsList)
+{
+       if (!node || !coordsList) return;
+
+       JsonArray *resultArray = json_node_get_array(node);
+
+       int length = json_array_get_length(resultArray);
+
+       int index = 0;
+       for (index = 0; index < length; index++) {
+
+               JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+               if (obj) {
+                       JsonNode *latLngNode = json_object_get_member(obj, "latLng");
+
+                       if (latLngNode)
+                               __parse_lat_lng(latLngNode, coordsList);
+               }
+       }
+}
+
+static void __parse_geocode_response(char *response, int size, int *status, GList **coordsList)
+{
+       if (!response || !status || !coordsList) return;
+
+       *coordsList = NULL;
+
+       JsonParser *parser = NULL;
+       JsonNode *root = NULL;
+       JsonNode *node = NULL;
+       JsonObject *object = NULL;
+       GError *error = NULL;
+       char data[size + 1];
+
+       parser = json_parser_new();
+
+       strncpy(data, response, size);
+       data[size] = '\0';
+
+       if (!json_parser_load_from_data(parser, data, -1, &error)) {
+               MAP_DEBUG("Error in file parsing JSON..");
+               g_error_free(error);
+               g_object_unref(parser);
+               return;
+       }
+
+       root = json_parser_get_root(parser);
+
+       object = json_node_get_object(root);
+
+       node = json_object_get_member(object, "info");
+       JsonObject *infoObj = json_node_get_object(node);
+       if (infoObj) {
+               JsonNode *statusNode = json_object_get_member(infoObj, "statuscode");
+
+               if (statusNode) {
+                       *status = json_node_get_int(statusNode);
+                       MAP_DEBUG("status :: >>> %d", *status);
+               }
+       }
+
+       if (*status != 0) {     /* SUCCESS */
+               *coordsList = NULL;
+               return;
+       }
+
+       node = json_object_get_member(object, "results");
+       JsonArray *resultArray = json_node_get_array(node);
+
+       int length = json_array_get_length(resultArray);
+
+       int index = 0;
+       for (index = 0; index < length; index++) {
+
+               JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+               if (obj) {
+                       JsonNode *locNode = json_object_get_member(obj, "locations");
+
+                       if (locNode)
+                               __parse_locations(locNode, coordsList);
+               }
+       }
+
+       g_object_unref(parser);
+}
+
+/****************** REVERSE GEOCODE *********************/
+
+static void __parse_revgeocode_address(JsonNode *node, mapquest_address_resp_s **respAddr)
+{
+       if (!node || !respAddr) return;
+
+       char *streetAddr = NULL;
+       char *neighbourhood = NULL;
+       char *city = NULL;
+       char *county =  NULL;
+       char *state = NULL;
+       char *country = NULL;
+       char *postalCode = NULL;
+
+       JsonArray *resultArray = json_node_get_array(node);
+
+       int length = json_array_get_length(resultArray);
+
+       int index = 0;
+       for (index = 0; index < length; index++) {
+
+               JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+               if (obj) {
+                       JsonNode *tmp = NULL;
+
+                       /* Street */
+                       tmp = json_object_get_member(obj, "street");
+                       if (tmp) {
+                               streetAddr = (char *) json_node_get_string(tmp);
+                               if (streetAddr && strlen(streetAddr) <= 0)
+                                       streetAddr = NULL;
+                       } else {
+                               streetAddr = NULL;
+                       }
+
+                       /* Neighborhood */
+                       tmp = json_object_get_member(obj, "adminArea6");
+                       if (tmp) {
+                               neighbourhood = (char *) json_node_get_string(tmp);
+                               if (neighbourhood && strlen(neighbourhood) <= 0)
+                                       neighbourhood = NULL;
+                       } else {
+                               neighbourhood = NULL;
+                       }
+
+                       /* City */
+                       tmp = json_object_get_member(obj, "adminArea5");
+                       if (tmp) {
+                               city = (char *) json_node_get_string(tmp);
+                               if (city && strlen(city) <= 0)
+                                       city = NULL;
+                       } else {
+                               city = NULL;
+                       }
+
+                       /* State */
+                       tmp = json_object_get_member(obj, "adminArea3");
+                       if (tmp) {
+                               state = (char *) json_node_get_string(tmp);
+                               if (state && strlen(state) <= 0)
+                                       state = NULL;
+                       } else {
+                               state = NULL;
+                       }
+
+                       /* County */
+                       tmp = json_object_get_member(obj, "adminArea4");
+                       if (tmp) {
+                               county = (char *) json_node_get_string(tmp);
+                               if (county && strlen(county) <= 0)
+                                       county = NULL;
+                       } else {
+                               county = NULL;
+                       }
+
+                       /* Country */
+                       tmp = json_object_get_member(obj, "adminArea1");
+                       if (tmp) {
+                               country = (char *) json_node_get_string(tmp);
+                               if (country && strlen(country) <= 0)
+                                       country = NULL;
+                       } else {
+                               country = NULL;
+                       }
+
+                       /* Postal Code */
+                       tmp = json_object_get_member(obj, "postalCode");
+                       if (tmp) {
+                               postalCode = (char *) json_node_get_string(tmp);
+                               if (postalCode && strlen(postalCode) <= 0)
+                                       postalCode = NULL;
+                       } else {
+                               postalCode = NULL;
+                       }
+
+                       if (!streetAddr && !neighbourhood && !city && !state && !county && !country && !postalCode)
+                               continue;
+
+                       *respAddr = (mapquest_address_resp_s *)g_malloc(sizeof(mapquest_address_resp_s));
+
+                       if (*respAddr != NULL) {
+                               /* Street Address */
+                               if (streetAddr != NULL) {
+                                       (*respAddr)->street_add = (gchar *)g_malloc(strlen((char *)streetAddr) + 1);
+                                       strcpy((*respAddr)->street_add, (char *) streetAddr);
+                               } else {
+                                       MAP_DEBUG("street is NULL");
+                                       (*respAddr)->street_add = NULL;
+                               }
+
+                               /* Neighbourhood */
+                               if (neighbourhood != NULL) {
+                                       (*respAddr)->neighbourhood =    (gchar *)g_malloc(strlen((char *)neighbourhood) + 1);
+                                       strcpy((*respAddr)->neighbourhood, (char *) neighbourhood);
+                               } else {
+                                       MAP_DEBUG("neighbourhood is NULL");
+                                       (*respAddr)->neighbourhood = NULL;
+                               }
+
+                               /* City */
+                               if (city != NULL) {
+                                       (*respAddr)->city = (gchar *)g_malloc(strlen((char *)city) + 1);
+                                       strcpy((*respAddr)->city, (char *) city);
+                               } else {
+                                       MAP_DEBUG("city is NULL");
+                                       (*respAddr)->city = NULL;
+                               }
+
+                               /* County */
+                               if (county != NULL) {
+                                       (*respAddr)->county = (gchar *)g_malloc(strlen((char *)county) + 1);
+                                       strcpy((*respAddr)->county, (char *) county);
+                               } else {
+                                       MAP_DEBUG("county is NULL");
+                                       (*respAddr)->county = NULL;
+                               }
+
+                               /* State */
+                               if (state != NULL) {
+                                       (*respAddr)->state = (gchar *)g_malloc(strlen((char *)state) + 1);
+                                       strcpy((*respAddr)->state, (char *) state);
+                               } else {
+                                       MAP_DEBUG("state is NULL");
+                                       (*respAddr)->state = NULL;
+                               }
+
+                               /* Country */
+                               if (country != NULL) {
+                                       (*respAddr)->country = (gchar *)g_malloc(strlen((char *)country) + 1);
+                                       strcpy((*respAddr)->country, (char *) country);
+                               } else {
+                                       MAP_DEBUG("country is NULL");
+                                       (*respAddr)->country = NULL;
+                               }
+
+                               /* Country code */
+                               MAP_DEBUG("country code is NULL");
+                               (*respAddr)->country_code = NULL;
+
+                               /* Postal Code */
+                               if (postalCode != NULL) {
+                                       (*respAddr)->postal_code = (gchar *)g_malloc(strlen((char *)postalCode) + 1);
+                                       strcpy((*respAddr)->postal_code, (char *) postalCode);
+                               } else {
+                                       MAP_DEBUG("postal_code is NULL");
+                                       (*respAddr)->postal_code = NULL;
+                               }
+                       }
+               }
+       }
+}
+
+static void __parse_revgeocode_response(char *response, int size, int *status, mapquest_address_resp_s **respAddr)
+{
+       if (!response || !status || !respAddr) return;
+
+       *respAddr = NULL;
+
+       JsonParser *parser;
+       JsonNode *root;
+       JsonNode *node;
+       JsonObject *object;
+       GError *error = NULL;
+       char data[size + 1];
+
+       parser = json_parser_new();
+
+       strncpy(data, response, size);
+       data[size] = '\0';
+
+       if (!json_parser_load_from_data(parser, data, -1, &error)) {
+               MAP_DEBUG("Error in file parsing JSON..");
+               g_error_free(error);
+               g_object_unref(parser);
+               return;
+       }
+
+       root = json_parser_get_root(parser);
+
+       object = json_node_get_object(root);
+
+       node = json_object_get_member(object, "info");
+       JsonObject *infoObj = json_node_get_object(node);
+       if (infoObj) {
+               JsonNode *statusNode = json_object_get_member(infoObj, "statuscode");
+
+               if (statusNode) {
+                       *status = json_node_get_int(statusNode);
+                       MAP_DEBUG("status :: >>> %d", *status);
+               }
+       }
+
+       if (*status != 0) {     /* SUCCESS */
+               *respAddr = NULL;
+               return;
+       }
+
+       node = json_object_get_member(object, "results");
+       JsonArray *resultArray = json_node_get_array(node);
+
+       int length = json_array_get_length(resultArray);
+
+       int index = 0;
+       for (index = 0; index < length; index++) {
+
+               JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+               if (obj) {
+                       JsonNode *locNode = json_object_get_member(obj, "locations");
+
+                       if (locNode)
+                               __parse_revgeocode_address(locNode, respAddr);
+               }
+       }
+
+       g_object_unref(parser);
+}
+
+/****************  PLACE SEARCH ********************/
+
+static void __place_address_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+       if (!object || !member_name || !member_node || !user_data) return;
+
+       mapquest_address_resp_s **respAddr = (mapquest_address_resp_s **) user_data;
+
+       if (*respAddr) {
+               JsonNode *tmp = json_object_get_member(object, member_name);
+
+               if (!strcmp(member_name, "road"))
+                       (*respAddr)->street_add = (char *) json_node_dup_string(tmp);
+               else if (!strcmp(member_name, "neighbourhood"))
+                       (*respAddr)->neighbourhood = (char *) json_node_dup_string(tmp);
+               else if (!strcmp(member_name, "house_number"))
+                       (*respAddr)->building_number = (char *) json_node_dup_string(tmp);
+               else if (!strcmp(member_name, "city"))
+                       (*respAddr)->city = (char *) json_node_dup_string(tmp);
+               else if (!strcmp(member_name, "county"))
+                       (*respAddr)->county = (char *) json_node_dup_string(tmp);
+               else if (!strcmp(member_name, "state"))
+                       (*respAddr)->state = (char *) json_node_dup_string(tmp);
+               else if (!strcmp(member_name, "country"))
+                       (*respAddr)->country = (char *) json_node_dup_string(tmp);
+               else if (!strcmp(member_name, "country_code"))
+                       (*respAddr)->country_code = (char *) json_node_dup_string(tmp);
+               else if (!strcmp(member_name, "postcode"))
+                       (*respAddr)->postal_code = (char *) json_node_dup_string(tmp);
+       } else {
+               *respAddr = NULL;
+       }
+}
+
+static void __place_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+       if (!object || !member_name || !member_node || !user_data) return;
+
+       mapquest_place_resp_s **respPlaces = (mapquest_place_resp_s **) user_data;
+
+       JsonNode *tmp = json_object_get_member(object, member_name);
+       char *str;
+
+       if (!strcmp(member_name, "place_id")) {
+               (*respPlaces)->place_id = (char *) json_node_get_string(tmp);
+       } else if (!strcmp(member_name, "lat")) {
+               str = (char *) json_node_get_string(tmp);
+               ((*respPlaces)->coordinates).latitude = (str ? atof(str) : 0);
+       } else if (!strcmp(member_name, "lon")) {
+               str = (char *) json_node_get_string(tmp);
+               ((*respPlaces)->coordinates).longitude = (str ? atof(str) : 0);
+       } else if (!strcmp(member_name, "class")) {
+               (*respPlaces)->category = (char *) json_node_dup_string(tmp);
+       } else if (!strcmp(member_name, "type")) {
+               (*respPlaces)->subcategory = (char *) json_node_dup_string(tmp);
+       } else if (!strcmp(member_name, "display_name")) {
+               (*respPlaces)->display_name = (char *) json_node_dup_string(tmp);
+       } else if (!strcmp(member_name, "address")) {
+               JsonObject *obj = json_node_get_object(member_node);
+
+               (*respPlaces)->address = (mapquest_address_resp_s *)g_malloc(sizeof(mapquest_address_resp_s));
+               if ((*respPlaces)->address) {
+                       (*respPlaces)->address->street_add = NULL;
+                       (*respPlaces)->address->neighbourhood = NULL;
+                       (*respPlaces)->address->building_number = NULL;
+                       (*respPlaces)->address->city = NULL;
+                       (*respPlaces)->address->county = NULL;
+                       (*respPlaces)->address->state = NULL;
+                       (*respPlaces)->address->country = NULL;
+                       (*respPlaces)->address->country_code = NULL;
+                       (*respPlaces)->address->postal_code = NULL;
+               }
+
+               json_object_foreach_member(obj, __place_address_foreach, &((*respPlaces)->address));
+       } else if (!strcmp(member_name, "icon")) {
+               (*respPlaces)->icon_url = (char *) json_node_get_string(tmp);
+       }
+}
+
+static void __parse_place_response(char *response, int size, GList **placeList)
+{
+       if (!response || !placeList) return;
+
+       *placeList = NULL;
+
+       JsonParser *parser;
+       JsonNode *root;
+       GError *error = NULL;
+       char data[size + 1];
+
+       parser = json_parser_new();
+       if (!parser) return;
+
+       strncpy(data, response, size);
+       data[size] = '\0';
+
+       if (!json_parser_load_from_data(parser, data, -1, &error)) {
+               MAP_DEBUG("Error in file parsing JSON..");
+               g_error_free(error);
+               g_object_unref(parser);
+               return;
+       }
+
+       root = json_parser_get_root(parser);
+
+       JsonArray *placeArray = json_node_get_array(root);
+
+       int length = json_array_get_length(placeArray);
+       MAP_DEBUG("Places result count :: %d", length);
+
+       int index = 0;
+       for (index = 0; index < length; index++) {
+
+               JsonObject *obj = json_array_get_object_element(placeArray, index);
+
+               if (obj) {
+                       mapquest_place_resp_s *respPlaces = (mapquest_place_resp_s *)g_malloc(sizeof(mapquest_place_resp_s));
+
+                       if (respPlaces) {
+                               respPlaces->place_id = NULL;
+                               respPlaces->category = NULL;
+                               respPlaces->subcategory = NULL;
+                               respPlaces->display_name = NULL;
+                               respPlaces->address = NULL;
+                               respPlaces->icon_url = NULL;
+
+                               json_object_foreach_member(obj, __place_foreach, &respPlaces);
+
+                               if (*placeList == NULL)
+                                       *placeList = g_list_append(*placeList, respPlaces);
+                               else
+                                       *placeList = g_list_insert_before(*placeList, NULL, respPlaces);
+                       }
+               }
+       }
+
+       g_object_unref(parser);
+}
+
+/********************* ROUTE RESPONSE ***********************/
+
+static double __convert_distance_unit(double distance)
+{
+       double val = 0.0;
+       switch (__route_unit) {
+       case ROUTE_UNIT_M:
+               val = ROUTE_UNIT_CONVERSION_MILE_TO_M(distance);
+               break;
+       case ROUTE_UNIT_KM:
+               val = ROUTE_UNIT_CONVERSION_MILE_TO_KM(distance);
+               break;
+       case ROUTE_UNIT_FT:
+               val = ROUTE_UNIT_CONVERSION_MILE_TO_FT(distance);
+               break;
+       case ROUTE_UNIT_YD:
+               val = ROUTE_UNIT_CONVERSION_MILE_TO_YD(distance);
+               break;
+       }
+
+       return val;
+}
+
+static void __maneuver_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+       if (!object || !member_name || !member_node || !user_data) return;
+
+       mapquest_route_maneuver **maneuver = (mapquest_route_maneuver **) user_data;
+
+       JsonNode *tmp = json_object_get_member(object, member_name);
+
+       if (!strcmp(member_name, "startPoint")) {
+               JsonObject *coordsObj = json_node_get_object(tmp);
+
+               if (coordsObj) {
+                       double latitude = 0.0;
+                       double longitude = 0.0;
+                       JsonNode *latNode = json_object_get_member(coordsObj, "lat");
+
+                       if (latNode)
+                               latitude = json_node_get_double(latNode);
+
+                       JsonNode *lngNode = json_object_get_member(coordsObj, "lng");
+
+                       if (lngNode)
+                               longitude = json_node_get_double(lngNode);
+
+                       coords_s start_point;
+                       start_point.latitude = latitude;
+                       start_point.longitude = longitude;
+
+                       (*maneuver)->start_point = start_point;
+               }
+       } else if (!strcmp(member_name, "narrative")) {
+               (*maneuver)->instruction = (char *) json_node_dup_string(tmp);
+       } else if (!strcmp(member_name, "distance")) {
+               double dist = json_node_get_double(tmp);
+               (*maneuver)->distance = __convert_distance_unit(dist);
+       } else if (!strcmp(member_name, "time")) {
+               (*maneuver)->time = json_node_get_int(tmp);
+       } else if (!strcmp(member_name, "formattedTime")) {
+               (*maneuver)->formatted_time = (char *) json_node_dup_string(tmp);
+       } else if (!strcmp(member_name, "attributes")) {
+               (*maneuver)->attribute = json_node_get_int(tmp);
+       } else if (!strcmp(member_name, "turnType")) {
+               (*maneuver)->turn_type = json_node_get_int(tmp);
+       } else if (!strcmp(member_name, "direction")) {
+               (*maneuver)->direction = json_node_get_int(tmp);
+       } else if (!strcmp(member_name, "directionName")) {
+               (*maneuver)->direction_name = (char *) json_node_dup_string(tmp);
+       } else if (!strcmp(member_name, "index")) {
+               (*maneuver)->index = json_node_get_int(tmp);
+       } else if (!strcmp(member_name, "streets")) {
+               JsonArray *streetsArray = json_node_get_array(tmp);
+
+               int length = json_array_get_length(streetsArray);
+
+               char street_name[512];
+               strcpy(street_name, "");
+               int index = 0;
+               for (index = 0; index < length; index++) {
+                       char *name = (char *) json_array_get_string_element(streetsArray, index);
+                       if (name) {
+                               if (index == 0) {
+                                       strncpy(street_name, name, sizeof(street_name)-1);
+                               } else {
+                                       strcat(street_name, "/");
+                                       strncat(street_name, name, sizeof(street_name)-strlen(street_name)-1);
+                               }
+                       }
+               }
+
+               if (strlen(street_name) > 0) {
+                       (*maneuver)->street_name = (gchar *)g_malloc0((strlen((char *)street_name)) + 1);
+                       if ((*maneuver)->street_name)
+                               strcpy((*maneuver)->street_name, (char *) street_name);
+               } else {
+                       (*maneuver)->street_name = NULL;
+               }
+       }
+}
+
+static void __parse_maneuvers(JsonNode *node, mapquest_route_resp_s **routeResp)
+{
+       if (!node || !routeResp) return;
+
+       JsonArray *resultArray = json_node_get_array(node);
+
+       int length = json_array_get_length(resultArray);
+
+       int index = 0;
+       for (index = 0; index < length; index++) {
+
+               JsonObject *obj = json_array_get_object_element(resultArray, index);
+
+               if (obj) {
+                       mapquest_route_maneuver *maneuver = (mapquest_route_maneuver *)g_malloc(sizeof(mapquest_route_maneuver));
+
+                       if (maneuver) {
+                               json_object_foreach_member(obj, __maneuver_foreach, &maneuver);
+
+                               if (__maneuver_index != 0) {
+                                       if (maneuver->distance == 0.0 && maneuver->time == 0) {
+                                               maneuver->start_point = __destination_point;
+                                               maneuver->end_point = __destination_point;
+                                       } else {
+
+                                       }
+
+                                       GList *list = NULL;
+                                       list = g_list_last((*routeResp)->maneuvers);
+                                       if (list) {
+                                               mapquest_route_maneuver *tmp = (mapquest_route_maneuver *)list->data;
+                                               tmp->end_point = maneuver->start_point;
+                                       }
+                               }
+
+                               if ((*routeResp)->maneuvers == NULL)
+                                       (*routeResp)->maneuvers = g_list_append((*routeResp)->maneuvers, (gpointer)maneuver);
+                               else
+                                       (*routeResp)->maneuvers = g_list_insert_before((*routeResp)->maneuvers, NULL, (gpointer)maneuver);
+                       }
+                       __maneuver_index++;
+               }
+       }
+}
+
+static void __shape_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+       if (!object || !member_name || !member_node || !user_data) return;
+
+       mapquest_route_resp_s **routeResp = (mapquest_route_resp_s **) user_data;
+
+       JsonNode *tmp = json_object_get_member(object, member_name);
+
+       if (!strcmp(member_name, "shapePoints")) {
+               JsonArray *shapePointsArray = json_node_get_array(tmp);
+
+               int length = json_array_get_length(shapePointsArray);
+
+               int index = 0;
+               double val = 0.0;
+               coords_s *coords = NULL;
+               for (index = 0; index < length; index++) {
+
+                       val = (double) json_array_get_double_element(shapePointsArray, index);
+
+                       if ((index % 2) == 0) {
+                               /* Lat */
+                               coords = (coords_s *)g_malloc0(sizeof(coords_s));
+                               if (coords)
+                                       coords->latitude = val;
+                       } else {
+                               /* Lon */
+                               if (coords) {
+                                       coords->longitude = val;
+                                       if ((*routeResp)->shapePoints == NULL)
+                                               (*routeResp)->shapePoints = g_list_append((*routeResp)->shapePoints, (gpointer)coords);
+                                       else
+                                               (*routeResp)->shapePoints = g_list_insert_before((*routeResp)->shapePoints, NULL, (gpointer)coords);
+                               }
+                       }
+               }
+       }
+
+}
+
+static void __bbox_foreach(JsonObject *object, const gchar *member_name, JsonNode *member_node, gpointer user_data)
+{
+       if (!object || !member_name || !member_node || !user_data) return;
+
+       mapquest_route_resp_s **routeResp = (mapquest_route_resp_s **) user_data;
+
+       JsonNode *tmp = json_object_get_member(object, member_name);
+
+       JsonObject *coordsObj = json_node_get_object(tmp);
+       double latitude = 0.0;
+       double longitude = 0.0;
+
+       if (coordsObj) {
+               JsonNode *latNode = json_object_get_member(coordsObj, "lat");
+
+               if (latNode)
+                       latitude = json_node_get_double(latNode);
+
+               JsonNode *lngNode = json_object_get_member(coordsObj, "lng");
+
+               if (lngNode)
+                       longitude = json_node_get_double(lngNode);
+       }
+
+       if (!strcmp(member_name, "ul")) {
+               ((*routeResp)->bounding_box).top_left.latitude = latitude;
+               ((*routeResp)->bounding_box).top_left.longitude = longitude;
+       } else if (!strcmp(member_name, "lr")) {
+               ((*routeResp)->bounding_box).bottom_right.latitude = latitude;
+               ((*routeResp)->bounding_box).bottom_right.longitude = longitude;
+       }
+}
+
+static void __parse_route_response(char *response, int size, int *status, mapquest_route_resp_s **routeResp)
+{
+       if (!response || !status || !routeResp) return;
+
+       *routeResp = NULL;
+
+       JsonParser *parser;
+       JsonNode *root;
+       JsonNode *node;
+       JsonObject *object;
+       GError *error = NULL;
+       char data[size + 1];
+
+       parser = json_parser_new();
+
+       strncpy(data, response, size);
+       data[size] = '\0';
+
+       if (!json_parser_load_from_data(parser, data, -1, &error)) {
+               MAP_DEBUG("Error in file parsing JSON..");
+               g_error_free(error);
+               g_object_unref(parser);
+               return;
+       }
+
+       root = json_parser_get_root(parser);
+
+       object = json_node_get_object(root);
+
+       node = json_object_get_member(object, "info");
+       JsonObject *infoObj = json_node_get_object(node);
+       if (infoObj) {
+               JsonNode *statusNode = json_object_get_member(infoObj, "statuscode");
+
+               if (statusNode) {
+                       *status = json_node_get_int(statusNode);
+                       MAP_DEBUG("status :: >>> %d", *status);
+               }
+       }
+
+       if (*status != 0) {     /* SUCCESS */
+               *routeResp = NULL;
+               return;
+       }
+
+       *routeResp = (mapquest_route_resp_s *)g_malloc(sizeof(mapquest_route_resp_s));
+
+       if (!(*routeResp))
+               return;
+
+       (*routeResp)->maneuvers = NULL;
+       (*routeResp)->shapePoints = NULL;
+
+       node = json_object_get_member(object, "route");
+
+       if (!node)
+               return;
+
+       JsonObject *routeObject = json_node_get_object(node);
+
+       JsonNode *tmp = json_object_get_member(routeObject, "distance");
+
+       if (tmp) {
+               double dist = json_node_get_double(tmp);
+               (*routeResp)->distance = __convert_distance_unit(dist);
+               (*routeResp)->distance_unit = __route_unit;
+       }
+
+       tmp = json_object_get_member(routeObject, "boundingBox");
+
+       if (tmp) {
+               JsonObject *bbox = json_node_get_object(tmp);
+
+               json_object_foreach_member(bbox, __bbox_foreach, routeResp);
+       }
+
+       tmp = json_object_get_member(routeObject, "formattedTime");
+
+       if (tmp)
+               (*routeResp)->formatted_time = (char *) json_node_dup_string(tmp);
+
+       tmp = json_object_get_member(routeObject, "routeType");
+       if (tmp) {
+               (*routeResp)->type = ROUTE_TYPE_BICYCLE;
+
+               char *type = (char *) json_node_get_string(tmp);
+               if (type) {
+                       if (!strcmp(type, "FASTEST"))
+                               (*routeResp)->type = ROUTE_TYPE_FASTEST;
+                       else if (!strcmp(type, "SHORTEST"))
+                               (*routeResp)->type = ROUTE_TYPE_SHORTEST;
+                       else if (!strcmp(type, "PEDESTRIAN"))
+                               (*routeResp)->type = ROUTE_TYPE_PEDESTRIAN;
+                       else if (!strcmp(type, "MULTIMODAL"))
+                               (*routeResp)->type = ROUTE_TYPE_MULTIMODAL;
+               }
+       }
+
+       tmp = json_object_get_member(routeObject, "time");
+
+       if (tmp) {
+               int time = json_node_get_int(tmp);
+               (*routeResp)->time = time;
+       }
+
+       tmp = json_object_get_member(routeObject, "legs");
+
+       if (tmp) {
+               JsonArray *legsArray = json_node_get_array(tmp);
+
+               int length = json_array_get_length(legsArray);
+
+               int index = 0;
+               for (index = 0; index < length; index++) {
+
+                       JsonObject *obj = json_array_get_object_element(legsArray, index);
+
+                       if (obj) {
+                               JsonNode *maneuversNode = json_object_get_member(obj, "maneuvers");
+
+                               if (maneuversNode)
+                                       __parse_maneuvers(maneuversNode, routeResp);
+                       }
+               }
+       }
+
+       tmp = json_object_get_member(routeObject, "shape");
+
+       if (tmp) {
+               JsonObject *shape = json_node_get_object(tmp);
+
+               json_object_foreach_member(shape, __shape_foreach, routeResp);
+       }
+
+       g_object_unref(parser);
+}
+
+void post_curl_response(char *response, int size, mapquest_resp_type type, void *user_data)
+{
+       if (!response) return;
+
+       if (!user_data) {
+               MAP_DEBUG("Response data is NULL");
+               return;
+       }
+
+       MAP_DEBUG("Response received from Curl. [Size=%d]", size);
+       switch (type) {
+       case RESP_TYPE_GEOCODE:
+               {
+                       MAP_DEBUG("Inside Geocode JSON Parsing..");
+                       int status = -1;
+                       MapquestGeocodeQueryData *queryData = (MapquestGeocodeQueryData *)user_data;
+                       MapquestGeocodeResponseData *responseData = (MapquestGeocodeResponseData *)g_malloc(sizeof(MapquestGeocodeResponseData));
+
+                       if (responseData) {
+                               responseData->requestId = queryData->requestId;
+                               responseData->geocode_cb = queryData->geocode_cb;
+                               responseData->user_data = queryData->user_data;
+
+                               if (response && (size > 0)) {
+                                       GList *coordsList = NULL;
+                                       __parse_geocode_response(response, size, &status, &coordsList);
+
+                                       if (coordsList != NULL) {
+                                               /* Put the response in queue */
+                                               responseData->error = __convert_status(status);
+                                               responseData->coords = coordsList;
+                                       } else {
+                                               /* Response parsing failure */
+                                               responseData->error = __convert_status(status);
+                                               responseData->coords = NULL;
+                                       }
+                               } else {
+                                       responseData->error = __convert_status(status);
+                                       responseData->coords = NULL;
+                               }
+
+                               mapquest_push_to_queue(type, (gpointer)responseData);
+                       }
+
+                       if (queryData) {
+                               g_free(queryData);
+                               queryData = NULL;
+                       }
+                       break;
+               }
+       case RESP_TYPE_REVGEOCODE:
+               {
+                       MAP_DEBUG("Inside Rev Geocode JSON Parsing..");
+                       int status = -1;
+                       MapquestRevGeocodeQueryData *queryData = (MapquestRevGeocodeQueryData *)user_data;
+                       MapquestRevGeocodeResponseData *responseData = (MapquestRevGeocodeResponseData *)g_malloc(sizeof(MapquestRevGeocodeResponseData));
+
+                       if (responseData) {
+                               responseData->requestId = queryData->requestId;
+                               responseData->reverse_geocode_cb = queryData->reverse_geocode_cb;
+                               responseData->user_data = queryData->user_data;
+
+                               if (response && (size > 0)) {
+                                       /* Coords Result GList */
+                                       mapquest_address_resp_s *addrResponse = NULL;
+
+                                       MAP_DEBUG("Rev Geocode :- Parsing json Response");
+                                       __parse_revgeocode_response(response, size, &status, &addrResponse);
+
+                                       if (addrResponse != NULL) {
+                                               /* Put the response in queue */
+                                               responseData->error = __convert_status(status);
+                                               responseData->addressDetails = addrResponse;
+                                       } else {
+                                               /* REPSONSE PARSING FAILURE */
+                                               MAP_DEBUG("addr Response is NULL");
+                                               responseData->error = __convert_status(status);
+                                               responseData->addressDetails = NULL;
+                                       }
+                               } else {
+                                       MAP_DEBUG("JSON Response is NULL..");
+                                       responseData->error = __convert_status(status);
+                                       responseData->addressDetails = NULL;
+                               }
+
+                               mapquest_push_to_queue(type, (gpointer)responseData);
+                       }
+
+                       if (queryData) {
+                               g_free(queryData);
+                               queryData = NULL;
+                       }
+                       break;
+               }
+       case RESP_TYPE_PLACES:
+               {
+                       MAP_DEBUG("Inside Places JSON Parsing..");
+                       MapquestPlaceQueryData *queryData = (MapquestPlaceQueryData *)user_data;
+                       MapquestPlaceResponseData *responseData = (MapquestPlaceResponseData *)g_malloc(sizeof(MapquestPlaceResponseData));
+
+                       if (responseData) {
+                               responseData->requestId = queryData->requestId;
+                               responseData->place_search_cb = queryData->place_search_cb;
+                               responseData->user_data = queryData->user_data;
+
+                               if (response && (size > 0)) {
+                                       /* Coords Result GList */
+                                       GList *placeList = NULL;
+
+                                       MAP_DEBUG("Search Places :- Parsing Json Response");
+                                       __parse_place_response(response, size, &placeList);
+
+                                       if (placeList != NULL) {
+                                               /* Put the response in queue */
+                                               responseData->error = MAPQUEST_ERROR_NONE;
+                                               responseData->places = placeList;
+                                       } else {
+                                               /* REPSONSE PARSING FAILURE */
+                                               MAP_DEBUG("addr Response is NULL");
+                                               responseData->error = MAPQUEST_ERROR_UNKNOWN;
+                                               responseData->places = NULL;
+                                       }
+                               } else {
+                                       responseData->error = MAPQUEST_ERROR_UNKNOWN;
+                                       responseData->places = NULL;
+                               }
+
+                               mapquest_push_to_queue(type, (gpointer)responseData);
+                       }
+
+                       if (queryData) {
+                               g_free(queryData);
+                               queryData = NULL;
+                       }
+
+                       break;
+               }
+       case RESP_TYPE_ROUTE:
+               {
+                       MAP_DEBUG("Inside Route JSON Parsing..");
+                       int status = -1;
+                       MapquestRouteQueryData *queryData = (MapquestRouteQueryData *)user_data;
+                       __route_unit = queryData->unit;
+                       __maneuver_index = 0;
+                       __destination_point = queryData->destination;
+
+                       MapquestRouteResponseData *responseData = (MapquestRouteResponseData *)g_malloc(sizeof(MapquestRouteResponseData));
+
+                       if (responseData) {
+                               responseData->requestId = queryData->requestId;
+                               responseData->route_cb = queryData->route_cb;
+                               responseData->user_data = queryData->user_data;
+
+                               if (response && (size > 0)) {
+                                       /* Coords Result GList */
+                                       mapquest_route_resp_s *routeResponse = NULL;
+
+                                       MAP_DEBUG("Route :- Parsing Response");
+                                       __parse_route_response(response, size, &status, &routeResponse);
+
+                                       if (routeResponse != NULL) {
+                                               /* Put the response in queue */
+                                               responseData->error = __convert_status(status);
+                                               responseData->routeResponse = routeResponse;
+                                       } else {
+                                               /* REPSONSE PARSING FAILURE */
+                                               MAP_DEBUG("route Response is NULL");
+                                               responseData->error = __convert_status(status);
+                                               responseData->routeResponse = NULL;
+                                       }
+                               } else {
+                                       responseData->error = __convert_status(status);
+                                       responseData->routeResponse = NULL;
+                               }
+
+                               mapquest_push_to_queue(type, (gpointer)responseData);
+                       }
+
+                       if (queryData) {
+                               g_free(queryData);
+                               queryData = NULL;
+                       }
+
+                       break;
+               }
+       default:
+               {
+                       MAP_DEBUG("Inside default JSON Parsing..");
+                       break;
+               }
+       }
+}
diff --git a/src/mapquest/mapquest_jsonparser.h b/src/mapquest/mapquest_jsonparser.h
new file mode 100644 (file)
index 0000000..19e4f1e
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_JSONPARSER_H_
+#define _MAPQUEST_JSONPARSER_H_
+
+#include "mapquest_server_private.h"
+
+void post_curl_response(char *response, int size, mapquest_resp_type type, void *user_data);
+
+#endif /* _MAPQUEST_JSONPARSER_H_ */
diff --git a/src/mapquest/mapquest_place.c b/src/mapquest/mapquest_place.c
new file mode 100644 (file)
index 0000000..52a05bc
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <pthread.h>
+#include "mapquest_place.h"
+#include "mapquest_types.h"
+#include "mapquest_server_private.h"
+#include "mapquest_debug.h"
+#include "mapquest_queue.h"
+#include "mapquest_restcurl.h"
+#include "mapquest_util.h"
+
+#define PLACES_URL     "https://open.mapquestapi.com/nominatim/v1/search.php?format=json"
+
+int query_places(gchar *maps_key, gchar *search_str, mapquest_boundary_s *boundary, int num_res, gpointer user_data)
+{
+       char url[1024];
+       char tmpStr[512];
+
+       strcpy(url, PLACES_URL);
+
+       if (search_str != NULL) {
+               snprintf(tmpStr, sizeof(tmpStr), "&q=%s", search_str);
+               strncat(url, tmpStr, sizeof(url)-strlen(url)-1);
+       }
+
+       if (boundary != NULL) {
+               if (boundary->type == MAPQUEST_BOUNDARY_RECT) {
+                       snprintf(tmpStr, sizeof(tmpStr), "&viewbox=%f,%f,%f,%f", boundary->rect.top_left.longitude, boundary->rect.top_left.latitude, boundary->rect.bottom_right.longitude, boundary->rect.bottom_right.latitude);
+
+                       strncat(url, tmpStr, sizeof(url)-strlen(url)-1);
+               } else if (boundary->type == MAPQUEST_BOUNDARY_CIRCLE) {
+                       coords_s *top_left = NULL, *bottom_right = NULL;
+                       coords_s circle = boundary->circle.center;
+                       gdouble radius = (boundary->circle.radius) * 0.001;
+
+                       /* Calculate the top left coordinate of bounding box. */
+                       calculate_point(circle.latitude, circle.longitude, 315, radius, &top_left);
+
+                       /* Calculate the bottom right coordinate of bounding box. */
+                       calculate_point(circle.latitude, circle.longitude, 135, radius, &bottom_right);
+
+                       if (top_left && bottom_right) {
+                               snprintf(tmpStr, sizeof(tmpStr), "&viewbox=%f,%f,%f,%f", top_left->longitude, top_left->latitude, bottom_right->longitude, bottom_right->latitude);
+                               strncat(url, tmpStr, sizeof(url)-strlen(url)-1);
+                       }
+
+                       if (top_left) {
+                               g_free(top_left);
+                               top_left = NULL;
+                       }
+                       if (bottom_right) {
+                               g_free(bottom_right);
+                               bottom_right = NULL;
+                       }
+               }
+
+               strcat(url, "&bounded=1");
+       }
+
+       strcat(url, "&addressdetails=1");
+
+       if (num_res > 0) {
+               snprintf(tmpStr, sizeof(tmpStr), "&limit=%d", num_res);
+               strcat(url, tmpStr);
+       }
+
+       add_handle(url, REQ_TYPE_PLACES, user_data);
+
+       return 0;
+}
diff --git a/src/mapquest/mapquest_place.h b/src/mapquest/mapquest_place.h
new file mode 100644 (file)
index 0000000..40812a5
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_PLACES_H_
+#define _MAPQUEST_PLACES_H_
+
+#include "mapquest_api.h"
+#include "mapquest_types.h"
+
+int query_places(gchar *maps_key, gchar *search_str, mapquest_boundary_s *boundary, int num_res, gpointer user_data);
+
+#endif /* _MAPQUEST_PLACES_H_ */
diff --git a/src/mapquest/mapquest_queue.c b/src/mapquest/mapquest_queue.c
new file mode 100644 (file)
index 0000000..98b9aca
--- /dev/null
@@ -0,0 +1,1263 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include<stdlib.h>
+#include "mapquest_queue.h"
+#include "mapquest_geocode.h"
+#include "mapquest_revgeocode.h"
+#include "mapquest_route.h"
+#include "mapquest_place.h"
+#include "mapquest_restcurl.h"
+#include "mapquest_util.h"
+#include "mapquest_debug.h"
+#include <json-glib/json-glib.h>
+
+pthread_mutex_t __requestLock;
+static GAsyncQueue *responseQueue = NULL;
+int __ResponseQueueLen = 0;
+bool __response_timer_running = false;
+
+/* Request List */
+GList *requestList = NULL;
+
+/* Request Cancel List */
+GList *reqCancelList = NULL;
+
+static void __free_geocode_response(void *ptr);
+static void __free_revgeocode_response(void *ptr);
+static void __free_place_response(void *ptr);
+static void __free_route_response(void *ptr);
+
+int add_to_geocode_list(mapquest_geocode_req_s *req_details, mapquest_geocode_cb callback, int request_id, void *user_data)
+{
+       mapquest_request_s *req = (mapquest_request_s *)g_malloc0(sizeof(mapquest_request_s));
+
+       if (req != NULL) {
+
+               req->type = REQ_TYPE_GEOCODE;
+
+               mapquest_geocode_req *data = (mapquest_geocode_req *)g_malloc0(sizeof(mapquest_geocode_req));
+
+               if (data != NULL) {
+                       data->req_details = req_details;
+                       data->requestId = request_id;
+                       data->geocode_cb = callback;
+                       data->user_data = user_data;
+
+                       req->request = data;
+
+                       MAP_DEBUG("Added GEOCODE REQUEST to geocode List");
+
+                       pthread_mutex_lock(&__requestLock);
+                       if (requestList == NULL)
+                               requestList = g_list_append(requestList, (gpointer)req);
+                       else
+                               requestList = g_list_insert_before(requestList, NULL, (gpointer)req);
+                       pthread_mutex_unlock(&__requestLock);
+               }
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int add_to_revgeocode_list(mapquest_revgeocode_req_s *req_details, mapquest_reverse_geocode_cb callback, int request_id, void *user_data)
+{
+       mapquest_request_s *req = (mapquest_request_s *)g_malloc0(sizeof(mapquest_request_s));
+
+       if (req != NULL) {
+
+               req->type = REQ_TYPE_REVGEOCODE;
+
+               mapquest_revgeocode_req *data = (mapquest_revgeocode_req *)g_malloc0(sizeof(mapquest_revgeocode_req));
+
+               if (data != NULL) {
+                       data->req_details = req_details;
+                       data->requestId = request_id;
+                       data->revgeocode_cb = callback;
+                       data->user_data = user_data;
+
+                       req->request = data;
+
+                       MAP_DEBUG("Added REVERSE GEOCODE request to geocode List");
+
+                       pthread_mutex_lock(&__requestLock);
+                       if (requestList == NULL)
+                               requestList = g_list_append(requestList, (gpointer)req);
+                       else
+                               requestList = g_list_insert_before(requestList, NULL, (gpointer)req);
+                       pthread_mutex_unlock(&__requestLock);
+               }
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int add_to_places_list(mapquest_search_req_s *req_details, mapquest_place_search_cb callback, int request_id, void *user_data)
+{
+       mapquest_request_s *req = (mapquest_request_s *)g_malloc0(sizeof(mapquest_request_s));
+
+       if (req != NULL) {
+
+               req->type = REQ_TYPE_PLACES;
+
+               mapquest_search_place_req *data = (mapquest_search_place_req *)g_malloc0(sizeof(mapquest_search_place_req));
+
+               if (data != NULL) {
+                       data->req_details = req_details;
+                       data->requestId = request_id;
+                       data->search_place_cb = callback;
+                       data->user_data = user_data;
+
+                       req->request = data;
+
+                       MAP_DEBUG("Added PLACE request to places List");
+
+                       pthread_mutex_lock(&__requestLock);
+                       if (requestList == NULL)
+                               requestList = g_list_append(requestList, (gpointer)req);
+                       else
+                               requestList = g_list_insert_before(requestList, NULL, (gpointer)req);
+                       pthread_mutex_unlock(&__requestLock);
+               }
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int add_to_route_list(mapquest_route_req_s *req_details, mapquest_route_cb callback, int request_id, void *user_data)
+{
+       mapquest_request_s *req = (mapquest_request_s *)g_malloc0(sizeof(mapquest_request_s));
+
+       if (req != NULL) {
+
+               req->type = REQ_TYPE_ROUTE;
+
+               mapquest_route_req *data = (mapquest_route_req *)g_malloc0(sizeof(mapquest_route_req));
+
+               if (data != NULL) {
+                       data->req_details = req_details;
+                       data->requestId = request_id;
+                       data->route_cb = callback;
+                       data->user_data = user_data;
+
+                       req->request = data;
+
+                       MAP_DEBUG("Added request to route List");
+
+                       pthread_mutex_lock(&__requestLock);
+                       if (requestList == NULL)
+                               requestList = g_list_append(requestList, (gpointer)req);
+                       else
+                               requestList = g_list_insert_before(requestList, NULL, (gpointer)req);
+                       pthread_mutex_unlock(&__requestLock);
+               }
+
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+static int __add_to_cancel_list(int request_id)
+{
+       if (reqCancelList == NULL)
+               reqCancelList = g_list_append(reqCancelList, (gpointer) GINT_TO_POINTER(request_id));
+       else
+               reqCancelList = g_list_insert_before(reqCancelList, NULL, (gpointer) GINT_TO_POINTER(request_id));
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+static int __remove_from_cancel_list(int request_id)
+{
+       if (g_list_length(reqCancelList) != 0)
+               reqCancelList = g_list_remove(reqCancelList, (gpointer) GINT_TO_POINTER(request_id));
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int remove_from_request_list(int request_id)
+{
+       bool is_request_cancelled = false;
+       GList *list = NULL;
+       pthread_mutex_lock(&__requestLock);
+       list = g_list_first(requestList);
+       pthread_mutex_unlock(&__requestLock);
+       mapquest_request_s *req = NULL;
+
+       while (list != NULL) {
+               req = (mapquest_request_s *) list->data;
+
+               if (req != NULL) {
+                       if (req->type == REQ_TYPE_GEOCODE) {
+                               mapquest_geocode_req *geocode_req = (mapquest_geocode_req *) req->request;
+
+                               if (geocode_req->requestId == request_id) {
+                                       /* Means the request is pending in queue. Not started yet */
+                                       /* Deleting the request from the request queue */
+                                       pthread_mutex_lock(&__requestLock);
+                                       requestList = g_list_remove(requestList, (gpointer)req);
+                                       pthread_mutex_unlock(&__requestLock);
+                                       mapquest_geocode_req_s *geocode_req_details = (mapquest_geocode_req_s *)geocode_req->req_details;
+
+                                       if (geocode_req_details)
+                                               g_free(geocode_req_details);
+                                       geocode_req_details = NULL;
+
+                                       g_free(geocode_req);
+                                       geocode_req = NULL;
+
+                                       g_free(req);
+                                       req = NULL;
+
+                                       __remove_from_cancel_list(request_id);
+
+                                       is_request_cancelled = true;
+                                       break;
+                               }
+                       } else if (req->type == REQ_TYPE_REVGEOCODE) {
+                               mapquest_revgeocode_req *revgeocode_req = (mapquest_revgeocode_req *)req->request;
+
+                               if (revgeocode_req->requestId == request_id) {
+                                       /* Means the request is pending in queue. Not started yet */
+                                       /* Deleting the request from the request queue */
+                                       pthread_mutex_lock(&__requestLock);
+                                       requestList = g_list_remove(requestList, (gpointer)req);
+                                       pthread_mutex_unlock(&__requestLock);
+                                       mapquest_revgeocode_req_s *reverse_geocode_req_details = (mapquest_revgeocode_req_s *)revgeocode_req->req_details;
+
+                                       if (reverse_geocode_req_details)
+                                               g_free(reverse_geocode_req_details);
+                                       reverse_geocode_req_details = NULL;
+
+                                       g_free(revgeocode_req);
+                                       revgeocode_req = NULL;
+
+                                       g_free(req);
+                                       req = NULL;
+
+                                       __remove_from_cancel_list(request_id);
+
+                                       is_request_cancelled = true;
+                                       break;
+                               }
+                       } else if (req->type == REQ_TYPE_ROUTE) {
+                               mapquest_route_req *route_req = (mapquest_route_req *) req->request;
+
+                               if (route_req->requestId == request_id) {
+                                       /* Means the request is pending in queue. Not started yet */
+                                       /* Deleting the request from the request queue */
+                                       pthread_mutex_lock(&__requestLock);
+                                       requestList = g_list_remove(requestList, (gpointer)req);
+                                       pthread_mutex_unlock(&__requestLock);
+                                       mapquest_route_req_s *route_req_details = (mapquest_route_req_s *)route_req->req_details;
+
+                                       if (route_req_details)
+                                               g_free(route_req_details);
+                                       route_req_details = NULL;
+
+                                       g_free(route_req);
+                                       route_req = NULL;
+
+                                       g_free(req);
+                                       req = NULL;
+
+                                       __remove_from_cancel_list(request_id);
+
+                                       is_request_cancelled = true;
+                                       break;
+                               }
+                       } else if (req->type == REQ_TYPE_PLACES) {
+                               mapquest_search_place_req *places_req = (mapquest_search_place_req *) req->request;
+
+                               if (places_req->requestId == request_id) {
+                                       /* Means the request is pending in queue. Not started yet */
+                                       /* Deleting the request from the request queue */
+                                       pthread_mutex_lock(&__requestLock);
+                                       requestList = g_list_remove(requestList, (gpointer)req);
+                                       pthread_mutex_unlock(&__requestLock);
+                                       mapquest_search_req_s *place_req_details = (mapquest_search_req_s *)places_req->req_details;
+
+                                       if (place_req_details)
+                                               g_free(place_req_details);
+                                       place_req_details = NULL;
+
+                                       g_free(places_req);
+                                       places_req = NULL;
+
+                                       g_free(req);
+                                       req = NULL;
+
+                                       __remove_from_cancel_list(request_id);
+
+                                       is_request_cancelled = true;
+                                       break;
+                               }
+                       }
+               }
+
+               list = g_list_next(list);
+       }
+
+       if (!is_request_cancelled) {
+               /* Means it is currently running. */
+               /* Cancel the request */
+               cancel_request(request_id);
+               /* add to cancel list */
+               __add_to_cancel_list(request_id);
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+static bool __is_request_in_cancel_list(int requestId)
+{
+       bool match_id = false;
+
+       GList *list = NULL;
+       list = g_list_first(reqCancelList);
+
+       while (list != NULL) {
+
+               int id = (int) GPOINTER_TO_INT(list->data);
+
+               if (id == requestId) {
+                       match_id = true;
+                       break;
+               }
+
+               list = g_list_next(list);
+       }
+
+       return match_id;
+}
+
+mapquest_request_s *get_next_request()
+{
+       if (g_list_length(requestList) > 0) {
+               pthread_mutex_lock(&__requestLock);
+               GList *list = g_list_first(requestList);
+               pthread_mutex_unlock(&__requestLock);
+
+               if (list) {
+                       mapquest_request_s *req = (mapquest_request_s *) list->data;
+                       return req;
+               } else {
+                       return NULL;
+               }
+       }
+
+       return NULL;
+}
+
+static gboolean __timeout_cb(gpointer data)
+{
+       MAP_DEBUG("timeout_cb");
+       __response_timer_running = true;
+       g_async_queue_ref(responseQueue);
+
+       __ResponseQueueLen = g_async_queue_length(responseQueue);
+       MAP_DEBUG("Queue Len :: [%d]", __ResponseQueueLen);
+       while (__ResponseQueueLen > 0) {
+               gpointer data = g_async_queue_try_pop(responseQueue);
+               if (!data)
+                       continue;
+
+               MapquestQueueData *response = (MapquestQueueData *) data;
+
+               switch (response->type) {
+               case RESP_TYPE_GEOCODE:
+                       {
+                               MAP_DEBUG("Got geocode response..");
+                               MapquestGeocodeResponseData *geocodeData = (MapquestGeocodeResponseData *) (response->data);
+                               if (geocodeData) {
+                                       if (__is_request_in_cancel_list(geocodeData->requestId) == false) {
+                                               /* Deliver results to consumer */
+                                               geocodeData->geocode_cb(geocodeData->error, geocodeData->requestId, geocodeData->coords, geocodeData->user_data);
+                                       } else {
+                                               /* If present in cancel list, dont trigger the response. */
+                                               /* Remove the requestId from cancel list. */
+                                               __remove_from_cancel_list(geocodeData->requestId);
+                                       }
+                                       __free_geocode_response(geocodeData);
+
+                                       g_free(geocodeData);
+                                       geocodeData = NULL;
+                               }
+
+                               /* Start the Next valid request */
+                               if (get_num_running_requests() < CURL_MAX_CONNECTS) {
+                                       MAP_DEBUG("Fetching the next request from the request list....");
+                                       mapquest_request_s *req = get_next_request();
+                                       if (req) {
+                                               pthread_mutex_lock(&__requestLock);
+                                               requestList = g_list_remove(requestList, (gpointer)req);
+                                               pthread_mutex_unlock(&__requestLock);
+
+                                               if (req->type == REQ_TYPE_GEOCODE) {
+                                                       mapquest_geocode_req *geocode_req = (mapquest_geocode_req *) req->request;
+                                                       if (geocode_req != NULL) {
+                                                               start_geocode_service(geocode_req->req_details, geocode_req->geocode_cb, geocode_req->requestId, geocode_req->user_data);
+
+                                                               g_free(geocode_req);
+                                                               geocode_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_REVGEOCODE) {
+                                                       mapquest_revgeocode_req *revgeocode_req = (mapquest_revgeocode_req *) req->request;
+                                                       if (revgeocode_req != NULL) {
+                                                               start_reversegeocode_service(revgeocode_req->req_details, revgeocode_req->revgeocode_cb, revgeocode_req->requestId, revgeocode_req->user_data);
+
+                                                               g_free(revgeocode_req);
+                                                               revgeocode_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_PLACES) {
+                                                       mapquest_search_place_req *places_req = (mapquest_search_place_req *) req->request;
+                                                       if (places_req) {
+                                                               start_places_service(places_req->req_details, places_req->search_place_cb, places_req->requestId, places_req->user_data);
+
+                                                               g_free(places_req);
+                                                               places_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_ROUTE) {
+                                                       mapquest_route_req *route_req = (mapquest_route_req *) req->request;
+                                                       if (route_req) {
+                                                               start_route_service(route_req->req_details, route_req->route_cb, route_req->requestId, route_req->user_data);
+
+                                                               g_free(route_req);
+                                                               route_req = NULL;
+                                                       }
+                                               }
+
+                                               g_free(req);
+                                               req = NULL;
+                                       } else {
+                                               MAP_DEBUG("No request in queue or request type is wrong");
+                                       }
+                               } else {
+                                       MAP_DEBUG("Libcurl request queue is FULL..");
+                               }
+                       }
+                       break;
+
+               case RESP_TYPE_REVGEOCODE:
+                       {
+                               MapquestRevGeocodeResponseData *revGeocodeData = (MapquestRevGeocodeResponseData *) (response->data);
+                               if (revGeocodeData) {
+                                       if (__is_request_in_cancel_list(revGeocodeData->requestId) == false) {
+                                               /* Deliver results to consumer */
+                                               revGeocodeData->reverse_geocode_cb(revGeocodeData->error, revGeocodeData->requestId, revGeocodeData->addressDetails, revGeocodeData->user_data);
+                                       } else {
+                                               /* If present in cancel list, dont trigger the response. */
+                                               /* Remove the requestId from cancel list. */
+                                               __remove_from_cancel_list(revGeocodeData->requestId);
+                                       }
+                                       __free_revgeocode_response(revGeocodeData);
+
+                                       g_free(revGeocodeData);
+                                       revGeocodeData = NULL;
+                               }
+
+                               /* Start the Next valid request */
+                               MAP_DEBUG(">> Condition Check <<");
+                               if (get_num_running_requests() < CURL_MAX_CONNECTS) {
+                                       MAP_DEBUG("Fetching the next request from the request list....");
+                                       mapquest_request_s *req = get_next_request();
+                                       if (req) {
+                                               pthread_mutex_lock(&__requestLock);
+                                               requestList = g_list_remove(requestList, (gpointer)req);
+                                               pthread_mutex_unlock(&__requestLock);
+
+                                               if (req->type == REQ_TYPE_GEOCODE) {
+                                                       mapquest_geocode_req *geocode_req = (mapquest_geocode_req *) req->request;
+                                                       if (geocode_req != NULL) {
+                                                               start_geocode_service(geocode_req->req_details, geocode_req->geocode_cb, geocode_req->requestId, geocode_req->user_data);
+
+                                                               g_free(geocode_req);
+                                                               geocode_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_REVGEOCODE) {
+                                                       mapquest_revgeocode_req *revgeocode_req = (mapquest_revgeocode_req *) req->request;
+                                                       if (revgeocode_req != NULL) {
+                                                               start_reversegeocode_service(revgeocode_req->req_details, revgeocode_req->revgeocode_cb, revgeocode_req->requestId, revgeocode_req->user_data);
+
+                                                               g_free(revgeocode_req);
+                                                               revgeocode_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_PLACES) {
+                                                       mapquest_search_place_req *places_req = (mapquest_search_place_req *) req->request;
+                                                       if (places_req) {
+                                                               start_places_service(places_req->req_details, places_req->search_place_cb, places_req->requestId, places_req->user_data);
+
+                                                               g_free(places_req);
+                                                               places_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_ROUTE) {
+                                                       mapquest_route_req *route_req = (mapquest_route_req *) req->request;
+                                                       if (route_req) {
+                                                               start_route_service(route_req->req_details, route_req->route_cb, route_req->requestId, route_req->user_data);
+
+                                                               g_free(route_req);
+                                                               route_req = NULL;
+                                                       }
+                                               }
+
+                                               g_free(req);
+                                               req = NULL;
+                                       } else {
+                                               MAP_DEBUG("No request in queue or request type is wrong");
+                                       }
+                               } else {
+                                       MAP_DEBUG("Libcurl request queue is FULL..");
+                               }
+                       }
+                       break;
+
+               case RESP_TYPE_ROUTE:
+                       {
+                               MapquestRouteResponseData *routeData = (MapquestRouteResponseData *) (response->data);
+                               if (routeData != NULL) {
+                                       if (__is_request_in_cancel_list(routeData->requestId) == false) {
+                                               /* Deliver results to consumer */
+                                               routeData->route_cb(routeData->error, routeData->requestId, routeData->routeResponse, routeData->user_data);
+                                       } else {
+                                               /* If present in cancel list, dont trigger the response. */
+                                               /* Remove the requestId from cancel list. */
+                                               __remove_from_cancel_list(routeData->requestId);
+                                       }
+                                       __free_route_response(routeData);
+
+                                       g_free(routeData);
+                                       routeData = NULL;
+                               }
+
+                               /* Start the Next valid request */
+                               if (get_num_running_requests() < CURL_MAX_CONNECTS) {
+                                       MAP_DEBUG("Fetching the next request from the request list....");
+                                       mapquest_request_s *req = get_next_request();
+                                       if (req) {
+                                               pthread_mutex_lock(&__requestLock);
+                                               requestList = g_list_remove(requestList, (gpointer)req);
+                                               pthread_mutex_unlock(&__requestLock);
+
+                                               if (req->type == REQ_TYPE_GEOCODE) {
+                                                       mapquest_geocode_req *geocode_req = (mapquest_geocode_req *) req->request;
+                                                       if (geocode_req != NULL) {
+                                                               start_geocode_service(geocode_req->req_details, geocode_req->geocode_cb, geocode_req->requestId, geocode_req->user_data);
+
+                                                               g_free(geocode_req);
+                                                               geocode_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_REVGEOCODE) {
+                                                       mapquest_revgeocode_req *revgeocode_req = (mapquest_revgeocode_req *) req->request;
+                                                       if (revgeocode_req != NULL) {
+                                                               start_reversegeocode_service(revgeocode_req->req_details, revgeocode_req->revgeocode_cb, revgeocode_req->requestId, revgeocode_req->user_data);
+
+                                                               g_free(revgeocode_req);
+                                                               revgeocode_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_PLACES) {
+                                                       mapquest_search_place_req *places_req = (mapquest_search_place_req *) req->request;
+                                                       if (places_req) {
+                                                               start_places_service(places_req->req_details, places_req->search_place_cb, places_req->requestId, places_req->user_data);
+
+                                                               g_free(places_req);
+                                                               places_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_ROUTE) {
+                                                       mapquest_route_req *route_req = (mapquest_route_req *) req->request;
+                                                       if (route_req) {
+                                                               start_route_service(route_req->req_details, route_req->route_cb, route_req->requestId, route_req->user_data);
+
+                                                               g_free(route_req);
+                                                               route_req = NULL;
+                                                       }
+                                               }
+
+                                               g_free(req);
+                                               req = NULL;
+                                       } else {
+                                               MAP_DEBUG("No request in queue or request type is wrong");
+                                       }
+                               } else {
+                                       MAP_DEBUG("Libcurl request queue is FULL..");
+                               }
+                       }
+                       break;
+
+               case RESP_TYPE_PLACES:
+                       {
+                               MapquestPlaceResponseData *placesData = (MapquestPlaceResponseData *) (response->data);
+                               if (placesData != NULL) {
+                                       MAP_DEBUG("Sending places result..");
+                                       if (__is_request_in_cancel_list(placesData->requestId) == false) {
+                                               /* Deliver results to consumer */
+                                               placesData->place_search_cb(placesData->error, placesData->requestId, placesData->places, placesData->user_data);
+                                       } else {
+                                               /* If present in cancel list, dont trigger the response. */
+                                               /* Remove the requestId from cancel list. */
+                                               __remove_from_cancel_list(placesData->requestId);
+                                       }
+                                       __free_place_response(placesData);
+
+                                       g_free(placesData);
+                                       placesData = NULL;
+                               }
+
+                               /* Start the Next valid request */
+                               if (get_num_running_requests() < CURL_MAX_CONNECTS) {
+                                       MAP_DEBUG("Fetching the next request from the request list....");
+                                       mapquest_request_s *req = get_next_request();
+                                       if (req) {
+                                               pthread_mutex_lock(&__requestLock);
+                                               requestList = g_list_remove(requestList, (gpointer)req);
+                                               pthread_mutex_unlock(&__requestLock);
+
+                                               if (req->type == REQ_TYPE_GEOCODE) {
+                                                       mapquest_geocode_req *geocode_req = (mapquest_geocode_req *) req->request;
+                                                       if (geocode_req != NULL) {
+                                                               start_geocode_service(geocode_req->req_details, geocode_req->geocode_cb, geocode_req->requestId, geocode_req->user_data);
+
+                                                               g_free(geocode_req);
+                                                               geocode_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_REVGEOCODE) {
+                                                       mapquest_revgeocode_req *revgeocode_req = (mapquest_revgeocode_req *) req->request;
+                                                       if (revgeocode_req != NULL) {
+                                                               start_reversegeocode_service(revgeocode_req->req_details, revgeocode_req->revgeocode_cb, revgeocode_req->requestId, revgeocode_req->user_data);
+
+                                                               g_free(revgeocode_req);
+                                                               revgeocode_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_PLACES) {
+                                                       mapquest_search_place_req *places_req = (mapquest_search_place_req *) req->request;
+                                                       if (places_req) {
+                                                               start_places_service(places_req->req_details, places_req->search_place_cb, places_req->requestId, places_req->user_data);
+
+                                                               g_free(places_req);
+                                                               places_req = NULL;
+                                                       }
+                                               } else if (req->type == REQ_TYPE_ROUTE) {
+                                                       mapquest_route_req *route_req = (mapquest_route_req *) req->request;
+                                                       if (route_req) {
+                                                               start_route_service(route_req->req_details, route_req->route_cb, route_req->requestId, route_req->user_data);
+
+                                                               g_free(route_req);
+                                                               route_req = NULL;
+                                                       }
+                                               }
+
+                                               g_free(req);
+                                               req = NULL;
+                                       } else {
+                                               MAP_DEBUG("No request in queue or request type is wrong");
+                                       }
+                               } else {
+                                       MAP_DEBUG("Libcurl request queue is FULL..");
+                               }
+                       }
+                       break;
+
+               default:
+                       MAP_DEBUG("UNKNOWN RESPONSE TYPE");
+                       break;
+               }
+
+               __ResponseQueueLen = g_async_queue_length(responseQueue);
+
+               if (response) {
+                       g_free(response);
+                       response = NULL;
+               }
+       };
+
+       g_async_queue_unref(responseQueue);
+
+       __response_timer_running = false;
+
+       return false;
+}
+
+static void __free_geocode_response(void *ptr)
+{
+       MapquestGeocodeResponseData *geocodeData = (MapquestGeocodeResponseData *) (ptr);
+
+       if (geocodeData) {
+               GList *coords = NULL;
+               coords = g_list_first(geocodeData->coords);
+
+               while (coords) {
+                       coords_s *data = (coords_s *) coords->data;
+
+                       if (data) {
+                               geocodeData->coords = g_list_remove(geocodeData->coords, (gpointer)data);
+
+                               g_free(data);
+                               data = NULL;
+                       }
+                       coords = g_list_first(geocodeData->coords);
+               }
+
+               g_list_free(geocodeData->coords);
+               geocodeData->coords = NULL;
+
+               if (geocodeData->user_data) {
+                       g_free(geocodeData->user_data);
+                       geocodeData->user_data = NULL;
+               }
+       }
+}
+
+static void __free_revgeocode_response(void *ptr)
+{
+       MapquestRevGeocodeResponseData *revGeocodeData = (MapquestRevGeocodeResponseData *) (ptr);
+       if (revGeocodeData) {
+               if (revGeocodeData->addressDetails) {
+                       if (revGeocodeData->addressDetails->street_add) {
+                               g_free(revGeocodeData->addressDetails->street_add);
+                               revGeocodeData->addressDetails->street_add = NULL;
+                       }
+                       if (revGeocodeData->addressDetails->neighbourhood) {
+                               g_free(revGeocodeData->addressDetails->neighbourhood);
+                               revGeocodeData->addressDetails->neighbourhood = NULL;
+                       }
+                       if (revGeocodeData->addressDetails->city) {
+                               g_free(revGeocodeData->addressDetails->city);
+                               revGeocodeData->addressDetails->city = NULL;
+                       }
+                       if (revGeocodeData->addressDetails->county) {
+                               g_free(revGeocodeData->addressDetails->county);
+                               revGeocodeData->addressDetails->county = NULL;
+                       }
+                       if (revGeocodeData->addressDetails->state) {
+                               g_free(revGeocodeData->addressDetails->state);
+                               revGeocodeData->addressDetails->state = NULL;
+                       }
+                       if (revGeocodeData->addressDetails->country) {
+                               g_free(revGeocodeData->addressDetails->country);
+                               revGeocodeData->addressDetails->country = NULL;
+                       }
+                       if (revGeocodeData->addressDetails->country_code) {
+                               g_free(revGeocodeData->addressDetails->country_code);
+                               revGeocodeData->addressDetails->country_code = NULL;
+                       }
+                       if (revGeocodeData->addressDetails->postal_code) {
+                               g_free(revGeocodeData->addressDetails->postal_code);
+                               revGeocodeData->addressDetails->postal_code = NULL;
+                       }
+
+                       g_free(revGeocodeData->addressDetails);
+                       revGeocodeData->addressDetails = NULL;
+               }
+
+               if (revGeocodeData->user_data) {
+                       g_free(revGeocodeData->user_data);
+                       revGeocodeData->user_data = NULL;
+               }
+       }
+}
+
+static void __free_place_response(void *ptr)
+{
+       MapquestPlaceResponseData *placeData = (MapquestPlaceResponseData *) (ptr);
+       if (placeData) {
+               GList *place = NULL;
+               place = g_list_first(placeData->places);
+
+               while (place) {
+                       mapquest_place_resp_s *mapquest_place = (mapquest_place_resp_s *) place->data;
+
+                       if (mapquest_place->address) {
+                                       if (mapquest_place->address->street_add) {
+                                               g_free(mapquest_place->address->street_add);
+                                               mapquest_place->address->street_add = NULL;
+                                       }
+                                       if (mapquest_place->address->neighbourhood) {
+                                               g_free(mapquest_place->address->neighbourhood);
+                                               mapquest_place->address->neighbourhood = NULL;
+                                       }
+                                       if (mapquest_place->address->building_number) {
+                                               g_free(mapquest_place->address->building_number);
+                                               mapquest_place->address->building_number = NULL;
+                                       }
+                                       if (mapquest_place->address->city) {
+                                               g_free(mapquest_place->address->city);
+                                               mapquest_place->address->city = NULL;
+                                       }
+                                       if (mapquest_place->address->county) {
+                                               g_free(mapquest_place->address->county);
+                                               mapquest_place->address->county = NULL;
+                                       }
+                                       if (mapquest_place->address->state) {
+                                               g_free(mapquest_place->address->state);
+                                               mapquest_place->address->state = NULL;
+                                       }
+                                       if (mapquest_place->address->country) {
+                                               g_free(mapquest_place->address->country);
+                                               mapquest_place->address->country = NULL;
+                                       }
+                                       if (mapquest_place->address->country_code) {
+                                               g_free(mapquest_place->address->country_code);
+                                               mapquest_place->address->country_code = NULL;
+                                       }
+                                       if (mapquest_place->address->postal_code) {
+                                               g_free(mapquest_place->address->postal_code);
+                                               mapquest_place->address->postal_code = NULL;
+                                       }
+                               g_free(mapquest_place->address);
+                               mapquest_place->address = NULL;
+                       }
+
+                       if (mapquest_place->category) {
+                               g_free(mapquest_place->category);
+                               mapquest_place->category = NULL;
+                       }
+                       if (mapquest_place->subcategory) {
+                               g_free(mapquest_place->subcategory);
+                               mapquest_place->subcategory = NULL;
+                       }
+                       if (mapquest_place->display_name) {
+                               g_free(mapquest_place->display_name);
+                               mapquest_place->display_name = NULL;
+                       }
+
+                       placeData->places = g_list_remove(placeData->places, (gpointer)mapquest_place);
+
+                       g_free(mapquest_place);
+                       mapquest_place = NULL;
+
+                       place = g_list_first(placeData->places);
+               }
+               g_list_free(placeData->places);
+               placeData->places = NULL;
+
+               if (placeData->user_data) {
+                       g_free(placeData->user_data);
+                       placeData->user_data = NULL;
+               }
+       }
+}
+
+static void __free_route_response(void *ptr)
+{
+       MapquestRouteResponseData *routeData = (MapquestRouteResponseData *) (ptr);
+       if (routeData) {
+                mapquest_route_resp_s *route_info = routeData->routeResponse;
+               if (route_info) {
+                       GList *maneuver_data = NULL;
+                       maneuver_data = g_list_first(route_info->maneuvers);
+                       while (maneuver_data) {
+                               mapquest_route_maneuver *maneuver = (mapquest_route_maneuver *) maneuver_data->data;
+
+                               if (maneuver->instruction) {
+                                       g_free(maneuver->instruction);
+                                       maneuver->instruction = NULL;
+                               }
+                               if (maneuver->formatted_time) {
+                                       g_free(maneuver->formatted_time);
+                                       maneuver->formatted_time = NULL;
+                               }
+                               if (maneuver->direction_name) {
+                                       g_free(maneuver->direction_name);
+                                       maneuver->direction_name = NULL;
+                               }
+                               if (maneuver->street_name) {
+                                       g_free(maneuver->street_name);
+                                       maneuver->street_name = NULL;
+                               }
+
+                               route_info->maneuvers = g_list_remove(route_info->maneuvers, (gpointer)maneuver);
+
+                               g_free(maneuver);
+                               maneuver = NULL;
+
+                               /* Fetching the next item from Maneuver/Segment list */
+                               maneuver_data = g_list_first(route_info->maneuvers);
+                       }
+                       g_list_free(route_info->maneuvers);
+                       route_info->maneuvers = NULL;
+
+                       GList *shapePoints = NULL;
+                       shapePoints = g_list_first(route_info->shapePoints);
+                       while (shapePoints) {
+                               coords_s *data = (coords_s *) shapePoints->data;
+
+                               route_info->shapePoints = g_list_remove(route_info->shapePoints, (gpointer)data);
+
+                               g_free(data);
+                               data = NULL;
+
+                               shapePoints = g_list_first(route_info->shapePoints);
+                       }
+                       g_list_free(route_info->shapePoints);
+                       route_info->shapePoints = NULL;
+
+                       if (route_info->formatted_time) {
+                               g_free(route_info->formatted_time);
+                               route_info->formatted_time = NULL;
+                       }
+                       g_free(route_info);
+                       route_info = NULL;
+               }
+               if (routeData->user_data) {
+                       g_free(routeData->user_data);
+                       routeData->user_data = NULL;
+               }
+       }
+}
+
+int mapquest_init_queue()
+{
+#if !GLIB_CHECK_VERSION(2, 35, 0)
+       g_type_init();          /* Needed for using json in Emulator */
+#endif
+
+       pthread_mutex_init(&__requestLock, NULL);
+
+       /* Queue initialize */
+       responseQueue = g_async_queue_new();
+
+       /* Initialise Curl Service */
+       int ret = init_curl();
+
+       if (ret != MAPQUEST_ERROR_NONE)
+               return MAPQUEST_ERROR_UNKNOWN;
+
+       pthread_mutex_lock(&__requestLock);
+       requestList = NULL;
+       pthread_mutex_unlock(&__requestLock);
+       reqCancelList = NULL;
+       __ResponseQueueLen = 0;
+       __response_timer_running = false;
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int mapquest_deinit_queue()
+{
+       deinit_curl();
+
+       g_list_free(reqCancelList);
+       reqCancelList = NULL;
+
+       pthread_mutex_destroy(&__requestLock);
+
+       /* Free the queue */
+       if (responseQueue) {
+               g_async_queue_ref(responseQueue);
+               __ResponseQueueLen = g_async_queue_length(responseQueue);
+               MAP_DEBUG("Queue len : %d", __ResponseQueueLen);
+
+               while (__ResponseQueueLen > 0) {
+                       gpointer data = g_async_queue_try_pop(responseQueue);
+                       if (!data) {
+                               __ResponseQueueLen = g_async_queue_length(responseQueue);
+                               continue;
+                       }
+
+                       MapquestQueueData *response = (MapquestQueueData *) data;
+
+                       switch (response->type) {
+                       case RESP_TYPE_GEOCODE:
+                               {
+                                       MapquestGeocodeResponseData *geocodeData = (MapquestGeocodeResponseData *) (response->data);
+                                       if (geocodeData) {
+                                               __free_geocode_response(geocodeData);
+
+                                               g_free(geocodeData);
+                                               geocodeData = NULL;
+                                       }
+                               }
+                               break;
+                       case RESP_TYPE_REVGEOCODE:
+                               {
+                                       MapquestRevGeocodeResponseData *revGeocodeData = (MapquestRevGeocodeResponseData *) (response->data);
+                                       if (revGeocodeData) {
+                                               __free_revgeocode_response(revGeocodeData);
+
+                                               g_free(revGeocodeData);
+                                               revGeocodeData = NULL;
+                                       }
+                               }
+                               break;
+                       case RESP_TYPE_PLACES:
+                               {
+                                       MapquestPlaceResponseData *placeData = (MapquestPlaceResponseData *) (response->data);
+                                       if (placeData != NULL) {
+                                               __free_place_response(placeData);
+
+                                               g_free(placeData);
+                                               placeData = NULL;
+                                       }
+                               }
+                               break;
+                       case RESP_TYPE_ROUTE:
+                               {
+                                       MapquestRouteResponseData *routeData = (MapquestRouteResponseData *) (response->data);
+                                       if (routeData != NULL) {
+                                               __free_route_response(routeData);
+
+                                               g_free(routeData);
+                                               routeData = NULL;
+                                       }
+                               }
+                               break;
+                       default:
+                               break;
+                       }
+
+                       __ResponseQueueLen = g_async_queue_length(responseQueue);
+
+                       if (response) {
+                               g_free(response);
+                               response = NULL;
+                       }
+               }
+               g_async_queue_unref(responseQueue);
+               responseQueue = NULL;
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int mapquest_push_to_queue(mapquest_resp_type type, gpointer data)
+{
+       MAP_DEBUG("Pushing to Queue....");
+
+       MapquestQueueData *queueData = (MapquestQueueData *)g_malloc0(sizeof(MapquestQueueData));
+       if (!queueData) return MAPQUEST_ERROR_OUT_OF_MEMORY;
+
+       queueData->type = type;
+       queueData->data = data;
+
+       g_async_queue_ref(responseQueue);
+       g_async_queue_push(responseQueue, (gpointer)queueData);
+       g_async_queue_unref(responseQueue);
+
+       if (!__response_timer_running) {
+               MAP_DEBUG(">>>>>>>>>>>>>>>>>>>>>>> TRIGGER RESPONSE TIMER <<<<<<<<<<<<<<<<<<<<<<<<<");
+               g_timeout_add_seconds(1, __timeout_cb, NULL);   /* timeout : 1 sec */
+       } else {
+               __ResponseQueueLen = g_async_queue_length(responseQueue);
+               MAP_DEBUG(">>>>>>>>>>>>>>>>>> Timer already running. Response Queue Len [%d] <<<<<<<<<<<<<<<<<", __ResponseQueueLen);
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int start_geocode_service(mapquest_geocode_req_s *req_details, mapquest_geocode_cb callback, int request_id, void *user_data)
+{
+       int num_running_req = get_num_running_requests();
+
+       if (num_running_req >= CURL_MAX_CONNECTS) {
+               /* Add the request to queue */
+               add_to_geocode_list(req_details, callback, request_id, user_data);
+       } else {
+               MapquestGeocodeQueryData *queryData = (MapquestGeocodeQueryData *)g_malloc0(sizeof(MapquestGeocodeQueryData));
+
+               if (queryData != NULL) {
+                       queryData->requestId = request_id;
+                       queryData->geocode_cb = callback;
+                       queryData->user_data = user_data;
+
+                       if (req_details->boundary != NULL) {
+                               if (req_details->boundary->type == MAPQUEST_BOUNDARY_RECT) {
+                                       MAP_DEBUG("TOP LEFT >>><<< LATITUDE : %f, LONGITUDE : %f", req_details->boundary->rect.top_left.latitude, req_details->boundary->rect.top_left.longitude);
+                                       MAP_DEBUG("BOTTOM RIGHT >>><<< LATITUDE : %f, LONGITUDE : %f", req_details->boundary->rect.bottom_right.latitude, req_details->boundary->rect.bottom_right.longitude);
+
+                                       query_geocode_within_bounds(req_details->maps_key, req_details->address, req_details->boundary->rect.top_left, req_details->boundary->rect.bottom_right, req_details->num_res, queryData);
+
+                               } else if (req_details->boundary->type == MAPQUEST_BOUNDARY_CIRCLE) {
+
+                                       coords_s *top_left = NULL, *bottom_right = NULL;
+                                       coords_s circle = req_details->boundary->circle.center;
+                                       gdouble radius = (req_details->boundary->circle.radius) * 0.001;
+
+                                       MAP_DEBUG("User input LATITUDE : %f, LONGITUDE : %f", circle.latitude, circle.longitude);
+
+                                       /* Calculate the top left coordinate of bounding box. */
+                                       calculate_point(circle.latitude, circle.longitude, 315, radius, &top_left);
+
+                                       /* Calculate the bottom right coordinate of bounding box. */
+                                       calculate_point(circle.latitude, circle.longitude, 135, radius, &bottom_right);
+
+                                       if ((top_left != NULL) && (bottom_right != NULL)) {
+                                               MAP_DEBUG("Top Left LATITUDE : %f, LONGITUDE : %f", top_left->latitude, top_left->longitude);
+                                               MAP_DEBUG("Bottom Right LATITUDE : %f, LONGITUDE : %f", bottom_right->latitude, bottom_right->longitude);
+
+                                               query_geocode_within_bounds(req_details->maps_key, req_details->address, *top_left, *bottom_right, req_details->num_res, queryData);
+
+                                               g_free(top_left);
+                                               top_left = NULL;
+
+                                               g_free(bottom_right);
+                                               bottom_right = NULL;
+                                       }
+
+                               } else {
+                                       query_geocode(req_details->maps_key, req_details->address, req_details->num_res, queryData);
+                               }
+
+                       } else {
+                               MAP_DEBUG("BOUNDARY is NULL.. NORMAL GEOCODE QUERY WITHOUT BOUNDS");
+
+                               query_geocode(req_details->maps_key, req_details->address, req_details->num_res, queryData);
+                       }
+               }
+
+               if (req_details) {
+                       if (req_details->address) {
+                               g_free(req_details->address);
+                               req_details->address = NULL;
+                       }
+                       if (req_details->maps_key) {
+                               g_free(req_details->maps_key);
+                               req_details->maps_key = NULL;
+                       }
+                       if (req_details->boundary) {
+                               g_free(req_details->boundary);
+                               req_details->boundary = NULL;
+                       }
+                       g_free(req_details);
+                       req_details = NULL;
+               }
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int start_reversegeocode_service(mapquest_revgeocode_req_s *req_details, mapquest_reverse_geocode_cb callback, int request_id, void *user_data)
+{
+       int num_running_req = get_num_running_requests();
+
+       if (num_running_req >= CURL_MAX_CONNECTS) {
+               /* Add the request to queue */
+               add_to_revgeocode_list(req_details, callback, request_id, user_data);
+       } else {
+               MapquestRevGeocodeQueryData *queryData = (MapquestRevGeocodeQueryData *)g_malloc0(sizeof(MapquestRevGeocodeQueryData));
+
+               if (queryData != NULL) {
+                       queryData->requestId = request_id;
+                       queryData->reverse_geocode_cb = callback;
+                       queryData->user_data = user_data;
+
+                       coords_s coords = req_details->coordinates;
+
+                       query_revgeocode(req_details->maps_key, coords.latitude, coords.longitude, queryData);
+               }
+
+               if (req_details) {
+                       if (req_details->maps_key) {
+                               g_free(req_details->maps_key);
+                               req_details->maps_key = NULL;
+                       }
+                       g_free(req_details);
+                       req_details = NULL;
+               }
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int start_route_service(mapquest_route_req_s *req_details, mapquest_route_cb callback, int request_id, void *user_data)
+{
+       int num_running_req = get_num_running_requests();
+
+       if (num_running_req >= CURL_MAX_CONNECTS) {
+               /* Add the request to queue */
+               add_to_route_list(req_details, callback, request_id, user_data);
+       } else {
+               MapquestRouteQueryData *queryData = (MapquestRouteQueryData *)g_malloc0(sizeof(MapquestRouteQueryData));
+
+               if (queryData != NULL) {
+                       queryData->requestId = request_id;
+                       queryData->route_cb = callback;
+                       queryData->origin = req_details->from;
+                       queryData->destination = req_details->to;
+                       queryData->unit = req_details->unit;
+                       queryData->user_data = user_data;
+
+                       query_route(req_details->maps_key, req_details->from, req_details->to, req_details->type, req_details->avoids, req_details->driving_style, req_details->way_points, queryData);
+               }
+
+               if (req_details) {
+                       if (req_details->maps_key) {
+                               g_free(req_details->maps_key);
+                               req_details->maps_key = NULL;
+                       }
+                       if (req_details->way_points) {
+                               if (g_list_length(req_details->way_points) > 0) {
+                                       GList *list = NULL;
+                                       list = g_list_first(req_details->way_points);
+                                       while (list) {
+                                               coords_s *data = (coords_s *)list->data;
+                                               if (data) {
+                                                       req_details->way_points = g_list_remove(req_details->way_points, (gpointer)data);
+
+                                                       g_free(data);
+                                                       data = NULL;
+                                               }
+                                               list = g_list_first(req_details->way_points);
+                                       }
+                               }
+                               g_list_free(req_details->way_points);
+                               req_details->way_points = NULL;
+                       }
+                       g_free(req_details);
+                       req_details = NULL;
+               }
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+int start_places_service(mapquest_search_req_s *req_details, mapquest_place_search_cb callback, int request_id, void *user_data)
+{
+       int num_running_req = get_num_running_requests();
+
+       if (num_running_req >= CURL_MAX_CONNECTS) {
+               /* Add the request to queue */
+               add_to_places_list(req_details, callback, request_id, user_data);
+       } else {
+               MapquestPlaceQueryData *queryData = (MapquestPlaceQueryData *)g_malloc0(sizeof(MapquestPlaceQueryData));
+
+               if (queryData != NULL) {
+                       queryData->requestId = request_id;
+                       queryData->place_search_cb = callback;
+                       queryData->user_data = user_data;
+
+                       query_places(req_details->maps_key, req_details->search_string, req_details->boundary, req_details->num_res, queryData);
+               }
+
+               if (req_details) {
+                       if (req_details->maps_key) {
+                               g_free(req_details->maps_key);
+                               req_details->maps_key = NULL;
+                       }
+                       if (req_details->boundary) {
+                               g_free(req_details->boundary);
+                               req_details->boundary = NULL;
+                       }
+                       if (req_details->search_string) {
+                               g_free(req_details->search_string);
+                               req_details->search_string = NULL;
+                       }
+                       g_free(req_details);
+                       req_details = NULL;
+               }
+       }
+
+       return MAPQUEST_ERROR_NONE;
+}
diff --git a/src/mapquest/mapquest_queue.h b/src/mapquest/mapquest_queue.h
new file mode 100644 (file)
index 0000000..587dbb6
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_QUEUE_H_
+#define _MAPQUEST_QUEUE_H_
+
+#include <glib.h>
+#include "mapquest_server_private.h"
+
+typedef struct {
+       mapquest_req_type type;
+       void *request;
+} mapquest_request_s;
+
+typedef struct {
+       mapquest_geocode_req_s *req_details;
+       int requestId;
+       mapquest_geocode_cb geocode_cb;
+       void *user_data;
+} mapquest_geocode_req;
+
+typedef struct {
+       mapquest_revgeocode_req_s *req_details;
+       int requestId;
+       mapquest_reverse_geocode_cb revgeocode_cb;
+       void *user_data;
+} mapquest_revgeocode_req;
+
+typedef struct {
+       mapquest_route_req_s *req_details;
+       mapquest_route_cb route_cb;
+       int requestId;
+       void *user_data;
+} mapquest_route_req;
+
+typedef struct {
+       mapquest_search_req_s *req_details;
+       mapquest_place_search_cb search_place_cb;
+       int requestId;
+       void *user_data;
+} mapquest_search_place_req;
+
+int add_to_geocode_list(mapquest_geocode_req_s *req_details, mapquest_geocode_cb callback, int request_id, void *user_data);
+int add_to_revgeocode_list(mapquest_revgeocode_req_s *req_details, mapquest_reverse_geocode_cb callback, int request_id, void *user_data);
+int add_to_route_list(mapquest_route_req_s *req_details, mapquest_route_cb callback, int request_id, void *user_data);
+int add_to_places_list(mapquest_search_req_s *req_details, mapquest_place_search_cb callback, int request_id, void *user_data);
+
+int remove_from_request_list(int request_id);
+
+int start_geocode_service(mapquest_geocode_req_s *req_details, mapquest_geocode_cb callback, int request_id, void *user_data);
+int start_reversegeocode_service(mapquest_revgeocode_req_s *req_details, mapquest_reverse_geocode_cb callback, int request_id, void *user_data);
+int start_route_service(mapquest_route_req_s *req_details, mapquest_route_cb callback, int request_id, void *user_data);
+int start_places_service(mapquest_search_req_s *req_details, mapquest_place_search_cb callback, int request_id, void *user_data);
+
+int mapquest_init_queue();
+int mapquest_deinit_queue();
+int mapquest_push_to_queue(mapquest_resp_type type, gpointer data);
+
+#endif /* _MAPQUEST_QUEUE_H_ */
diff --git a/src/mapquest/mapquest_restcurl.c b/src/mapquest/mapquest_restcurl.c
new file mode 100644 (file)
index 0000000..7347f81
--- /dev/null
@@ -0,0 +1,671 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <curl/curl.h>
+#include <curl/easy.h>
+#include <pthread.h>
+#include <network/net_connection.h>
+#include "mapquest_restcurl.h"
+#include "mapquest_types.h"
+#include "mapquest_jsonparser.h"
+#include "mapquest_debug.h"
+
+#define RESTCURL_USE_MULTI_CURL
+
+CURLM *__cm_handle;
+pthread_t __CurlThread;
+pthread_mutex_t __MultiCurlArgsLock;
+pthread_mutex_t __CmHandleLock;
+static bool __thread_running_for_curlmulti = false;
+static int __MultiCurlArgsRemain = 0;
+pthread_cond_t __curl_delivered_cond;
+pthread_mutex_t __curl_deliver_mutex;
+static char *__proxy_address = NULL;
+GList *__cancel_req_list = NULL;
+
+typedef struct {
+       char *memory;
+       size_t size;
+} MemoryStruct_s;
+
+struct MultiCurlArg {
+       MemoryStruct_s m_chunk;
+       CURL *curl_handle;
+       mapquest_req_type req_type;
+       int request_id;
+       void *user_data;
+       char url[1024];
+};
+
+/****************** LIST for maintaining easy curl related data *******************/
+
+struct MultiCurlArg_List {
+       struct MultiCurlArg *mcArg;
+       struct MultiCurlArg_List *next;
+};
+
+struct MultiCurlArg_List *head = NULL;
+struct MultiCurlArg_List *curr = NULL;
+
+static struct MultiCurlArg_List *__create_list(struct MultiCurlArg *mcArg)
+{
+       MAP_DEBUG("\n creating list with headnode as [%p]\n", mcArg);
+       struct MultiCurlArg_List *ptr = (struct MultiCurlArg_List *)g_malloc0(sizeof(struct MultiCurlArg_List));
+       if (NULL == ptr) {
+               MAP_DEBUG("\n Node creation failed \n");
+               return NULL;
+       }
+       ptr->mcArg = mcArg;
+       ptr->next = NULL;
+
+       head = curr = ptr;
+       return ptr;
+}
+
+static struct MultiCurlArg_List *__add_to_list(struct MultiCurlArg *mcArg, bool add_to_end)
+{
+       if (NULL == head)
+               return (__create_list(mcArg));
+
+       struct MultiCurlArg_List *ptr = (struct MultiCurlArg_List *)g_malloc0(sizeof(struct MultiCurlArg_List));
+       if (NULL == ptr) {
+               MAP_DEBUG("\n Node creation failed \n");
+               return NULL;
+       }
+       ptr->mcArg = mcArg;
+       ptr->next = NULL;
+
+       if (add_to_end) {
+               curr->next = ptr;
+               curr = ptr;
+       } else {
+               ptr->next = head;
+               head = ptr;
+       }
+       return ptr;
+}
+
+static struct MultiCurlArg_List *__search_in_list(CURL * handle, struct MultiCurlArg_List **prev)
+{
+       struct MultiCurlArg_List *ptr = head;
+       struct MultiCurlArg_List *tmp = NULL;
+       bool found = false;
+
+       MAP_DEBUG("\n Searching the list for value\n");
+
+       while (ptr != NULL) {
+               if (ptr->mcArg->curl_handle == handle) {
+                       found = true;
+                       break;
+               } else {
+                       tmp = ptr;
+                       ptr = ptr->next;
+               }
+       }
+
+       if (true == found) {
+               if (prev)
+                       *prev = tmp;
+               return ptr;
+       } else {
+               return NULL;
+       }
+}
+
+static struct MultiCurlArg_List *__delete_from_list(CURL *handle)
+{
+       struct MultiCurlArg_List *prev = NULL;
+       struct MultiCurlArg_List *del = NULL;
+
+       MAP_DEBUG("\n Deleting value handle from list\n");
+
+       del = __search_in_list(handle, &prev);
+       if (del == NULL) {
+               return NULL;
+       } else {
+               if (prev != NULL)
+                       prev->next = del->next;
+
+               if (del == curr) {
+                       curr = prev;
+                       if (prev == NULL)
+                               head = NULL;
+               } else if (del == head) {
+                       head = del->next;
+               }
+       }
+
+       del->next = NULL;
+
+       return del;
+}
+
+/*****************************************/
+
+mapquest_error_e __get_proxy_address()
+{
+       mapquest_error_e err = MAPQUEST_ERROR_NONE;
+
+       connection_h con = NULL;
+       int errorCode = CONNECTION_ERROR_NOT_SUPPORTED;
+       char *address = NULL;
+
+       errorCode = connection_create(&con);
+
+       if (errorCode == CONNECTION_ERROR_NONE)
+               errorCode = connection_get_proxy(con, CONNECTION_ADDRESS_FAMILY_IPV4, &address);
+
+       if (errorCode != CONNECTION_ERROR_NONE) {
+               err = MAPQUEST_ERROR_UNKNOWN;
+               switch (errorCode) {
+               case CONNECTION_ERROR_INVALID_PARAMETER:
+                       MAP_DEBUG("Invalid parameter");
+                       err = MAPQUEST_ERROR_INVALID_PARAMETER;
+                       break;
+               case CONNECTION_ERROR_OUT_OF_MEMORY:
+                       MAP_DEBUG("Out of memory error");
+                       err = MAPQUEST_ERROR_OUT_OF_MEMORY;
+                       break;
+               case CONNECTION_ERROR_INVALID_OPERATION:
+                       MAP_DEBUG("Invalid Operation");
+                       err = MAPQUEST_ERROR_INVALID_OPERATION;
+                       break;
+               case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
+                       MAP_DEBUG("Address family not supported");
+                       err = MAPQUEST_ERROR_NOT_SUPPORTED;
+                       break;
+               /*
+               case CONNECTION_ERROR_PERMISSION_DENIED:
+                       MAP_DEBUG("Permission denied");
+                       err = MAPQUEST_ERROR_PERMISSION_DENIED;
+                       break;
+               */
+               case CONNECTION_ERROR_OPERATION_FAILED:
+                       MAP_DEBUG("Operation failed");
+                       err = MAPQUEST_ERROR_INVALID_OPERATION;
+                       break;
+               case CONNECTION_ERROR_ITERATOR_END:
+                       MAP_DEBUG("End of iteration");
+                       break;
+               case CONNECTION_ERROR_NO_CONNECTION:
+                       MAP_DEBUG("There is no connection");
+                       err = MAPQUEST_ERROR_NETWORK_UNREACHABLE;
+                       break;
+               case CONNECTION_ERROR_NOW_IN_PROGRESS:
+                       MAP_DEBUG("Now in progress");
+                       err = MAPQUEST_ERROR_RESOURCE_BUSY;
+                       break;
+               case CONNECTION_ERROR_ALREADY_EXISTS:
+                       MAP_DEBUG("Already exists");
+                       break;
+               case CONNECTION_ERROR_OPERATION_ABORTED:
+                       MAP_DEBUG("Operation is aborted");
+                       err = MAPQUEST_ERROR_CANCELED;
+                       break;
+               case CONNECTION_ERROR_DHCP_FAILED:
+                       MAP_DEBUG("DHCP failed");
+                       break;
+               case CONNECTION_ERROR_INVALID_KEY:
+                       MAP_DEBUG("Invalid key");
+                       err = MAPQUEST_ERROR_KEY_NOT_AVAILABLE;
+                       break;
+               case CONNECTION_ERROR_NO_REPLY:
+                       MAP_DEBUG("No reply");
+                       err = MAPQUEST_ERROR_RESOURCE_BUSY;
+                       break;
+               case CONNECTION_ERROR_NOT_SUPPORTED:
+                       MAP_DEBUG("Not Supported");
+                       err = MAPQUEST_ERROR_NOT_SUPPORTED;
+                       break;
+               default:
+                       MAP_DEBUG("Unknown");
+                       break;
+               }
+               MAP_DEBUG("errorCode = %ld", (long)errorCode);
+       }
+
+       if (con)
+               connection_destroy(con);
+
+       if (err != MAPQUEST_ERROR_NONE)
+               return err;
+
+       if (address) {
+               int len = strlen(address);
+               if (len > 0) {
+                       __proxy_address = (char *)g_malloc0(len+1);
+                       strncpy(__proxy_address, address, len);
+                       __proxy_address[len] = '\0';
+               }
+               g_free(address);
+               address = NULL;
+       }
+
+       MAP_DEBUG("Proxy = %s", (__proxy_address ? __proxy_address : "(null)"));
+
+       return MAPQUEST_ERROR_NONE;
+}
+
+static size_t __write_memory_callback(void *contents, size_t size, size_t nmemb, void *userp)
+{
+       size_t realsize = size * nmemb;
+#ifdef RESTCURL_USE_MULTI_CURL
+       MemoryStruct_s *mem = &(((struct MultiCurlArg *) userp)->m_chunk);
+#else
+       MemoryStruct_s *mem = (MemoryStruct_s *) userp;
+#endif
+
+       if (mem->memory == NULL)
+               mem->memory = g_malloc(realsize);
+       else
+               mem->memory = g_realloc(mem->memory, mem->size + realsize);
+
+       if (mem->memory == NULL)
+               return 0;
+
+       memcpy(mem->memory + mem->size, contents, realsize);
+
+       mem->size += realsize;
+
+       MAP_DEBUG("REal size : %d", realsize);
+       MAP_DEBUG("response size :: %d", strlen(mem->memory));
+
+       return realsize;
+}
+
+static int __xferinfo(void *p, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
+{
+       struct MultiCurlArg *pMultiCurlArg = (struct MultiCurlArg *) p;
+
+       GList *list = NULL;
+       list = g_list_first(__cancel_req_list);
+       int req_id_to_be_cancelled = -1;
+       bool cancel_request = false;
+
+       while (list) {
+               req_id_to_be_cancelled = (int) GPOINTER_TO_INT(list->data);
+               MAP_DEBUG("Req id in the list waiting to get cancelled [%d]", req_id_to_be_cancelled);
+               if (pMultiCurlArg->request_id == req_id_to_be_cancelled) {
+                       MAP_DEBUG(">>>>>>>>>>>> Req id matched :: To be cancelled [%d]", req_id_to_be_cancelled);
+                       cancel_request = true;
+                       break;
+               }
+               list = list->next;
+       }
+
+       if (cancel_request) {
+               MAP_DEBUG(">>>>>>>> Req Id to be aborted :: [%d] <<<<<<<<<<<<<", req_id_to_be_cancelled);
+               /* Remove the request id from cancel list */
+               __cancel_req_list = g_list_remove(__cancel_req_list, (gpointer) GINT_TO_POINTER(req_id_to_be_cancelled));
+               MAP_DEBUG(">>>>>>>>>> Request removed from cancel list <<<<<<<<");
+               return 1;               /* Returning Non-Zero value will abort the transfer */
+       }
+
+       return 0;
+}
+
+static int __progress_info(void *p, double dltotal, double dlnow, double ultotal, double ulnow)
+{
+       return __xferinfo(p, (curl_off_t)dltotal, (curl_off_t)dlnow, (curl_off_t)ultotal, (curl_off_t)ulnow);
+}
+
+int add_handle(char *url, mapquest_req_type type, void *user_data)
+{
+       if (!url || !user_data) return -1;
+
+       int req_id = -1;
+
+       switch (type) {
+       case REQ_TYPE_GEOCODE:
+               req_id = ((MapquestGeocodeQueryData *) user_data)->requestId;
+               break;
+       case REQ_TYPE_REVGEOCODE:
+               req_id = ((MapquestRevGeocodeQueryData *) user_data)->requestId;
+               break;
+       case REQ_TYPE_PLACES:
+               req_id = ((MapquestRouteQueryData *) user_data)->requestId;
+               break;
+       case REQ_TYPE_ROUTE:
+               req_id = ((MapquestPlaceQueryData *) user_data)->requestId;
+               break;
+       default:
+               break;
+       }
+
+#ifdef RESTCURL_USE_MULTI_CURL
+       MAP_DEBUG("HTTP Req URL [%s]", url);
+       CURL *curl_handle;
+
+       struct MultiCurlArg *pMultiCurlArg = (struct MultiCurlArg *)g_malloc0(sizeof(struct MultiCurlArg));
+
+       if (!pMultiCurlArg) return -1;
+
+       (pMultiCurlArg->m_chunk).memory = (char *) g_malloc0(1);        /* will be grown as needed by the realloc above */
+       (pMultiCurlArg->m_chunk).size = 0;      /* no data at this point */
+
+       /* init the curl session */
+       curl_handle = curl_easy_init();
+
+       /* set URL to get */
+       curl_easy_setopt(curl_handle, CURLOPT_URL, url);
+
+       curl_easy_setopt(curl_handle, CURLOPT_PROGRESSFUNCTION, __progress_info);
+       curl_easy_setopt(curl_handle, CURLOPT_PROGRESSDATA, NULL);
+
+#if LIBCURL_VERSION_NUM >= 0x72000
+       curl_easy_setopt(curl_handle, CURLOPT_XFERINFOFUNCTION, __xferinfo);
+       curl_easy_setopt(curl_handle, CURLOPT_XFERINFODATA, (void *)pMultiCurlArg);
+#endif
+
+       curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 0L);
+
+       curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
+
+       curl_easy_setopt(curl_handle, CURLOPT_PROXY , __proxy_address);
+
+       /* send all data to this function  */
+       curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, __write_memory_callback);
+
+       /* we want the headers to this file handle */
+       curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)pMultiCurlArg);
+
+       /* some servers don't like requests that are made without a user-agent field, so we provide one */
+       curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
+
+       pMultiCurlArg->curl_handle = curl_handle;
+       pMultiCurlArg->req_type = type;
+       pMultiCurlArg->request_id = req_id;
+       pMultiCurlArg->user_data = user_data;
+       strncpy(pMultiCurlArg->url, url, sizeof(pMultiCurlArg->url)-1);
+
+       pthread_mutex_lock(&__MultiCurlArgsLock);
+       __MultiCurlArgsRemain++;
+       __add_to_list(pMultiCurlArg, true);
+       pthread_mutex_unlock(&__MultiCurlArgsLock);
+
+       pthread_mutex_lock(&__CmHandleLock);
+       curl_multi_add_handle(__cm_handle, curl_handle);
+       pthread_mutex_unlock(&__CmHandleLock);
+
+       pthread_mutex_lock(&__curl_deliver_mutex);
+       pthread_cond_signal(&__curl_delivered_cond);
+       pthread_mutex_unlock(&__curl_deliver_mutex);
+#endif
+       return 0;
+}
+
+static void __post_curl(mapquest_req_type type, MemoryStruct_s *m_chunk, void *user_data)
+{
+       mapquest_resp_type resp_type = RESP_TYPE_NONE;
+       switch (type) {
+       case REQ_TYPE_GEOCODE:
+               resp_type = RESP_TYPE_GEOCODE;
+               break;
+       case REQ_TYPE_REVGEOCODE:
+               resp_type = RESP_TYPE_REVGEOCODE;
+               break;
+       case REQ_TYPE_PLACES:
+               resp_type = RESP_TYPE_PLACES;
+               break;
+       case REQ_TYPE_ROUTE:
+               resp_type = RESP_TYPE_ROUTE;
+               break;
+       default:
+               resp_type = RESP_TYPE_NONE;
+               break;
+       }
+
+       post_curl_response(m_chunk->memory, m_chunk->size, resp_type, user_data);
+}
+
+static void *__curl_thread_handler(void *user_data)
+{
+       __thread_running_for_curlmulti = true;
+       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+
+#ifdef RESTCURL_USE_MULTI_CURL
+       CURLMsg *msg;
+       int Q;
+       int still_running = -1;
+
+       while (__thread_running_for_curlmulti || __MultiCurlArgsRemain) {
+               while (__MultiCurlArgsRemain) {
+                       pthread_mutex_lock(&__CmHandleLock);
+                       curl_multi_perform(__cm_handle, &still_running);
+                       pthread_mutex_unlock(&__CmHandleLock);
+
+                       if (still_running != __MultiCurlArgsRemain) {
+                               pthread_mutex_lock(&__CmHandleLock);
+                               msg = curl_multi_info_read(__cm_handle, &Q);
+                               pthread_mutex_unlock(&__CmHandleLock);
+
+                               if (msg == 0)
+                                       break;
+
+                               if (msg->msg == CURLMSG_DONE) {
+                                       MAP_DEBUG("Transfer completed for one handle");
+                                       CURL *e = msg->easy_handle;
+
+                                       pthread_mutex_lock(&__MultiCurlArgsLock);
+                                       struct MultiCurlArg_List *del = NULL;
+                                       if ((del = __delete_from_list(e)) != NULL) {
+                                                       MAP_DEBUG("Decrementing the handle counter in multiCurl..");
+                                                       __MultiCurlArgsRemain--;
+                                       }
+                                       pthread_mutex_unlock(&__MultiCurlArgsLock);
+
+                                       if (del && del->mcArg) {
+                                               MAP_DEBUG("HTTP Url [%s]", del->mcArg->url);
+                                               MAP_DEBUG("Posting the result..");
+                                               __post_curl(del->mcArg->req_type, &(del->mcArg->m_chunk), del->mcArg->user_data);
+
+                                               if ((del->mcArg->m_chunk).memory) {
+                                                       g_free((del->mcArg->m_chunk).memory);
+                                                       (del->mcArg->m_chunk).memory = NULL;
+                                               }
+
+                                               pthread_mutex_lock(&__CmHandleLock);
+                                               curl_multi_remove_handle(__cm_handle, del->mcArg->curl_handle);
+                                               pthread_mutex_unlock(&__CmHandleLock);
+
+                                               curl_easy_cleanup(del->mcArg->curl_handle);
+
+                                               g_free(del->mcArg);
+                                               del->mcArg = NULL;
+
+                                               g_free(del);
+                                               del = NULL;
+                                       }
+                               } else {
+                                       MAP_DEBUG("E: CURLMsg (%d)\n", msg->msg);
+                               }
+                       }
+               }
+
+               if (__thread_running_for_curlmulti && !__MultiCurlArgsRemain) {
+                       pthread_mutex_lock(&__curl_deliver_mutex);
+                       pthread_cond_wait(&__curl_delivered_cond, &__curl_deliver_mutex);
+                       pthread_mutex_unlock(&__curl_deliver_mutex);
+               }
+       }
+
+#else
+       /* curl_easy_perform */
+#endif
+       pthread_exit(NULL);
+
+       return 0;
+}
+
+void cancel_request(int request_id)
+{
+       if (__cancel_req_list == NULL)
+               __cancel_req_list = g_list_append(__cancel_req_list, (gpointer) GINT_TO_POINTER(request_id));
+       else
+               __cancel_req_list = g_list_insert_before(__cancel_req_list, NULL, (gpointer) GINT_TO_POINTER(request_id));
+}
+
+int get_num_running_requests()
+{
+       MAP_DEBUG("Num of running requests :: >>>> [%d]", __MultiCurlArgsRemain);
+       return __MultiCurlArgsRemain;
+}
+
+int init_curl()
+{
+       __cancel_req_list = NULL;
+
+       head = NULL;
+       curr = NULL;
+
+       __get_proxy_address();
+
+#ifdef RESTCURL_USE_MULTI_CURL
+       pthread_mutex_init(&__MultiCurlArgsLock, NULL);
+       pthread_mutex_init(&__CmHandleLock, NULL);
+       pthread_mutex_init(&__curl_deliver_mutex, NULL);
+       pthread_cond_init(&__curl_delivered_cond, NULL);
+
+       curl_global_init(CURL_GLOBAL_ALL);
+
+       __cm_handle = curl_multi_init();
+       curl_multi_setopt(__cm_handle, CURLMOPT_MAXCONNECTS, (long)CURL_MAX_CONNECTS);
+
+       __MultiCurlArgsRemain = 0;
+       int ret = pthread_create(&__CurlThread, NULL, &__curl_thread_handler, NULL);
+       __thread_running_for_curlmulti = true;
+#endif
+
+       return ret;
+}
+
+int deinit_curl()
+{
+#ifdef RESTCURL_USE_MULTI_CURL
+       __thread_running_for_curlmulti = false;
+       __MultiCurlArgsRemain = 0;
+
+       pthread_mutex_lock(&__curl_deliver_mutex);
+       pthread_cond_signal(&__curl_delivered_cond);
+       pthread_mutex_unlock(&__curl_deliver_mutex);
+
+       pthread_cancel(__CurlThread);
+
+       pthread_join(__CurlThread, NULL);
+
+       curl_multi_cleanup(__cm_handle);
+       curl_global_cleanup();
+
+       pthread_mutex_destroy(&__MultiCurlArgsLock);
+       pthread_mutex_destroy(&__CmHandleLock);
+       pthread_cond_destroy(&__curl_delivered_cond);
+       pthread_mutex_destroy(&__curl_deliver_mutex);
+#endif
+
+       if (__proxy_address) {
+               g_free(__proxy_address);
+               __proxy_address = NULL;
+       }
+
+       struct MultiCurlArg_List *temp = head;
+       struct MultiCurlArg_List *next;
+
+       while (temp) {
+               next = temp->next;
+               struct MultiCurlArg *curlArg = temp->mcArg;
+
+               if (curlArg) {
+                       if ((curlArg->m_chunk).memory) {
+                               g_free((curlArg->m_chunk).memory);
+                               (curlArg->m_chunk).memory = NULL;
+                       }
+
+                       if (curlArg->user_data) {
+                               switch (curlArg->req_type) {
+                               case REQ_TYPE_GEOCODE:
+                               {
+                                       MapquestGeocodeQueryData *queryData = (MapquestGeocodeQueryData *)curlArg->user_data;
+                                       if (queryData) {
+                                               if (queryData->user_data) {
+                                                       g_free(queryData->user_data);
+                                                       queryData->user_data = NULL;
+                                               }
+                                               g_free(queryData);
+                                               queryData = NULL;
+                                       }
+                               }
+                                       break;
+                               case REQ_TYPE_REVGEOCODE:
+                               {
+                                       MapquestRevGeocodeQueryData *queryData = (MapquestRevGeocodeQueryData *)curlArg->user_data;
+                                       if (queryData) {
+                                               if (queryData->user_data) {
+                                                       g_free(queryData->user_data);
+                                                       queryData->user_data = NULL;
+                                               }
+                                               g_free(queryData);
+                                               queryData = NULL;
+                                       }
+                               }
+                                       break;
+                               case REQ_TYPE_PLACES:
+                               {
+                                       MapquestPlaceQueryData *queryData = (MapquestPlaceQueryData *)curlArg->user_data;
+                                       if (queryData) {
+                                               if (queryData->user_data) {
+                                                       g_free(queryData->user_data);
+                                                       queryData->user_data = NULL;
+                                               }
+                                               g_free(queryData);
+                                               queryData = NULL;
+                                       }
+                               }
+                                       break;
+                               case REQ_TYPE_ROUTE:
+                               {
+                                       MapquestRouteQueryData *queryData = (MapquestRouteQueryData *)curlArg->user_data;
+                                       if (queryData) {
+                                               if (queryData->user_data) {
+                                                       g_free(queryData->user_data);
+                                                       queryData->user_data = NULL;
+                                               }
+                                               g_free(queryData);
+                                               queryData = NULL;
+                                       }
+                               }
+                                       break;
+                               default:
+                                       break;
+                               }
+                       }
+
+                       curl_easy_cleanup(curlArg->curl_handle);
+
+                       g_free(curlArg);
+                       curlArg  = NULL;
+               }
+               g_free(temp);
+
+               temp = next;
+       }
+       head = NULL;
+
+       g_list_free(__cancel_req_list);
+       __cancel_req_list = NULL;
+
+       return 0;
+}
diff --git a/src/mapquest/mapquest_restcurl.h b/src/mapquest/mapquest_restcurl.h
new file mode 100644 (file)
index 0000000..b1d5a2a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_RESTCURL_H_
+#define _MAPQUEST_RESTCURL_H_
+
+#include "mapquest_server_private.h"
+
+#define CURL_MAX_CONNECTS      30
+
+int init_curl();
+
+int deinit_curl();
+
+int get_num_running_requests();
+
+int add_handle(char *url, mapquest_req_type type, void *user_data);
+
+void cancel_request(int request_id);
+
+#endif /* _MAPQUEST_RESTCURL_H_ */
diff --git a/src/mapquest/mapquest_revgeocode.c b/src/mapquest/mapquest_revgeocode.c
new file mode 100644 (file)
index 0000000..246bee6
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include <pthread.h>
+#include "mapquest_revgeocode.h"
+#include "mapquest_types.h"
+#include "mapquest_server_private.h"
+#include "mapquest_debug.h"
+#include "mapquest_queue.h"
+#include "mapquest_restcurl.h"
+
+#define REVERSE_GEOCODE_URL    "https://open.mapquestapi.com/geocoding/v1/reverse?key=%s&outFormat=json"
+
+int query_revgeocode(gchar *maps_key, gdouble latitude, gdouble longitude, gpointer user_data)
+{
+       char url[1024];
+       char tmpStr[512];
+
+       if (maps_key != NULL)
+               snprintf(tmpStr, sizeof(tmpStr), REVERSE_GEOCODE_URL, maps_key);
+       else
+               snprintf(tmpStr, sizeof(tmpStr), REVERSE_GEOCODE_URL, "null");
+
+       strcpy(url, tmpStr);
+
+       snprintf(tmpStr, sizeof(tmpStr), "&location=%f,%f", latitude, longitude);
+       strcat(url, tmpStr);
+
+       add_handle(url, REQ_TYPE_REVGEOCODE, user_data);
+
+       return 0;
+}
diff --git a/src/mapquest/mapquest_revgeocode.h b/src/mapquest/mapquest_revgeocode.h
new file mode 100644 (file)
index 0000000..d337733
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_REVGEOCODE_H_
+#define _MAPQUEST_REVGEOCODE_H_
+
+#include "mapquest_api.h"
+#include "mapquest_types.h"
+
+int query_revgeocode(gchar *maps_key, gdouble latitude, gdouble longitude, gpointer user_data);
+
+#endif /* _MAPQUEST_REVGEOCODE_H_ */
diff --git a/src/mapquest/mapquest_route.c b/src/mapquest/mapquest_route.c
new file mode 100644 (file)
index 0000000..a4ec225
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include <pthread.h>
+#include "mapquest_route.h"
+#include "mapquest_types.h"
+#include "mapquest_server_private.h"
+#include "mapquest_debug.h"
+#include "mapquest_queue.h"
+#include "mapquest_restcurl.h"
+
+#define ROUTE_URL       "https://open.mapquestapi.com/directions/v2/route?key=%s&ambiguities=ignore&outFormat=json&shapeFormat=raw&generalize=0"
+
+int query_route(gchar *maps_key, coords_s startPoint, coords_s endPoint, route_type type, route_feature_avoids avoids, route_driving_style style, GList *waypoints, gpointer user_data)
+{
+       char url[1024];
+       char tmpStr[512];
+
+       if (maps_key != NULL)
+               snprintf(tmpStr, sizeof(tmpStr), ROUTE_URL, maps_key);
+       else
+               snprintf(tmpStr, sizeof(tmpStr), ROUTE_URL, "null");
+
+       strcpy(url, tmpStr);
+
+       strcat(url, "&unit=m"); /* Keeping default as miles and conversion will be done later */
+
+       if (type == ROUTE_TYPE_FASTEST)
+               strcat(url, "&routeType=fastest");
+       else if (type == ROUTE_TYPE_SHORTEST)
+               strcat(url, "&routeType=shortest");
+       else if (type == ROUTE_TYPE_PEDESTRIAN)
+               strcat(url, "&routeType=pedestrian");
+       else if (type == ROUTE_TYPE_MULTIMODAL)
+               strcat(url, "&routeType=multimodal");
+       else if (type == ROUTE_TYPE_BICYCLE)
+               strcat(url, "&routeType=bicycle");
+
+       if (avoids == ROUTE_AVOID_LIMITED_ACCESS)
+               strcat(url, "&avoids=Limited Access");
+       else if (avoids == ROUTE_AVOID_TOLL_ROAD)
+               strcat(url, "&avoids=Tollroad");
+       else if (avoids == ROUTE_AVOID_FERRY)
+               strcat(url, "&avoids=Ferry");
+       else if (avoids == ROUTE_AVOID_UNPAVED)
+               strcat(url, "&avoids=Unpaved");
+       else if (avoids == ROUTE_AVOID_SEASONAL_CLOSURE)
+               strcat(url, "&avoids=Approximate Seasonal Closure");
+       else if (avoids == ROUTE_AVOID_COUNTRY_BORDER_CROSSING)
+               strcat(url, "&avoids=Country border crossing");
+
+       if (style == DRIVING_STYLE_NORMAL)
+               strcat(url, "&drivingStyle=2");
+       else if (style == DRIVING_STYLE_CAUTIOUS)
+               strcat(url, "&drivingStyle=1");
+       else if (style == DRIVING_STYLE_AGGRESSIVE)
+               strcat(url, "&drivingStyle=3");
+
+       int length = g_list_length(waypoints);
+       if (length != 0) {
+               int index = 0;
+               GList *waypoints_list = NULL;
+               waypoints_list = g_list_first(waypoints);
+
+               while (waypoints_list) {
+
+                       coords_s *data = (coords_s *) waypoints_list->data;
+
+                       if (data) {
+                               if (index == 0)
+                                       snprintf(tmpStr, sizeof(tmpStr), "&from=%f,%f", data->latitude, data->longitude);
+                               else
+                                       snprintf(tmpStr, sizeof(tmpStr), "&to=%f,%f", data->latitude, data->longitude);
+                               strcat(url, tmpStr);
+                       }
+
+                       waypoints_list = g_list_next(waypoints_list);
+                       index++;
+               }
+       } else {
+               snprintf(tmpStr, sizeof(tmpStr), "&from=%f,%f", startPoint.latitude, startPoint.longitude);
+               strcat(url, tmpStr);
+
+               snprintf(tmpStr, sizeof(tmpStr), "&to=%f,%f", endPoint.latitude, endPoint.longitude);
+               strcat(url, tmpStr);
+       }
+
+       add_handle(url, REQ_TYPE_ROUTE, user_data);
+
+       return 0;
+}
diff --git a/src/mapquest/mapquest_route.h b/src/mapquest/mapquest_route.h
new file mode 100644 (file)
index 0000000..8a71d07
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_ROUTE_H_
+#define _MAPQUEST_ROUTE_H_
+
+#include "mapquest_api.h"
+#include "mapquest_types.h"
+
+int query_route(gchar *maps_key, coords_s startPoint, coords_s endPoint, route_type type, route_feature_avoids avoids, route_driving_style style, GList *waypoints, gpointer user_data);
+
+#endif /* _MAPQUEST_ROUTE_H_ */
diff --git a/src/mapquest/mapquest_server_private.h b/src/mapquest/mapquest_server_private.h
new file mode 100644 (file)
index 0000000..cba948f
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_PRIVATE_H_
+#define _MAPQUEST_PRIVATE_H_
+
+#include "mapquest_api.h"
+
+typedef enum {
+       REQ_TYPE_GEOCODE = 0,
+       REQ_TYPE_REVGEOCODE,
+       REQ_TYPE_PLACES,
+       REQ_TYPE_ROUTE,
+       REQ_TYPE_NONE
+} mapquest_req_type;
+
+typedef enum {
+       RESP_TYPE_GEOCODE = 0,
+       RESP_TYPE_REVGEOCODE,
+       RESP_TYPE_PLACES,
+       RESP_TYPE_ROUTE,
+       RESP_TYPE_NONE
+} mapquest_resp_type;
+
+typedef struct {
+       int requestId;
+       mapquest_geocode_cb geocode_cb;
+       void *user_data;
+} MapquestGeocodeQueryData;
+
+typedef struct {
+       int requestId;
+       mapquest_reverse_geocode_cb reverse_geocode_cb;
+       void *user_data;
+} MapquestRevGeocodeQueryData;
+
+typedef struct {
+       int requestId;
+       mapquest_route_cb route_cb;
+       coords_s origin;
+       coords_s destination;
+       route_unit unit;
+       void *user_data;
+} MapquestRouteQueryData;
+
+typedef struct {
+       int requestId;
+       mapquest_place_search_cb place_search_cb;
+       void *user_data;
+} MapquestPlaceQueryData;
+
+typedef struct {
+       mapquest_error_e error;
+       int requestId;
+       mapquest_geocode_cb geocode_cb;
+       GList *coords;
+       void *user_data;
+} MapquestGeocodeResponseData;
+
+typedef struct {
+       mapquest_error_e error;
+       int requestId;
+       mapquest_reverse_geocode_cb reverse_geocode_cb;
+       mapquest_address_resp_s *addressDetails;
+       void *user_data;
+} MapquestRevGeocodeResponseData;
+
+typedef struct {
+       mapquest_error_e error;
+       int requestId;
+       mapquest_route_cb route_cb;
+       mapquest_route_resp_s *routeResponse;
+       void *user_data;
+} MapquestRouteResponseData;
+
+typedef struct {
+       mapquest_error_e error;
+       int requestId;
+       mapquest_place_search_cb place_search_cb;
+       GList *places;
+       void *user_data;
+} MapquestPlaceResponseData;
+
+typedef struct {
+       mapquest_resp_type type;
+       void *data;
+} MapquestQueueData;
+
+#endif /* _MAPQUEST_PRIVATE_H_ */
diff --git a/src/mapquest/mapquest_types.h b/src/mapquest/mapquest_types.h
new file mode 100644 (file)
index 0000000..79ce1fc
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_TYPES_H_
+#define _MAPQUEST_TYPES_H_
+
+#include <glib.h>
+
+typedef enum {
+       MAPQUEST_ERROR_NONE = 0,                /**< Successful */
+        MAPQUEST_ERROR_PERMISSION_DENIED,       /**< Permission Denied */
+        MAPQUEST_ERROR_OUT_OF_MEMORY,           /**< Out of memory */
+        MAPQUEST_ERROR_INVALID_PARAMETER,       /**< Invalid parameter */
+        MAPQUEST_ERROR_NOT_SUPPORTED,           /**< Not supported */
+        MAPQUEST_ERROR_CONNECTION_TIMED_OUT,    /**< Timeout error, no answer */
+        MAPQUEST_ERROR_NETWORK_UNREACHABLE,     /**< Network unavailable */
+        MAPQUEST_ERROR_INVALID_OPERATION,       /**< Opeartion is not valid */
+        MAPQUEST_ERROR_KEY_NOT_AVAILABLE,       /**< Invalid key */
+        MAPQUEST_ERROR_RESOURCE_BUSY,           /**< Resource busy */
+        MAPQUEST_ERROR_CANCELED,                /**< Service canceled */
+        MAPQUEST_ERROR_UNKNOWN,                 /**< Unknown error */
+        MAPQUEST_ERROR_SERVICE_NOT_AVAILABLE,   /**< Service unavailabe*/
+        MAPQUEST_ERROR_NOT_FOUND,               /**< Result not found */
+} mapquest_error_e;
+
+typedef enum {
+       MAPQUEST_BOUNDARY_NONE = 0,     /*  Undefined geographical area type. */
+       MAPQUEST_BOUNDARY_RECT,         /*  Rectangular geographical area type. */
+       MAPQUEST_BOUNDARY_CIRCLE,       /*  Circle geographical area type. */
+} boundary_type;
+
+typedef enum {
+       ROUTE_TYPE_FASTEST = 0,
+       ROUTE_TYPE_SHORTEST,
+       ROUTE_TYPE_PEDESTRIAN,
+       ROUTE_TYPE_MULTIMODAL,
+       ROUTE_TYPE_BICYCLE
+} route_type;
+
+typedef enum {
+       ROUTE_UNIT_M = 0,               /* for Meter */
+       ROUTE_UNIT_KM,          /* for Kilometer */
+       ROUTE_UNIT_FT,          /* for Foot     */
+       ROUTE_UNIT_YD           /*for Yard */
+} route_unit;
+
+typedef enum {
+       ROUTE_AVOID_NONE = 0,
+       ROUTE_AVOID_LIMITED_ACCESS,
+       ROUTE_AVOID_TOLL_ROAD,
+       ROUTE_AVOID_FERRY,
+       ROUTE_AVOID_UNPAVED,
+       ROUTE_AVOID_SEASONAL_CLOSURE,
+       ROUTE_AVOID_COUNTRY_BORDER_CROSSING
+} route_feature_avoids;
+
+typedef enum {
+       DRIVING_STYLE_NORMAL = 0,
+       DRIVING_STYLE_CAUTIOUS,
+       DRIVING_STYLE_AGGRESSIVE
+} route_driving_style;
+
+typedef struct {
+       gdouble latitude;
+       gdouble longitude;
+} coords_s;
+
+typedef struct {
+       coords_s top_left;
+       coords_s bottom_right;
+} rectangle_s;
+
+typedef struct {
+       coords_s center;
+       gdouble radius;
+} circle_s;
+
+typedef struct {
+       boundary_type type;
+       union {
+               rectangle_s rect;
+               circle_s circle;
+       };
+} mapquest_boundary_s;
+
+typedef struct {
+       gchar *maps_key;
+       gchar *address;
+       mapquest_boundary_s *boundary;
+       gint num_res;
+} mapquest_geocode_req_s;
+
+typedef struct {
+       gchar *maps_key;
+       gint num_res;
+       coords_s coordinates;
+} mapquest_revgeocode_req_s;
+
+typedef struct {
+       gchar *maps_key;
+       gchar *search_string;
+       gint num_res;
+       gchar *country_code;
+       mapquest_boundary_s *boundary;
+       GList *excludes;
+} mapquest_search_req_s;
+
+typedef struct {
+       gchar *maps_key;
+       coords_s from;
+       coords_s to;
+       route_unit unit;
+       route_type type;
+       route_feature_avoids avoids;            /* List of type strings. (Limited Access, Toll Road, Ferry, Unpaved, Seasonal Closure, Country Crossing) */
+       route_driving_style driving_style;      /* (1 - cautious, 2 - normal, 3 - aggressive) */
+       GList *way_points;                              /* List of type coords_s */
+} mapquest_route_req_s;
+
+typedef struct {
+       gint zoom_level;
+       coords_s center_coords;
+} mapquest_tiledata_req_s;
+
+typedef struct {
+       gchar *street_add;
+       gchar *neighbourhood;
+       gchar *building_number;
+       gchar *city;
+       gchar *county;
+       gchar *state;
+       gchar *country;
+       gchar *country_code;
+       gchar *postal_code;
+} mapquest_address_resp_s;
+
+typedef struct {
+       gchar *place_id;
+       gchar *display_name;
+       mapquest_address_resp_s *address;
+       rectangle_s bounding_box;
+       coords_s coordinates;
+       gchar *category;
+       gchar *subcategory;
+       gchar *icon_url;
+} mapquest_place_resp_s;
+
+typedef struct {
+       guint type;
+       guint direction;
+       guint text;
+       gchar *icon_url;
+} mapquest_route_maneuver_signs;
+
+typedef struct {
+       coords_s start_point;
+       coords_s end_point;
+       gdouble distance;
+       guint time;
+       gchar *formatted_time;
+       guint attribute;
+       guint turn_type;
+       guint direction;
+       gchar *instruction;
+       gchar *direction_name;
+       guint index;
+       gchar *street_name;
+} mapquest_route_maneuver;
+
+typedef struct {
+       rectangle_s bounding_box;
+       gdouble distance;
+       route_unit distance_unit;
+       guint time;
+       gchar *formatted_time;
+       route_type type;
+       GList *maneuvers;               /* List of type mapquest_route_maneuver */
+       GList *shapePoints;
+} mapquest_route_resp_s;
+
+#endif /* _MAPQUEST_TYPES_H_ */
diff --git a/src/mapquest/mapquest_util.c b/src/mapquest/mapquest_util.c
new file mode 100644 (file)
index 0000000..fc71d12
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "mapquest_util.h"
+#include "mapquest_debug.h"
+#include <math.h>
+
+#define PI 3.14159265359
+#define EARTH_RADIUS   6371
+
+void calculate_point(gdouble Lat1, gdouble Lon1, int dBearing, gdouble dist, coords_s **coord)
+{
+       Lat1 = (Lat1 / 180.0) * PI;
+       Lon1 = (Lon1 / 180.0) * PI;
+
+       gdouble dLat = asin(sin(Lat1) * cos(dist / EARTH_RADIUS) + (cos(Lat1) * sin(dist / EARTH_RADIUS) * cos(dBearing)));
+
+       dLat = (180.0 * dLat) / PI;
+
+       gdouble dLon = Lon1 + atan2(sin(dBearing) * sin(dist / EARTH_RADIUS) * cos(Lat1), cos(dist / EARTH_RADIUS) - sin(Lat1) * sin((dLat / 180.0) * PI));
+
+       dLon = (180.0 * dLon) / PI;
+
+       if (*coord == NULL)
+               *coord = (coords_s *)g_malloc0(sizeof(coords_s));
+
+       if (*coord) {
+               (*coord)->latitude = dLat;
+               (*coord)->longitude = dLon;
+       }
+}
+
diff --git a/src/mapquest/mapquest_util.h b/src/mapquest/mapquest_util.h
new file mode 100644 (file)
index 0000000..b62a3d5
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _MAPQUEST_UTIL_H_
+#define _MAPQUEST_UTIL_H_
+
+#include "mapquest_types.h"
+
+void calculate_point(gdouble Lat1, gdouble Lon1, int dBearing, gdouble dist, coords_s **coord);
+
+#endif /* _MAPQUEST_UTIL_H_ */
diff --git a/src/mapquest_plugin.c b/src/mapquest_plugin.c
new file mode 100644 (file)
index 0000000..9b119f2
--- /dev/null
@@ -0,0 +1,1394 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "mapquest_plugin.h"
+#include "mapquest_plugin_internal.h"
+#include "mapquest_api.h"
+#include <maps_error.h>
+#include <maps_route_plugin.h>
+#include <maps_route_segment_plugin.h>
+#include <maps_route_maneuver_plugin.h>
+#include <maps_place_plugin.h>
+#include <maps_place_category.h>
+#include <maps_place_image_plugin.h>
+#include <maps_place_rating_plugin.h>
+
+#define DEFAULT_NUM_RESULTS    10
+#define _PROVIDER_KEY_MAX_SIZE 1024
+
+static const double LATITUDE_RANGE = 85.05113;
+static const double LONGITUDE_RANGE = 180.0;
+
+static int __request_id = 0;
+static maps_plugin_h __plugin = NULL;
+static char __provider_key[_PROVIDER_KEY_MAX_SIZE] = { 0 };
+
+static maps_item_hashtable_h preference_plugin = NULL;
+
+int __maps_service_instance_count = 0;
+
+static int __convert_to_maps_error(int ret)
+{
+       switch (ret) {
+       case MAPQUEST_ERROR_NONE:
+               return MAPS_ERROR_NONE;
+       case MAPQUEST_ERROR_PERMISSION_DENIED:
+               return MAPS_ERROR_PERMISSION_DENIED;
+       case MAPQUEST_ERROR_OUT_OF_MEMORY:
+               return MAPS_ERROR_OUT_OF_MEMORY;
+       case MAPQUEST_ERROR_INVALID_PARAMETER:
+               return MAPS_ERROR_INVALID_PARAMETER;
+       case MAPQUEST_ERROR_NOT_SUPPORTED:
+               return MAPS_ERROR_NOT_SUPPORTED;
+       case MAPQUEST_ERROR_CONNECTION_TIMED_OUT:
+               return MAPS_ERROR_CONNECTION_TIME_OUT;
+       case MAPQUEST_ERROR_NETWORK_UNREACHABLE:
+               return MAPS_ERROR_NETWORK_UNREACHABLE;
+       case MAPQUEST_ERROR_INVALID_OPERATION:
+               return MAPS_ERROR_INVALID_OPERATION;
+       case MAPQUEST_ERROR_KEY_NOT_AVAILABLE:
+               return MAPS_ERROR_KEY_NOT_AVAILABLE;
+       case MAPQUEST_ERROR_RESOURCE_BUSY:
+               return MAPS_ERROR_RESOURCE_BUSY;
+       case MAPQUEST_ERROR_CANCELED:
+               return MAPS_ERROR_CANCELED;
+       case MAPQUEST_ERROR_UNKNOWN:
+               return MAPS_ERROR_UNKNOWN;
+       case MAPQUEST_ERROR_SERVICE_NOT_AVAILABLE:
+               return MAPS_ERROR_SERVICE_NOT_AVAILABLE;
+       case MAPQUEST_ERROR_NOT_FOUND:
+               return MAPS_ERROR_NOT_FOUND;
+       default:
+               return MAPS_ERROR_UNKNOWN;
+       }
+}
+
+static maps_route_turn_type_e __convert_route_turn_type(int index)
+{
+       maps_route_turn_type_e type = MAPS_ROUTE_TURN_TYPE_NONE;
+
+       if (index == 0)
+               type = MAPS_ROUTE_TURN_TYPE_STRAIGHT;
+       else if (index == 1)
+               type = MAPS_ROUTE_TURN_TYPE_LIGHT_RIGHT;
+       else if (index == 2)
+               type = MAPS_ROUTE_TURN_TYPE_RIGHT;
+       else if (index == 3)
+               type = MAPS_ROUTE_TURN_TYPE_HARD_RIGHT;
+       else if (index == 5)
+               type = MAPS_ROUTE_TURN_TYPE_HARD_LEFT;
+       else if (index == 6)
+               type = MAPS_ROUTE_TURN_TYPE_LIGHT_LEFT;
+       else if (index == 7)
+               type = MAPS_ROUTE_TURN_TYPE_LIGHT_LEFT;
+       else if (index == 8)
+               type = MAPS_ROUTE_TURN_TYPE_UTURN_RIGHT;
+       else if (index == 9)
+               type = MAPS_ROUTE_TURN_TYPE_UTURN_LEFT;
+       else if (index == 16)
+               type = MAPS_ROUTE_TURN_TYPE_RIGHT_FORK;
+       else if (index == 17)
+               type = MAPS_ROUTE_TURN_TYPE_LEFT_FORK;
+       else if (index == 18)
+               type = MAPS_ROUTE_TURN_TYPE_STRAIGHT_FORK;
+       else
+               type = MAPS_ROUTE_TURN_TYPE_NONE;
+
+       return type;
+}
+
+static bool __replace_space(char *place_name, char **modified_place_name)
+{
+       if (!place_name) return false;
+
+       int new_str_len = 0;
+       char *ch;
+       for (ch = place_name; *ch != '\0'; ch++) {
+               if (*ch == ' ')
+                       new_str_len += 2;
+               new_str_len++;
+       }
+
+       if (strlen(place_name) < new_str_len) {
+               *modified_place_name = (char *)g_malloc((new_str_len + 1) * sizeof(char));
+               if (*modified_place_name) {
+                       char *ch1, *ch2;
+                       for (ch1 = place_name, ch2 = *modified_place_name; *ch1 != '\0'; ch1++) {
+                               if (*ch1 == ' ') {
+                                       ch2[0] = '%';
+                                       ch2[1] = '2';
+                                       ch2[2] = '0';
+                                       ch2 += 3;
+                               } else {
+                                       *ch2 = *ch1;
+                                       ch2++;
+                               }
+                       }
+                       *ch2 = '\0';
+
+                       return true;
+               }
+       }
+       return false;
+}
+
+EXPORT_API int maps_plugin_init(maps_plugin_h *plugin)
+{
+       if (!plugin)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = MAPS_ERROR_NONE;
+       if (!__plugin) {
+               ret = mapquest_init();
+       }
+
+       if (ret == MAPS_ERROR_NONE) {
+               __maps_service_instance_count++;
+               __plugin = plugin;
+       }
+
+       return __convert_to_maps_error(ret);
+}
+
+EXPORT_API int maps_plugin_shutdown(maps_plugin_h plugin)
+{
+       MAPS_LOGD("PLUGIN SHUTDOWN");
+       if (!plugin)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       __maps_service_instance_count--;
+
+       int ret = MAPS_ERROR_NONE;
+       if (__maps_service_instance_count == 0) {
+               ret = mapquest_shutdown();
+               __plugin = NULL;
+       }
+
+       return __convert_to_maps_error(ret);
+}
+
+EXPORT_API int maps_plugin_is_service_supported(maps_service_e service, bool *supported)
+{
+       if (!supported)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       switch (service) {
+       case MAPS_SERVICE_GEOCODE:
+       case MAPS_SERVICE_GEOCODE_INSIDE_AREA:
+       case MAPS_SERVICE_GEOCODE_BY_STRUCTURED_ADDRESS:
+       case MAPS_SERVICE_REVERSE_GEOCODE:
+       case MAPS_SERVICE_SEARCH_PLACE:
+       case MAPS_SERVICE_SEARCH_PLACE_BY_AREA:
+       case MAPS_SERVICE_SEARCH_PLACE_BY_ADDRESS:
+       case MAPS_SERVICE_SEARCH_ROUTE:
+       case MAPS_SERVICE_SEARCH_ROUTE_WAYPOINTS:
+       case MAPS_SERVICE_CANCEL_REQUEST:
+               *supported = true;
+               return MAPS_ERROR_NONE;
+       default:
+               *supported = false;
+               return MAPS_ERROR_NOT_SUPPORTED;
+       }
+}
+
+EXPORT_API int maps_plugin_is_data_supported(maps_service_data_e data, bool *supported)
+{
+       if (!supported)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       switch (data) {
+       case MAPS_PLACE_ADDRESS:
+       case MAPS_PLACE_CATEGORIES:
+       case MAPS_PLACE_IMAGE:
+               /* unsupported */
+               /* case MAPS_PLACE_RATING: */
+               /* case MAPS_PLACE_ATTRIBUTES: */
+               /* case MAPS_PLACE_CONTACTS: */
+               /* case MAPS_PLACE_EDITORIALS: */
+               /* case MAPS_PLACE_REVIEWS: */
+               /* case MAPS_PLACE_SUPPLIER: */
+               /* case MAPS_PLACE_RELATED: */
+
+       case MAPS_ROUTE_PATH:
+       case MAPS_ROUTE_SEGMENTS_PATH:
+       case MAPS_ROUTE_SEGMENTS_MANEUVERS:
+               *supported = true;
+               return MAPS_ERROR_NONE;
+       default:
+               *supported = false;
+               return MAPS_ERROR_NOT_SUPPORTED;
+       }
+}
+
+EXPORT_API int maps_plugin_get_info(maps_plugin_info_h *info)
+{
+       if (!info)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       maps_plugin_info_create(info);
+       maps_plugin_info_set_provider_name(*info, "MAPQUEST");
+
+       return MAPS_ERROR_NONE;
+}
+
+EXPORT_API int maps_plugin_set_provider_key(const char *provider_key)
+{
+       if (!provider_key)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       g_snprintf(__provider_key, _PROVIDER_KEY_MAX_SIZE, "%s", provider_key);
+
+       return MAPS_ERROR_NONE;
+}
+
+EXPORT_API int maps_plugin_get_provider_key(char **provider_key)
+{
+       if (!provider_key)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       *provider_key = g_strndup(__provider_key, _PROVIDER_KEY_MAX_SIZE);
+
+       return MAPS_ERROR_NONE;
+}
+
+EXPORT_API int maps_plugin_set_preference(maps_item_hashtable_h preference)
+{
+       if (!preference)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       maps_item_hashtable_clone(preference, &preference_plugin);
+       return MAPS_ERROR_NONE;
+}
+
+EXPORT_API int maps_plugin_get_preference(maps_item_hashtable_h *preference)
+{
+       if (!preference)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       maps_item_hashtable_clone(preference_plugin, preference);
+       return MAPS_ERROR_NONE;
+}
+
+static void __mapquest_geocode_cb(mapquest_error_e result, int request_id, GList *co_ordinates, void *user_data)
+{
+       MAPS_LOGD("Got GEOCODE callback from ENGINE");
+
+       callback_info_geocode *calldata_geocode = (callback_info_geocode *) user_data;
+
+       if ((result != MAPQUEST_ERROR_NONE) || (co_ordinates == NULL)) {
+               MAPS_LOGD(">>>>> Invalid GEOCODE result <<<<<");
+               calldata_geocode->callback((maps_error_e)__convert_to_maps_error(result), calldata_geocode->reqID, 0, 0, NULL, calldata_geocode->data);
+       } else {
+               int total_count = (int) g_list_length(co_ordinates);
+               int index = 0;
+
+               GList *coords = NULL;
+               coords = g_list_first(co_ordinates);
+
+               while (coords) {
+                       MAPS_LOGD("coordinate %d", index);
+                       coords_s *data = (coords_s *) coords->data;
+
+                       if (data != NULL) {
+                               maps_coordinates_h resultCoords;
+                               maps_coordinates_create(data->latitude, data->longitude, &resultCoords);
+                               bool b = calldata_geocode->callback(MAPS_ERROR_NONE, calldata_geocode->reqID, index, total_count, resultCoords, calldata_geocode->data);
+                               if (!b)
+                                       return;
+                       }
+                       index++;
+                       coords = coords->next;
+               }
+       }
+}
+
+EXPORT_API int maps_plugin_geocode(const char *address, const maps_preference_h preference, maps_service_geocode_cb callback, void *user_data, int *request_id)
+{
+       if (!address || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       callback_info_geocode *calldata_geocode = (callback_info_geocode *)g_malloc0(sizeof(callback_info_geocode));
+       if (calldata_geocode == NULL)
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+
+       calldata_geocode->callback = callback;
+       calldata_geocode->data = user_data;
+
+       mapquest_geocode_req_s *geocode_req = (mapquest_geocode_req_s *)g_malloc0(sizeof(mapquest_geocode_req_s));
+       if (geocode_req == NULL) {
+               g_free(calldata_geocode);
+               calldata_geocode = NULL;
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+       }
+
+       char *modified_address = NULL;
+       bool b_isAddress_modified = false;
+       b_isAddress_modified = __replace_space((char *)address, &modified_address);
+
+       if (b_isAddress_modified)
+               geocode_req->address = g_strdup((gchar *) modified_address);
+       else
+               geocode_req->address = g_strdup((gchar *) address);
+
+       if (modified_address) {
+               g_free(modified_address);
+               modified_address = NULL;
+       }
+
+       geocode_req->maps_key = g_strdup((gchar *) __provider_key);
+       geocode_req->boundary = NULL;
+
+       int max_result = 0;
+       maps_preference_get_max_results(preference, &max_result);
+
+       if (max_result <= 0)
+               geocode_req->num_res = DEFAULT_NUM_RESULTS;
+       else
+               geocode_req->num_res = max_result;
+
+       *request_id = ++__request_id;
+       calldata_geocode->reqID = __request_id;
+
+       int ret = mapquest_geocode(geocode_req, __mapquest_geocode_cb, __request_id, (void *) calldata_geocode);
+
+       return __convert_to_maps_error(ret);
+}
+
+EXPORT_API int maps_plugin_geocode_inside_area(const char *address, const maps_area_h bounds, const maps_preference_h preference, maps_service_geocode_cb callback, void *user_data, int *request_id)
+{
+       if (!bounds || !address || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       callback_info_geocode *calldata_geocode = (callback_info_geocode *)g_malloc0(sizeof(callback_info_geocode));
+       if (calldata_geocode == NULL)
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+
+       calldata_geocode->callback = callback;
+       calldata_geocode->data = user_data;
+
+       mapquest_geocode_req_s *geocode_req = (mapquest_geocode_req_s *)g_malloc0(sizeof(mapquest_geocode_req_s));
+       if (geocode_req == NULL) {
+               free(calldata_geocode);
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+       }
+
+       char *modified_address = NULL;
+       bool b_isAddress_modified = false;
+       b_isAddress_modified = __replace_space((char *)address, &modified_address);
+
+       if (b_isAddress_modified)
+               geocode_req->address = g_strdup((gchar *) modified_address);
+       else
+               geocode_req->address = g_strdup((gchar *) address);
+
+       if (modified_address) {
+               g_free(modified_address);
+               modified_address = NULL;
+       }
+
+       geocode_req->maps_key = g_strdup((gchar *) __provider_key);
+
+       int max_result = 0;
+       maps_preference_get_max_results(preference, &max_result);
+
+       if (max_result <= 0)
+               geocode_req->num_res = DEFAULT_NUM_RESULTS;
+       else
+               geocode_req->num_res = max_result;
+
+       geocode_req->boundary = NULL;
+       geocode_req->boundary = (mapquest_boundary_s *)g_malloc0(sizeof(mapquest_boundary_s));
+
+       maps_area_s *area = (maps_area_s *) bounds;
+
+       if (area && geocode_req->boundary) {
+               if (area->type == MAPS_AREA_RECTANGLE) {
+                       geocode_req->boundary->type = MAPQUEST_BOUNDARY_RECT;
+                       geocode_req->boundary->rect.top_left.latitude = area->rect.top_left.latitude;
+                       geocode_req->boundary->rect.top_left.longitude = area->rect.top_left.longitude;
+                       geocode_req->boundary->rect.bottom_right.latitude = area->rect.bottom_right.latitude;
+                       geocode_req->boundary->rect.bottom_right.longitude = area->rect.bottom_right.longitude;
+               } else if (area->type == MAPS_AREA_CIRCLE) {
+                       geocode_req->boundary->type = MAPQUEST_BOUNDARY_CIRCLE;
+                       geocode_req->boundary->circle.center.latitude = area->circle.center.latitude;
+                       geocode_req->boundary->circle.center.longitude = area->circle.center.longitude;
+                       geocode_req->boundary->circle.radius = area->circle.radius;
+               }
+       }
+
+       *request_id = ++__request_id;
+       calldata_geocode->reqID = __request_id;
+
+       int ret = mapquest_geocode(geocode_req, __mapquest_geocode_cb, __request_id, (void *) calldata_geocode);
+
+       return __convert_to_maps_error(ret);
+}
+
+EXPORT_API int maps_plugin_geocode_by_structured_address(const maps_address_h address, const maps_preference_h preference, maps_service_geocode_cb callback, void *user_data, int *request_id)
+{
+       if (!address || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       callback_info_geocode *calldata_geocode = (callback_info_geocode *)g_malloc0(sizeof(callback_info_geocode));
+       if (calldata_geocode == NULL)
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+
+       calldata_geocode->callback = callback;
+       calldata_geocode->data = user_data;
+
+       mapquest_geocode_req_s *geocode_req = (mapquest_geocode_req_s *)g_malloc0(sizeof(mapquest_geocode_req_s));
+       if (geocode_req == NULL) {
+               free(calldata_geocode);
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+       }
+
+       char resultAddressQuery[1024];
+       strcpy(resultAddressQuery, "");
+
+       char *street = NULL;
+       maps_address_get_street(address, &street);
+       if (street != NULL)
+               strcat(resultAddressQuery, street);
+
+       char *city = NULL;
+       maps_address_get_city(address, &city);
+       if ((strlen(resultAddressQuery) > 0) && (city != NULL)) {
+               strcat(resultAddressQuery, ",");
+               strcat(resultAddressQuery, city);
+       } else if (city != NULL) {
+               strcat(resultAddressQuery, city);
+       }
+
+       char *state = NULL;
+       maps_address_get_state(address, &state);
+       if ((strlen(resultAddressQuery) > 0) && (state != NULL)) {
+               strcat(resultAddressQuery, ",");
+               strcat(resultAddressQuery, state);
+       } else if (state != NULL) {
+               strcat(resultAddressQuery, state);
+       }
+
+#if 0
+       char *district = NULL;
+       maps_address_get_district(address, &district);
+       if ((strlen(resultAddressQuery) > 0) && (district != NULL)) {
+               strcat(resultAddressQuery, ", ");
+               strcat(resultAddressQuery, district);
+       }
+
+       char *country = NULL;
+       maps_address_get_country(address, &country);
+       if ((strlen(resultAddressQuery) > 0) && (country != NULL)) {
+               strcat(resultAddressQuery, ", ");
+               strcat(resultAddressQuery, country);
+       }
+
+       char *country_code = NULL;
+       maps_address_get_country_code(address, &country_code);
+       if ((strlen(resultAddressQuery) > 0) && (country_code != NULL)) {
+               strcat(resultAddressQuery, ", ");
+               strcat(resultAddressQuery, country_code);
+       } else if (country_code != NULL) {
+               strcat(resultAddressQuery, country_code);
+       }
+
+       char *county = NULL;
+       maps_address_get_county(address, &county);
+       if ((strlen(resultAddressQuery) > 0) && (county != NULL)) {
+               strcat(resultAddressQuery, ", ");
+               strcat(resultAddressQuery, county);
+       }
+#endif
+
+       char *postal_code = NULL;
+       maps_address_get_postal_code(address, &postal_code);
+       if ((strlen(resultAddressQuery) > 0) && (postal_code != NULL)) {
+               strcat(resultAddressQuery, ",");
+               strcat(resultAddressQuery, postal_code);
+       } else if (postal_code != NULL) {
+               strcat(resultAddressQuery, postal_code);
+       }
+
+       char *modified_address = NULL;
+       bool b_isAddress_modified = false;
+       b_isAddress_modified = __replace_space(resultAddressQuery, &modified_address);
+
+       if (b_isAddress_modified)
+               geocode_req->address = g_strdup((gchar *) modified_address);
+       else
+               geocode_req->address = g_strdup((gchar *) resultAddressQuery);
+
+       if (modified_address) {
+               g_free(modified_address);
+               modified_address = NULL;
+       }
+
+       geocode_req->maps_key = g_strdup((gchar *) __provider_key);
+       geocode_req->boundary = NULL;
+
+       int max_result = 0;
+       maps_preference_get_max_results(preference, &max_result);
+
+       if (max_result <= 0)
+               geocode_req->num_res = DEFAULT_NUM_RESULTS;
+       else
+               geocode_req->num_res = max_result;
+
+       *request_id = ++__request_id;
+       calldata_geocode->reqID = __request_id;
+
+       int ret = mapquest_geocode(geocode_req, __mapquest_geocode_cb, __request_id, (void *) calldata_geocode);
+
+       return __convert_to_maps_error(ret);
+}
+
+static void __mapquest_reverse_geocode_cb(mapquest_error_e result, int request_id, mapquest_address_resp_s *address, void *user_data)
+{
+       MAPS_LOGD("Got REV GEOCODE callback from ENGINE");
+       callback_info_reverse_geocode *calldata_reverse_geocode = (callback_info_reverse_geocode *) user_data;
+       if (result != MAPQUEST_ERROR_NONE || address == NULL) {
+               calldata_reverse_geocode->callback((maps_error_e) __convert_to_maps_error(result), calldata_reverse_geocode->reqID, 0, 0, NULL, calldata_reverse_geocode->data);
+       } else {
+               int total_count = 1;
+               int index = 0;
+
+               maps_address_h addr = NULL;
+               maps_address_create(&addr);
+
+               maps_address_set_street(addr, address->street_add);
+               maps_address_set_city(addr, address->city);
+               maps_address_set_county(addr, address->county);
+               maps_address_set_state(addr, address->state);
+               maps_address_set_country(addr, address->country);
+               maps_address_set_country_code(addr, address->country_code);
+               maps_address_set_postal_code(addr, address->postal_code);
+
+               calldata_reverse_geocode->callback(MAPS_ERROR_NONE, calldata_reverse_geocode->reqID, index, total_count, addr, calldata_reverse_geocode->data);
+       }
+}
+
+EXPORT_API int maps_plugin_reverse_geocode(double latitude, double longitude, const maps_preference_h preference, maps_service_reverse_geocode_cb callback, void *user_data, int *request_id)
+{
+       if (!callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       if (latitude > LATITUDE_RANGE || latitude < -LATITUDE_RANGE)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       if (longitude > LONGITUDE_RANGE || longitude < -LONGITUDE_RANGE)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       callback_info_reverse_geocode *calldata_reverse_geocode = (callback_info_reverse_geocode *)g_malloc0(sizeof(callback_info_reverse_geocode));
+       if (calldata_reverse_geocode == NULL)
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+
+       calldata_reverse_geocode->callback = callback;
+       calldata_reverse_geocode->data = user_data;
+
+       mapquest_revgeocode_req_s *reverse_geocode_req = (mapquest_revgeocode_req_s *)g_malloc0(sizeof(mapquest_revgeocode_req_s));
+       if (reverse_geocode_req == NULL) {
+               g_free(calldata_reverse_geocode);
+               calldata_reverse_geocode = NULL;
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+       }
+
+       reverse_geocode_req->maps_key = g_strdup((gchar *) __provider_key);
+       reverse_geocode_req->coordinates.latitude = latitude;
+       reverse_geocode_req->coordinates.longitude = longitude;
+
+       *request_id = ++__request_id;
+       calldata_reverse_geocode->reqID = __request_id;
+
+       int ret = mapquest_reverse_geocode(reverse_geocode_req, __mapquest_reverse_geocode_cb, __request_id, (void *) calldata_reverse_geocode);
+
+       return __convert_to_maps_error(ret);
+}
+
+static void __mapquest_route_cb(mapquest_error_e result, int request_id, mapquest_route_resp_s *route_info, void *user_data)
+{
+       MAPS_LOGD("__mapquest_route_cb");
+       callback_info_route *calldata_route = (callback_info_route *) user_data;
+
+       if (route_info) {
+               maps_route_h route;
+               maps_route_create(&route);
+
+               maps_coordinates_h top_left;
+               maps_coordinates_create(route_info->bounding_box.top_left.latitude, route_info->bounding_box.top_left.longitude, &top_left);
+
+               maps_coordinates_h bottom_right;
+               maps_coordinates_create(route_info->bounding_box.bottom_right.latitude, route_info->bounding_box.bottom_right.longitude, &bottom_right);
+
+               maps_area_h bounds = NULL;
+               maps_area_create_rectangle(top_left, bottom_right, &bounds);
+               maps_route_set_bounding_box(route, bounds);
+               maps_area_destroy(bounds);
+
+               maps_coordinates_destroy(top_left);
+               maps_coordinates_destroy(bottom_right);
+
+               maps_distance_unit_e unit = MAPS_DISTANCE_UNIT_M;
+
+               switch (route_info->distance_unit) {
+               case ROUTE_UNIT_M:
+                       unit = MAPS_DISTANCE_UNIT_M;
+                       break;
+               case ROUTE_UNIT_KM:
+                       unit = MAPS_DISTANCE_UNIT_KM;
+                       break;
+               case ROUTE_UNIT_FT:
+                       unit = MAPS_DISTANCE_UNIT_FT;
+                       break;
+               case ROUTE_UNIT_YD:
+                       unit = MAPS_DISTANCE_UNIT_YD;
+                       break;
+               }
+
+               maps_route_set_distance_unit(route, unit);
+               maps_route_set_total_distance(route, route_info->distance);
+               maps_route_set_total_duration(route, (long) route_info->time);
+               if (route_info->type == ROUTE_TYPE_FASTEST)
+                       maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_CAR);
+               else if (route_info->type == ROUTE_TYPE_PEDESTRIAN)
+                       maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN);
+               else if (route_info->type == ROUTE_TYPE_BICYCLE)
+                       maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_BICYCLE);
+               else if (route_info->type == ROUTE_TYPE_MULTIMODAL)
+                       maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT);
+               else
+                       maps_route_set_transport_mode(route, MAPS_ROUTE_TRANSPORT_MODE_CAR);
+
+               maps_item_list_h segment_list = NULL;
+               maps_item_list_create(&segment_list);
+
+               GList *maneuver_data = NULL;
+               maneuver_data = g_list_first(route_info->maneuvers);
+
+               while (maneuver_data) {
+                       maps_route_segment_h segment = NULL;
+                       maps_route_segment_create(&segment);
+
+                       maps_route_maneuver_h man = NULL;
+                       maps_route_maneuver_create(&man);
+                       mapquest_route_maneuver *maneuver = (mapquest_route_maneuver *) maneuver_data->data;
+
+                       /* Segment Origin and Destination */
+                       maps_coordinates_h segmentStartPoint;
+                       maps_coordinates_create(maneuver->start_point.latitude, maneuver->start_point.longitude, &segmentStartPoint);
+                       maps_route_segment_set_origin(segment, segmentStartPoint);      /* origin */
+                       maps_coordinates_destroy(segmentStartPoint);
+
+                       maps_coordinates_h segmentEndPoint;
+                       maps_coordinates_create(maneuver->end_point.latitude, maneuver->end_point.longitude, &segmentEndPoint);
+
+                       MAPS_LOGD(">>> Segment start : %f, %f <<<", maneuver->start_point.latitude, maneuver->start_point.longitude);
+                       MAPS_LOGD(">>> Segment end : %f, %f <<<", maneuver->end_point.latitude, maneuver->end_point.longitude);
+
+                       maps_route_segment_set_destination(segment, segmentEndPoint);   /* destination */
+                       maps_coordinates_destroy(segmentEndPoint);
+
+                       /* Segment distance */
+                       maps_route_segment_set_distance(segment, maneuver->distance);
+                       maps_route_segment_set_duration(segment, maneuver->time);
+
+                       /* Maneuver distance */
+                       maps_route_maneuver_set_distance_to_next_instruction(man, maneuver->distance);
+                       maps_route_maneuver_set_time_to_next_instruction(man, maneuver->time);
+
+                       maps_route_maneuver_set_turn_type(man, __convert_route_turn_type(maneuver->turn_type));
+
+                       /* maneuver_set_traffic_direction(man, (traffic_direction_e)action_id); */
+
+                       /* Maneuver Instruction */
+                       if (maneuver->instruction)
+                               maps_route_maneuver_set_instruction_text(man, (char *) maneuver->instruction);
+
+                       /* Maneuver Street Name */
+                       if (maneuver->street_name) {
+                               MAPS_LOGD("Street Name >>>> %s", maneuver->street_name);
+                               maps_route_maneuver_set_road_name(man, (char *) maneuver->street_name);
+                       } else {
+                               MAPS_LOGD("Street Name >>>> NIL");
+                       }
+
+                       /* Maneuver start position */
+                       maps_coordinates_h coord;
+                       maps_coordinates_create(maneuver->start_point.latitude, maneuver->start_point.longitude, &coord);
+
+                       maps_route_maneuver_set_position(man, coord);
+                       maps_coordinates_destroy(coord);
+
+                       maps_item_list_h maneuver_list = NULL;
+                       maps_item_list_create(&maneuver_list);
+                       maps_item_list_append(maneuver_list, (gpointer) man, maps_route_maneuver_clone);
+                       maps_route_segment_set_maneuvers(segment, maneuver_list);
+
+                       maps_item_list_destroy(maneuver_list);
+                       maps_route_maneuver_destroy(man);
+
+                       maps_item_list_append(segment_list, (gpointer) segment, maps_route_segment_clone);
+                       maps_route_segment_destroy(segment);
+
+                       /* Fetching the next item from Maneuver/Segment list */
+                       maneuver_data = g_list_next(maneuver_data);
+               }
+               maps_route_set_segments(route, segment_list);
+               maps_item_list_destroy(segment_list);
+
+               /* Shape points - path */
+               maps_item_list_h path_list = NULL;
+               maps_item_list_create(&path_list);
+
+               GList *shapePoints = NULL;
+               shapePoints = g_list_first(route_info->shapePoints);
+
+               while (shapePoints) {
+                       coords_s *data = (coords_s *) shapePoints->data;
+
+                       maps_coordinates_h shapeCoords;
+                       maps_coordinates_create(data->latitude, data->longitude, &shapeCoords);
+
+                       maps_item_list_append(path_list, (gpointer) shapeCoords, maps_coordinates_clone);
+
+                       maps_coordinates_destroy(shapeCoords);
+
+                       shapePoints = g_list_next(shapePoints);
+               }
+               maps_route_set_path(route, path_list);
+               maps_item_list_destroy(path_list);
+
+               bool b = calldata_route->callback((maps_error_e)__convert_to_maps_error(result), calldata_route->reqID, 0, 1, route, calldata_route->data);
+               if (!b)
+                       return;
+       } else {
+               calldata_route->callback((maps_error_e)__convert_to_maps_error(result), calldata_route->reqID, 0, 0, NULL, calldata_route->data);
+       }
+}
+
+EXPORT_API int maps_plugin_search_route(const maps_coordinates_h origin, const maps_coordinates_h destination, maps_preference_h preference,   maps_service_search_route_cb callback, void *user_data, int *request_id)
+{
+       if (!origin || !destination || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       callback_info_route *calldata_route = (callback_info_route *)g_malloc0(sizeof(callback_info_route));
+       if (calldata_route == NULL)
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+
+       calldata_route->callback = callback;
+       calldata_route->data = user_data;
+
+       mapquest_route_req_s *route_req = (mapquest_route_req_s *)g_malloc0(sizeof(mapquest_route_req_s));
+       if (route_req == NULL) {
+               g_free(calldata_route);
+               calldata_route = NULL;
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+       }
+
+       route_req->maps_key = g_strdup((gchar *) __provider_key);
+
+       double origin_lat, origin_lon;
+       double dest_lat, dest_lon;
+
+       maps_coordinates_get_latitude(origin, &origin_lat);
+       maps_coordinates_get_longitude(origin, &origin_lon);
+
+       maps_coordinates_get_latitude(destination, &dest_lat);
+       maps_coordinates_get_longitude(destination, &dest_lon);
+
+       route_req->from.latitude = origin_lat;
+       route_req->from.longitude = origin_lon;
+
+       route_req->to.latitude = dest_lat;
+       route_req->to.longitude = dest_lon;
+
+       MAPS_LOGD("getting transport mode..");
+       maps_route_transport_mode_e transport_mode;
+       maps_preference_get_route_transport_mode(preference, &transport_mode);
+
+       if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_CAR)
+               route_req->type = ROUTE_TYPE_FASTEST;
+       else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN)
+               route_req->type = ROUTE_TYPE_PEDESTRIAN;
+       else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_BICYCLE)
+               route_req->type = ROUTE_TYPE_BICYCLE;
+       else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT)
+               route_req->type = ROUTE_TYPE_MULTIMODAL;
+       else
+               route_req->type = ROUTE_TYPE_FASTEST;   /* Keeping it as default */
+
+       route_req->driving_style = DRIVING_STYLE_NORMAL;        /* Keeping it as default */
+
+       /* Unit */
+       maps_distance_unit_e unit;
+       maps_preference_get_distance_unit(preference, &unit);
+
+       switch (unit) {
+       case MAPS_DISTANCE_UNIT_M:
+               route_req->unit = ROUTE_UNIT_M;
+               break;
+       case MAPS_DISTANCE_UNIT_KM:
+               route_req->unit = ROUTE_UNIT_KM;
+               break;
+       case MAPS_DISTANCE_UNIT_FT:
+               route_req->unit = ROUTE_UNIT_FT;
+               break;
+       case MAPS_DISTANCE_UNIT_YD:
+               route_req->unit = ROUTE_UNIT_YD;
+               break;
+       }
+
+       route_req->avoids = ROUTE_AVOID_NONE;
+       maps_route_feature_weight_e routeWeight;
+       maps_preference_get_route_feature_weight(preference, &routeWeight);
+
+       if (routeWeight == MAPS_ROUTE_FEATURE_WEIGHT_AVOID) {
+               maps_route_feature_e routeFeature;
+               maps_preference_get_route_feature(preference, &routeFeature);
+
+               if (routeFeature == MAPS_ROUTE_FEATURE_TOLL)
+                       route_req->avoids = ROUTE_AVOID_TOLL_ROAD;
+               else if (routeFeature == MAPS_ROUTE_FEATURE_MOTORWAY)
+                       route_req->avoids = ROUTE_AVOID_LIMITED_ACCESS;
+               else if ((routeFeature == MAPS_ROUTE_FEATURE_BOATFERRY) || (routeFeature == MAPS_ROUTE_FEATURE_RAILFERRY))
+                       route_req->avoids = ROUTE_AVOID_FERRY;
+               else if (routeFeature == MAPS_ROUTE_FEATURE_DIRTROAD)
+                       route_req->avoids = ROUTE_AVOID_UNPAVED;
+               else
+                       route_req->avoids = ROUTE_AVOID_NONE;
+       }
+
+       route_req->way_points = NULL;
+
+       *request_id = ++__request_id;
+       calldata_route->reqID = __request_id;
+
+       int ret = mapquest_start_route(route_req, __mapquest_route_cb, __request_id, (void *)calldata_route);
+
+       return __convert_to_maps_error(ret);
+}
+
+EXPORT_API int maps_plugin_search_route_waypoints(const maps_coordinates_h *waypoint_list, int waypoint_num, maps_preference_h preference, maps_service_search_route_cb callback, void *user_data, int *request_id)
+{
+       if (!waypoint_list || waypoint_num < 2 || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       callback_info_route *calldata_route = (callback_info_route *)g_malloc0(sizeof(callback_info_route));
+       if (calldata_route == NULL)
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+
+       calldata_route->callback = callback;
+       calldata_route->data = user_data;
+
+       mapquest_route_req_s *route_req = (mapquest_route_req_s *)g_malloc0(sizeof(mapquest_route_req_s));
+       if (route_req == NULL) {
+               g_free(calldata_route);
+               calldata_route = NULL;
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+       }
+
+       route_req->maps_key = g_strdup((gchar *) __provider_key);
+
+       route_req->from.latitude = 0.0;
+       route_req->from.longitude = 0.0;
+
+       route_req->to.latitude = 0.0;
+       route_req->to.longitude = 0.0;
+
+       MAPS_LOGD("getting transport mode..");
+       maps_route_transport_mode_e transport_mode;
+       maps_preference_get_route_transport_mode(preference, &transport_mode);
+
+       if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_CAR)
+               route_req->type = ROUTE_TYPE_FASTEST;
+       else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PEDESTRIAN)
+               route_req->type = ROUTE_TYPE_PEDESTRIAN;
+       else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_BICYCLE)
+               route_req->type = ROUTE_TYPE_BICYCLE;
+       else if (transport_mode == MAPS_ROUTE_TRANSPORT_MODE_PUBLICTRANSIT)
+               route_req->type = ROUTE_TYPE_MULTIMODAL;
+       else
+               route_req->type = ROUTE_TYPE_FASTEST;   /* Keeping it as default */
+
+       route_req->driving_style = DRIVING_STYLE_NORMAL;        /* Keeping it as default */
+
+       /* Unit */
+       maps_distance_unit_e unit;
+       maps_preference_get_distance_unit(preference, &unit);
+
+       switch (unit) {
+       case MAPS_DISTANCE_UNIT_M:
+               route_req->unit = ROUTE_UNIT_M;
+               break;
+       case MAPS_DISTANCE_UNIT_KM:
+               route_req->unit = ROUTE_UNIT_KM;
+               break;
+       case MAPS_DISTANCE_UNIT_FT:
+               route_req->unit = ROUTE_UNIT_FT;
+               break;
+       case MAPS_DISTANCE_UNIT_YD:
+               route_req->unit = ROUTE_UNIT_YD;
+               break;
+       }
+
+       route_req->avoids = ROUTE_AVOID_NONE;
+       maps_route_feature_weight_e routeWeight;
+       maps_preference_get_route_feature_weight(preference, &routeWeight);
+
+       if (routeWeight == MAPS_ROUTE_FEATURE_WEIGHT_AVOID) {
+               maps_route_feature_e routeFeature;
+               maps_preference_get_route_feature(preference, &routeFeature);
+
+               if (routeFeature == MAPS_ROUTE_FEATURE_TOLL)
+                       route_req->avoids = ROUTE_AVOID_TOLL_ROAD;
+               else if (routeFeature == MAPS_ROUTE_FEATURE_MOTORWAY)
+                       route_req->avoids = ROUTE_AVOID_LIMITED_ACCESS;
+               else if ((routeFeature == MAPS_ROUTE_FEATURE_BOATFERRY) || (routeFeature == MAPS_ROUTE_FEATURE_RAILFERRY))
+                       route_req->avoids = ROUTE_AVOID_FERRY;
+               else if (routeFeature == MAPS_ROUTE_FEATURE_DIRTROAD)
+                       route_req->avoids = ROUTE_AVOID_UNPAVED;
+               else
+                       route_req->avoids = ROUTE_AVOID_NONE;
+       }
+
+       /* Waypoints */
+       route_req->way_points = NULL;
+       if (waypoint_num != 0) {
+               int index = 0;
+               double latitude = 0.0, longitude = 0.0;
+               for (index = 0; index < waypoint_num; index++) {
+                       if (waypoint_list[index] != NULL) {
+                               maps_coordinates_get_latitude(waypoint_list[index], &latitude);
+                               maps_coordinates_get_longitude(waypoint_list[index], &longitude);
+
+                               coords_s *data = (coords_s *)g_malloc0(sizeof(coords_s));
+                               if (data) {
+                                       data->latitude = latitude;
+                                       data->longitude = longitude;
+
+                                       if (route_req->way_points == NULL)
+                                               route_req->way_points = g_list_append(route_req->way_points, (gpointer) data);
+                                       else
+                                               route_req->way_points = g_list_insert_before(route_req->way_points, NULL, (gpointer) data);
+                               }
+                       }
+               }
+       }
+
+       *request_id = ++__request_id;
+       calldata_route->reqID = __request_id;
+
+       int ret = mapquest_start_route(route_req, __mapquest_route_cb, __request_id, (void *)calldata_route);
+
+       return __convert_to_maps_error(ret);
+}
+
+static void __mapquest_place_search_cb(mapquest_error_e result, int request_id, GList *places, void *user_data)
+{
+       MAPS_LOGD("Got places result from ENGINE...");
+
+       callback_info_place *calldata_place = (callback_info_place *) user_data;
+
+       if (result != MAPQUEST_ERROR_NONE || places == NULL) {
+               MAPS_LOGD("Got places result from ENGINE...result is NULL");
+               calldata_place->callback((maps_error_e) __convert_to_maps_error(result), calldata_place->reqID, 0, 0, NULL, calldata_place->data);
+       } else {
+               guint total_count = 0;
+               int index = 0;
+               total_count = g_list_length(places);
+               if (total_count > 0) {
+                       maps_place_h place = NULL;
+                       MAPS_LOGD("Got places result from ENGINE... count -> %d", total_count);
+
+                       GList *temp_place = NULL;
+                       temp_place = g_list_first(places);
+
+                       while (temp_place) {
+                               maps_place_create(&place);
+                               mapquest_place_resp_s *mapquest_place = (mapquest_place_resp_s *) temp_place->data;
+                               maps_place_set_id(place, mapquest_place->place_id);
+                               maps_place_set_name(place, mapquest_place->display_name);
+
+                               MAPS_LOGD("Before address..");
+                               /* Address */
+                               if (mapquest_place->address) {
+                                       maps_address_h addr = NULL;
+                                       maps_address_create(&addr);
+
+                                       maps_address_set_street(addr, mapquest_place->address->street_add);
+                                       maps_address_set_building_number(addr, mapquest_place->address->building_number);
+                                       maps_address_set_city(addr, mapquest_place->address->city);
+                                       maps_address_set_county(addr, mapquest_place->address->county);
+                                       maps_address_set_state(addr, mapquest_place->address->state);
+                                       maps_address_set_country(addr, mapquest_place->address->country);
+                                       maps_address_set_country_code(addr, mapquest_place->address->country_code);
+                                       maps_address_set_postal_code(addr, mapquest_place->address->postal_code);
+                                       maps_address_set_freetext(addr, mapquest_place->display_name);
+
+                                       maps_place_set_address(place, addr);
+                                       maps_address_destroy(addr);
+                               } else {
+                                       maps_place_set_address(place, NULL);
+                               }
+
+                               maps_coordinates_h coord;
+                               maps_coordinates_create(mapquest_place->coordinates.latitude, mapquest_place->coordinates.longitude, &coord);
+
+                               maps_place_set_location(place, coord);
+                               maps_coordinates_destroy(coord);
+
+                               maps_place_category_h place_cat;
+                               maps_place_category_create(&place_cat);
+                               maps_place_category_set_name(place_cat, mapquest_place->category);
+
+                               maps_item_list_h cat_list;
+                               maps_item_list_create(&cat_list);
+                               maps_item_list_append(cat_list, (void *) place_cat, maps_place_category_clone);
+                               maps_place_set_categories(place, cat_list);
+
+                               maps_place_category_destroy(place_cat);
+                               maps_item_list_destroy(cat_list);
+
+                               maps_place_image_h place_image;
+                               maps_place_image_create(&place_image);
+                               maps_place_image_set_url(place_image, mapquest_place->icon_url);
+                               maps_item_list_h image_list;
+                               maps_item_list_create(&image_list);
+                               maps_item_list_append(image_list, (void *) place_image, maps_place_image_clone);
+                               maps_place_set_images(place, image_list);
+
+                               maps_place_image_destroy(place_image);
+                               maps_item_list_destroy(image_list);
+
+                               bool b = calldata_place->callback((maps_error_e)__convert_to_maps_error(result), calldata_place->reqID, index, total_count, place, calldata_place->data);
+                               if (!b)
+                                       return;
+
+                               index++;
+
+                               temp_place = temp_place->next;
+                       }
+               } else {
+                       calldata_place->callback((maps_error_e)__convert_to_maps_error(result), calldata_place->reqID, index, total_count, NULL, calldata_place->data);
+               }
+       }
+}
+
+EXPORT_API int maps_plugin_search_place(const maps_coordinates_h position, int distance, const maps_place_filter_h filter, const maps_preference_h preference, maps_service_search_place_cb callback, void *user_data, int *request_id)
+{
+       if (!position || !filter || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+       if (distance <= 0)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
+       if (calldata_place == NULL)
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+
+       calldata_place->callback = callback;
+       calldata_place->data = user_data;
+
+       mapquest_search_req_s *place_req = (mapquest_search_req_s *)g_malloc0(sizeof(mapquest_search_req_s));
+       if (place_req == NULL) {
+               g_free(calldata_place);
+               calldata_place = NULL;
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+       }
+
+       place_req->maps_key = g_strdup((gchar *) __provider_key);
+
+       int max_result;
+       maps_preference_get_max_results(preference, &max_result);
+
+       if (max_result == 0)
+               place_req->num_res = DEFAULT_NUM_RESULTS;
+       else
+               place_req->num_res = max_result;
+
+       MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
+
+       char *categoryName = NULL;
+       char *place_name = NULL;
+
+       maps_place_category_h category = NULL;
+       maps_place_filter_get_category(filter, &category);
+
+       if (category)
+               maps_place_category_get_name(category, &categoryName);
+
+       maps_place_filter_get_place_name(filter, &place_name);
+
+       char *modified_place_name = NULL;
+       bool b_isPlaceName_modified = false;
+       if (place_name)
+               b_isPlaceName_modified = __replace_space(place_name, &modified_place_name);
+
+       MAPS_LOGD("Modified Place String.. ");
+       MAPS_LOGD(" >>>> %s", modified_place_name);
+
+       if (categoryName && place_name) {
+               if (b_isPlaceName_modified)
+                       place_req->search_string = g_strdup_printf("%s[%s]", modified_place_name, categoryName);
+               else
+                       place_req->search_string = g_strdup_printf("%s[%s]", place_name, categoryName);
+       } else if (categoryName) {
+               place_req->search_string = g_strdup_printf("[%s]", categoryName);
+       } else if (place_name) {
+               if (b_isPlaceName_modified)
+                       place_req->search_string = g_strdup_printf("%s", modified_place_name);
+               else
+                       place_req->search_string = g_strdup_printf("%s", place_name);
+       } else {
+               g_free(calldata_place);
+               calldata_place = NULL;
+               g_free(place_req);
+               place_req = NULL;
+               return MAPS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (modified_place_name) {
+               g_free(modified_place_name);
+               modified_place_name = NULL;
+       }
+
+       MAPS_LOGD(">>>>>>>> Place search string :: %s <<<<<<<<<", place_req->search_string);
+
+       place_req->boundary = NULL;
+       place_req->boundary = (mapquest_boundary_s *)g_malloc0(sizeof(mapquest_boundary_s));
+
+       if (place_req->boundary) {
+               place_req->boundary->type = MAPQUEST_BOUNDARY_CIRCLE;
+               double lat, lon;
+               maps_coordinates_get_latitude(position, &lat);
+               maps_coordinates_get_longitude(position, &lon);
+               place_req->boundary->circle.center.latitude = lat;
+               place_req->boundary->circle.center.longitude = lon;
+               place_req->boundary->circle.radius = distance;
+       }
+
+       *request_id = ++__request_id;
+       calldata_place->reqID = __request_id;
+
+       int ret = mapquest_search_place(place_req, __mapquest_place_search_cb, __request_id, (void *) calldata_place);
+
+       return __convert_to_maps_error(ret);
+}
+
+EXPORT_API int maps_plugin_search_place_by_area(const maps_area_h boundary, const maps_place_filter_h filter, const maps_preference_h preference, maps_service_search_place_cb callback, void *user_data, int *request_id)
+{
+       if (!boundary || !filter || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
+       if (calldata_place == NULL)
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+
+       calldata_place->callback = callback;
+       calldata_place->data = user_data;
+
+       mapquest_search_req_s *place_req = (mapquest_search_req_s *)g_malloc0(sizeof(mapquest_search_req_s));
+       if (place_req == NULL) {
+               g_free(calldata_place);
+               calldata_place = NULL;
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+       }
+
+       place_req->maps_key = g_strdup((gchar *) __provider_key);
+
+       int max_result;
+       maps_preference_get_max_results(preference, &max_result);
+
+       if (max_result == 0)
+               place_req->num_res = DEFAULT_NUM_RESULTS;
+       else
+               place_req->num_res = max_result;
+
+       MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
+
+       char *categoryName = NULL;
+       char *place_name = NULL;
+
+       maps_place_category_h category = NULL;
+       maps_place_filter_get_category(filter, &category);
+
+       if (category)
+               maps_place_category_get_name(category, &categoryName);
+
+       maps_place_filter_get_place_name(filter, &place_name);
+
+       char *modified_place_name = NULL;
+       bool b_isPlaceName_modified = false;
+       if (place_name)
+               b_isPlaceName_modified = __replace_space(place_name, &modified_place_name);
+
+       if (categoryName && place_name) {
+               if (b_isPlaceName_modified)
+                       place_req->search_string = g_strdup_printf("%s[%s]", modified_place_name, categoryName);
+               else
+                       place_req->search_string = g_strdup_printf("%s[%s]", place_name, categoryName);
+       } else if (categoryName) {
+               place_req->search_string = g_strdup_printf("[%s]", categoryName);
+       } else if (place_name) {
+               if (b_isPlaceName_modified)
+                       place_req->search_string = g_strdup_printf("%s", modified_place_name);
+               else
+                       place_req->search_string = g_strdup_printf("%s", place_name);
+       } else {
+               g_free(calldata_place);
+               calldata_place = NULL;
+               g_free(place_req);
+               place_req = NULL;
+               return MAPS_ERROR_INVALID_PARAMETER;
+       }
+
+       if (modified_place_name) {
+               g_free(modified_place_name);
+               modified_place_name = NULL;
+       }
+
+       MAPS_LOGD(">>>>>>>> Place search string :: %s <<<<<<<<<", place_req->search_string);
+       place_req->boundary = NULL;
+       maps_area_s *bound = (maps_area_s *) boundary;
+
+       if (bound->type != MAPS_AREA_NONE) {
+               place_req->boundary = (mapquest_boundary_s *)g_malloc0(sizeof(mapquest_boundary_s));
+
+               if (place_req->boundary != NULL) {
+                       if (bound->type == MAPS_AREA_CIRCLE) {
+                               place_req->boundary->type = MAPQUEST_BOUNDARY_CIRCLE;
+                               place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
+                               place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
+                               place_req->boundary->circle.radius = bound->circle.radius;
+                       } else if (bound->type == MAPS_AREA_RECTANGLE) {
+                               place_req->boundary->type = MAPQUEST_BOUNDARY_RECT;
+                               place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
+                               place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
+                               place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
+                               place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
+                       }
+               }
+       }
+
+       *request_id = ++__request_id;
+       calldata_place->reqID = __request_id;
+
+       int ret = mapquest_search_place(place_req, __mapquest_place_search_cb, __request_id, (void *) calldata_place);
+
+       return __convert_to_maps_error(ret);
+}
+
+EXPORT_API int maps_plugin_search_place_by_address(const char *address, const maps_area_h boundary, const maps_place_filter_h filter, const maps_preference_h preference, maps_service_search_place_cb callback, void *user_data, int *request_id)
+{
+       if (!address || !boundary || !filter || !callback || !request_id)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       callback_info_place *calldata_place = (callback_info_place *)g_malloc0(sizeof(callback_info_place));
+       if (calldata_place == NULL)
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+
+       calldata_place->callback = callback;
+       calldata_place->data = user_data;
+
+       mapquest_search_req_s *place_req = (mapquest_search_req_s *)g_malloc0(sizeof(mapquest_search_req_s));
+       if (place_req == NULL) {
+               g_free(calldata_place);
+               calldata_place = NULL;
+               MAPS_PRINT_ERROR_CODE_RETURN(MAPS_ERROR_OUT_OF_MEMORY);
+       }
+
+       place_req->maps_key = g_strdup((gchar *) __provider_key);
+
+       int max_result;
+       maps_preference_get_max_results(preference, &max_result);
+
+       if (max_result == 0)
+               place_req->num_res = DEFAULT_NUM_RESULTS;
+       else
+               place_req->num_res = max_result;
+
+       MAPS_LOGD("Place Result limit :: %d", place_req->num_res);
+
+       char *categoryName = NULL;
+
+       maps_place_category_h category = NULL;
+       maps_place_filter_get_category(filter, &category);
+
+       if (category)
+               maps_place_category_get_name(category, &categoryName);
+
+       char *modified_address = NULL;
+       bool b_isAddress_modified = false;
+       if (address)
+               b_isAddress_modified = __replace_space((char *) address, &modified_address);
+
+       if (categoryName) {
+               if (b_isAddress_modified)
+                       place_req->search_string = g_strdup_printf("%s[%s]", modified_address, categoryName);
+               else
+                       place_req->search_string = g_strdup_printf("%s[%s]", address, categoryName);
+       } else {
+               if (b_isAddress_modified)
+                       place_req->search_string = g_strdup_printf("%s", modified_address);
+               else
+                       place_req->search_string = g_strdup_printf("%s", address);
+       }
+
+       if (modified_address) {
+               g_free(modified_address);
+               modified_address = NULL;
+       }
+
+       place_req->boundary = NULL;
+       maps_area_s *bound = (maps_area_s *) boundary;
+
+       if (bound->type != MAPS_AREA_NONE) {
+               place_req->boundary = (mapquest_boundary_s *)g_malloc0(sizeof(mapquest_boundary_s));
+
+               if (place_req->boundary != NULL) {
+                       if (bound->type == MAPS_AREA_CIRCLE) {
+                               place_req->boundary->type = MAPQUEST_BOUNDARY_CIRCLE;
+                               place_req->boundary->circle.center.latitude = bound->circle.center.latitude;
+                               place_req->boundary->circle.center.longitude = bound->circle.center.longitude;
+                               place_req->boundary->circle.radius = bound->circle.radius;
+                       } else if (bound->type == MAPS_AREA_RECTANGLE) {
+                               place_req->boundary->type = MAPQUEST_BOUNDARY_RECT;
+                               place_req->boundary->rect.top_left.latitude = bound->rect.top_left.latitude;
+                               place_req->boundary->rect.top_left.longitude = bound->rect.top_left.longitude;
+                               place_req->boundary->rect.bottom_right.latitude = bound->rect.bottom_right.latitude;
+                               place_req->boundary->rect.bottom_right.longitude = bound->rect.bottom_right.longitude;
+                       }
+               }
+       }
+
+       *request_id = ++__request_id;
+       calldata_place->reqID = __request_id;
+
+       int ret = mapquest_search_place(place_req, __mapquest_place_search_cb, __request_id, (void *) calldata_place);
+
+       return __convert_to_maps_error(ret);
+}
+
+EXPORT_API int maps_plugin_cancel_request(int request_id)
+{
+       MAPS_LOGD("Plugin_Cancel_Request...");
+       if (request_id < 0)
+               return MAPS_ERROR_INVALID_PARAMETER;
+
+       int ret = mapquest_cancel_request(request_id);
+
+       return __convert_to_maps_error(ret);
+}