Code Sync up from tizen_2.4 50/50850/1 accepted/tizen/mobile/20151211.055324 accepted/tizen/tv/20151211.062312 accepted/tizen/wearable/20151211.061203 submit/tizen/20151211.044210 submit/tizen_common/20151229.142028 submit/tizen_common/20151229.144031 submit/tizen_common/20151229.154718
authorHyihong Chae <hh.chae@samsung.com>
Tue, 3 Nov 2015 02:42:59 +0000 (11:42 +0900)
committerHyihong Chae <hh.chae@samsung.com>
Tue, 3 Nov 2015 02:47:18 +0000 (11:47 +0900)
Change-Id: I1742218bdb2b3a01568236d72a65bba68aed4f68
Signed-off-by: HyiHong Chae <hh.chae@samsung.com>
47 files changed:
CMakeLists.txt [new file with mode: 0755]
LICENSE.APLv2 [new file with mode: 0755]
include/entity/mtp_device.h [new file with mode: 0755]
include/entity/mtp_object.h [new file with mode: 0755]
include/entity/mtp_property.h [new file with mode: 0755]
include/entity/mtp_store.h [new file with mode: 0755]
include/mtp_cmd_handler.h [new file with mode: 0755]
include/mtp_cmd_handler_util.h [new file with mode: 0755]
include/mtp_config.h [new file with mode: 0755]
include/mtp_datatype.h [new file with mode: 0755]
include/mtp_event_handler.h [new file with mode: 0755]
include/mtp_init.h [new file with mode: 0755]
include/mtp_inoti_handler.h [new file with mode: 0755]
include/ptp_container.h [new file with mode: 0755]
include/ptp_datacodes.h [new file with mode: 0755]
include/transport/mtp_transport.h [new file with mode: 0755]
include/transport/mtp_usb_driver.h [new file with mode: 0755]
include/util/mtp_fs.h [new file with mode: 0755]
include/util/mtp_list.h [new file with mode: 0755]
include/util/mtp_media_info.h [new file with mode: 0755]
include/util/mtp_msgq.h [new file with mode: 0755]
include/util/mtp_support.h [new file with mode: 0755]
include/util/mtp_thread.h [new file with mode: 0755]
include/util/mtp_util.h [new file with mode: 0755]
mtp-responder.conf [new file with mode: 0755]
mtp-responder.service [new file with mode: 0755]
packaging/mtp-responder.manifest [new file with mode: 0755]
packaging/mtp-responder.spec [new file with mode: 0755]
src/entity/mtp_device.c [new file with mode: 0755]
src/entity/mtp_object.c [new file with mode: 0755]
src/entity/mtp_property.c [new file with mode: 0755]
src/entity/mtp_store.c [new file with mode: 0755]
src/mtp_cmd_handler.c [new file with mode: 0755]
src/mtp_cmd_handler_util.c [new file with mode: 0755]
src/mtp_event_handler.c [new file with mode: 0755]
src/mtp_init.c [new file with mode: 0755]
src/mtp_inoti_handler.c [new file with mode: 0755]
src/ptp_container.c [new file with mode: 0755]
src/transport/mtp_transport.c [new file with mode: 0755]
src/transport/mtp_usb_driver.c [new file with mode: 0755]
src/util/mtp_fs.c [new file with mode: 0755]
src/util/mtp_list.c [new file with mode: 0755]
src/util/mtp_media_info.c [new file with mode: 0755]
src/util/mtp_msgq.c [new file with mode: 0755]
src/util/mtp_support.c [new file with mode: 0755]
src/util/mtp_thread.c [new file with mode: 0755]
src/util/mtp_util.c [new file with mode: 0755]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..7346a98
--- /dev/null
@@ -0,0 +1,32 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(mtp-responder C)
+
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/entity)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/transport)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include/util)
+
+AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src/entity SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src/transport SRCS)
+AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src/util SRCS)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED glib-2.0 capi-content-media-content
+       capi-media-metadata-extractor vconf dlog tapi libprivilege-control capi-system-info)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall -Werror-implicit-function-declaration")
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fexceptions -fvisibility=hidden")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE")
+SET(CMAKE_EXE_LINKER_FLAGS " -Wl,--as-needed -pie -Wl,--hash-style=both")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} pthread rt gcrypt)
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
+INSTALL(FILES mtp-responder.conf DESTINATION /opt/var/lib/misc)
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100755 (executable)
index 0000000..ec68963
--- /dev/null
@@ -0,0 +1,206 @@
+Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+                                 Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      "License" shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      "Licensor" shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      "Legal Entity" shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      "control" means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      "You" (or "Your") shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      "Source" form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      "Object" form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      "Work" shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      "Derivative Works" shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      "Contribution" shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, "submitted"\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+      "Contributor" shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a "NOTICE" text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets "[]"\r
+      replaced with your own identifying information. (Don't include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same "printed page" as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+\r
+\r
diff --git a/include/entity/mtp_device.h b/include/entity/mtp_device.h
new file mode 100755 (executable)
index 0000000..3e53f6c
--- /dev/null
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_DEVICE_H_
+#define _MTP_DEVICE_H_
+
+#include "mtp_store.h"
+#include "mtp_property.h"
+
+#define MTP_NUM_DEVICE_DEFAULT         3
+
+#define MTP_NUM_DEVICE_WMP11           1
+
+#ifdef MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL
+#define MTP_NUM_DEVICE_BATTLEVEL       1
+#else /*MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL*/
+#define MTP_NUM_DEVICE_BATTLEVEL       0
+#endif /*MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL*/
+
+#ifdef MTP_SUPPORT_DEVICE_CLASS
+#define MTP_NUM_DEVICE_DSC             1
+#else /*MTP_SUPPORT_DEVICE_CLASS*/
+#define MTP_NUM_DEVICE_DSC             0
+#endif /*MTP_SUPPORT_DEVICE_CLASS*/
+
+#define MTP_NUM_DEVICE_SVC             0
+
+/* currently not supported */
+#define MTP_NUM_DEVICE_PLAYBACK_2WIRE  4
+#define MTP_NUM_DEVICE_OMADRM          1
+
+#define NUM_DEVICE_PROPERTIES          (MTP_NUM_DEVICE_DEFAULT + \
+               MTP_NUM_DEVICE_WMP11 + \
+               MTP_NUM_DEVICE_BATTLEVEL + MTP_NUM_DEVICE_DSC + \
+               MTP_NUM_DEVICE_SVC)
+
+/*This number can be changed based on MAX number or stores allowed*/
+#define        MAX_NUM_DEVICE_STORES           3
+
+#define MTP_STANDARD_VERSION           0x64
+#define MTP_VENDOR_EXTN_ID             0x06
+#define MTP_VENDOR_EXTN_VERSION                0x64
+
+
+/* This enumeration specifies the type of store. */
+typedef enum {
+       MTP_STORAGE_INTERNAL = 0,
+       MTP_STORAGE_EXTERNAL,
+       MTP_STORAGE_ALL
+} store_type_t;
+
+
+/* Defines the status of the Device */
+typedef enum {
+       DEVICE_STATUSOK = 0,            /* Device OK */
+       DEVICE_DEVICEERROR = 4          /* Fatal device error, can't continue */
+} device_status_t;
+
+/* Defines the phase in which device is*/
+typedef enum {
+       DEVICE_PHASE_NOTREADY = 0,      /* busy state */
+       DEVICE_PHASE_IDLE = 1,          /* idle state */
+       DEVICE_PHASE_DATAIN = 3,        /* data-in phase */
+       DEVICE_PHASE_DATAOUT = 4,       /* data out phase */
+       DEVICE_PHASE_RESPONSE = 5       /* response phase */
+} device_phase_t;
+
+/*
+ * device_info_t structure
+ * brief Structure for MTP device information.
+ */
+typedef struct {
+       mtp_uint16 std_version;         /* Version of the MTP spec supported */
+       mtp_uint32 vendor_extn_id;      /* Vendor extension ID */
+       mtp_uint16 vendor_extn_version; /* Vendor extension version */
+       ptp_string_t vendor_extn_desc;  /* Vendor extension description */
+       mtp_uint16 functional_mode;     /* Funtional mode. */
+       mtp_uint16 *ops_supported;      /* Array of operations supported */
+       mtp_uint16 *events_supported;   /* Array of events supported */
+       mtp_uint16 *device_prop_supported;/* Array of device prop supported */
+       mtp_uint16 *capture_fmts;       /* Array of captured fmts supported */
+       mtp_uint16 *object_fmts;        /* Array of file fmts supported */
+       ptp_string_t manufacturer;      /* The manufacturer's name. */
+       ptp_string_t model;             /* model name string */
+       ptp_string_t device_version;    /* Device version string */
+       ptp_string_t serial_no;         /* The serial number string. */
+} device_info_t;
+
+/*
+ * MTP device structure.
+ * A structure containing an instance of the MTP device.
+ */
+typedef struct {
+       device_status_t status;         /* device status */
+       device_phase_t phase;           /* device phase */
+       device_info_t device_info;      /* Device information */
+       mtp_store_t *store_list;        /* pointer to List of stores */
+       mtp_uchar num_stores;           /* Number of valid stores */
+       /* Used when SendObjectInfo does not specift store_id */
+       mtp_uint32 default_store_id;
+       /* Used when SendObjectInfo doesn't specify Parent Object Handle */
+       mtp_uint32 default_hparent;
+       /* A pointer to array of device property. */
+       device_prop_desc_t *device_prop_list;
+       mtp_char device_name[MTP_MAX_REG_STRING + 1];
+       mtp_char sync_partner[MTP_MAX_REG_STRING + 1];
+       mtp_bool is_mounted[MTP_STORAGE_ALL];
+} mtp_device_t;
+
+/*
+ * void _init_mtp_device(void)
+ * This function initializes mtp device structure.
+ * @return     none.
+ */
+void _init_mtp_device(void);
+
+/*
+ * mtp_uint32 _get_device_info_size()
+ * This function returns the size of device_info structure
+ * @return     returns the size of this device_info.
+ */
+mtp_uint32 _get_device_info_size(void);
+
+/*
+ * mtp_uint32 _pack_device_info(mtp_uchar *buf, mtp_uint32 buf_sz)
+ * This Functions Fills the device_info structure
+ * @param[in]  buf     address of a buffer
+ * @param[in]  buf_sz  size of the buffer
+ * @return the length of useful data in the buffer.
+ */
+mtp_uint32 _pack_device_info(mtp_uchar *buf, mtp_uint32 buf_sz);
+
+/*
+ * void _reset_mtp_device()
+ * This functions resets device state to IDLE/Command Ready
+ * @return     none
+ */
+void _reset_mtp_device(void);
+
+/*
+ * device_prop_desc_t *_device_get_device_property(mtp_uint32 prop_code)
+ * This function will get the property with the input property code
+ * @param[in]  prop_code       Property code
+ * @return     pointer to the property if success else NULL.
+ */
+device_prop_desc_t *_device_get_device_property(mtp_uint32 prop_code);
+
+mtp_bool _device_is_store_mounted(mtp_int32 store_type);
+
+/*
+ * mtp_bool _device_install_storage(mtp_int32 type)
+ * This function add the storage.
+ * @param[in]  type    Specifies the Storage : AUTO, INTERNAL, EXTERNAL, ALL
+ * @return     If success, returns TRUE. Otherwise returns FALSE.
+ */
+mtp_bool _device_install_storage(mtp_int32 type);
+
+/* mtp_bool _device_uninstall_storage(mtp_int32 type)
+ * This function removes the storage.
+ * @param[in]  type    Specifies the Storage : AUTO, INTERNAL, EXTERNAL, ALL
+ * @return     If success, returns TRUE. Otherwise returns FALSE.
+ */
+mtp_bool _device_uninstall_storage(mtp_int32 type);
+
+/*
+ * mtp_store_t *_device_get_store(mtp_uint32 store_id)
+ * This function will get the store with store_id.
+ * @param[in]  store_id        ID of the store
+ * @return     the pointer to the store with store ID, otherwise NULL.
+ */
+mtp_store_t *_device_get_store(mtp_uint32 store_id);
+
+/*
+ * mtp_uint32 _device_get_store_ids(ptp_array_t *store_ids)
+ * This function returns a list of storage ID's of all stores in the device.
+ * @param[out] store_ids               reference to the store ID list
+ * @return     the number of Storage IDs in the list.
+ */
+mtp_uint32 _device_get_store_ids(ptp_array_t *store_ids);
+
+/*
+ * mtp_uint32 _device_get_num_objects(mtp_uint32 store_id)
+ * This functions will get the number of objects in the store
+ * @param[in]  store_id        storage id
+ * @return     the number of objects.
+ */
+mtp_uint32 _device_get_num_objects(mtp_uint32 store_id);
+
+/*
+ * mtp_uint32 _device_get_num_objects_with_format(mtp_uint32 store_id,
+ * mtp_uint32 format)
+ * This function will get the number of objects with certain format code in the
+ * specified store
+ * @param[in]  store_id        storage id
+ * @param[in]  format  format code of the objects
+ * @return     the number of objects with the formatcode.
+ */
+mtp_uint32 _device_get_num_objects_with_format(mtp_uint32 store_id,
+               mtp_uint32 format);
+
+/*
+ * mtp_obj_t *_device_get_object_with_handle(mtp_uint32 obj_handle)
+ * This fuctions returns the object with the obj_handle
+ * @param[in]  obj_handle      object handle of the desired object
+ * @return     the object pointer if find; otherwise NULL;
+ */
+mtp_obj_t *_device_get_object_with_handle(mtp_uint32 obj_handle);
+
+/*
+ * mtp_obj_t *_device_get_object_with_path(mtp_char *full_path)
+ * This function return the pointer to the object if it exists.
+ * @param[in]  full_path               points to the object full path
+ * @return     the object pointer if found; otherwise NULL;
+ */
+mtp_obj_t *_device_get_object_with_path(mtp_char *full_path);
+
+/*
+ * mtp_uint16 _device_delete_object(mtp_uint32 obj_handle, mtp_uint32 fmt)
+ * This function will delete the objects entry corresponding to the
+ * object handle and the formatcode.
+ * @param[in]  obj_handle      Object handle number
+ * @param[in]  fmt             Object formatCode
+ * @return     the response of the delete.
+ */
+mtp_uint16 _device_delete_object(mtp_uint32 obj_handle, mtp_uint32 fmt);
+
+/*
+ * mtp_store_t *_device_get_store_containing_obj(mtp_uint32 obj_handle)
+ * This function will return the pointer to the store where the the object is.
+ * @param[in]  obj_handle      Object handle number
+ * @return     the store pointer if find, otherwise NULL.
+ */
+mtp_store_t *_device_get_store_containing_obj(mtp_uint32 obj_handle);
+mtp_store_t *_device_get_store_at_index(mtp_uint32 index);
+device_prop_desc_t *_device_get_ref_prop_list(void);
+
+/*
+ * Get current playback object from device property
+ */
+mtp_bool _device_get_playback_obj(mtp_uint32 *playback_obj);
+
+/*
+ * Set current playback object in device property,
+ * and send out property change event.
+ */
+mtp_bool _device_set_playback_obj(mtp_uint32 playback_obj);
+void _device_get_serial(mtp_char *serial_no, mtp_uint32 len);
+void _device_set_phase(device_phase_t phase);
+device_phase_t _device_get_phase(void);
+mtp_uint32 _device_get_default_store_id(void);
+mtp_uint32 _device_get_default_parent_handle(void);
+mtp_uint32 _device_get_num_stores(void);
+device_status_t _device_get_status(void);
+void _device_set_device_name(mtp_char *dev_name);
+mtp_char *_device_get_device_name(void);
+mtp_char *_device_get_sync_partner(void);
+void _device_set_sync_partner(mtp_char *sync_ptr);
+
+#endif /* _MTP_DEVICE_H_ */
diff --git a/include/entity/mtp_object.h b/include/entity/mtp_object.h
new file mode 100755 (executable)
index 0000000..46128a7
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_OBJECT_H_
+#define _MTP_OBJECT_H_
+
+#include "mtp_list.h"
+#include "ptp_datacodes.h"
+#include "mtp_fs.h"
+#include "mtp_media_info.h"
+
+#define FIXED_LENGTH_MEMBERS_SIZE \
+       (4 * sizeof(mtp_uint16) + 11 * sizeof(mtp_uint32))
+
+/*
+ * MAX size for sendObjectInfo
+ * SIZE_IN_BYTES_OF_FIXED_LENGTH_MEMBERS + 4 * (sizeof(ptp_string_t)) = 2096
+ */
+#define MAX_SIZE_IN_BYTES_OF_OBJECT_INFO       (4000*8)
+
+/*
+ * obj_info_t structure : Contains object metadata related information
+ * Size = 26 Bytes
+ */
+typedef struct {
+       mtp_uint32 store_id;            /* The storage the object resides */
+       mtp_uint16 obj_fmt;             /* object format code */
+       mtp_uint16 protcn_status;       /* object protection status */
+       mtp_uint64 file_size;           /* object compressed size */
+       mtp_uint32 thumb_file_size;     /* thumbnail compressedsize */
+       mtp_uint32 h_parent;            /* parent object handle */
+       mtp_uint16 association_type;    /* association type */
+} obj_info_t;
+
+/*
+ * mtp_obj_t structure : Contains object related information
+ * Gets created for each enumerated file/dir on the device
+ * Size : 42 Bytes
+ */
+typedef struct {
+       mtp_uint32 obj_handle;
+       obj_info_t *obj_info;
+       mtp_char *file_path;
+       ptp_array_t child_array;        /* Include all the renferences */
+       slist_t propval_list;   /* Object Properties implemented */
+} mtp_obj_t;
+
+mtp_bool _entity_get_file_times(mtp_obj_t *obj, ptp_time_string_t *create_tm,
+               ptp_time_string_t *modify_tm);
+obj_info_t *_entity_alloc_object_info(void);
+void _entity_init_object_info(obj_info_t *info);
+mtp_uint32 _entity_get_object_info_size(mtp_obj_t *obj, ptp_string_t *file_name);
+void _entity_init_object_info_params(obj_info_t *obj_info, mtp_uint32 dwStore,
+               mtp_uint32 hParent, mtp_char *pszFilename, dir_entry_t *fileInfo);
+mtp_uint32 _entity_parse_raw_obj_info(mtp_uchar *buf, mtp_uint32 buf_sz,
+               obj_info_t *info, mtp_char *file_name, mtp_uint16 fname_len);
+void _entity_copy_obj_info(obj_info_t *dst, obj_info_t *src);
+mtp_uint32 _entity_pack_obj_info(mtp_obj_t *obj, ptp_string_t *file_name,
+               mtp_uchar *buf, mtp_uint32 buf_sz);
+void _entity_dealloc_obj_info(obj_info_t *info);
+mtp_obj_t *_entity_alloc_mtp_object(void);
+mtp_bool _entity_init_mtp_object_params(
+               mtp_obj_t *obj,
+               mtp_uint32 store_id,
+               mtp_uint32 h_parent,
+               mtp_char *file_path,
+               mtp_char *file_name,
+               dir_entry_t *file_info);
+mtp_bool _entity_set_object_file_path(mtp_obj_t *obj, void *file_path,
+               char_mode_t char_type);
+mtp_bool _entity_check_child_obj_path(mtp_obj_t *obj, mtp_char *src_path,
+               mtp_char *dest_path);
+mtp_bool _entity_set_child_object_path(mtp_obj_t *obj, mtp_char *src_path,
+               mtp_char *dest_path);
+mtp_bool _entity_add_reference_child_array(mtp_obj_t *obj, mtp_uint32 handle);
+ptp_array_t* _entity_get_reference_child_array(mtp_obj_t *obj);
+mtp_bool _entity_set_reference_child_array(mtp_obj_t *obj, mtp_uchar *buf,
+               mtp_uint32 buf_sz);
+void _entity_copy_mtp_object(mtp_obj_t *dst, mtp_obj_t *src);
+mtp_bool _entity_remove_reference_child_array(mtp_obj_t *obj, mtp_uint32 handle);
+void _entity_dealloc_mtp_obj(mtp_obj_t *obj);
+
+#endif /* _MTP_OBJECT_H_ */
diff --git a/include/entity/mtp_property.h b/include/entity/mtp_property.h
new file mode 100755 (executable)
index 0000000..4bb6591
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_PROPERTY_H_
+#define _MTP_PROPERTY_H_
+
+#include "mtp_list.h"
+#include "mtp_object.h"
+
+#define MAX_SIZE_IN_BYTES_OF_PROP_VALUE                16000
+#define ELEMENT_NOT_FOUND                      -1
+#define INITIAL_ARRAY_SIZE                     100
+#define NUM_OBJECT_PROP_DESC                   38
+#define NUM_OBJECT_PROP_DESC_DEFAULT           13
+#define NUM_OBJECT_PROP_DESC_MP3               14
+#define NUM_OBJECT_PROP_DESC_WMA               14
+#define MTP_HEAP_CAL_INTERVAL                  100
+
+#ifdef MTP_SUPPORT_PROPERTY_SAMPLE
+#define NUM_OBJECT_PROP_DESC_WMV               28
+#else /* MTP_SUPPORT_PROPERTY_SAMPLE */
+#define NUM_OBJECT_PROP_DESC_WMV               22
+#endif /* MTP_SUPPORT_PROPERTY_SAMPLE */
+
+#ifdef MTP_SUPPORT_PROPERTY_SAMPLE
+#define NUM_OBJECT_PROP_DESC_ALBUM             8
+#else /* MTP_SUPPORT_PROPERTY_SAMPLE */
+#define NUM_OBJECT_PROP_DESC_ALBUM             2
+#endif /* MTP_SUPPORT_PROPERTY_SAMPLE */
+
+typedef struct _interdep_prop_config {
+       mtp_uint32 format_code;
+       slist_t propdesc_list;
+} interdep_prop_config_t;
+
+/*
+ * brief The property form flag.
+ * This enumerated type defines what kind of data the structure contains.
+ */
+typedef enum {
+       NONE = 0x00,
+       RANGE_FORM = 0x01,
+       ENUM_FORM = 0x02,
+       DATE_TIME_FORM = 0x03,
+       REGULAR_EXPRESSION_FORM = 0x04,
+       BYTE_ARRAY_FORM = 0x05,
+       LONG_STRING_FORM = 0xFF,
+} form_flag_t;
+
+enum {
+       GROUP_CODE_NONE = 0x00000000,
+       GROUP_CODE_SYNC_PROPS = 0x00000001,
+       GROUP_CODE_UI_PROPS = 0x00000002,
+       GROUP_CODE_OBJ_Info = 0x00000004,
+       GROUP_CODE_OFTEN_USED = 0x00000008,
+       GROUP_CODE_SUPPLEMENTAL = 0x00000100,
+       GROUP_CODE_UNKNOWN_PROP = 0x00010000,
+       GROUP_CODE_SLOW = 0x00FF0000,
+       GROUP_CODE_ALL = 0xFFFFFFFF
+};
+
+#define MTP_PROP_GROUPCODE_GENERAL     GROUP_CODE_OFTEN_USED
+#define MTP_PROP_GROUPCODE_OBJECT      GROUP_CODE_OFTEN_USED
+#define MTP_PROP_GROUPCODE_ALBUMART    GROUP_CODE_OFTEN_USED
+
+#define node_alloc_and_append()\
+       do {\
+               mtp_bool ret;\
+               ret = _util_add_node(&(obj->propval_list), (void *)prop_val);\
+               if (FALSE == ret) {\
+                       _prop_destroy_obj_propval(prop_val);\
+                       ERR("_util_add_node() Fail");\
+                       return (FALSE);\
+               }\
+       } while (0);
+
+#define propvalue_alloc_and_check(prop_val)\
+       do {\
+               prop_val = _prop_alloc_obj_propval(prop);\
+               if (prop_val == NULL) {\
+                       ERR("prop_val == NULL");\
+                       return (FALSE);\
+               } \
+       } while (0);
+
+#define init_default_value(value)\
+       do {\
+               memset(&default_val, 0, sizeof(default_val));\
+               default_val = value;\
+       } while (0);
+
+typedef struct {
+       mtp_uint32 min_val;     /* Minimum value */
+       mtp_uint32 max_val;     /* Maximum value */
+       mtp_uint32 step_size;   /* Step value */
+} range_form_t;
+
+/* This structure contains property info */
+typedef struct {
+       mtp_uint16 prop_code;   /* Property code */
+       mtp_uint16 data_type;   /* type of the data */
+       mtp_uint32 dts_size;    /* Count of Byte Size of the
+                                                          Data-Type-Specific value (DTS) */
+       mtp_uchar get_set;      /* Set possible or not */
+       mtp_uchar form_flag;    /* Indicates the form of the valid values */
+       range_form_t range;     /* Range Values */
+       slist_t supp_value_list; /*Enum Values */
+       union {
+               mtp_uchar integer[16];  /* Default value for any integer value
+                                                                  type (UINT8, mtp_uint16, mtp_uint32) */
+               ptp_string_t *str;      /* Default value for String type */
+               ptp_array_t *array;     /* Default array */
+       } default_val;          /* Default value */
+} prop_info_t;
+
+/* This structure contains device property description dataset */
+typedef struct {
+       prop_info_t propinfo;
+       union {
+               mtp_uchar integer[16];  /* Current value for any integer value
+                                                                  type (UINT8, mtp_uint16, mtp_uint32) */
+               ptp_string_t *str;      /* Current value for String type */
+               ptp_array_t *array;     /* Current value for array data type
+                                                          (AINT8, AUINT8) */
+       } current_val;                      /*Current value */
+} device_prop_desc_t;
+
+/* This structure contains object property description dataset */
+typedef struct {
+       prop_info_t propinfo;
+       mtp_uint32 group_code;  /* Identifies the group of this property */
+       union {
+               ptp_string_t *reg_exp;  /* Regular Expression Form */
+               mtp_uint32 max_len; /* LongString Form */
+       } prop_forms;            /*Object property-specific forms */
+} obj_prop_desc_t;
+
+/* This structure contains current value of a object property */
+typedef struct {
+       obj_prop_desc_t *prop;
+       union {
+               mtp_uchar integer[16];  /* Current value for any integer */
+               ptp_string_t *str;      /* Current value for String type */
+               ptp_array_t *array;
+       } current_val;
+} obj_prop_val_t;
+
+/* This structure defines ObjectPropQuad for GetObjectPropList */
+typedef struct {
+       mtp_uint32 obj_handle;
+       mtp_uint16 prop_code;
+       mtp_uint16 data_type;
+       mtp_uchar *pval;
+       mtp_uint32 val_size;    /* a useful helper,
+                                                          not part of the Object Property Quadruple */
+} prop_quad_t;
+
+/* This structure contains a list of MTP Object properties */
+typedef struct {
+       slist_t prop_quad_list;
+} obj_proplist_t;
+
+/* This structure contains a list of InterdependentProperties  */
+typedef struct {
+       slist_t plist;
+} obj_interdep_proplist_t ;
+
+/*
+ * Ptparray functions
+ */
+void _prop_init_ptparray(ptp_array_t *parray, data_type_t type);
+ptp_array_t *_prop_alloc_ptparray(data_type_t type);
+mtp_uint32 _prop_get_size_ptparray(ptp_array_t *parray);
+mtp_uint32 _prop_get_size_ptparray_without_elemsize(ptp_array_t *parray);
+mtp_bool _prop_grow_ptparray(ptp_array_t *parray, mtp_uint32 new_size);
+mtp_int32 _prop_find_ele_ptparray(ptp_array_t *parray, mtp_uint32 element);
+mtp_bool _prop_get_ele_ptparray(ptp_array_t *parray, mtp_uint32 index, void *ele);
+mtp_bool _prop_append_ele_ptparray(ptp_array_t *parray, mtp_uint32 element);
+mtp_bool _prop_append_ele128_ptparray(ptp_array_t *parray, mtp_uint64 *element);
+mtp_bool _prop_copy_ptparray(ptp_array_t *dst, ptp_array_t *src);
+mtp_uint32 _prop_pack_ptparray(ptp_array_t *parray, mtp_uchar *buf,
+               mtp_uint32 bufsize);
+mtp_uint32 _prop_pack_ptparray_without_elemsize(ptp_array_t *parray,
+               mtp_uchar *buf, mtp_uint32 bufsize);
+mtp_bool _prop_rem_elem_ptparray(ptp_array_t *parray, mtp_uint32 element);
+void _prop_deinit_ptparray(ptp_array_t *parray);
+void _prop_destroy_ptparray(ptp_array_t *parray);
+
+/*
+ * PtpString Functions
+ */
+void _prop_init_ptpstring(ptp_string_t *pstring);
+void _prop_init_ptptimestring(ptp_time_string_t *pstring);
+void _prop_copy_time_to_ptptimestring(ptp_time_string_t *pString,
+               system_time_t *sys_time);
+void _prop_copy_ptpstring(ptp_string_t *dst, ptp_string_t *src);
+void _prop_copy_ptptimestring(ptp_time_string_t *dst, ptp_time_string_t *src);
+void _prop_copy_char_to_ptpstring(ptp_string_t *pstring, void *str,
+               char_mode_t cmode);
+mtp_uint32 _prop_size_ptpstring(ptp_string_t *pstring);
+mtp_uint32 _prop_size_ptptimestring(ptp_time_string_t *pstring);
+mtp_uint32 _prop_pack_ptpstring(ptp_string_t *pstring, mtp_uchar *buf,
+               mtp_uint32 size);
+mtp_uint32 _prop_pack_ptptimestring(ptp_time_string_t *pstring, mtp_uchar *buf,
+               mtp_uint32 size);
+mtp_uint32 _prop_parse_rawstring(ptp_string_t *pstring, mtp_uchar *buf,
+               mtp_uint32 size);
+void _prop_destroy_ptpstring(ptp_string_t *pstring);
+
+/*
+ * DevicePropDesc Functions
+ */
+void _prop_init_device_property_desc(device_prop_desc_t *prop,
+               mtp_uint16 propcode, mtp_uint16 data_type, mtp_uchar get_set,
+               mtp_uchar form_flag);
+mtp_uint32 _prop_size_device_prop_desc(device_prop_desc_t *prop);
+mtp_uint32 _prop_pack_device_prop_desc(device_prop_desc_t *prop,
+               mtp_uchar *buf, mtp_uint32 size);
+mtp_uint32 _prop_pack_curval_device_prop_desc(device_prop_desc_t *prop,
+               mtp_uchar *buf, mtp_uint32 size);
+void _prop_reset_device_prop_desc(device_prop_desc_t *prop);
+
+/*
+ * ObjectPropVal Functions
+ */
+obj_prop_val_t *_prop_alloc_obj_propval(obj_prop_desc_t *prop);
+obj_prop_val_t *_prop_get_prop_val(mtp_obj_t *obj, mtp_uint32 prop_code);
+mtp_uint32 _prop_pack_obj_propval(obj_prop_val_t *val, mtp_uchar *buf,
+               mtp_uint32 size);
+mtp_uint32 _prop_size_obj_propval(obj_prop_val_t *val);
+void _prop_destroy_obj_propval(obj_prop_val_t *pval);
+mtp_bool _prop_set_default_integer(prop_info_t *prop_info, mtp_uchar *value);
+mtp_bool _prop_set_default_string(prop_info_t *prop_info, mtp_wchar *val);
+mtp_bool _prop_set_range_integer(prop_info_t *prop_info, mtp_uint32 min,
+               mtp_uint32 max, mtp_uint32 step);
+mtp_bool _prop_set_maxlen(obj_prop_desc_t *prop, mtp_uint32 max);
+mtp_bool _prop_set_default_array(prop_info_t *prop_info, mtp_uchar *parray,
+               mtp_uint32 num_ele);
+mtp_bool _prop_add_supp_integer_val(prop_info_t *prop_info, mtp_uint32 val);
+mtp_bool _prop_add_supp_string_val(prop_info_t *prop_info, mtp_wchar *val);
+mtp_bool _prop_is_valid_integer(prop_info_t *prop_info, mtp_uint64 value);
+mtp_bool _prop_is_valid_string(prop_info_t *prop, ptp_string_t *str);
+mtp_bool _prop_is_equal_ptpstring(ptp_string_t *dst, ptp_string_t *src);
+mtp_bool _prop_set_current_integer(device_prop_desc_t *prop, mtp_uint32 val);
+mtp_bool _prop_set_current_string(device_prop_desc_t *prop, ptp_string_t *str);
+mtp_bool _prop_set_current_array(device_prop_desc_t *prop, mtp_uchar *arr);
+mtp_bool _prop_set_current_device_prop(device_prop_desc_t *prop, mtp_uchar *val,
+               mtp_uint32 size);
+mtp_bool _prop_set_current_integer_val(obj_prop_val_t *propval, mtp_uint64 val);
+mtp_bool _prop_set_current_string_val(obj_prop_val_t *propval, ptp_string_t *str);
+mtp_bool _prop_set_current_array_val(obj_prop_val_t *propval, mtp_uchar *arr,
+               mtp_uint32 size);
+#ifdef __BIG_ENDIAN__
+mtp_bool _prop_set_current_array_val_usbrawdata(obj_prop_val_t *val,
+               mtp_uchar *arr, mtp_uint32 size);
+#endif /* __BIG_ENDIAN__ */
+mtp_bool _prop_set_regexp(obj_prop_desc_t *prop, mtp_wchar *regex);
+
+/*
+ * ObjectPropDesc Functions
+ */
+mtp_uint32 _prop_size_obj_prop_desc(obj_prop_desc_t *prop);
+mtp_uint32 _prop_pack_obj_prop_desc(obj_prop_desc_t *prop, mtp_uchar *buf,
+               mtp_uint32 size);
+mtp_uint32 _prop_pack_default_val_obj_prop_desc(obj_prop_desc_t *prop,
+               mtp_uchar *buf, mtp_uint32 size);
+obj_prop_desc_t *_prop_get_obj_prop_desc(mtp_uint32 format_code,
+               mtp_uint32 prop_code);
+
+/*
+ * ObjectProplist Functions
+ */
+mtp_bool _prop_update_property_values_list(mtp_obj_t *obj);
+mtp_uint32 _prop_size_obj_proplist(obj_proplist_t *prop_list);
+mtp_uint32 _prop_get_obj_proplist(mtp_obj_t *pObject, mtp_uint32 prop_code,
+               mtp_uint32 group_code, obj_proplist_t *prop_list);
+mtp_uint32 _prop_pack_obj_proplist(obj_proplist_t *prop_list, mtp_uchar *buf,
+               mtp_uint32 size);
+void _prop_destroy_obj_proplist(obj_proplist_t *prop_list);
+
+/*
+ * ObjectProp Functions
+ */
+mtp_uint32 _prop_get_supp_obj_props(mtp_uint32 format_code,
+               ptp_array_t *supp_props);
+mtp_bool _prop_build_supp_props_mp3(void);
+mtp_bool _prop_build_supp_props_wma(void);
+mtp_bool _prop_build_supp_props_wmv(void);
+mtp_bool _prop_build_supp_props_album(void);
+mtp_bool _prop_build_supp_props_default(void);
+void _prop_destroy_supp_obj_props(void);
+
+/*
+ *Interdependent Prop Functions
+ */
+mtp_uint32 _prop_get_size_interdep_prop(interdep_prop_config_t *prop);
+mtp_uint32 _prop_pack_interdep_prop(interdep_prop_config_t *prop, mtp_uchar *buf,
+               mtp_uint32 size);
+mtp_uint32 _prop_get_size_interdep_proplist(obj_interdep_proplist_t *config_list,
+               mtp_uint32 format_code);
+mtp_uint32 _prop_pack_interdep_proplist(obj_interdep_proplist_t *config_list,
+               mtp_uint32 format_code, mtp_uchar *buf, mtp_uint32 size);
+mtp_bool _get_oma_drm_status(void);
+
+#endif /* _MTP_PROPERTY_H_ */
diff --git a/include/entity/mtp_store.h b/include/entity/mtp_store.h
new file mode 100755 (executable)
index 0000000..32f2427
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_STORE_H_
+#define _MTP_STORE_H_
+
+#include "mtp_object.h"
+
+
+/* First six members of SStorageInfo structure */
+#define FIXED_LENGTH_MEMBERS_MTPSTORE_SIZE \
+       (sizeof(mtp_uint16) * 3 + sizeof(mtp_uint64) * 2 + sizeof(mtp_uint32))
+
+typedef enum {
+       MTPSTORE_WMPINFO_PHONE = 1,
+       MTPSTORE_WMPINFO_CARD
+} store_special_obj_t;
+
+/*
+ * store_info
+ * This structure stores store information for each store
+ */
+typedef struct {
+       mtp_uint16 store_type;  /*storage type*/
+       mtp_uint16 fs_type;     /*file system type*/
+       mtp_uint16 access;      /*access capability(read/write)*/
+       mtp_uint64 capacity;    /*maximum capacity in bytes*/
+       mtp_uint64 free_space;  /*free space in bytes*/
+       mtp_uint32 free_space_in_objs;  /*free space in objects*/
+       ptp_string_t store_desc;
+       ptp_string_t vol_label; /*optional volume label: variable length*/
+} store_info_t;
+
+/*
+ * MTP store structure.
+ * This structure is instantiated for each store within the MTP device.
+ */
+typedef struct {
+       mtp_char *root_path;    /* Root path of the store */
+       mtp_uint32 store_id;
+       store_info_t store_info;
+       slist_t obj_list;
+       mtp_bool is_hidden;     /*for hidden storage*/
+} mtp_store_t;
+
+typedef struct {
+       mtp_uint32 h_parent;
+       mtp_store_t *store;
+       ptp_array_t child_data;
+} missing_child_data_t;
+
+typedef enum {
+       MTP_INTERNAL_STORE_ID = 0x10001,
+       MTP_EXTERNAL_STORE_ID = 0x20001
+} mtp_store_id_t;
+
+typedef enum {
+       MTP_ADDREM_AUTO,
+       MTP_ADDREM_INTERNAL,
+       MTP_ADDREM_EXTERNAL,
+       MTP_ADDREM_ALL
+} add_rem_store_t;
+
+void _entity_update_store_info_run_time(store_info_t *info,
+               mtp_char *root_path);
+mtp_bool _entity_get_store_path_by_id(mtp_uint32 store_id, mtp_char *path);
+mtp_uint32 _entity_get_store_info_size(store_info_t *info);
+mtp_uint32 _entity_pack_store_info(store_info_t *info, mtp_uchar *buf,
+               mtp_uint32 buf_sz);
+mtp_uint32 _entity_get_store_id_by_path(const mtp_char *path_name);
+mtp_bool _entity_init_mtp_store(mtp_store_t *store, mtp_uint32 store_id,
+               mtp_char *store_path);
+mtp_obj_t *_entity_add_file_to_store(mtp_store_t *store, mtp_uint32 h_parent,
+               mtp_char *file_path, mtp_char *file_name, dir_entry_t *file_info);
+mtp_obj_t *_entity_add_folder_to_store(mtp_store_t *store, mtp_uint32 h_parent,
+               mtp_char *file_path, mtp_char *file_name, dir_entry_t *file_info);
+mtp_bool _entity_add_object_to_store(mtp_store_t *store, mtp_obj_t *obj);
+mtp_obj_t *_entity_get_object_from_store(mtp_store_t *store, mtp_uint32 handle);
+mtp_obj_t *_entity_get_last_object_from_store(mtp_store_t *store,
+               mtp_uint32 handle);
+mtp_obj_t *_entity_get_object_from_store_by_path(mtp_store_t *store,
+               mtp_char *file_path);
+mtp_uint32 _entity_get_objects_from_store(mtp_store_t *store,
+               mtp_uint32 obj_handle, mtp_uint32 fmt, ptp_array_t *obj_arr);
+mtp_uint32 _entity_get_objects_from_store_till_depth(mtp_store_t *store,
+               mtp_uint32 obj_handle, mtp_uint32 fmt_code, mtp_uint32 depth,
+               ptp_array_t *obj_arr);
+mtp_uint32 _entity_get_objects_from_store_by_format(mtp_store_t *store,
+               mtp_uint32 format, ptp_array_t *obj_arr);
+mtp_uint32 _entity_get_num_object_with_same_format(mtp_store_t *store,
+               mtp_uint32 format);
+mtp_uint32 _entity_get_num_children(mtp_store_t *store, mtp_uint32 h_parent,
+               mtp_uint32 format);
+mtp_uint32 _entity_get_child_handles(mtp_store_t *store, mtp_uint32 h_parent,
+               ptp_array_t *child_arr);
+mtp_uint32 _entity_get_child_handles_with_same_format(mtp_store_t *store,
+               mtp_uint32 h_parent, mtp_uint32 format, ptp_array_t *child_arr);
+mtp_bool _entity_remove_object_mtp_store(mtp_store_t *store, mtp_obj_t *obj,
+               mtp_uint32 format, mtp_uint16 *response, mtp_bool *atleast_one,
+               mtp_bool read_only);
+mtp_uint16 _entity_delete_obj_mtp_store(mtp_store_t *store,
+               mtp_uint32 obj_handle, mtp_uint32 fmt, mtp_bool read_only);
+mtp_uint32 _entity_get_object_tree_size(mtp_store_t *store, mtp_obj_t *obj);
+mtp_bool _entity_check_if_B_parent_of_A(mtp_store_t *store,
+               mtp_uint32 handleA, mtp_uint32 handleB);
+mtp_uint32 _entity_generate_next_obj_handle(void);
+mtp_uint16 _entity_format_store(mtp_store_t *store, mtp_uint32 fs_format);
+void _entity_destroy_mtp_store(mtp_store_t *store);
+void _entity_store_recursive_enum_folder_objects(mtp_store_t *store,
+               mtp_obj_t *pobj);
+void _entity_list_modified_files(mtp_uint32 minutes);
+void _entity_copy_store_data(mtp_store_t *dst, mtp_store_t *src);
+
+#endif /* _MTP_STORE_H_ */
diff --git a/include/mtp_cmd_handler.h b/include/mtp_cmd_handler.h
new file mode 100755 (executable)
index 0000000..1fc6992
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_CMD_HANDLER_H_
+#define _MTP_CMD_HANDLER_H_
+
+#include "mtp_object.h"
+#include "mtp_device.h"
+#include "ptp_container.h"
+#include "mtp_event_handler.h"
+
+#ifdef MTP_SUPPORT_PRINT_COMMAND
+#define MTP_MAX_CMD_LENGTH 40
+#endif /* MTP_SUPPORT_PRINT_COMMAND */
+
+/*
+ * A structure for containing the object infomation. It is used for saving
+ * information in between paired operations like send_obj_info
+ * and send_object.
+ * @see obj_info
+ */
+typedef struct {
+       mtp_uint32 store_id;    /* The storage ID. */
+       mtp_uint32 h_parent;    /* Handle of the parent object */
+       /* Reserved Handle for the incoming object. */
+       mtp_uint32 obj_handle;
+       /* Indicates if the ObjectInfo dataset is valid. */
+       mtp_bool is_valid;
+       mtp_bool is_data_sent;  /* Indicates whether data was actually sent */
+       mtp_uint64 file_size;
+       mtp_obj_t *obj;         /* Object containing info for SendObject */
+} data_4send_object_t;
+
+/*
+ * A structure for handling the operations of the MTP protocol.
+ * It is the main driving structure behind the MTP protocol handling. The
+ * MTP device contains device information and other data buffers.
+ *
+ * @see mtp_device
+ * @see cmd_blk_t
+ * @see data4_send_obj
+ */
+typedef struct {
+       cmd_container_t usb_cmd;        /* A USB command container block. */
+       /* Data saved during paired operations: SendObjectInfo/SendObject. */
+       data_4send_object_t data4_send_obj;
+       mtp_uint32 session_id;          /* Current session ID. */
+       mtp_uint32 last_opcode;         /* Current transaction ID. */
+       mtp_uint16 last_fmt_code;       /* Last Format Code */
+} mtp_handler_t;
+
+typedef struct {
+       mtp_uint32 recent_tid;
+       mtp_uint32 cur_index;
+       mtp_uint32 mod;
+} wmp_meta_info_t;
+
+/*
+ * This structure specifies the buffer of Mtp.
+ */
+typedef struct {
+       mtp_char cmd_buf[MTP_MAX_CMD_BLOCK_SIZE];
+       mtp_char header_buf[MTP_USB_HEADER_LENGTH];
+       mtp_uint32 cmd_size;
+       mtp_uint32 data_size;
+       mtp_uint32 data_count;
+       mtp_uint32 fhandle;     /* for temporary mtp file */
+       mtp_char *filepath;
+       mtp_uint32 file_size;
+       mtp_uint32 size_remaining;
+       /* PC-> Device file transfer user space buffering till 512K*/
+       mtp_char *temp_buff;
+} temp_file_struct_t;
+
+typedef struct {
+       temp_file_struct_t ftemp_st;
+       mtp_handler_t hdlr;
+       wmp_meta_info_t meta_info;
+} mtp_mgr_t;
+
+void _cmd_hdlr_reset_cmd(mtp_handler_t *hdlr);
+mtp_bool _cmd_hdlr_send_response(mtp_handler_t *hdlr, mtp_uint16 resp,
+               mtp_uint32 num_param, mtp_uint32 *params);
+mtp_bool _cmd_hdlr_send_response_code(mtp_handler_t *hdlr, mtp_uint16 resp);
+void _receive_mq_data_cb(mtp_char *buffer, mtp_int32 buf_len);
+
+#endif /* _MTP_CMD_HANDLER_H_ */
diff --git a/include/mtp_cmd_handler_util.h b/include/mtp_cmd_handler_util.h
new file mode 100755 (executable)
index 0000000..f360329
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_CMD_HANDLER_UTIL_H_
+#define        _MTP_CMD_HANDLER_UTIL_H_
+
+#include "mtp_device.h"
+
+typedef struct {
+       mtp_uint32 store_id;
+       mtp_uint64 obj_size;
+       mtp_obj_t *obj;
+} obj_data_t;
+
+mtp_err_t _hutil_get_storage_entry(mtp_uint32 store_id, store_info_t *info);
+mtp_err_t _hutil_get_storage_ids(ptp_array_t *store_ids);
+mtp_err_t _hutil_get_device_property(mtp_uint32 prop_id,
+               device_prop_desc_t* dev_prop);
+mtp_err_t _hutil_set_device_property(mtp_uint32 prop_id, void *data,
+               mtp_uint32 data_sz);
+mtp_err_t _hutil_reset_device_entry(mtp_uint32 prop_id);
+mtp_err_t _hutil_add_object_entry(obj_info_t *obj_info, mtp_char *file_name,
+               mtp_obj_t **new_obj);
+mtp_err_t _hutil_remove_object_entry(mtp_uint32 obj_handle, mtp_uint32 format);
+mtp_err_t _hutil_get_object_entry(mtp_uint32 obj_handle, mtp_obj_t **obj_ptr);
+mtp_err_t _hutil_copy_object_entries(mtp_uint32 dst_store_id,
+               mtp_uint32 src_store_id, mtp_uint32 h_parent, mtp_uint32 obj_handle,
+               mtp_uint32 *new_hobj, mtp_bool keep_handle);
+mtp_err_t _hutil_move_object_entry(mtp_uint32 dst_store_id, mtp_uint32 h_parent,
+               mtp_uint32 obj_handle);
+mtp_err_t _hutil_duplicate_object_entry(mtp_uint32 dst_store_id,
+               mtp_uint32 h_parent, mtp_uint32 obj_handle, mtp_uint32 *new_handle);
+mtp_err_t _hutil_read_file_data_from_offset(mtp_uint32 obj_handle, off_t offset,
+               void *data, mtp_uint32 *data_sz);
+mtp_err_t _hutil_write_file_data(mtp_uint32 store_id, mtp_obj_t *obj,
+               mtp_char *fpath);
+mtp_err_t _hutil_get_object_entry_size(mtp_uint32 obj_handle, mtp_uint64 *obj_sz);
+mtp_err_t _hutil_set_protection(mtp_uint32 obj_handle, mtp_uint16 prot_status);
+mtp_err_t _hutil_get_num_objects(mtp_uint32 store_id, mtp_uint32 h_parent,
+               mtp_uint32 format, mtp_uint32 *num_obj);
+mtp_err_t _hutil_get_object_handles(mtp_uint32 store_id, mtp_uint32 format,
+               mtp_uint32 h_parent, ptp_array_t *handle_arr);
+mtp_err_t _hutil_construct_object_entry(mtp_uint32 store_id, mtp_uint32 h_parent,
+               obj_data_t *objdata, mtp_obj_t **obj, void *data, mtp_uint32 data_sz);
+mtp_err_t _hutil_construct_object_entry_prop_list(
+               mtp_uint32 store_id,
+               mtp_uint32 h_parent,
+               mtp_uint16 format,
+               mtp_uint64 obj_sz,
+               obj_data_t *obj_data,
+               mtp_obj_t **obj_ptr,
+               void *data,
+               mtp_int32 data_sz,
+               mtp_uint32 *err_idx);
+mtp_err_t _hutil_get_object_prop_value(mtp_uint32 obj_handle, mtp_uint32 prop_code,
+               obj_prop_val_t  *prop_val, mtp_obj_t **obj);
+mtp_err_t _hutil_update_object_property(
+               mtp_uint32 obj_handle,
+               mtp_uint32 prop_code,
+               mtp_uint16 *data_type,
+               void *buf,
+               mtp_uint32 buf_sz,
+               mtp_uint32 *prop_sz);
+mtp_err_t _hutil_get_prop_desc(mtp_uint32 format, mtp_uint32 prop_code, void *data);
+mtp_err_t _hutil_get_object_prop_supported(mtp_uint32 format,
+               ptp_array_t *prop_arr);
+
+#ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+mtp_err_t _hutil_get_object_prop_list(mtp_uint32 obj_handle,
+               mtp_uint32 format,
+               mtp_uint32 prop_code,
+               mtp_uint32 group_code,
+               mtp_uint32 depth,
+               obj_proplist_t *prop_list,
+               ptp_array_t *obj_arr);
+#else /* MTP_USE_RUNTIME_GETOBJECTPROPVALUE */
+mtp_err_t _hutil_get_object_prop_list(
+               mtp_uint32 obj_handle,
+               mtp_uint32 format,
+               mtp_uint32 prop_code,
+               mtp_uint32 group_code,
+               mtp_uint32 depth,
+               obj_proplist_t *prop_list);
+#endif /* MTP_USE_RUNTIME_GETOBJECTPROPVALUE */
+
+mtp_err_t _hutil_add_object_references_enhanced(mtp_uint32 obj_handle,
+               mtp_uchar *buffer, mtp_uint32 buf_sz);
+mtp_err_t _hutil_remove_object_reference(mtp_uint32 obj_handle,
+               mtp_uint32 ref_handle);
+mtp_err_t _hutil_get_object_references(mtp_uint32 obj_handle,
+               ptp_array_t *parray, mtp_uint32 *num_ele);
+mtp_err_t _hutil_get_number_of_objects(mtp_uint32 store_id,
+               mtp_uint32 *num_obj);
+mtp_err_t _hutil_get_interdep_prop_config_list_size(mtp_uint32 *list_sz,
+               mtp_uint32 format);
+mtp_err_t _hutil_get_interdep_prop_config_list_data(void *data,
+               mtp_uint32 list_sz, mtp_uint32 format);
+mtp_err_t _hutil_get_playback_skip(mtp_int32 skip_param);
+mtp_err_t _hutil_format_storage(mtp_uint32 store_id, mtp_uint32 fs_format);
+mtp_uint32 _hutil_get_storage_info_size(store_info_t *store_info);
+
+#endif /* _MTP_CMD_HANDLER_UTIL_H_ */
diff --git a/include/mtp_config.h b/include/mtp_config.h
new file mode 100755 (executable)
index 0000000..87d7d23
--- /dev/null
@@ -0,0 +1,243 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_CONFIG_H_
+#define _MTP_CONFIG_H_
+
+#include <stdbool.h>
+
+/* Function Features */
+#define MTP_USE_INFORMATION_REGISTRY           /* for get and set some information value */
+
+/* Set write-protection for read-only files */
+/*#define MTP_SUPPORT_SET_PROTECTION*/
+
+/*MtpObject.c, for unknown metadata */
+#define MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN
+
+/*define MTP_USE_VARIABLE_PTP_STRING_MALLOC*/  /*allocPtpString in ptpstring.c*/
+#define MTP_USE_RUNTIME_GETOBJECTPROPVALUE     /*use runtime get object property list*/
+
+/*keywords has many space. not support*/
+/*#define MTP_USE_OBJPROPERTY_KEYWORDS*/
+/*#define MTP_USE_SELFMAKE_ABSTRACTION*/
+
+/*after db loading(mass files), there are some duplicate open session packet*/
+/*#define MTP_USE_SKIP_CONTINUOUS_OPENSESSION*/
+
+/* Support Features */
+
+/* cancel transactio, device reset, mainly used in mtpmain.c */
+#define MTP_SUPPORT_CONTROL_REQUEST
+
+#define MTP_SUPPORT_ALBUM_ART          /* album art image file */
+/*#define MTP_SUPPORT_DELETE_MEDIA_ALBUM_FILE*/
+
+/*support battery level using mtp_pal_phone_get_status(MTP_PAL_BATTLEVEL) */
+#define MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL
+
+/*support get wmpinfo.xml from hidden file list */
+/*#define MTP_SUPPORT_HIDE_WMPINFO_XML*/
+
+/*support mtp command GetInterdependentPropDesc (0x9807) */
+/*#define MTP_SUPPORT_INTERDEPENDENTPROP*/
+
+/*mobile class. this should be set with ms os descriptor. see portable device installation consideration */
+#define MTP_SUPPORT_DEVICE_CLASS
+
+/*#define MTP_SUPPORT_WMV_ENCODINGPROFILE */           /* for WMV encoding profile */
+
+/*Representive Sample Properties are not supported by either music player or libmm-fileinfo */
+#ifdef MTP_SUPPORT_ALBUM_ART
+/*#define MTP_SUPPORT_PROPERTY_SAMPLE*/
+#endif/*MTP_SUPPORT_ALBUM_ART*/
+
+/* external features */
+#define MTP_SUPPORT_OBJECTADDDELETE_EVENT
+
+/*For printing Commands sent by initiator
+ *This needs to be diabled later before commercial binary release
+ */
+#define MTP_SUPPORT_PRINT_COMMAND
+
+/*
+ * Transport related configuration
+ */
+/* Internal Storage */
+#define MTP_STORE_PATH_CHAR            "/opt/usr/media"
+
+/* External Storage */
+#define MTP_EXTERNAL_PATH_CHAR         "/opt/storage/sdcard"
+#define MTP_DEVICE_ICON                        "/usr/share/mtp/device_icon.ico"
+
+/* File For WMP extesions */
+#define MTP_FILES_MODIFIED_FILES       "/tmp/mtp_mod_files.log"
+
+/* Base MTP USER Directory */
+#define MTP_USER_DIRECTORY             "/opt/usr/media/user"
+
+/* Hidden Root directory */
+#define MTP_HIDDEN_PHONE               ".HiddenPhone"
+#define MTP_HIDDEN_CARD                        ".HiddenCard"
+
+/* Windows Media Player xml file */
+#define MTP_FILE_NAME_WMPINFO_XML      "WMPInfo.xml"
+
+/* MTP extension name */
+#define MTP_EXT_NAME_REGISTRY          "ini"
+
+/* special extension */
+#define MTP_ALBUMFILE_EXTENSION                "alb"
+
+/* Reference Key name */
+#define MTP_REF_KEYNAME_CHAR           "Reference"
+
+/*STORAGE*/
+#define MTP_MAX_STORAGE                        (30*1024*1024)  /*30MB */
+#define MTP_MAX_STORAGE_IN_OBJTS       0xFFFFFFFF
+#define MTP_MAX_INT_OBJECT_NUM         10000000
+#define MTP_MIN_EXT_OBJECT_NUM         5000000
+
+#define MTP_BUF_SIZE_FOR_INT           11      /* 2^32 - 1 = 4294967295 (10 digits) */
+
+/*To determine whether command is for Samsung mobile*/
+#define MTP_SAMSUNG_MOBILE             0x1000
+#define MTP_STORAGE_DESC_INT           "Phone"
+#define MTP_STORAGE_DESC_EXT           "Card"
+
+/*Devices Property*/
+#define MTP_DEFAULT_MODEL_NAME                 "SAMSUNG Mobile"
+#define MTP_DEFAULT_DEVICE_VERSION             ""
+#define MTP_DEV_PROPERTY_SYNCPARTNER           "Longhorn Sync Engine"
+#define MTP_DEV_PROPERTY_FRIENDLYNAME          "SAMSUNG Mobile"
+#define MTP_DEV_PROPERTY_NULL_SYNCPARTNER      "{00000000-0000-0000-0000-000000000000}"
+
+/*temporary file*/
+#define MTP_TEMP_FILE                  ".mtptemp.tmp"
+#define MTP_TEMP_FILE_DEFAULT          "/tmp/.mtptemp.tmp"
+
+/*Unknown Metadata default name*/
+#define MTP_UNKNOWN_METADATA           "Unknown"
+
+/*2006.10.20 empty metadata folder problem*/
+#define MTP_UNKNOWN_METADATAW          L"Unknown"
+
+/* strlen(/opt/usr/share/crash/) + MTP path len limit */
+#define MTP_MAX_PATHNAME_SIZE          (21 + 255)      /* except \0 */
+#define MTP_MAX_FILENAME_SIZE          (254)   /* except \0 */
+
+#define MTP_MAX_CMD_BLOCK_SIZE         36      /* Bytes */
+
+#define MTP_MAX_PACKET_SIZE_SEND_HS    512     /* High speed */
+#define MTP_MAX_PACKET_SIZE_SEND_FS    64      /* Full speed */
+#define MTP_FILESIZE_4GB               4294967296L
+
+/* approximately 3 times of media files. consider album*/
+#define MTP_MAX_REFDB_ROWCNT           4500
+#define MTP_MAX_EXTENSION_LENGTH       11
+#define MTP_MAX_REG_STRING             128
+
+#define MTP_SERIAL_LEN_MAX             32
+#define MD5_HASH_LEN                   16
+#define MTP_MODEL_NAME_LEN_MAX         32
+#define MTP_DEVICE_NAME_LEN_MAX                64
+
+/*
+ *  User defined Configureations
+ */
+/*#define MTP_USE_DEPEND_DEFAULT_MEMORY*/
+#define MTP_SUPPORT_OMADRM_EXTENSION
+
+/* Image Height/Width */
+#define MTP_MAX_IMG_WIDTH              32672
+#define MTP_MAX_IMG_HEIGHT             32672
+
+#define MTP_MAX_VIDEO_WIDTH            1920
+#define MTP_MAX_VIDEO_HEIGHT           1080
+
+#define MTP_MIN_VIDEO_WIDTH            0
+#define MTP_MIN_VIDEO_HEIGHT           0
+
+/* about 976kbytes for object property value like sample data*/
+#define MTP_MAX_PROP_DATASIZE          1000000
+
+#define MTP_MAX_METADATA               204800  /* 200KB */
+
+#define MTP_VENDOR_EXTENSIONDESC_CHAR  \
+       "microsoft.com/WMDRMPD:10.1;microsoft.com/playready:1.10; "
+
+#define MTP_MANUFACTURER_CHAR          "Tizen"
+#define HAVE_OWN_WCHAR_CONVERSION
+
+#define MTP_MMAP_THRESHOLD     524288
+#define MTP_READ_USB_SIZE      4096
+#define MTP_WRITE_USB_SIZE     4096
+#define MTP_READ_FILE_SIZE     524288
+#define MTP_WRITE_FILE_SIZE    524288
+#define MTP_INIT_RX_IPC_SIZE   32768
+#define MTP_INIT_TX_IPC_SIZE   262144
+#define MTP_MAX_RX_IPC_SIZE    32768
+#define MTP_MAX_TX_IPC_SIZE    262144
+#define MTP_MAX_IO_BUF_SIZE    10485760        /* 10MB */
+#define MTP_READ_FILE_DELAY    0               /* us */
+
+#define MTP_SUPPORT_PTHREAD_SCHED      false
+#define MTP_INHERITSCHED               'i'
+#define MTP_SCHEDPOLICY                        'o'
+#define MTP_FILE_SCHEDPARAM            0
+#define MTP_USB_SCHEDPARAM             0
+
+#define MTP_CONFIG_FILE_PATH           "/opt/var/lib/misc/mtp-responder.conf"
+
+typedef struct {
+       /* Speed related config */
+       int mmap_threshold;     /* Max. 512KB. If requested memory is lesser than this, malloc is used. Otherwise, mmap is used */
+
+       int read_usb_size;      /* USB read request size */
+       int write_usb_size;     /* USB write request size */
+
+       int read_file_size;     /* File read request size */
+       int write_file_size;    /* File write request size */
+
+       int init_rx_ipc_size;   /* Init. Rx(PC -> Phone) IPC size between USB and File threads */
+       int init_tx_ipc_size;   /* Init. Tx(Phone -> PC) IPC size between USB and File threads */
+       int max_rx_ipc_size;    /* Max. Rx(PC -> Phone) IPC size between USB and File threads */
+       int max_tx_ipc_size;    /* Max. Tx(Phone -> PC) IPC size between USB and File threads */
+
+       int max_io_buf_size;    /* Max. Heap memory size for buffer between USB and File threads */
+
+       int read_file_delay;
+
+       /* Experimental */
+       bool support_pthread_sched;
+       char inheritsched;      /* i : Inherit, e : Explicit */
+       char schedpolicy;       /* f : FIFO, r : Round Robin, o : Other */
+       int file_schedparam;    /* File I/O thread's priority for scheduling */
+       int usb_schedparam;     /* USB I/O thread's priority for scheduling */
+
+       /* Experimental (End) */
+       /* Speed related config (End) */
+
+       /* MTP Features */
+       /* MTP Features (End) */
+
+       /* Vendor Features */
+       /* Features (End) */
+
+       bool is_init;
+} mtp_config_t;
+
+#endif /* _MTP_CONFIG_H_ */
diff --git a/include/mtp_datatype.h b/include/mtp_datatype.h
new file mode 100755 (executable)
index 0000000..07f51f4
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_DATATYPES_H_
+#define _MTP_DATATYPES_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef _MTP_USE_OWNTYPES
+#define _MTP_USE_OWNTYPES
+#endif
+#ifdef _MTP_USE_OWNTYPES
+
+#define INVALID_FILE           (0)
+
+typedef unsigned char mtp_byte;
+typedef unsigned char mtp_bool;
+typedef unsigned char mtp_uchar;
+typedef char mtp_char ;
+
+typedef unsigned short mtp_uint16;
+typedef unsigned short mtp_word;
+typedef unsigned short mtp_wchar;
+typedef short mtp_int16;
+
+typedef unsigned int mtp_uint32;
+typedef int mtp_htimer;
+typedef int mtp_int32;
+
+typedef unsigned long mtp_ulong ;
+typedef unsigned long mtp_dword ;
+
+typedef unsigned long long  mtp_uint64;
+typedef long long mtp_int64;
+
+#endif
+
+#ifndef FALSE
+#define FALSE  0
+#endif
+#ifndef TRUE
+#define TRUE   1
+#endif
+
+typedef enum {
+       MTP_ERROR_NONE = 0,
+       MTP_ERROR_GENERAL = -1,
+       MTP_ERROR_INVALID_STORE = -2,
+       MTP_ERROR_STORE_READ_ONLY = -3,
+       MTP_ERROR_STORE_FULL = -4,
+       MTP_ERROR_INVALID_DATASET = -5,
+       MTP_ERROR_INVALID_OBJECTHANDLE = -6,
+       MTP_ERROR_INVALID_OBJ_PROP_CODE = -7,
+       MTP_ERROR_INVALID_OBJECT_PROP_FORMAT = -8,
+       MTP_ERROR_INVALID_OBJ_PROP_VALUE = -9,
+       MTP_ERROR_INVALID_PARENT = -10,
+       MTP_ERROR_ACCESS_DENIED = -11,
+       MTP_ERROR_STORE_NOT_AVAILABLE = -12,
+       MTP_ERROR_INVALID_PARAM = -13,
+       MTP_ERROR_INVALID_OBJECT_INFO = -14,
+       MTP_ERROR_OBJECT_WRITE_PROTECTED = -15,
+       MTP_ERROR_PARTIAL_DELETION = -16,
+       MTP_ERROR_NO_SPEC_BY_FORMAT = -17,
+       MTP_ERROR_OPERATION_NOT_SUPPORTED = -19,
+       MTP_ERROR_MAX = -20
+} mtp_err_t;
+
+#define WCHAR_SIZ      2
+
+/**
+ * \brief The CharMode enumeration.
+ *
+ * The CharMode enumerates character type by which string is written.
+ * CHAR_TYPE means that one character consists of 8-bits.
+ * WCHAR_TYPE means that one character consists of 16-bits.
+ */
+typedef enum _char_mode {
+       CHAR_TYPE = 0,
+       WCHAR_TYPE
+} char_mode_t;
+
+#endif /* _MTP_DATATYPES_H_ */
diff --git a/include/mtp_event_handler.h b/include/mtp_event_handler.h
new file mode 100755 (executable)
index 0000000..2a20cea
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_EVENT_HANDLER_H_
+#define _MTP_EVENT_HANDLER_H_
+
+#include <vconf.h>
+#include "mtp_datatype.h"
+#include "mtp_util.h"
+
+typedef enum {
+       MTP_TURN_OFF,
+       MTP_ASK_TURN_ON,
+       MTP_ALWAYS_TURN_ON
+} on_off_state_t;
+
+typedef enum {
+       USB_INSERTED,
+       USB_REMOVED
+} usb_state_t;
+
+typedef struct {
+       mtp_uint32 action;
+       mtp_ulong param1;
+       mtp_ulong param2;
+       mtp_ulong param3;
+} mtp_event_t;
+
+typedef enum {
+       EVENT_CANCEL_INITIALIZATION,
+       EVENT_START_MAIN_OP,
+       EVENT_CLOSE,
+       EVENT_USB_REMOVED,
+       EVENT_OBJECT_ADDED,
+       EVENT_OBJECT_REMOVED,
+       EVENT_OBJECT_PROP_CHANGED,
+       EVENT_START_DATAIN,
+       EVENT_DONE_DATAIN,
+       EVENT_START_DATAOUT,
+       EVENT_DONE_DATAOUT,
+       EVENT_MAX
+} event_code_t;
+
+mtp_bool _eh_register_notification_callbacks(void);
+mtp_bool _eh_handle_usb_events(mtp_uint32 type);
+void _eh_deregister_notification_callbacks(void);
+void _handle_mmc_notification(keynode_t *key, void *data);
+void _eh_send_event_req_to_eh_thread(event_code_t action, mtp_ulong param1,
+               mtp_ulong param2, void *param3);
+
+#endif /* _MTP_EVENT_HANDLER_H_ */
diff --git a/include/mtp_init.h b/include/mtp_init.h
new file mode 100755 (executable)
index 0000000..2ce28a5
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 __MTPMAIN_H_INCLUDED
+#define __MTPMAIN_H_INCLUDED
+
+#include "mtp_store.h"
+
+#define MTP_LOG_FILE                   "/var/log/mtp.log"
+#define MTP_LOG_MAX_SIZE               5 * 1024 * 1024 /*5MB*/
+
+void _mtp_init(add_rem_store_t sel);
+void _mtp_deinit(void);
+void _features_supported_info(void);
+void mtp_end_event(void);
+
+#endif /* _MTP_MAIN_H_ */
diff --git a/include/mtp_inoti_handler.h b/include/mtp_inoti_handler.h
new file mode 100755 (executable)
index 0000000..778d226
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_INOTI_HANDLER_H_
+#define _MTP_INOTI_HANDLER_H_
+
+#include "mtp_config.h"
+#ifdef MTP_SUPPORT_OBJECTADDDELETE_EVENT
+#include <sys/inotify.h>
+#include <limits.h>
+#include "mtp_datatype.h"
+
+#define INOTI_EVENT_SIZE       (sizeof(struct inotify_event))
+#define INOTI_BUF_LEN          (INOTI_EVENT_SIZE + NAME_MAX + 1)
+#define INOTI_FOLDER_COUNT_MAX (1024)
+
+typedef struct {
+       mtp_int32 wd;
+       mtp_char *forlder_name;
+} inoti_watches_t;
+
+typedef struct _open_files_info {
+       mtp_char *name;
+       mtp_int32 wd;
+       struct _open_files_info* previous;
+       struct _open_files_info* next;
+} open_files_info_t;
+
+void *_thread_inoti(void *arg);
+void _inoti_add_watch_for_fs_events(mtp_char *path);
+mtp_bool _inoti_init_filesystem_evnts();
+void _inoti_deinit_filesystem_events();
+#endif /* MTP_SUPPORT_OBJECTADDDELETE_EVENT */
+
+#endif /* _MTP_INOTI_HANDLER_H_ */
diff --git a/include/ptp_container.h b/include/ptp_container.h
new file mode 100755 (executable)
index 0000000..e69380b
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _PTP_CONTAINER_H_
+#define _PTP_CONTAINER_H_
+
+#include "mtp_datatype.h"
+
+#define MAX_MTP_PARAMS                 5
+#define MTP_USB_HEADER_LENGTH          12
+
+typedef enum {
+       CONTAINER_UNDEFINED = 0x00,
+       CONTAINER_CMD_BLK,
+       CONTAINER_DATA_BLK,
+       CONTAINER_RESP_BLK,
+       CONTAINER_EVENT_BLK
+} container_type_t;
+
+/*
+ * A generic USB container header.
+ */
+typedef struct {
+       mtp_uint32 len;         /* the valid container size in BYTES */
+       mtp_uint16 type;        /* Container type */
+       mtp_uint16 code;        /* Operation, response or Event code */
+       mtp_uint32 tid;         /* host generated transaction id */
+} header_container_t;
+
+/*
+ * A generic USB container.
+ */
+typedef struct {
+       mtp_uint32 len;         /* the valid container size in BYTES */
+       mtp_uint16 type;        /* Container type */
+       mtp_uint16 code;        /* Operation, response or Event code */
+       mtp_uint32 tid;         /* host generated transaction id */
+       mtp_uint32 params[MAX_MTP_PARAMS];
+       mtp_uint32 no_param;
+} cmd_container_t;
+
+/*
+ * A USB container for sending data.
+ */
+typedef struct {
+       mtp_uint32 len;         /* the valid container size in BYTES */
+       mtp_uint16 type;        /* Container type */
+       mtp_uint16 code;        /* Operation, response or Event code */
+       mtp_uint32 tid;         /* host generated transaction id */
+       mtp_uint32 params[MAX_MTP_PARAMS];
+       mtp_uint32 no_param;
+       mtp_uchar *data;
+} data_container_t;
+
+typedef cmd_container_t cmd_blk_t;
+typedef cmd_container_t resp_blk_t;
+typedef data_container_t data_blk_t;
+
+void _hdlr_init_cmd_container(cmd_container_t *cntr);
+mtp_uint32 _hdlr_get_param_cmd_container(cmd_container_t *cntr,
+               mtp_uint32 index);
+void _hdlr_copy_cmd_container_unknown_params(cmd_container_t *src,
+               cmd_container_t *dst);
+void _hdlr_copy_cmd_container(cmd_container_t *src, cmd_container_t *dst);
+mtp_bool _hdlr_add_param_resp_container(resp_blk_t *dst, mtp_uint32 num,
+               mtp_uint32 *params);
+mtp_bool _hdlr_validate_cmd_container(mtp_uchar *blk, mtp_uint32 size);
+void _hdlr_init_data_container(data_container_t *dst, mtp_uint16 code,
+               mtp_uint32 trans_id);
+mtp_uchar *_hdlr_alloc_buf_data_container(data_container_t *dst,
+               mtp_uint32 bufsz, mtp_uint64 pkt_size);
+mtp_bool _hdlr_send_data_container(data_container_t *dst);
+mtp_bool _hdlr_send_bulk_data(mtp_uchar *dst, mtp_uint32 len);
+mtp_bool _hdlr_rcv_data_container(data_container_t *dst, mtp_uint32 size);
+mtp_bool _hdlr_rcv_file_in_data_container(data_container_t *dst,
+               mtp_char *filepath, mtp_uint32 path_len);
+mtp_uint32 _hdlr_get_payload_size(data_container_t *dst);
+mtp_uchar *_hdlr_get_payload_data(data_container_t *dst);
+void _hdlr_resp_container_init(cmd_container_t *dst, mtp_uint16 resp_code,
+               mtp_uint32 tid);
+mtp_bool _hdlr_send_resp_container(cmd_container_t *dst);
+void _hdlr_init_event_container(cmd_container_t *dst, mtp_uint16 code,
+               mtp_uint32 tid, mtp_uint32 param1, mtp_uint32 param2);
+void _hdlr_init_event_container_with_param(cmd_container_t *dst,
+               mtp_uint16 code, mtp_uint32 tid, mtp_uint32 param1, mtp_uint32 param2);
+mtp_bool _hdlr_send_event_container(cmd_container_t *dst);
+void _hdlr_conv_cmd_container_byte_order(cmd_container_t *dst);
+void _hdlr_conv_data_container_byte_order(data_container_t *dst);
+
+#endif /* _PTP_CONTAINER_H_ */
diff --git a/include/ptp_datacodes.h b/include/ptp_datacodes.h
new file mode 100755 (executable)
index 0000000..f524b21
--- /dev/null
@@ -0,0 +1,822 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _PTP_DATACODES_H_
+#define _PTP_DATACODES_H_
+
+/*
+ * PTP Data type codes.
+ */
+#define PTP_DATATYPE_UNDEFINED         0x0000
+#define PTP_DATATYPE_INT8              0x0001
+#define PTP_DATATYPE_UINT8             0x0002
+#define PTP_DATATYPE_INT16             0x0003
+#define PTP_DATATYPE_UINT16            0x0004
+#define PTP_DATATYPE_INT32             0x0005
+#define PTP_DATATYPE_UINT32            0x0006
+#define PTP_DATATYPE_INT64             0x0007
+#define PTP_DATATYPE_UINT64            0x0008
+#define PTP_DATATYPE_INT128            0x0009
+#define PTP_DATATYPE_UINT128           0x000A
+#define PTP_DATATYPE_AINT8             0x4001
+#define PTP_DATATYPE_AUINT8            0x4002
+#define PTP_DATATYPE_AINT16            0x4003
+#define PTP_DATATYPE_AUINT16           0x4004
+#define PTP_DATATYPE_AINT32            0x4005
+#define PTP_DATATYPE_AUINT32           0x4006
+#define PTP_DATATYPE_AINT64            0x4007
+#define PTP_DATATYPE_AUINT64           0x4008
+#define PTP_DATATYPE_AINT128           0x4009
+#define PTP_DATATYPE_AUINT128          0x400A
+#define PTP_DATATYPE_STRING            0xFFFF
+#define PTP_DATATYPE_ARRAYMASK         0x4FF0
+#define PTP_DATATYPE_ARRAY             0x4000
+#define PTP_DATATYPE_VALUEMASK         0xFFF0
+#define PTP_DATATYPE_VALUE             0x0000
+
+/*
+ * Data code ranges and masks. Each data code has 16 bits:
+ * Bit 15(std/vendor)
+ * 0 -- the code is defined by PTP standard
+ * 1 -- the code is vendor specific
+ *
+ * Bit 14 - 12(data type)
+ * 14 13 12
+ * 0  0  0    -- undefined data type
+ * 0  0  1    -- op code
+ * 0  1  0    -- response code
+ * 0  1  1    -- format code
+ * 1  0  0    -- event code
+ * 1  0  1    -- property code
+ * 1  1  0    -- reserved
+ * 1  1  1    -- reserved
+ *
+ * Bit 11 - bit 0 (data value)
+ */
+#define  PTP_DATACODE_VENDORMASK       0x8000
+#define  PTP_DATACODE_TYPEMASK         0x7000
+#define  PTP_DATACODE_VALUEMASK                0x0FFF
+#define  PTP_DATACODE_TYPE_UNKNOWN     0x0000
+#define  PTP_DATACODE_TYPE_OPERATION   0x1000
+#define  PTP_DATACODE_TYPE_RESPONSE    0x2000
+#define  PTP_DATACODE_TYPE_FORMAT      0x3000
+#define  PTP_DATACODE_TYPE_EVENT       0x4000
+#define  PTP_DATACODE_TYPE_PROPERTY    0x5000
+#define  PTP_DATACODE_TYPE_RESERVED_1  0x6000
+#define  PTP_DATACODE_TYPE_RESERVED_2  0x7000
+
+/*
+ * To verify an op code
+ *  (Code & PTP_DATACODE_TYPEMASK) == PTP_DATACODE_TYPE_OPERATION
+ * To verify a response code
+ *  (Code & PTP_DATACODE_TYPEMASK) == PTP_DATACODE_TYPE_RESPONSE)
+ */
+
+/*
+ * Image format codes receive special treatment.
+ */
+#define  PTP_DATACODE_TYPEIMAGEMASK    0x7800;
+#define  PTP_DATACODE_TYPE_IMAGEFORMAT 0x3800;
+#define  PTP_DATACODE_VALUE_IMAGEVMASK 0x07FF;
+/*
+ * To verify an image code
+ * (Code & PTP_DATACODE_TYPEIMAGEMASK) == PTP_DATACODE_TYPE_IMAGEFORMAT
+ */
+
+/*
+ * PTP specially defined constants
+ */
+#define PTP_OBJECTHANDLE_ALL           0xFFFFFFFF
+#define PTP_OBJECTHANDLE_UNDEFINED     0x0
+#define PTP_OBJECTHANDLE_ROOT          0x0
+#define PTP_PROPERTY_ALL               0xFFFFFFFF
+#define PTP_PROPERTY_UNDEFINED         0x0
+#define PTP_STORAGEID_ALL              0xFFFFFFFF
+#define PTP_STORAGEID_DEFAULT          0
+#define PTP_STORAGEID_UNDEFINED                0
+#define PTP_STORAGEID_PHYSICAL         0x0000FFFF
+#define PTP_STORAGEID_LOGICAL          0xFFFF0000
+#define PTP_SESSIONID_ALL              0
+#define PTP_SESSIONID_NOSESSION                0
+#define PTP_FORMATCODE_NOTUSED         0x0
+#define PTP_FORMATCODE_ALL             0xFFFFFFFF
+#define PTP_FORMATCODE_DEFAULT         0x0000
+#define PTP_TRANSACTIONID_ALL          0xFFFFFFFF
+#define PTP_TRANSACTIONID_NOSESSION    0
+
+/*
+ * standard operation codes:
+ */
+#define PTP_OPCODE_UNDEFINED           0x1000
+#define PTP_OPCODE_GETDEVICEINFO       0x1001
+#define PTP_OPCODE_OPENSESSION         0x1002
+#define PTP_OPCODE_CLOSESESSION                0x1003
+#define PTP_OPCODE_GETSTORAGEIDS       0x1004
+#define PTP_OPCODE_GETSTORAGEINFO      0x1005
+#define PTP_OPCODE_GETNUMOBJECTS       0x1006
+#define PTP_OPCODE_GETOBJECTHANDLES    0x1007
+#define PTP_OPCODE_GETOBJECTINFO       0x1008
+#define PTP_OPCODE_GETOBJECT           0x1009
+#define PTP_OPCODE_DELETEOBJECT                0x100B
+#define PTP_OPCODE_SENDOBJECTINFO      0x100C
+#define PTP_OPCODE_SENDOBJECT          0x100D
+#define PTP_OPCODE_INITIATECAPTURE     0x100E
+#define PTP_OPCODE_FORMATSTORE         0x100F
+#define PTP_OPCODE_RESETDEVICE         0x1010
+#define PTP_OPCODE_SELFTEST            0x1011
+#define PTP_OPCODE_SETOBJECTPROTECTION 0x1012
+#define PTP_OPCODE_POWERDOWN           0x1013
+#define PTP_OPCODE_GETDEVICEPROPDESC   0x1014
+#define PTP_OPCODE_GETDEVICEPROPVALUE  0x1015
+#define PTP_OPCODE_SETDEVICEPROPVALUE  0x1016
+#define PTP_OPCODE_RESETDEVICEPROPVALUE 0x1017
+#define PTP_OPCODE_TERMINATECAPTURE    0x1018
+#define PTP_OPCODE_MOVEOBJECT  0x1019
+#define PTP_OPCODE_COPYOBJECT          0x101A
+#define PTP_OPCODE_GETPARTIALOBJECT    0x101B
+#define PTP_OPCODE_INITIATEOPENCAPTURE 0x101C
+#define PTP_OPCODE_VENDOREXTENDEDBASE  0x9000
+#define PTP_CODE_VENDOR_OP1            0x9001
+
+/* MTP extended operations */
+#define        MTP_OPCODE_UNDEFINED                    0x9800
+#define        MTP_OPCODE_GETOBJECTPROPSUPPORTED       0x9801
+#define        MTP_OPCODE_GETOBJECTPROPDESC            0x9802
+#define        MTP_OPCODE_GETOBJECTPROPVALUE           0x9803
+#define        MTP_OPCODE_SETOBJECTPROPVALUE           0x9804
+#define        MTP_OPCODE_GETOBJECTPROPLIST            0x9805
+#define MTP_OPCODE_SETOBJECTPROPLIST           0x9806
+#define MTP_OPCODE_GETINTERDEPPROPDESC         0x9807
+#define MTP_OPCODE_SENDOBJECTPROPLIST          0x9808
+#define        MTP_OPCODE_GETOBJECTREFERENCES          0x9810
+#define        MTP_OPCODE_SETOBJECTREFERENCES          0x9811
+
+/* MTP Playback control operation */
+#define        MTP_OPCODE_PLAYBACK_SKIP                0x9820
+
+/* Operation for Windows Media 10 MTP extension */
+#define        MTP_OPCODE_WMP_UNDEFINED                                0x9200
+#define        MTP_OPCODE_WMP_METADATAROUNDTRIP                        0x9201
+#define        MTP_OPCODE_WMP_REPORTACQUIREDCONTENT                    0x9202
+
+/*
+ * standard event codes:
+ */
+#define PTP_EVENTCODE_UNDEFINED                        0x4000
+#define PTP_EVENTCODE_CANCELTRANSACTION                0x4001
+#define PTP_EVENTCODE_OBJECTADDED              0x4002
+#define PTP_EVENTCODE_OBJECTREMOVED            0x4003
+#define PTP_EVENTCODE_STOREADDED               0x4004
+#define PTP_EVENTCODE_STOREREMOVED             0x4005
+#define PTP_EVENTCODE_DEVICEPROPCHANGED                0x4006
+#define PTP_EVENTCODE_OBJECTINFOCHANGED                0x4007
+#define PTP_EVENTCODE_DEVICEINFOCHANGED                0x4008
+#define PTP_EVENTCODE_REQUESTOBJECTTRANSFER    0x4009
+#define PTP_EVENTCODE_STOREFULL                        0x400A
+#define PTP_EVENTCODE_DEVICERESET              0x400B
+#define PTP_EVENTCODE_STORAGEINFOCHANGED       0x400C
+#define PTP_EVENTCODE_CAPTURECOMPLETE          0x400D
+#define PTP_EVENTCODE_UNREPORTEDSTATUS         0x400E
+#define PTP_EVENTCODE_VENDOREXTENTION1         0xC001
+#define PTP_EVENTCODE_VENDOREXTENTION2         0xC002
+
+/*
+ * MTP-extended Events
+ */
+#define MTP_EVENTCODE_UNDEFINED                        0xB800
+#define MTP_EVENTCODE_OBJECTPROPCHANGED                0xC801
+#define MTP_EVENTCODE_OBJECTPROPDESCCHANGED    0xC802
+#define MTP_EVENTCODE_OBJECTREFERENCESCHANGED  0xC803
+#define MTP_EVENTCODE_DEVICEPROPDESCCHANGED    0xB804
+
+/* Events for Janus MTP extension */
+#define MTP_EVENTCODE_JANUS_UNDEFINED          0xC100
+#define MTP_EVENTCODE_JANUS_EVENT1             0xC101
+
+/*
+ * standard response codes:
+ */
+#define PTP_RESPONSE_UNDEFINED                 0x2000
+#define PTP_RESPONSE_OK                                0x2001
+#define PTP_RESPONSE_GEN_ERROR                 0x2002
+#define PTP_RESPONSE_SESSIONNOTOPEN            0x2003
+#define PTP_RESPONSE_INVALID_TRANSACTIONID     0x2004
+#define PTP_RESPONSE_OP_NOT_SUPPORTED          0x2005
+#define PTP_RESPONSE_PARAM_NOTSUPPORTED                0x2006
+#define PTP_RESPONSE_INCOMPLETETRANSFER                0x2007
+#define PTP_RESPONSE_INVALID_STORE_ID          0x2008
+#define PTP_RESPONSE_INVALID_OBJ_HANDLE                0x2009
+#define PTP_RESPONSE_PROP_NOTSUPPORTED         0x200A
+#define PTP_RESPONSE_INVALID_OBJ_FMTCODE       0x200B
+#define PTP_RESPONSE_STOREFULL                 0x200C
+#define PTP_RESPONSE_OBJ_WRITEPROTECTED                0x200D
+#define PTP_RESPONSE_STORE_READONLY            0x200E
+#define PTP_RESPONSE_ACCESSDENIED              0x200F
+#define PTP_RESPONSE_SELFTEST_FAILED           0x2011
+#define PTP_RESPONSE_PARTIAL_DELETION          0x2012
+#define PTP_RESPONSE_STORENOTAVAILABLE         0x2013
+#define PTP_RESPONSE_NOSPECIFICATIONBYFORMAT   0x2014
+#define PTP_RESPONSE_NOVALID_OBJINFO           0x2015
+#define PTP_RESPONSE_INVALIDCODEFORMAT         0x2016
+#define PTP_RESPONSE_UNKNOWN_VENDORCODE                0x2017
+#define PTP_RESPONSE_CAPTURE_ALREADYTERMINATED 0x2018
+#define PTP_RESPONSE_DEVICEBUSY                        0x2019
+#define PTP_RESPONSE_INVALIDPARENT             0x201A
+#define PTP_RESPONSE_INVALIDPROPFORMAT         0x201B
+#define PTP_RESPONSE_INVALIDPROPVALUE          0x201C
+#define PTP_RESPONSE_INVALIDPARAM              0x201D
+#define PTP_RESPONSE_SESSIONALREADYOPENED      0x201E
+#define PTP_RESPONSE_TRANSACTIONCANCELLED      0x201F
+/*
+ * MTP responses
+ */
+#define MTP_RESPONSE_UNDEFINED                         0xA800
+#define MTP_RESPONSE_INVALIDOBJPROPCODE                        0xA801
+#define MTP_RESPONSE_INVALIDOBJPROPFORMAT              0xA802
+#define MTP_RESPONSE_INVALIDOBJPROPVALUE               0xA803
+#define MTP_RESPONSE_INVALIDOBJREFERENCE               0xA804
+#define MTP_RESPONSE_INVALIDOBJGROUPCODE               0xA805
+#define MTP_RESPONSECODE_INVALIDDATASET                        0xA806
+#define MTP_RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED 0xA807
+#define MTP_RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED 0xA808
+#define MTP_RESPONSE_OBJECT_TOO_LARGE                  0xA809
+
+/*
+ * standard property codes:
+ */
+#define PTP_PROPERTYCODE_UNDEFINED             0x5000
+#define PTP_PROPERTYCODE_BATTERYLEVEL          0x5001
+#define PTP_PROPERTYCODE_FUNCTIONMODE          0x5002
+#define PTP_PROPERTYCODE_IMAGESIZE             0x5003
+#define PTP_PROPERTYCODE_COMPRESSIONSETTING    0x5004
+#define PTP_PROPERTYCODE_WHITEBALANCE           0x5005
+#define PTP_PROPERTYCODE_RGBGAIN                0x5006
+#define PTP_PROPERTYCODE_FNUMBER                0x5007
+#define PTP_PROPERTYCODE_FOCALLENGTH            0x5008
+#define PTP_PROPERTYCODE_FOCUSDISTANCE         0x5009
+#define PTP_PROPERTYCODE_FOCUSMODE              0x500A
+#define PTP_PROPERTYCODE_EXPOSUREMETERINGMODE   0x500B
+#define PTP_PROPERTYCODE_FLASHMODE              0x500C
+#define PTP_PROPERTYCODE_EXPOSURETIME           0x500D
+#define PTP_PROPERTYCODE_EXPOSUREPROGRAMMODE    0x500E
+#define PTP_PROPERTYCODE_EXPOSUREINDEX          0x500F
+#define PTP_PROPERTYCODE_EXPOSURECOMPENSATION   0x5010
+#define PTP_PROPERTYCODE_DATETIME               0x5011
+#define PTP_PROPERTYCODE_CAPTUREDELAY           0x5012
+#define PTP_PROPERTYCODE_STILLCAPTUREMODE       0x5013
+#define PTP_PROPERTYCODE_CONTRAST               0x5014
+#define PTP_PROPERTYCODE_SHARPNESS              0x5015
+#define PTP_PROPERTYCODE_DIGITALZOOM            0x5016
+#define PTP_PROPERTYCODE_EFFECTMODE            0x5017
+#define PTP_PROPERTYCODE_BURSTNUMBER            0x5018
+#define PTP_PROPERTYCODE_BURSTINTERVAL          0x5019
+#define PTP_PROPERTYCODE_TIMELAPSENUMBER        0x501A
+#define PTP_PROPERTYCODE_TIMELAPSEINTERVAL     0x501B
+#define PTP_PROPERTYCODE_FOCUSMETERINGMODE     0x501C
+#define PTP_PROPERTYCODE_UPLOADURL             0x501D
+#define PTP_PROPERTYCODE_ARTIST                        0x501E
+#define PTP_PROPERTYCODE_COPYRIGHT             0x501F
+#define PTP_PROPERTYCODE_VENDOREXTENTION1      0xD001
+#define PTP_PROPERTYCODE_VENDOREXTENTION2      0xD002
+
+/*
+ * MTP defined Device properties
+ */
+#define MTP_PROPERTYCODE_UNDEFINED                     0xD400
+#define MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER                0xD401
+#define MTP_PROPERTYCODE_DEVICEFRIENDLYNAME            0xD402
+
+#define MTP_PROPERTYCODE_SUPPORTEDFORMATSORDERED       0xD404
+#define MTP_PROPERTYCODE_DEVICEICON                    0xD405
+
+#ifdef MTP_SUPPORT_DEVICE_CLASS
+#define MTP_PROPERTYCODE_PERCEIVEDDEVICETYPE           0xD407
+#endif
+
+/* Device properties for MTP Playback */
+#define MTP_PROPERTYCODE_PLAYBACK_RATE                         0xD410
+#define MTP_PROPERTYCODE_PLAYBACK_OBJECT                       0xD411
+#define MTP_PROPERTYCODE_PLAYBACK_CONT_INDEX                   0xD412
+#define MTP_PROPERTYCODE_PLAYBACK_POSITION                     0xD413
+
+/* MTP extended object property codes */
+#define        MTP_OBJ_PROPERTYCODE_PURCHASE_ALBTRK                    0xD901
+
+/* for support OMA DRM, request of Vodafone */
+#define MTP_OBJ_PROPERTYCODE_OMADRMSTATUS                      0xDB01
+#define MTP_OBJ_PROPERTYCODE_OMADRMRIGHTSOBJECT                        0xDB02
+
+#define MTP_OBJ_PROPERTYCODE_STORAGEID                         0xDC01
+#define MTP_OBJ_PROPERTYCODE_OBJECTFORMAT                      0xDC02
+#define MTP_OBJ_PROPERTYCODE_PROTECTIONSTATUS                  0xDC03
+#define MTP_OBJ_PROPERTYCODE_OBJECTSIZE                                0xDC04
+#define MTP_OBJ_PROPERTYCODE_ASSOCIATIONTYPE                   0xDC05
+#define MTP_OBJ_PROPERTYCODE_ASSOCIATIONDESC                   0xDC06
+#define MTP_OBJ_PROPERTYCODE_OBJECTFILENAME                    0xDC07
+#define MTP_OBJ_PROPERTYCODE_DATECREATED                       0xDC08
+#define MTP_OBJ_PROPERTYCODE_DATEMODIFIED                      0xDC09
+#define MTP_OBJ_PROPERTYCODE_KEYWORDS                          0xDC0A
+#define MTP_OBJ_PROPERTYCODE_PARENT                            0xDC0B
+
+#define MTP_OBJ_PROPERTYCODE_PERSISTENTGUID                    0xDC41
+#define MTP_OBJ_PROPERTYCODE_SYNCID                            0xDC42
+#define MTP_OBJ_PROPERTYCODE_PROPERTYBAG                       0xDC43
+#define MTP_OBJ_PROPERTYCODE_NAME                              0xDC44
+#define MTP_OBJ_PROPERTYCODE_CREATEDBY                         0xDC45
+#define MTP_OBJ_PROPERTYCODE_ARTIST                            0xDC46
+#define MTP_OBJ_PROPERTYCODE_DATEAUTHORED                      0xDC47
+#define MTP_OBJ_PROPERTYCODE_DESCRIPTION                       0xDC48
+#define MTP_OBJ_PROPERTYCODE_URLREFERENCE                      0xDC49
+#define MTP_OBJ_PROPERTYCODE_LANGUAGELOCALE                    0xDC4A
+#define MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO                     0xDC4B
+#define MTP_OBJ_PROPERTYCODE_SOURCE                            0xDC4C
+#define MTP_OBJ_PROPERTYCODE_ORIGINLOCATION                    0xDC4D
+#define MTP_OBJ_PROPERTYCODE_DATEADDED                         0xDC4E
+#define MTP_OBJ_PROPERTYCODE_NONCONSUMABLE                     0xDC4F
+#define MTP_OBJ_PROPERTYCODE_CORRUPTUNPLAYABLE                 0xDC50
+
+#define MTP_OBJ_PROPERTYCODE_SAMPLEFORMAT                      0xDC81
+#define MTP_OBJ_PROPERTYCODE_SAMPLESIZE                                0xDC82
+#define MTP_OBJ_PROPERTYCODE_SAMPLEHEIGHT                      0xDC83
+#define MTP_OBJ_PROPERTYCODE_SAMPLEWIDTH                       0xDC84
+#define MTP_OBJ_PROPERTYCODE_SAMPLEDURATION                    0xDC85
+#define MTP_OBJ_PROPERTYCODE_SAMPLEDATA                                0xDC86
+#define MTP_OBJ_PROPERTYCODE_WIDTH                             0xDC87
+#define MTP_OBJ_PROPERTYCODE_HEIGHT                            0xDC88
+#define MTP_OBJ_PROPERTYCODE_DURATION                          0xDC89
+#define MTP_OBJ_PROPERTYCODE_USERRATING                                0xDC8A
+#define MTP_OBJ_PROPERTYCODE_TRACK                             0xDC8B
+#define MTP_OBJ_PROPERTYCODE_GENRE                             0xDC8C
+#define MTP_OBJ_PROPERTYCODE_CREDITS                           0xDC8D
+#define MTP_OBJ_PROPERTYCODE_LYRICS                            0xDC8E
+#define MTP_OBJ_PROPERTYCODE_SUBSCRIPCONTENTID                 0xDC8F
+#define MTP_OBJ_PROPERTYCODE_PRODUCEDBY                                0xDC90
+#define MTP_OBJ_PROPERTYCODE_USECOUNT                          0xDC91
+#define MTP_OBJ_PROPERTYCODE_SKIPCOUNT                         0xDC92
+#define MTP_OBJ_PROPERTYCODE_LASTACCESSED                      0xDC93
+#define MTP_OBJ_PROPERTYCODE_PARENTALRATING                    0xDC94
+#define MTP_OBJ_PROPERTYCODE_METAGENRE                         0xDC95
+#define MTP_OBJ_PROPERTYCODE_COMPOSER                          0xDC96
+#define MTP_OBJ_PROPERTYCODE_EFFECTIVERATING                   0xDC97
+#define MTP_OBJ_PROPERTYCODE_SUBTITLE                          0xDC98
+#define MTP_OBJ_PROPERTYCODE_ORIGINALRELEASEDATE               0xDC99
+#define MTP_OBJ_PROPERTYCODE_ALBUMNAME                         0xDC9A
+#define MTP_OBJ_PROPERTYCODE_ALBUMARTIST                       0xDC9B
+#define MTP_OBJ_PROPERTYCODE_MOOD                              0xDC9C
+#define MTP_OBJ_PROPERTYCODE_DRMSTATUS                         0xDC9D
+#define MTP_OBJ_PROPERTYCODE_SUBDESCRIPTION                    0xDC9E
+
+#define MTP_OBJ_PROPERTYCODE_ISCROPPED                         0xDCD1
+#define MTP_OBJ_PROPERTYCODE_ISCOLORCORRECTED                  0xDCD2
+
+#define MTP_OBJ_PROPERTYCODE_TOTALBITRATE                      0xDE91
+#define MTP_OBJ_PROPERTYCODE_BITRATETYPE                       0xDE92
+#define MTP_OBJ_PROPERTYCODE_SAMPLERATE                                0xDE93
+#define MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS                  0xDE94
+#define MTP_OBJ_PROPERTYCODE_AUDIOBITDEPTH                     0xDE95
+#define MTP_OBJ_PROPERTYCODE_SCANTYPE                          0xDE97
+#define MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC                    0xDE99
+#define MTP_OBJ_PROPERTYCODE_AUDIOBITRATE                      0xDE9A
+#define MTP_OBJ_PROPERTYCODE_VIDEOFOURCCCODEC                  0xDE9B
+#define MTP_OBJ_PROPERTYCODE_VIDEOBITRATE                      0xDE9C
+#define MTP_OBJ_PROPERTYCODE_FRAMESPER1KSECONDS                        0xDE9D
+#define MTP_OBJ_PROPERTYCODE_KEYFRAMEDISTANCE                  0xDE9E
+#define MTP_OBJ_PROPERTYCODE_BUFFERSIZE                                0xDE9F
+#define MTP_OBJ_PROPERTYCODE_ENCODINGQUALITY                   0xDEA0
+#define MTP_OBJ_PROPERTYCODE_ENCODINGPROFILE                   0xDEA1
+#define        MTP_OBJ_PROPERTYCODE_PLAYBACK_RATE                      0xDF01
+#define        MTP_OBJ_PROPERTYCODE_PLAYBACK_OBJECT                    0xDF02
+#define        MTP_OBJ_PROPERTYCODE_PLAYBACK_CONT_INDEX                0xDF03
+#define        MTP_OBJ_PROPERTYCODE_PLAYBACK_POSITION                  0xDF04
+
+/* standard format codes */
+#define  PTP_FORMATMASK_IMAGE          0x0800
+
+#define  PTP_FMT_UNDEF                 0x3000
+#define  PTP_FMT_ASSOCIATION           0x3001
+#define  PTP_FMT_SCRIPT                        0x3002
+#define  PTP_FMT_EXEC                  0x3003
+#define  PTP_FMT_TEXT                  0x3004
+#define  PTP_FMT_HTML                  0x3005
+#define  PTP_FMT_DPOF                  0x3006
+#define  PTP_FMT_AIFF                  0x3007
+#define  PTP_FMT_WAVE                  0x3008
+#define  PTP_FMT_MP3                   0x3009
+#define  PTP_FMT_AVI                   0x300A
+#define  PTP_FMT_MPEG                  0x300B
+#define  PTP_FMT_ASF                   0x300C
+
+#define  PTP_FMT_IMG_UNDEF             0x3800
+#define  PTP_FMT_IMG_EXIF              0x3801
+#define  PTP_FMT_IMG_TIFFEP            0x3802
+#define  PTP_FMT_IMG_FLASHPIX          0x3803
+#define  PTP_FMT_IMG_BMP               0x3804
+#define  PTP_FMT_IMG_CIFF              0x3805
+#define  PTP_FMT_IMG_GIF               0x3807
+#define  PTP_FMT_IMG_JFIF              0x3808
+#define  PTP_FMT_IMG_PCD               0x3809
+#define  PTP_FMT_IMG_PICT              0x380A
+#define  PTP_FMT_IMG_PNG               0x380B
+#define  PTP_FMT_IMG_TIFF              0x380D
+#define  PTP_FMT_IMG_TIFFIT            0x380E
+#define  PTP_FMT_IMG_JP2               0x380F
+#define  PTP_FMT_IMG_JPX               0x3810
+
+/* MTP-defined Object Formats */
+#define  MTP_FMT_UNDEFINED_FIRMWARE            0xB802
+#define  MTP_FMT_WINDOWS_IMG_FORMAT            0xB881
+#define  MTP_FMT_UNDEFINED_AUDIO               0xB900
+#define  MTP_FMT_WMA                           0xB901
+#define  MTP_FMT_UNDEFINED_VIDEO               0xB980
+#define  MTP_FMT_WMV                           0xB981
+#define  MTP_FMT_UNDEFINED_COLLECTION          0xBA00
+#define  MTP_FMT_ABSTRACT_MULTIMEDIA_ALBUM     0xBA01
+#define  MTP_FMT_ABSTRACT_IMG_ALBUM            0xBA02
+#define  MTP_FMT_ABSTRACT_AUDIO_ALBUM          0xBA03
+#define  MTP_FMT_ABSTRACT_VIDEO_ALBUM          0xBA04
+#define  MTP_FMT_ABSTRACT_CONTACT_GROUP                0xBA06
+#define  MTP_FMT_ABSTRACT_MESSAGE_FOLDER       0xBA07
+#define  MTP_FMT_ABSTRACT_CHAPTERED_PRODUCTION  0xBA08
+#define  MTP_FMT_UNDEFINED_DOC                 0xBA80
+#define  MTP_FMT_ABSTRACT_DOC                  0xBA81
+#define  MTP_FMT_UNDEFINED_MESSAGE             0xBB00
+#define  MTP_FMT_ABSTRACT_MESSAGE              0xBB01
+#define  MTP_FMT_UNDEFINED_CONTACT             0xBB80
+#define  MTP_FMT_ABSTRACT_CONTACT              0xBB81
+#define  MTP_FMT_VCARD2                                0xBB82
+#define  MTP_FMT_VCARD3                                0xBB83
+#define  MTP_FMT_UNDEFINED_CALENDAR_ITEM       0xBE00
+#define  MTP_FMT_ABSTRACT_CALENDAR_ITEM                0xBE01
+#define  MTP_FMT_VCALENDAR1                    0xBE02
+#define  MTP_FMT_UNDEFINED_WINDOWS_EXECUTABLE  0xBE80
+
+#define  MTP_FMT_FLAC                          0xB906
+#define         MTP_FMT_MP4                            0xB982
+#define         MTP_FMT_3GP                            0xB984
+
+/*
+ * Property description data set form flags definitions
+ */
+#define PTP_FORMFLAGS_NONE                     0x00
+#define PTP_FORMFLAGS_RANGE                    0x01
+#define PTP_FORMFLAGS_ENUM                     0x02
+
+/*
+ * power states:
+ */
+#define PTP_POWERSTATE_DEVICEOFF               0x0000
+#define PTP_POWERSTATE_SLEEP                   0x0001
+#define PTP_POWERSTATE_FULL                    0x0002
+
+/*
+ * white balances:
+ */
+#define PTP_WHITEBALANCE_UNDEFINED             0x0000
+#define PTP_WHILEBALANCE_MANUAL                        0x0001
+#define PTP_WHITEBALANCE_AUTOMATIC             0x0002
+#define PTP_WHITEBALANCE_ONEPUSHAUTO           0x0003
+#define PTP_WHITEBALANCE_DAYLIGHT              0x0004
+#define PTP_WHITEBALANCE_FLORESCENT            0x0005
+#define PTP_WHITEBALANCE_TUNGSTEN              0x0006
+#define PTP_WHITEBALANCE_FLASH                 0x0007
+
+/*
+ * focus modes:
+ */
+#define PTP_FOCUSMODE_UNDEFINED                        0x0000
+#define PTP_FOCUSMODE_MANUAL                   0x0001
+#define PTP_FOCUSMODE_AUTO                     0x0002
+#define PTP_FOCUSMODE_MACRO                    0x0003
+
+/*
+ * focus metering:
+ */
+#define  PTP_FOCUSMETERING_UNDEFINED           0x0000
+#define  PTP_FOCUSMETERING_CENTERSPOT          0x0001
+#define  PTP_FOCUSMETERING_MULTISPOT           0x0002
+
+/*
+ * flash modes:
+ */
+#define PTP_FLASHMODE_UNDEFINED                        0x0000
+#define PTP_FLASHMODE_AUTO                     0x0001
+#define PTP_FLASHMODE_OFF                      0x0002
+#define PTP_FLASHMODE_FILL                     0x0003
+#define PTP_FLASHMODE_REDEYEAUTO               0x0004
+#define PTP_FLASHMODE_REDEYEFILL               0x0005
+#define PTP_FLASHMODE_EXTERNALSYNC             0x0006
+#define PTP_FLASHMODE_MASK                     0xFFF0
+
+/*
+ * exposure modes:
+ */
+#define PTP_EXPOSUREMODE_UNDEFINED             0x0000
+#define PTP_EXPOSUREMODE_MANUALSETTING         0x0001
+#define PTP_EXPOSUREMODE_AUTOPROGRAM           0x0002
+#define PTP_EXPOSUREMODE_APERTUREPRIORITY      0x0003
+#define PTP_EXPOSUREMODE_SHUTTERPRIORITY       0x0004
+#define PTP_EXPOSUREMODE_PROGRAMCREATIVE       0x0005
+#define PTP_EXPOSUREMODE_PROGRAMACTION         0x0006
+#define PTP_EXPOSUREMODE_PORTRAIT              0x0007
+
+/*
+ * capturing modes
+ */
+#define  PTP_CAPTUREMODE_UNDEFINED             0x0000
+#define  PTP_CAPTUREMODE_NORMAL                        0x0001
+#define  PTP_CAPTUREMODE_BURST                 0x0002
+#define  PTP_CAPTUREMODE_TIMELAPSE             0x0003
+
+/*
+ * focus metering modes
+ */
+#define  PTP_FOCUSMETERMODE_UNDEFINED          0x0000
+#define  PTP_FOCUSMETERMODE_CENTERSPOT         0x0001
+#define  PTP_FOCUSMETERMODE_MULTISPOT          0x0002
+
+/*
+ * effect modes
+ */
+#define PTP_EFFECTMODE_UNDEFINED               0x0000
+#define PTP_EFFECTMODE_COLOR                   0x0001
+#define PTP_EFFECTMODE_BW                      0x0002
+#define PTP_EFFECTMODE_SEPIA                   0x0003
+
+/*
+ * storage types
+ */
+#define PTP_STORAGETYPE_UNDEFINED              0x0000
+#define PTP_STORAGETYPE_FIXEDROM               0x0001
+#define PTP_STORAGETYPE_REMOVABLEROM           0x0002
+#define PTP_STORAGETYPE_FIXEDRAM               0x0003
+#define PTP_STORAGETYPE_REMOVABLERAM           0x0004
+
+/*
+ * storage access capabilities
+ */
+#define PTP_STORAGEACCESS_RWD                  0x0000
+#define PTP_STORAGEACCESS_R                    0x0001
+#define PTP_STORAGEACCESS_RD                   0x0002
+
+/*
+ * association types:
+ */
+#define PTP_ASSOCIATIONTYPE_UNDEFINED          0x0000
+#define PTP_ASSOCIATIONTYPE_FOLDER             0x0001
+#define PTP_ASSOCIATIONTYPE_ALBUM              0x0002
+#define PTP_ASSOCIATIONTYPE_BURST              0x0003
+#define PTP_ASSOCIATIONTYPE_HPANORAMA          0x0004
+#define PTP_ASSOCIATIONTYPE_VPANORAMA          0x0005
+#define PTP_ASSOCIATIONTYPE_2DPANORAMA         0x0006
+#define PTP_ASSOCIATIONTYPE_ANCILLARYDATA      0x0007
+#define PTP_ASSOCIATIONTYPE_MASK               0xFFF0
+
+/*
+ * protection status:
+ */
+#define PTP_PROTECTIONSTATUS_NOPROTECTION              0x0000
+#define PTP_PROTECTIONSTATUS_READONLY                  0x0001
+#define MTP_PROTECTIONSTATUS_READONLY_DATA             0x8002
+#define MTP_PROTECTIONSTATUS_NONTRANSFERABLE_DATA      0x8003
+
+/* file system types */
+#define PTP_FILESYSTEMTYPE_UNDEFINED                   0x0000
+#define PTP_FILESYSTEMTYPE_FLAT                                0x0001
+#define PTP_FILESYSTEMTYPE_HIERARCHICAL                        0x0002
+#define PTP_FILESYSTEMTYPE_DCF                         0x0003
+
+/*
+ * functional modes:
+ */
+#define  PTP_FUNCTIONMODE_STANDARD                     0x0000
+#define  PTP_FUNCTIONMODE_SLEEP                                0x0001
+
+/*
+ * Get/Set
+ */
+#define  PTP_PROPGETSET_GETONLY                                0x00
+#define  PTP_PROPGETSET_GETSET                         0x01
+#define         PTP_PROPGETSET_GETSET2                         0x02
+
+/* Common Audio Sample Rate */
+#define MTP_AUDIO_SAMPLERATE_UNKNOWN                   0
+#define MTP_AUDIO_SAMPLERATE_8K                                8000
+#define MTP_AUDIO_SAMPLERATE_32K                       32000
+#define MTP_AUDIO_SAMPLERATE_CD                                44100
+#define MTP_AUDIO_SAMPLERATE_48K                       48000
+#define MTP_AUDIO_SAMPLERATE_DVD                       96000
+
+/* Common Audio Bit Rate */
+#define MTP_AUDIO_BITRATE_UNKNOWN                      0
+#define MTP_AUDIO_BITRATE_GSM                          13000
+#define MTP_AUDIO_BITRATE_16K                          16999
+#define MTP_AUDIO_BITRATE_G721                         32000
+#define MTP_AUDIO_BITRATE_G711                         64000
+#define MTP_AUDIO_BITRATE_128K                         128999
+#define MTP_AUDIO_BITRATE_CDDA                         144100
+#define MTP_AUDIO_BITRATE_160K                         160999
+#define MTP_AUDIO_BITRATE_192K                         192999
+#define MTP_AUDIO_BITRATE_256K                         256999
+#define MTP_AUDIO_BITRATE_STUDIO                       384999
+#define MTP_AUDIO_BITRATE_BLUERAY                      10000000
+
+
+/* Common Video Bit Rate */
+#define MTP_VIDEO_BITRATE_MINIMUM        1000
+#define MTP_VIDEO_BITRATE_BLUERAY        40000000
+
+/* Common Metagenre defined */
+#define MTP_METAGENRE_NOT_USED                         0x0000
+#define MTP_METAGENRE_GENERIC_MUSIC_AUDIO_FILE         0x0001
+#define MTP_METAGENRE_GENERIC_NONMUSIC_AUDIO_FILE      0x0011
+#define MTP_METAGENRE_SPOKEN_WORD_AUDIO_BOOK_FILES     0x0012
+#define MTP_METAGENRE_SPOKEN_WORD_NONAUDIO_BOOK_FILES  0x0013
+#define MTP_METAGENRE_SPOKEN_WORD_NEWS                 0x0014
+#define MTP_METAGENRE_SPOKEN_WORD_TALK_SHOWS           0x0015
+#define MTP_METAGENRE_GENERIC_VIDEO_FILE               0x0021
+#define MTP_METAGENRE_NEWS_VIDEO_FILE                  0x0022
+#define MTP_METAGENRE_MUSIC_VIDEO_FILE                 0x0023
+#define MTP_METAGENRE_HOME_VIDEO_FILE                  0x0024
+#define MTP_METAGENRE_FEATURE_FILM_VIDEO_FILE          0x0025
+#define MTP_METAGENRE_TV_SHOW_VIDEO_FILE               0x0026
+#define MTP_METAGENRE_TRAINING_VIDEO_FILE              0x0027
+#define MTP_METAGENRE_PHOTO_MONTAGE_VIDEO_FILE         0x0028
+#define MTP_METAGENRE_GENERIC_NONAUDIO_NONVIDEO_FILE   0x0030
+#define MTP_METAGENRE_AUDIO_MEDIA_CAST_FILE            0x0040
+#define MTP_METAGENRE_VIDEO_MEDIA_CAST_FILE            0x0041
+#define MTP_METAGENRE_MIXED_MEDIA_CAST_FILE            0x0042
+#define MTP_METAGENRE_VENDOR_DEFINED_MASK              0x8000
+
+/* Common NumberOfChannels defined */
+#define MTP_CHANNELS_NOT_USED                          0x0000
+#define MTP_CHANNELS_MONO                              0x0001
+#define MTP_CHANNELS_STEREO                            0x0002
+#define MTP_CHANNELS_2DOT1                             0x0003
+#define MTP_CHANNELS_3                                 0x0004
+#define MTP_CHANNELS_3DOT1                             0x0005
+#define MTP_CHANNELS_4                                 0x0006
+#define MTP_CHANNELS_4DOT1                             0x0007
+#define MTP_CHANNELS_5                                 0x0008
+#define MTP_CHANNELS_5DOT1                             0x0009
+#define MTP_CHANNELS_6                                 0x000A
+#define MTP_CHANNELS_6DOT1                             0x000B
+#define MTP_CHANNELS_7                                 0x000C
+#define MTP_CHANNELS_7DOT1                             0x000D
+#define MTP_CHANNELS_8                                 0x000E
+#define MTP_CHANNELS_8DOT1                             0x000F
+#define MTP_CHANNELS_9                                 0x0010
+#define MTP_CHANNELS_9DOT1                             0x0011
+
+/* Common ScanTypes defined */
+#define MTP_SCANTYPE_NOT_USED                          0x0000
+#define MTP_SCANTYPE_PROGESSIVE                                0x0001
+#define MTP_SCANTYPE_FIELDINTERLEAVEDUPPERFIRST                0x0002
+#define MTP_SCANTYPE_FIELDINTERLEAVEDLOWERFIRST                0x0003
+#define MTP_SCANTYPE_FIELDSINGLEUPPERFIRST             0x0004
+#define MTP_SCANTYPE_FIELDSINGLELOWERFIRST             0x0005
+#define MTP_SCANTYPE_MIXEDINTERLACE                    0x0006
+#define MTP_SCANTYPE_MIXEDINTERLACEANDPROGRESSIVE      0x0007
+
+/* Selected Audio Wave Formats */
+#define MTP_WAVEFORMAT_UNKNOWN                         0x0000
+#define MTP_WAVEFORMAT_PCM                             0x0001
+#define MTP_WAVEFORMAT_ADPCM                           0x0002
+#define MTP_WAVEFORMAT_IEEEFLOAT                       0x0003
+#define MTP_WAVEFORMAT_DTS                             0x0008
+#define MTP_WAVEFORMAT_DRM                             0x0009
+#define MTP_WAVEFORMAT_WMSP2                           0x000B
+#define MTP_WAVEFORMAT_GSM610                          0x0031
+#define MTP_WAVEFORMAT_MSNAUDIO                                0x0032
+#define MTP_WAVEFORMAT_MPEG                            0x0050
+#define MTP_WAVEFORMAT_MPEGLAYER3                      0x0055
+#define MTP_WAVEFORMAT_MSAUDIO1                                0x0160
+#define MTP_WAVEFORMAT_MSAUDIO2                                0x0161
+#define MTP_WAVEFORMAT_MSAUDIO3                                0x0162
+#define MTP_WAVEFORMAT_WMAUDIOLOSSLESS                 0x0163
+#define MTP_WAVEFORMAT_WMASPDIF                                0x0164
+#define MTP_WAVEFORMAT_AAC                             0xA106
+#define MTP_WAVEFORMAT_AMR_WB                          0xA104
+#define MTP_WAVEFORMAT_RAW_AAC1                                0x00FF
+#define MTP_WAVEFORMAT_MPEG_HEAAC                      0x1610
+
+
+/*
+ * Check Supported codec on Device
+ * Check Registered name on this site
+ * http://msdn.microsoft.com/en-us/library/aa904731.aspx
+ * Convert the name using this macro GST_MAKE_FOURCC(a, b, c, d)
+ */
+#define MTP_VIDEOFOURCC_UNKNOWN                        0
+#define MTP_VIDEOFOURCC_MP42                   0x3234504D
+#define MTP_VIDEOFOURCC_MP43                   0x3334504D
+#define MTP_VIDEOFOURCC_WMV1                   0x31564D57
+#define MTP_VIDEOFOURCC_WMV2                   0x32564D57
+#define MTP_VIDEOFOURCC_WMV3                   0x33564D57
+#define MTP_VIDEOFOURCC_DIVX                   0x58564944
+#define MTP_VIDEOFOURCC_XVID                   0x44495658
+#define MTP_VIDEOFOURCC_M4S2                   0x3253344D
+#define MTP_VIDEOFOURCC_MP4V                   0x5634504D
+#define MTP_VIDEOFOURCC_h264                   0x34363268
+#define MTP_VIDEOFOURCC_H263                   0x33363268
+#define MTP_VIDEOFOURCC_AVC1                   0x31435641
+#define MTP_VIDEOFOURCC_H264                   0x34363248
+#define MTP_VIDEOFOURCC_X264                   0x34363258
+#define MTP_VIDEOFOURCC_N264                   0x34363278
+
+/* BIT RATE */
+#define MTP_MIN_VIDEO_BITRATE                  0x0FA0
+#define MTP_MAX_VIDEO_BITRATE                  0x1312D00
+
+/* FPS */
+#define MTP_MIN_VIDEO_FPS                      0
+#define MTP_MAX_VIDEO_FPS                      0x7652
+
+#define MTP_VIDEO_HEIGHT_WIDTH_INTERVAL                0x2
+#define MTP_AUDIO_SAMPLE_RATE_INTERVAL         0x19
+
+/*
+ * USB class-specific requests
+ */
+#define USB_PTPREQUEST_TYPE_OUT                        0x21    /* Host to Device */
+#define USB_PTPREQUEST_TYPE_IN                 0xA1    /* Device to Host */
+#define USB_PTPREQUEST_CANCELIO                        0x64    /* Cancel request */
+#define USB_PTPREQUEST_GETEVENT                        0x65    /* Get extened event data */
+#define USB_PTPREQUEST_RESET                   0x66    /* Reset Device */
+#define USB_PTPREQUEST_GETSTATUS               0x67    /* Get Device Status */
+
+#define USB_PTPCANCELIO_ID                     0x4001
+#define USB_PTPREQUEST_CANCELIO_SIZE           6
+
+#define MAX_PTP_STRING_CHARS                   255
+#define MAX_PTP_TIME_STRING_CHARS              20      /* eg: 20050526T171236 */
+
+/*
+ * Enumerated type that defines the data witin the PTP array.
+ * Defines four types to be used with the PTP array.  The types include
+ * unsigned 8-bit, unsigned 16-bit, unsigned 32-bit, and pointers.
+ */
+typedef enum {
+       UINT8_TYPE,
+       UINT16_TYPE,
+       UINT32_TYPE,
+       PTR_TYPE,
+       UINT128_TYPE
+} data_type_t;
+
+/*
+ * brief A PTP array structure.
+ * The PTP array structure contains a variable length of data defined by the
+ * type field.
+ */
+typedef struct {
+       data_type_t type;
+       mtp_uint32 arr_size;
+       mtp_uint32 num_ele;
+       void *array_entry;
+} ptp_array_t;
+
+typedef struct {
+       mtp_word year;
+       mtp_word month;
+       mtp_word day_of_week;
+       mtp_word day;
+       mtp_word hour;
+       mtp_word minute;
+       mtp_word second;
+       mtp_word millisecond;
+} system_time_t;
+
+/*
+ * brief The PTP string structure.
+ * The PTP string structure contains a Unicode string (16-bit) that is limited
+ * to MAX_PTP_STRING_CHARS in length.  The default string length is defined as
+ * 255 including the NUL terminating character.
+ */
+typedef struct {
+       /* Num of chars in string including the NUL */
+       mtp_uchar num_chars;
+       /* Holds actual Unicode string with 2 bytes chars,'\0' terminated*/
+       mtp_wchar str[MAX_PTP_STRING_CHARS];
+} ptp_string_t;
+
+typedef struct {
+       /* Num of chars in string including the NUL */
+       mtp_uchar num_chars;
+       /* Holds actual Unicode string with 2 bytes chars,'\0' terminated*/
+       mtp_wchar str[MAX_PTP_TIME_STRING_CHARS];
+} ptp_time_string_t;
+
+#endif /* _PTP_DATACODES_H_ */
diff --git a/include/transport/mtp_transport.h b/include/transport/mtp_transport.h
new file mode 100755 (executable)
index 0000000..e0138c1
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_TRANSPORT_H_
+#define _MTP_TRANSPORT_H_
+
+#include "mtp_datatype.h"
+#include "mtp_util.h"
+
+/*
+ * This structure specifies the status information of Mtp.
+ */
+typedef struct {
+       mtp_int32 ctrl_event_code;
+       mtp_state_t mtp_op_state;
+       mtp_bool cancel_intialization;
+       mtp_bool is_usb_discon;
+} status_info_t;
+
+typedef void (*_cmd_handler_cb)(mtp_char *buf, mtp_int32 pkt_len);
+
+void _transport_save_cmd_buffer(mtp_char *buffer, mtp_uint32 size);
+mtp_err_t _transport_rcv_temp_file_data(mtp_byte *buffer, mtp_uint32 size,
+               mtp_uint32 *count);
+mtp_err_t _transport_rcv_temp_file_info(mtp_byte *buf, char *filepath,
+               mtp_uint64 *t_size, mtp_uint32 filepath_len);
+mtp_err_t _transport_send_event(mtp_byte *buf, mtp_uint32 size, mtp_uint32 *count);
+mtp_uint32 _transport_send_pkt_to_tx_mq(const mtp_byte *buf, mtp_uint32 pkt_len);
+mtp_uint32 _transport_send_bulk_pkt_to_tx_mq(const mtp_byte *buf,
+               mtp_uint32 pkt_len);
+void _transport_send_zlp(void);
+mtp_bool _transport_init_interfaces(_cmd_handler_cb func);
+void _transport_usb_finalize(void);
+void _transport_init_status_info(void);
+mtp_int32 _transport_get_control_event(void);
+void _transport_set_control_event(mtp_int32 event_code);
+mtp_state_t _transport_get_mtp_operation_state(void);
+void _transport_set_mtp_operation_state(mtp_state_t state);
+void _transport_set_usb_discon_state(mtp_bool is_usb_discon);
+mtp_bool _transport_get_usb_discon_state(void);
+void _transport_set_cancel_initialization(mtp_bool value);
+mtp_bool _transport_get_cancel_initialization(void);
+
+#endif /* _MTP_TRANSPORT_H_ */
diff --git a/include/transport/mtp_usb_driver.h b/include/transport/mtp_usb_driver.h
new file mode 100755 (executable)
index 0000000..cc63874
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_USB_DRIVER_H_
+#define _MTP_USB_DRIVER_H_
+
+#include "mtp_datatype.h"
+#include "mtp_msgq.h"
+
+/* Start of driver related defines */
+#define MTP_DRIVER_PATH                        "/dev/usb_mtp_gadget"
+
+/* These values come from f_mtp_slp.h of kernel source */
+#define MTP_IOCTL_LETTER               'Z'
+#define MTP_GET_HIGH_FULL_SPEED                _IOR(MTP_IOCTL_LETTER, 1, int)
+#define MTP_DISABLE                    _IO(MTP_IOCTL_LETTER, 2)
+#define MTP_CLEAR_HALT                 _IO(MTP_IOCTL_LETTER, 3)
+#define MTP_WRITE_INT_DATA             _IOW(MTP_IOCTL_LETTER, 4, char *)
+#define MTP_SET_USER_PID               _IOW(MTP_IOCTL_LETTER, 5, int)
+#define MTP_GET_SETUP_DATA             _IOR(MTP_IOCTL_LETTER, 6, char *)
+#define MTP_SET_SETUP_DATA             _IOW(MTP_IOCTL_LETTER, 7, char *)
+#define MTP_SEND_RESET_ACK             _IO(MTP_IOCTL_LETTER, 8)
+#define MTP_SET_ZLP_DATA               _IO(MTP_IOCTL_LETTER, 9)
+#define MTP_GET_MAX_PKT_SIZE           _IOR(MTP_IOCTL_LETTER, 22, void *)
+
+#define SIG_SETUP                      44
+/* End of driver related defines */
+
+typedef struct mtp_max_pkt_size {
+       mtp_uint32 tx;
+       mtp_uint32 rx;
+} mtp_max_pkt_size_t;
+
+/* Maximum repeat count for USB error recovery */
+#define MTP_USB_ERROR_MAX_RETRY                5
+
+mtp_bool _transport_init_usb_device(void);
+void _transport_deinit_usb_device(void);
+void *_transport_thread_usb_write(void *arg);
+void *_transport_thread_usb_read(void *arg);
+mtp_int32 _transport_mq_init(msgq_id_t *rx_mqid, msgq_id_t *tx_mqid);
+mtp_bool _transport_mq_deinit(msgq_id_t *rx_mqid, msgq_id_t *tx_mqid);
+mtp_uint32 _transport_get_usb_packet_len(void);
+mtp_uint32 _get_tx_pkt_size(void);
+mtp_uint32 _get_rx_pkt_size(void);
+
+#endif /* _MTP_USB_DRIVER_H_ */
diff --git a/include/util/mtp_fs.h b/include/util/mtp_fs.h
new file mode 100755 (executable)
index 0000000..3a88e55
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_FS_H_
+#define _MTP_FS_H_
+
+#include <dirent.h>
+#include "mtp_datatype.h"
+#include "mtp_config.h"
+
+#define LINUX_MAX_PATHNAME_LENGTH      4096
+#define MTP_FILE_ATTR_INVALID          0xFFFFFFFF
+#define MTP_LOG_FILE                   "/var/log/mtp.log"
+#define MTP_LOG_MAX_SIZE               5 * 1024 * 1024 /*5MB*/
+
+typedef enum {
+       MTP_FILE_TYPE = 0,
+       MTP_DIR_TYPE,
+       MTP_ALL_TYPE
+} file_type_t;
+
+typedef enum {
+       MTP_FILE_ATTR_MODE_NONE = 0x00000000,
+       MTP_FILE_ATTR_MODE_REG  = 0x00000100,
+       MTP_FILE_ATTR_MODE_DIR = 0x00000200,
+       MTP_FILE_ATTR_MODE_READ_ONLY = 0x00000400,
+       MTP_FILE_ATTR_MODE_HIDDEN = 0x00000800,
+       MTP_FILE_ATTR_MODE_SYSTEM = 0x00001000
+} file_attr_mode_t;
+
+typedef struct {
+       file_attr_mode_t attribute;
+       mtp_uint64 fsize;
+       time_t ctime;  /* created time */
+       time_t mtime;   /* modified time */
+} file_attr_t;
+
+typedef struct {
+       mtp_char filename[MTP_MAX_PATHNAME_SIZE + 1];
+       file_type_t type;
+       file_attr_t attrs;
+} dir_entry_t;
+
+typedef enum {
+       MTP_FILE_READ = 0x1,
+       MTP_FILE_WRITE = 0x2,
+       MTP_FILE_APPEND = 0x4,
+       MTP_FILE_TRUNCATE = 0x8
+} file_mode_t;
+
+typedef struct {
+       mtp_uint64 disk_size;
+       mtp_uint64 avail_size;
+       mtp_uint64 reserved_size;
+} fs_info_t;
+
+mtp_uint32 _util_file_open(const mtp_char *filename, file_mode_t mode,
+               mtp_int32 *error);
+void _util_file_read(mtp_uint32 fhandle, void *bufptr, mtp_uint32 size,
+               mtp_uint32 *read_count);
+mtp_uint32 _util_file_write(mtp_uint32 fhandle, void *bufptr, mtp_uint32 size);
+mtp_int32 _util_file_close(mtp_uint32 fhandle);
+mtp_bool _util_file_seek(mtp_uint32 fhandle, off_t offset, mtp_int32 whence);
+mtp_bool _util_file_copy(const mtp_char *origpath, const mtp_char *newpath,
+               mtp_int32 *error);
+mtp_bool _util_copy_dir_children_recursive(const mtp_char *origpath,
+               const mtp_char *newpath, mtp_int32 *error);
+mtp_bool _util_file_move(const mtp_char *origpath, const mtp_char *newpath,
+               mtp_int32 *error);
+mtp_bool _util_get_file_attrs(const mtp_char *filename, file_attr_t *attrs);
+mtp_bool _util_set_file_attrs(const mtp_char *filename, mtp_dword attrs);
+mtp_bool _util_dir_create(const mtp_char *dirname, mtp_int32 *error);
+mtp_int32 _util_remove_dir_children_recursive(const mtp_char *dirname,
+               mtp_uint32 *num_of_deleted_file, mtp_uint32 *num_of_file, mtp_bool readonly);
+mtp_bool _util_ifind_next(char *dir_name, DIR *dirp, dir_entry_t *dir_info);
+mtp_bool _util_ifind_first(char *dir_name, DIR **dirp, dir_entry_t *dir_info);
+mtp_bool _util_is_file_opened(const mtp_char *fullpath);
+mtp_bool _util_get_filesystem_info(mtp_char *storepath, fs_info_t *fs_info);
+void _util_count_num_lines(mtp_uint32 fhandle, mtp_uint32 *num_lines);
+void _util_fill_guid_array(void *guidarray, mtp_uint32 start_index, mtp_uint32 fhandle,
+               mtp_uint32 size);
+void FLOGD(const char *fmt, ...);
+
+#endif /* _MTP_FS_H_ */
diff --git a/include/util/mtp_list.h b/include/util/mtp_list.h
new file mode 100755 (executable)
index 0000000..2c50729
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_LIST_H_
+#define _MTP_LIST_H_
+
+#include "mtp_datatype.h"
+#include "mtp_util.h"
+
+typedef struct _slist_node {
+       void *value;
+       struct _slist_node *link;
+} slist_node_t;
+
+typedef struct {
+       slist_node_t *start;
+       slist_node_t *end;
+       mtp_uint32 nnodes;
+} slist_t;
+
+typedef struct {
+       slist_node_t *node_ptr;
+} slist_iterator;
+
+void _util_init_list(slist_t *l_ptr);
+mtp_bool _util_add_node(slist_t *l_ptr, void *data);
+slist_node_t *_util_delete_node(slist_t *l_ptr, void *data);
+slist_iterator *_util_init_list_iterator(slist_t *l_ptr);
+void *_util_get_list_next(slist_iterator *iter);
+slist_node_t *_util_get_first_node(slist_t *l_ptr);
+void _util_deinit_list_iterator(slist_iterator *iter);
+
+#endif /* _MTP_LIST_H_ */
diff --git a/include/util/mtp_media_info.h b/include/util/mtp_media_info.h
new file mode 100755 (executable)
index 0000000..553562e
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_MEDIA_INFO_H_
+#define _MTP_MEDIA_INFO_H_
+
+#include <glib.h>
+#include <media_content.h>
+#include "mtp_config.h"
+#include "mtp_datatype.h"
+
+#define MEDIA_PATH_COND                        "MEDIA_PATH="
+#define MEDIA_PATH_COND_LEN            13      /* MEDIA_PATH="" */
+#define MEDIA_PATH_COND_OR             " OR "
+#define MEDIA_PATH_COND_OR_LEN         4
+#define MEDIA_PATH_COND_MAX_LEN                MEDIA_PATH_COND_LEN + MTP_MAX_PATHNAME_SIZE
+
+#define MTP_PAL_SAFE_FREE(src) { g_free(src); src = NULL; }
+
+/*
+ * struct MtpCommonMetadata
+ * This structure contains common metadata fields between
+ * video and audio files.
+ */
+typedef struct {
+       mtp_char *artist;               /* A pointer to Artist */
+       mtp_char *album;                /* A pointer to Album name. */
+       mtp_char *genre;                /* A pointer to Genre */
+       mtp_char *author;               /* A pointer to Author name */
+       mtp_char *copyright;            /* A pointer to Copyright info */
+       mtp_char *year;                 /* A pointer to release year */
+       mtp_char *description;          /* A pointer to description */
+       mtp_int32 duration;             /* Duration of the track */
+       mtp_int32 audio_bitrate;        /* Audio bitrate */
+       mtp_int32 sample_rate;
+       mtp_int32 num_channel;
+       mtp_int32 audio_codec;
+       mtp_int32 rating;
+} common_meta_t;
+
+typedef struct {
+       mtp_int32 video_fps;
+       mtp_int32 video_br;
+       mtp_int32 video_h;
+       mtp_int32 video_w;
+       mtp_char *track;
+} video_meta_t;
+
+typedef struct {
+       mtp_int32 track;
+} audio_meta_t;
+
+typedef struct {
+       mtp_int32 ht;
+       mtp_int32 wt;
+} image_meta_t;
+
+typedef struct {
+       common_meta_t commonmeta;
+       audio_meta_t audiometa;
+} comp_audio_meta_t;
+
+typedef struct {
+       common_meta_t commonmeta;
+       video_meta_t videometa;
+} comp_video_meta_t;
+
+typedef struct {
+       void *data;
+       mtp_int32 count;
+       guint tid;
+       pthread_mutex_t *lock;
+} timeout_data_t;
+
+mtp_bool _util_get_audio_metadata(const mtp_char *filepath,
+               comp_audio_meta_t *audio_data);
+mtp_bool _util_get_video_metadata(mtp_char *filepath,
+               comp_video_meta_t *video_data);
+mtp_bool _util_get_image_ht_wt(const mtp_char *filepath, image_meta_t *image_data);
+mtp_bool _util_get_audio_meta_from_extractor(const mtp_char *filepath,
+               comp_audio_meta_t *audio_data);
+mtp_bool _util_get_video_meta_from_extractor(const mtp_char *filepath,
+               comp_video_meta_t *video_data);
+void _util_flush_db(void);
+void _util_delete_file_from_db(const mtp_char *filepath);
+void _util_add_file_to_db(const mtp_char *filepath);
+void _util_scan_folder_contents_in_db(const mtp_char *filepath);
+void _util_free_common_meta(common_meta_t *metadata);
+void _util_free_video_meta(video_meta_t *video);
+void _util_free_image_meta(image_meta_t *image);
+
+#endif /* _MTP_MEDIA_INFO_H_ */
diff --git a/include/util/mtp_msgq.h b/include/util/mtp_msgq.h
new file mode 100755 (executable)
index 0000000..c6726c2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_MSGQ_H_
+#define _MTP_MSGQ_H_
+
+#include "mtp_datatype.h"
+#include "mtp_util.h"
+
+typedef mtp_int32 msgq_id_t;
+
+typedef struct {
+       msg_type_t mtype;
+       mtp_uint32 length;
+       mtp_uint32 signal;
+       unsigned char *buffer;
+} msgq_ptr_t;
+
+mtp_bool _util_msgq_init(msgq_id_t *mq_id, mtp_uint32 flags);
+mtp_bool _util_msgq_send(msgq_id_t mq_id, void *buf, mtp_uint32 size,
+               mtp_uint32 flags);
+mtp_bool _util_msgq_receive(msgq_id_t mq_id, void *buf, mtp_uint32 size,
+               mtp_uint32 flags, mtp_int32 *nbytes);
+mtp_bool _util_msgq_deinit(msgq_id_t *msgq_id);
+mtp_bool _util_msgq_set_size(msgq_id_t mq_id, mtp_uint32 nbytes);
+mtp_bool _util_rcv_msg_from_mq(msgq_id_t mq_id, unsigned char **pkt,
+               mtp_uint32 *pkt_len, msg_type_t *mtype);
+
+#endif/*_MTP_MSGQ_H_*/
diff --git a/include/util/mtp_support.h b/include/util/mtp_support.h
new file mode 100755 (executable)
index 0000000..b0cc9c4
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_SUPPORT_H_
+#define        _MTP_SUPPORT_H_
+
+#include "mtp_datatype.h"
+#include "mtp_config.h"
+
+typedef struct {
+       mtp_char *extn;
+       mtp_uint16 fmt_code;
+} fmt_code_t;
+
+/*
+ * Convert byte order for big endian architecture
+ */
+void _util_conv_byte_order(void *data, mtp_int32 size);
+
+/*
+ * Convert byte order for WCHAR string
+ */
+void _util_conv_byte_order_wstring(mtp_uint16 *wstr, mtp_int32 size);
+void _util_conv_byte_order_gen_str(void *str, mtp_int32 size, mtp_int32 elem_sz);
+void _util_wchar_cpy(mtp_wchar *dest, const mtp_wchar *src);
+void _util_wchar_ncpy(mtp_wchar *dest, const mtp_wchar *src, unsigned long n);
+size_t _util_wchar_len(const mtp_wchar *s);
+mtp_wchar *mtp_wcscat_charstr(mtp_wchar *str1, const mtp_char *char_str);
+mtp_err_t _util_wchar_swprintf(mtp_wchar *mtp_wstr, mtp_int32 size,
+               mtp_char *format, ...);
+mtp_int32 _util_utf16_to_utf8(char *dest, mtp_int32 size, const mtp_wchar *src);
+mtp_int32 _util_utf8_to_utf16(mtp_wchar *dest, mtp_int32 no_of_item, const char *src);
+mtp_uint16 _util_get_fmtcode(const mtp_char *extn);
+mtp_bool _util_get_file_extn(const mtp_char *f_name, mtp_char *f_extn);
+mtp_bool _util_get_file_name(const mtp_char *fullpath, mtp_char *f_name);
+mtp_bool _util_get_file_name_wo_extn(const mtp_char *fullpath, mtp_char *f_name);
+mtp_bool _util_is_path_len_valid(const mtp_char *path);
+mtp_bool _util_create_path(mtp_char *path, mtp_uint32 size, const mtp_char *dir,
+               const mtp_char *filename);
+void _util_get_parent_path(const mtp_char *fullpath, mtp_char *p_path);
+void _util_conv_wstr_to_guid(mtp_wchar *wstr, mtp_uint64 *guid);
+mtp_bool _util_get_unique_dir_path(const mtp_char *exist_path, mtp_char *new_path,
+               mtp_uint32 new_path_buf_len);
+
+#endif /* _MTP_SUPPORT_H_ */
diff --git a/include/util/mtp_thread.h b/include/util/mtp_thread.h
new file mode 100755 (executable)
index 0000000..41c4cfe
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_THREAD_H_
+#define _MTP_THREAD_H_
+
+#include <pthread.h>
+#include "mtp_datatype.h"
+#include "mtp_util.h"
+
+typedef void *(*thread_func_t) (void *pArg);
+
+#define UTIL_LOCK_MUTEX(mut)\
+       do {\
+               int lock_ret = 0;\
+               DBG("Thread [%d] trying to lock the Mutex \n", syscall(__NR_gettid));\
+               lock_ret = pthread_mutex_lock(mut);\
+               if(lock_ret != 0) {\
+                       if(lock_ret == EDEADLK) {\
+                               DBG("Mutex is already locked by the same thread");\
+                       } else {\
+                               ERR("Error locking mutex. Error = %d \n", lock_ret);\
+                       }\
+               } else {\
+                       DBG("Mutex locked by thread [%d] \n", syscall(__NR_gettid));\
+               }\
+       } while (0);\
+
+
+#define UTIL_UNLOCK_MUTEX(mut)\
+       do {\
+               int unlock_ret = 0;\
+               unlock_ret = pthread_mutex_unlock(mut);\
+               if (unlock_ret != 0) {\
+                       ERR("Error unlocking mutex. Error = %d \n", unlock_ret);\
+               } else {\
+                       DBG("Mutex unlocked by thread [%d] \n", syscall(__NR_gettid));\
+               }\
+       } while (0);\
+
+mtp_bool _util_thread_create(pthread_t *tid, const mtp_char *tname,
+               mtp_int32 thread_state, thread_func_t thread_func, void *arg);
+mtp_bool _util_thread_join(pthread_t tid, void **data);
+mtp_bool _util_thread_cancel(pthread_t tid);
+void _util_thread_exit(void *val_ptr);
+
+#endif /*_MTP_THREAD_H_*/
diff --git a/include/util/mtp_util.h b/include/util/mtp_util.h
new file mode 100755 (executable)
index 0000000..22a39fb
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 _MTP_UTIL_H_
+#define _MTP_UTIL_H_
+
+#include <errno.h>
+#include "mtp_config.h"
+#include "mtp_datatype.h"
+
+#ifndef LOG_TAG
+#define LOG_TAG "MTP-RESPONDER"
+#endif /* LOG_TAG */
+#include <dlog.h>
+
+#define FIND_CMD_LEN                           300
+#define FIND_CMD       "/usr/bin/find %s \\( -iname '*.jpg' -o -iname '*.gif' " \
+       "-o -iname '*.exif' -o -iname '*.png' " \
+       "-o -iname '*.mpeg' -o -iname '*.asf' " \
+       "-o -iname '*.wmv' -o -iname '*.avi' -o -iname '*.wma' " \
+       "-o -iname '*.mp3' \\) -mmin -%d >> %s"
+
+#define VCONFKEY_MTP_PREFIX                    "db/private/mtp"
+#define VCONFKEY_MTP_SERIAL_NUMBER_STR VCONFKEY_MTP_PREFIX"/serial_number"
+#define VCONFKEY_MTP_SYNC_PARTNER_STR  VCONFKEY_MTP_PREFIX"/sync_partner"
+#define VCONFKEY_MTP_SYNC_TIME_INT             VCONFKEY_MTP_PREFIX"/sync_time"
+
+#define DBG(format, args...) SLOGD(format, ##args)
+#define ERR(format, args...) SLOGE(format, ##args)
+#define DBG_SECURE(format, args...) SECURE_SLOGD(format, ##args)
+#define ERR_SECURE(format, args...) SECURE_SLOGE(format, ##args)
+
+#define ret_if(expr) \
+       do { \
+               if (expr) { \
+                       ERR("(%s)", #expr); \
+                       return; \
+               } \
+       } while (0)
+
+#define retv_if(expr, val) \
+       do { \
+               if (expr) { \
+                       ERR("(%s)", #expr); \
+                       return (val); \
+               } \
+       } while (0)
+
+#define retm_if(expr, fmt, arg...) \
+       do { \
+               if (expr) { \
+                       ERR(fmt, ##arg); \
+                       return; \
+               } \
+       } while (0)
+
+#define retvm_if(expr, val, fmt, arg...) \
+       do { \
+               if (expr) { \
+                       ERR(fmt, ##arg); \
+                       return (val); \
+               } \
+       } while (0)
+
+typedef enum {
+       MTP_PHONE_USB_CONNECTED = 0,
+       MTP_PHONE_USB_DISCONNECTED,
+       MTP_PHONE_MMC_INSERTED,
+       MTP_PHONE_MMC_NONE,
+       MTP_PHONE_USB_MODE_OTHER,
+} phone_status_t;
+
+typedef struct {
+       phone_status_t mmc_state;
+       phone_status_t usb_state;
+       phone_status_t usb_mode_state;
+       phone_status_t lock_state;
+} phone_state_t;
+
+typedef enum {
+       MTP_DATA_PACKET = 1,
+       MTP_BULK_PACKET,
+       MTP_EVENT_PACKET,
+       MTP_ZLP_PACKET,
+       MTP_UNDEFINED_PACKET
+} msg_type_t;
+
+typedef enum {
+       MTP_STATE_STOPPED = 0,          /* stopped working */
+       MTP_STATE_INITIALIZING,         /* initializing device or enumerating*/
+       MTP_STATE_READY_SERVICE,        /* ready to handle commands */
+       MTP_STATE_ONSERVICE,            /* handling a command */
+       MTP_STATE_DATA_TRANSFER_DL,     /* file downloading */
+       MTP_STATE_DATA_PROCESSING       /* data processing */
+} mtp_state_t;
+
+/*
+ * PTP Cancellation Request
+ * mtp_uint16 io_code : Identifier for cancellation.
+ *     This must equal USB_PTPCANCELIO_ID.
+ * mtp_uint32 tid : Transaction to cancel.
+ */
+typedef struct {
+       mtp_uint16 io_code;
+       mtp_uint32 tid;
+} cancel_req_t;
+
+/*
+ * PTP Status Request
+ * mtp_uint16 len : Total length of the status data.
+ * mtp_uint16 code : Response code
+ * mtp_uint32 params : Params depends on the status code.
+ */
+typedef struct {
+       mtp_uint16 len;
+       mtp_uint16 code;
+       mtp_uint32 params[1];
+} usb_status_req_t;
+
+void _util_print_error();
+mtp_int32 _util_get_battery_level(void);
+mtp_bool _util_get_serial(mtp_char *serial, mtp_uint32 len);
+void _util_get_model_name(mtp_char *model_name, mtp_uint32 len);
+void _util_get_vendor_ext_desc(mtp_char *vendor_ext_desc, mtp_uint32 len);
+void _util_get_device_version(mtp_char *device_version, mtp_uint32 len);
+void _util_gen_alt_serial(mtp_char *serial, mtp_uint32 len);
+void _util_get_usb_status(phone_status_t *val);
+phone_status_t _util_get_local_usb_status(void);
+void _util_set_local_usb_status(const phone_status_t val);
+void _util_get_mmc_status(phone_status_t *val);
+phone_status_t _util_get_local_mmc_status(void);
+void _util_set_local_mmc_status(const phone_status_t val);
+void _util_get_usbmode_status(phone_status_t *val);
+phone_status_t _util_get_local_usbmode_status(void);
+void _util_set_local_usbmode_status(const phone_status_t val);
+
+#endif /* _MTP_UTIL_H_ */
diff --git a/mtp-responder.conf b/mtp-responder.conf
new file mode 100755 (executable)
index 0000000..a31d87c
--- /dev/null
@@ -0,0 +1,61 @@
+### MTP features
+#Nothing yet
+### MTP features (End)
+
+
+### Debug
+#
+# You can fix destination or source file path for SendObject or GetObject MTP commands when fake_copy is 1.
+# Default is 0(Not use).
+fake_copy=0
+# If you want to read data from USB without writing to file system, specify "write_to=null".
+# Available value : null or /dev/null
+write_to=null
+# If you want to write arbitrary data to USB without reading from file system, specify "read_from=null".
+# Available value : null or /dev/zero
+read_from=null
+### Debug (End)
+
+
+### Speed related config
+#
+# Max. 512KB. If requested memory is lesser than this, malloc is used. Otherwise, mmap is used
+mmap_threshold=524288
+
+read_usb_size=4096
+write_usb_size=4096
+
+# Init. IPC size between USB and File threads (< mmap_threshold and =< max_ipc_size)
+init_rx_ipc_size=32768
+init_tx_ipc_size=262144
+
+# Max. IPC size between USB and File threads (< mmap_threshold)
+max_rx_ipc_size=32768
+max_tx_ipc_size=262144
+
+# Max. Heap memory size for buffer between USb and File threads
+max_io_buf_size=10485760
+
+read_file_delay=0
+
+### Experimental
+#
+# I/O thread priority handling
+#support_pthread_sched=0
+
+# i : Inherit, e : Explicit
+#inheritsched=i
+
+# f : FIFO, r : Round Robin, o : Other
+#schedpolicy=o
+
+# File I/O thread's priority for scheduling
+#file_schedparam=0
+
+# USB I/O thread's priority for scheduling
+#usb_schedparam=0
+# I/O thread priority handling (End)
+
+#
+### Experimental (End)
+### Speed related config (End)
diff --git a/mtp-responder.service b/mtp-responder.service
new file mode 100755 (executable)
index 0000000..223075d
--- /dev/null
@@ -0,0 +1,10 @@
+[Unit]
+Description=MTP responder
+
+[Service]
+User=system
+Group=system
+SmackProcessLabel=mtp-responder
+Type=simple
+ExecStart=/usr/bin/mtp-responder
+KillMode=process
diff --git a/packaging/mtp-responder.manifest b/packaging/mtp-responder.manifest
new file mode 100755 (executable)
index 0000000..8d20faf
--- /dev/null
@@ -0,0 +1,27 @@
+<manifest>
+       <define>
+               <domain name="mtp-responder"/>
+               <request>
+                       <smack request="media-server" type="rwx"/>
+                       <smack request="sound-server" type="rwx"/>
+                       <smack request="device::mtp" type="rw"/>
+                       <smack request="device::sys_logging" type="w"/>
+                       <smack request="device::app_logging" type="w"/>
+                       <smack request="system::media" type="rwxat"/>
+                       <smack request="system::homedir" type="rwxat"/>
+                       <smack request="system::share" type="rwxat"/>
+                       <smack request="system::ext_storage" type="rl"/>
+                       <smack request="tizen::vconf::public::r" type="rl"/>
+                       <smack request="tizen::vconf::platform::rw" type="rw"/>
+                       <smack request="tizen::vconf::public::r::platform::rw" type="rl"/>
+                       <smack request="tizen::vconf::setting::admin" type="rl"/>
+                       <smack request="telephony_framework::api_modem" type="rl"/>
+               </request>
+               <permit>
+                       <smack permit="media-server" type="rw"/>
+               </permit>
+       </define>
+       <assign>
+               <filesystem path="/usr/bin/mtp-responder" exec_label="none"/>
+       </assign>
+</manifest>
diff --git a/packaging/mtp-responder.spec b/packaging/mtp-responder.spec
new file mode 100755 (executable)
index 0000000..0f62d7e
--- /dev/null
@@ -0,0 +1,61 @@
+ExclusiveArch: %arm aarch64
+%if "%{?tizen_profile_name}" == "tv"
+ExcludeArch: %arm aarch64
+%endif
+
+Name:       mtp-responder
+Summary:    Media Transfer Protocol daemon (responder)
+Version:    0.0.2
+Release:    1
+Group:      Network & Connectivity/Other
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+Source1001:    %{name}.manifest
+BuildRequires: cmake
+BuildRequires: libgcrypt-devel
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(tapi)
+BuildRequires: pkgconfig(libprivilege-control)
+BuildRequires: pkgconfig(capi-content-media-content)
+BuildRequires: pkgconfig(capi-media-metadata-extractor)
+BuildRequires: pkgconfig(capi-system-info)
+Requires(post): /usr/bin/vconftool
+
+
+%description
+This package includes a daemon which processes Media Transper Protocol(MTP) commands as MTP responder role.
+
+
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+
+%build
+%cmake .
+
+make %{?jobs:-j%jobs}
+
+
+%install
+%make_install
+
+install -D -m 0644 mtp-responder.service %{buildroot}%{_libdir}/systemd/system/mtp-responder.service
+
+%post
+/usr/bin/vconftool set -t string db/private/mtp/serial_number "" -u 5000 -g 5000 -i -f -s tizen::vconf::platform::rw
+/usr/bin/vconftool set -t string db/private/mtp/sync_partner "" -u 5000 -g 5000 -i -f -s tizen::vconf::platform::rw
+/usr/bin/vconftool set -t int db/private/mtp/sync_time 0 -u 5000 -g 5000 -i -f -s tizen::vconf::platform::rw
+
+mkdir -p %{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/
+ln -sf %{_libdir}/systemd/system/mtp-responder.service %{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/
+
+%files
+%manifest mtp-responder.manifest
+%defattr(-,system,system,-)
+%{_bindir}/mtp-responder
+%{_libdir}/systemd/system/mtp-responder.service
+/opt/var/lib/misc/mtp-responder.conf
+#%license LICENSE.APLv2
diff --git a/src/entity/mtp_device.c b/src/entity/mtp_device.c
new file mode 100755 (executable)
index 0000000..dad5fcb
--- /dev/null
@@ -0,0 +1,1107 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <unistd.h>
+#include <glib.h>
+#include "mtp_support.h"
+#include "mtp_util.h"
+#include "ptp_datacodes.h"
+#include "mtp_device.h"
+#include "mtp_transport.h"
+#include "ptp_container.h"
+
+#define MTP_DEVICE_VERSION_CHAR                "V1.0"
+
+/*
+ * GLOBAL AND EXTERN VARIABLES
+ */
+static mtp_device_t g_device = { 0 };
+
+/*
+ * STATIC VARIABLES
+ */
+static device_prop_desc_t g_device_props[NUM_DEVICE_PROPERTIES];
+static mtp_store_t g_store_list[MAX_NUM_DEVICE_STORES];
+static mtp_uint16 g_device_props_supported[NUM_DEVICE_PROPERTIES];
+
+static mtp_uint16 g_ops_supported[] = {
+       PTP_OPCODE_GETDEVICEINFO,
+       PTP_OPCODE_OPENSESSION,
+       PTP_OPCODE_CLOSESESSION,
+       PTP_OPCODE_GETSTORAGEIDS,
+       PTP_OPCODE_GETSTORAGEINFO,
+       PTP_OPCODE_GETNUMOBJECTS,
+       PTP_OPCODE_GETOBJECTHANDLES,
+       PTP_OPCODE_GETOBJECTINFO,
+       PTP_OPCODE_GETOBJECT,
+       PTP_OPCODE_DELETEOBJECT,
+       PTP_OPCODE_SENDOBJECTINFO,
+       PTP_OPCODE_SENDOBJECT,
+       PTP_OPCODE_FORMATSTORE,
+       PTP_OPCODE_GETDEVICEPROPDESC,
+       PTP_OPCODE_GETDEVICEPROPVALUE,
+       PTP_OPCODE_SETDEVICEPROPVALUE,
+       PTP_OPCODE_GETPARTIALOBJECT,
+       MTP_OPCODE_GETOBJECTREFERENCES,
+       MTP_OPCODE_SETOBJECTREFERENCES,
+       MTP_OPCODE_GETOBJECTPROPDESC,
+       MTP_OPCODE_GETOBJECTPROPSUPPORTED,
+       MTP_OPCODE_GETOBJECTPROPVALUE,
+       MTP_OPCODE_SETOBJECTPROPVALUE,
+       MTP_OPCODE_GETOBJECTPROPLIST,
+       MTP_OPCODE_SETOBJECTPROPLIST,
+#ifndef PMP_VER
+       /*PTP_OPCODE_RESETDEVICE,*/
+       PTP_OPCODE_SELFTEST,
+#ifdef MTP_SUPPORT_SET_PROTECTION
+       PTP_OPCODE_SETOBJECTPROTECTION,
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+       /*PTP_OPCODE_POWERDOWN,*/
+       PTP_OPCODE_RESETDEVICEPROPVALUE,
+       PTP_OPCODE_MOVEOBJECT,
+       PTP_OPCODE_COPYOBJECT,
+#ifdef MTP_SUPPORT_INTERDEPENDENTPROP
+       MTP_OPCODE_GETINTERDEPPROPDESC,
+#endif /*MTP_SUPPORT_INTERDEPENDENTPROP*/
+       MTP_OPCODE_SENDOBJECTPROPLIST,
+       /*PTP_CODE_VENDOR_OP1,*/
+#endif /*PMP_VER*/
+       MTP_OPCODE_WMP_REPORTACQUIREDCONTENT,
+};
+
+static mtp_uint16 g_event_supported[] = {
+       /*PTP_EVENTCODE_CANCELTRANSACTION,*/
+       PTP_EVENTCODE_OBJECTADDED,
+       PTP_EVENTCODE_OBJECTREMOVED,
+       PTP_EVENTCODE_STOREADDED,
+       PTP_EVENTCODE_STOREREMOVED,
+       /* PTP_EVENTCODE_DEVICEPROPCHANGED,
+          PTP_EVENTCODE_OBJECTINFOCHANGED,
+          PTP_EVENTCODE_DEVICEINFOCHANGED,
+          PTP_EVENTCODE_REQUESTOBJECTTRANSFER,
+          PTP_EVENTCODE_STOREFULL,
+          PTP_EVENTCODE_DEVICERESET,
+          PTP_EVENTCODE_STORAGEINFOCHANGED,
+          PTP_EVENTCODE_CAPTURECOMPLETE,
+          PTP_EVENTCODE_UNREPORTEDSTATUS,
+          PTP_EVENTCODE_VENDOREXTENTION1,
+          PTP_EVENTCODE_VENDOREXTENTION2 */
+};
+
+static mtp_uint16 g_capture_fmts[] = {
+       /* PTP_FORMATCODE_IMAGE_EXIF */
+       0
+};
+
+static mtp_uint16 g_object_fmts[] = {
+       MTP_FMT_3GP,
+       MTP_FMT_MP4,
+       PTP_FMT_MP3,
+       MTP_FMT_WMA,
+       MTP_FMT_WMV,
+       PTP_FMT_IMG_EXIF,
+       PTP_FMT_ASSOCIATION,
+       MTP_FMT_FLAC,
+       PTP_FMT_UNDEF,
+#ifndef PMP_VER
+       PTP_FMT_IMG_GIF,
+       PTP_FMT_IMG_BMP,
+       /* PTP_FORMATCODE_IMAGE_JFIF, */
+       PTP_FMT_IMG_PNG,
+       PTP_FMT_WAVE,
+       PTP_FMT_AVI,
+       PTP_FMT_MPEG,
+       PTP_FMT_ASF,
+       /* MTP_FORMATCODE_WINDOWS_IMAGE_FORMAT,
+          MTP_FORMATCODE_UNDEFINED_AUDIO,
+          MTP_FORMATCODE_UNDEFINED_VIDEO,
+          MTP_FORMATCODE_UNDEFINED_COLLECTION,
+          MTP_FORMATCODE_ABSTRACT_MULTIMEDIA_ALBUM,
+          MTP_FORMATCODE_ABSTRACT_IMAGE_ALBUM,
+          MTP_FORMATCODE_ABSTRACT_VIDEO_ALBUM,
+          MTP_FORMATCODE_ABSTRACT_CONTACT_GROUP,
+          MTP_FORMATCODE_UNDEFINED_DOCUMENT,
+          MTP_FORMATCODE_ABSTRACT_DOCUMENT,
+          MTP_FORMATCODE_UNDEFINED_MESSAGE,
+          MTP_FORMATCODE_ABSTRACT_MESSAGE,
+          MTP_FORMATCODE_UNDEFINED_CALENDAR_ITEM,
+          MTP_FORMATCODE_ABSTRACT_CALENDAR_ITEM,
+          MTP_FORMATCODE_VCALENDAR1,
+          MTP_FORMATCODE_UNDEFINED_WINDOWS_EXECUTABLE,*/
+#endif /*PMP_VER*/
+       MTP_FMT_ABSTRACT_AUDIO_ALBUM,
+       /* MTP_FORMATCODE_UNDEFINED_FIRMWARE */
+};
+
+/*
+ * STATIC FUNCTIONS
+ */
+static void __init_device_info(void);
+static mtp_bool __init_device_props(void);
+static mtp_err_t __clear_store_data(mtp_uint32 store_id);
+static mtp_bool __remove_store_from_device(store_type_t store_type);
+static mtp_bool __add_store_to_device(store_type_t store_type);
+
+/*
+ * FUNCTIONS
+ */
+
+/*
+ * static void __device_init_device_info()
+ * This function initializes MTP device information
+ *@return      none
+ */
+static void __init_device_info(void)
+{
+       mtp_int32 ii;
+       device_info_t *info = &(g_device.device_info);
+       mtp_char model_name[MTP_MODEL_NAME_LEN_MAX + 1] = { 0 };
+       mtp_char device_version[MAX_PTP_STRING_CHARS + 1] = { 0 };
+       mtp_char vendor_ext_desc[MAX_PTP_STRING_CHARS + 1] = { 0 };
+       mtp_char serial_no[MTP_SERIAL_LEN_MAX + 1] = { 0 };
+       mtp_wchar wtemp[MAX_PTP_STRING_CHARS + 1] = { 0 };
+
+       info->ops_supported = g_ops_supported;
+       info->events_supported = g_event_supported;
+       info->capture_fmts = g_capture_fmts;
+       info->object_fmts = g_object_fmts;
+       info->device_prop_supported = g_device_props_supported;
+       info->std_version = MTP_STANDARD_VERSION;
+       info->vendor_extn_id = MTP_VENDOR_EXTN_ID;
+       info->vendor_extn_version = MTP_VENDOR_EXTN_VERSION;
+       info->functional_mode = PTP_FUNCTIONMODE_SLEEP;
+
+       _prop_init_ptpstring(&(info->vendor_extn_desc));
+       _util_get_vendor_ext_desc(vendor_ext_desc, sizeof(vendor_ext_desc));
+       _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, vendor_ext_desc);
+       _prop_copy_char_to_ptpstring(&(info->vendor_extn_desc), wtemp, WCHAR_TYPE);
+
+       for (ii = 0; ii < NUM_DEVICE_PROPERTIES; ii++) {
+               info->device_prop_supported[ii] =
+                       g_device.device_prop_list[ii].propinfo.prop_code;
+       }
+
+       _prop_init_ptpstring(&(info->manufacturer));
+       _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, MTP_MANUFACTURER_CHAR);
+       _prop_copy_char_to_ptpstring(&(info->manufacturer), wtemp, WCHAR_TYPE);
+
+       _prop_init_ptpstring(&(info->model));
+       _util_get_model_name(model_name, sizeof(model_name));
+       _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, model_name);
+       _prop_copy_char_to_ptpstring(&(info->model), wtemp, WCHAR_TYPE);
+
+       _prop_init_ptpstring(&(info->device_version));
+       _util_get_device_version(device_version, sizeof(device_version));
+       _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, device_version);
+       _prop_copy_char_to_ptpstring(&(info->device_version), wtemp, WCHAR_TYPE);
+
+       _prop_init_ptpstring(&(info->serial_no));
+       if (FALSE == _util_get_serial(serial_no, sizeof(serial_no))) {
+               ERR("_util_get_serial() Fail");
+               _util_gen_alt_serial(serial_no, sizeof(serial_no));
+       }
+       _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ, serial_no);
+       _prop_copy_char_to_ptpstring(&(info->serial_no), wtemp, WCHAR_TYPE);
+
+       return;
+}
+
+/*
+ * static mtp_bool __device_init_device_props()
+ * this function will initialise all the properties of the device.
+ * @return     TRUE if success, otherwise FALSE.
+ */
+static mtp_bool __init_device_props()
+{
+       static mtp_bool already_init = FALSE;
+
+       device_prop_desc_t *dev_prop = NULL;
+       mtp_uint16 i = 0;
+       ptp_string_t tmp = { 0 };
+       mtp_uint32 default_val;
+
+       if (TRUE == already_init) {
+               ERR("Already initialized. just return...");
+               return TRUE;
+       }
+
+       g_device.device_prop_list = g_device_props;
+#ifdef MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL
+       /*
+        * Battery level from 0 to 100, with step of 10,
+        * won't change after a reset
+        */
+       dev_prop = &(g_device.device_prop_list[i]);
+       _prop_init_device_property_desc(dev_prop, PTP_PROPERTYCODE_BATTERYLEVEL,
+                       PTP_DATATYPE_UINT8, PTP_PROPGETSET_GETONLY, RANGE_FORM);
+       {
+               mtp_int32 batt_level = 0;
+
+               batt_level = _util_get_battery_level();
+               _prop_set_range_integer(&(dev_prop->propinfo), 0, 100, 5);
+               _prop_set_current_integer(dev_prop, batt_level);
+               default_val = 100;
+               _prop_set_default_integer(&(dev_prop->propinfo),
+                               (mtp_uchar *)&default_val);
+       }
+       i++;
+#endif /*MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL*/
+
+       /* Synchronization Partner */
+       dev_prop = &(g_device.device_prop_list[i]);
+       _prop_init_device_property_desc(dev_prop,
+                       MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER,
+                       PTP_DATATYPE_STRING, PTP_PROPGETSET_GETSET, NONE);
+#ifdef MTP_USE_INFORMATION_REGISTRY
+       {
+               mtp_char *sync_ptr = NULL;
+               mtp_wchar wtemp[MTP_MAX_REG_STRING + 1] = { 0 };
+               mtp_wchar wpartner[MTP_MAX_REG_STRING + 1] = { 0 };
+
+               sync_ptr = _device_get_sync_partner();
+               if (sync_ptr == NULL) {
+                       _util_utf8_to_utf16(wtemp, sizeof(wpartner) / WCHAR_SIZ,
+                                       MTP_DEV_PROPERTY_SYNCPARTNER);
+               } else {
+                       _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ,
+                                       sync_ptr);
+               }
+
+               _util_utf8_to_utf16(wpartner, sizeof(wpartner) / WCHAR_SIZ,
+                               MTP_DEV_PROPERTY_SYNCPARTNER);
+               _prop_copy_char_to_ptpstring(&tmp, wtemp, WCHAR_TYPE);
+               _prop_set_current_string(dev_prop, &tmp);
+               _prop_set_default_string(&(dev_prop->propinfo), wpartner);
+               g_free(sync_ptr);
+       }
+#else/*MTP_USE_INFORMATION_REGISTRY*/
+       {
+               mtp_wchar wtemp[MTP_MAX_REG_STRING + 1] = { 0 };
+
+               _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ,
+                               MTP_DEV_PROPERTY_SYNCPARTNER);
+               _prop_copy_char_to_ptpstring(&tmp, wtemp, WCHAR_TYPE);
+               _prop_set_current_string(dev_prop, &tmp);
+               _prop_set_default_string(&(dev_prop->propinfo), wtemp);
+       }
+#endif/*MTP_USE_INFORMATION_REGISTRY*/
+       i++;
+
+       /* Device Friendly Name */
+       dev_prop = &(g_device.device_prop_list[i]);
+       _prop_init_device_property_desc(dev_prop, MTP_PROPERTYCODE_DEVICEFRIENDLYNAME,
+                       PTP_DATATYPE_STRING, PTP_PROPGETSET_GETONLY, NONE);
+#ifdef MTP_USE_INFORMATION_REGISTRY
+       {
+               mtp_char *dev_ptr = NULL;
+               mtp_wchar wmodel[MTP_MAX_REG_STRING + 1] = { 0 };
+
+               dev_ptr = _device_get_device_name();
+               if (dev_ptr == NULL) {
+                       ERR("_device_get_device_name() Fail");
+                       _util_utf8_to_utf16(wmodel, sizeof(wmodel) / WCHAR_SIZ,
+                                       MTP_DEV_PROPERTY_FRIENDLYNAME);
+               } else {
+                       _util_utf8_to_utf16(wmodel, sizeof(wmodel) / WCHAR_SIZ,
+                                       dev_ptr);
+                       g_free(dev_ptr);
+               }
+               _prop_copy_char_to_ptpstring(&tmp, wmodel, WCHAR_TYPE);
+               _prop_set_current_string(dev_prop, &tmp);
+               _prop_set_default_string(&(dev_prop->propinfo), wmodel);
+       }
+#else /*MTP_USE_INFORMATION_REGISTRY*/
+       {
+               mtp_wchar wmodel[MTP_MAX_REG_STRING + 1] = { 0 };
+
+               _util_utf8_to_utf16(wmodel, sizeof(wmodel) / WCHAR_SIZ,
+                               MTP_DEV_PROPERTY_FRIENDLYNAME);
+               _prop_copy_char_to_ptpstring(&tmp, wmodel, WCHAR_TYPE);
+               _prop_set_current_string(dev_prop, &tmp);
+               _prop_set_default_string(&(dev_prop->propinfo), wmodel);
+       }
+#endif /*MTP_USE_INFORMATION_REGISTRY*/
+       i++;
+
+       /* supported formats ordered */
+       dev_prop = &(g_device.device_prop_list[i]);
+       _prop_init_device_property_desc(dev_prop,
+                       MTP_PROPERTYCODE_SUPPORTEDFORMATSORDERED,
+                       PTP_DATATYPE_UINT8, PTP_PROPGETSET_GETONLY, NONE);
+       {
+               default_val = 1;
+               _prop_set_default_integer(&(dev_prop->propinfo), (mtp_uchar *) &default_val);
+               _prop_set_current_integer(dev_prop, (mtp_uint32)1);
+       }
+       i++;
+
+#ifdef MTP_SUPPORT_DEVICE_CLASS
+       /* Perceived Device Type */
+       dev_prop = &(g_device.device_prop_list[i]);
+       _prop_init_device_property_desc(dev_prop,
+                       MTP_PROPERTYCODE_PERCEIVEDDEVICETYPE,
+                       PTP_DATATYPE_UINT32, PTP_PROPGETSET_GETONLY, NONE);
+       {
+               /*
+                * 0:generic, 1: DSC, 2: Media Player, 3: mobile,
+                * 4: digital video camera, 5: PDA, 6: audio recoder
+                */
+               default_val = 0x3;
+               _prop_set_default_integer(&(dev_prop->propinfo), (mtp_uchar *)&default_val);
+               _prop_set_current_integer(dev_prop, (mtp_uint32)0x3);
+       }
+       i++;
+#endif /*MTP_SUPPORT_DEVICE_CLASS*/
+
+       dev_prop = &(g_device.device_prop_list[i]);
+       _prop_init_device_property_desc(dev_prop, MTP_PROPERTYCODE_DEVICEICON,
+                       PTP_DATATYPE_AUINT8, PTP_PROPGETSET_GETONLY, NONE);
+       i++;
+
+       already_init = TRUE;
+
+       return TRUE;
+}
+
+void _init_mtp_device(void)
+{
+       static mtp_bool already_init = FALSE;
+
+       if (TRUE == already_init) {
+               DBG("Device is already initialized");
+               return;
+       }
+
+       already_init = TRUE;
+
+       g_device.status = DEVICE_STATUSOK;
+       g_device.phase = DEVICE_PHASE_IDLE;
+       g_device.num_stores = 0;
+       g_device.store_list = g_store_list;
+       g_device.default_store_id = MTP_INTERNAL_STORE_ID;
+       g_device.default_hparent = PTP_OBJECTHANDLE_ROOT;
+
+       __init_device_props();
+       _prop_build_supp_props_mp3();
+       _prop_build_supp_props_wmv();
+       _prop_build_supp_props_wma();
+       _prop_build_supp_props_album();
+       _prop_build_supp_props_default();
+       __init_device_info();
+
+       return;
+}
+
+mtp_uint32 _get_device_info_size(void)
+{
+       mtp_uint32 size = 0;
+       device_info_t *info = &(g_device.device_info);
+
+       size += sizeof(info->std_version);
+       size += sizeof(info->vendor_extn_id);
+       size += sizeof(info->vendor_extn_version);
+       size += _prop_size_ptpstring(&(info->vendor_extn_desc));
+       size += sizeof(info->functional_mode);
+       size += sizeof(mtp_uint32);     /*for number of supported ops*/
+       size += sizeof(g_ops_supported);
+       size += sizeof(mtp_uint32);
+       size += sizeof(g_event_supported);
+       size += sizeof(mtp_uint32);
+       size += NUM_DEVICE_PROPERTIES * sizeof(mtp_uint16);
+       size += sizeof(mtp_uint32);
+       size += sizeof(g_capture_fmts);
+       size += sizeof(mtp_uint32);
+       size += sizeof(g_object_fmts);
+       size += _prop_size_ptpstring(&(info->manufacturer));
+       size += _prop_size_ptpstring(&(info->model));
+       size += _prop_size_ptpstring(&(info->device_version));
+       size += _prop_size_ptpstring(&(info->serial_no));
+
+       return size;
+}
+
+mtp_uint32 _pack_device_info(mtp_uchar *buf, mtp_uint32 buf_sz)
+{
+       mtp_uint16 ii = 0;
+       mtp_uchar *ptr = buf;
+       mtp_uint32 count = 0;
+       device_info_t *info = &(g_device.device_info);
+
+       retv_if(NULL == buf, 0);
+
+       if (buf_sz < _get_device_info_size()) {
+               ERR("buffer size [%d] is less than device_info Size\n", buf_sz);
+               return 0;
+       }
+
+       memcpy(ptr, &info->std_version, sizeof(info->std_version));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(ptr, sizeof(info->std_version));
+#endif /*__BIG_ENDIAN__*/
+       ptr += sizeof(info->std_version);
+
+       memcpy(ptr, &info->vendor_extn_id, sizeof(info->vendor_extn_id));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(ptr, sizeof(info->vendor_extn_id));
+#endif /*__BIG_ENDIAN__*/
+       ptr += sizeof(info->vendor_extn_id);
+
+       memcpy(ptr, &info->vendor_extn_version,
+                       sizeof(info->vendor_extn_version));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(ptr, sizeof(info->vendor_extn_version));
+#endif /*__BIG_ENDIAN__*/
+       ptr += sizeof(info->vendor_extn_version);
+
+       ptr += _prop_pack_ptpstring(&(info->vendor_extn_desc), ptr,
+                       _prop_size_ptpstring(&(info->vendor_extn_desc)));
+
+       memcpy(ptr, &info->functional_mode, sizeof(info->functional_mode));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(ptr, sizeof(info->functional_mode));
+#endif /*__BIG_ENDIAN__*/
+       ptr += sizeof(info->functional_mode);
+
+       count = (sizeof(g_ops_supported) / sizeof(mtp_uint16));
+       memcpy(ptr, &count, sizeof(count));
+
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(ptr, sizeof(count));
+#endif /*__BIG_ENDIAN__*/
+       ptr += sizeof(count);
+       for (ii = 0; ii < count; ii++) {
+               memcpy(ptr, (void *)&(info->ops_supported[ii]),
+                               sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(ptr, sizeof(mtp_uint16));
+#endif /*__BIG_ENDIAN__*/
+               ptr += sizeof(mtp_uint16);
+       }
+
+       count = (sizeof(g_event_supported) / sizeof(mtp_uint16));
+       memcpy(ptr, &count, sizeof(count));
+
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(ptr, sizeof(count));
+#endif /*__BIG_ENDIAN__*/
+       ptr += sizeof(count);
+       for (ii = 0; ii < count; ii++) {
+               memcpy(ptr, (void *)&(info->events_supported[ii]),
+                               sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(ptr, sizeof(mtp_uint16));
+#endif /*__BIG_ENDIAN__*/
+               ptr += sizeof(mtp_uint16);
+       }
+
+       count = NUM_DEVICE_PROPERTIES;
+       memcpy(ptr, &count, sizeof(count));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(ptr, sizeof(count));
+#endif /*__BIG_ENDIAN__*/
+       ptr += sizeof(count);
+       for (ii = 0; ii < NUM_DEVICE_PROPERTIES; ii++) {
+               memcpy(ptr, (void *)&(info->device_prop_supported[ii]),
+                               sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(ptr, sizeof(mtp_uint16));
+#endif /*__BIG_ENDIAN__*/
+               ptr += sizeof(mtp_uint16);
+       }
+
+       count = (sizeof(g_capture_fmts) / sizeof(mtp_uint16));
+       memcpy(ptr, &count, sizeof(count));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(ptr, sizeof(count));
+#endif /*__BIG_ENDIAN__*/
+       ptr += sizeof(count);
+
+       for (ii = 0; ii < count; ii++) {
+               memcpy(ptr, (void *)&(info->capture_fmts[ii]),
+                               sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(ptr, sizeof(mtp_uint16));
+#endif /*__BIG_ENDIAN__*/
+               ptr += sizeof(mtp_uint16);
+       }
+
+       count = (sizeof(g_object_fmts) / sizeof(mtp_uint16));
+       memcpy(ptr, &count, sizeof(count));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(ptr, sizeof(count));
+#endif /*__BIG_ENDIAN__*/
+       ptr += sizeof(count);
+       for (ii = 0; ii < count; ii++) {
+               memcpy(ptr, (void *)&(info->object_fmts[ii]),
+                               sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(ptr, sizeof(mtp_uint16));
+#endif /*__BIG_ENDIAN__*/
+               ptr += sizeof(mtp_uint16);
+       }
+
+       ptr += _prop_pack_ptpstring(&(info->manufacturer), ptr,
+                       _prop_size_ptpstring(&(info->manufacturer)));
+
+       ptr += _prop_pack_ptpstring(&(info->model), ptr,
+                       _prop_size_ptpstring(&(info->model)));
+
+       ptr += _prop_pack_ptpstring(&(info->device_version), ptr,
+                       _prop_size_ptpstring(&(info->device_version)));
+
+       ptr += _prop_pack_ptpstring(&(info->serial_no), ptr,
+                       _prop_size_ptpstring(&(info->serial_no)));
+
+       return (mtp_uint32)(ptr - buf);
+}
+
+void _reset_mtp_device(void)
+{
+       _transport_set_control_event(0);
+       _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
+
+       /* resets device state to ok/Ready */
+       /* reset device phase to idle */
+
+       g_device.status = DEVICE_STATUSOK;
+       g_device.phase = DEVICE_PHASE_IDLE;
+       return;
+}
+
+device_prop_desc_t *_device_get_device_property(mtp_uint32 prop_code)
+{
+       mtp_uint16 ii = 0;
+
+       for (ii = 0; ii < NUM_DEVICE_PROPERTIES; ii++) {
+               if (g_device.device_prop_list[ii].propinfo.prop_code == prop_code)
+                       return &(g_device.device_prop_list[ii]);
+       }
+       return NULL;
+}
+
+/*
+ * static mtp_bool _device_add_store(store_type_t store_type)
+ * This function will add the store to the device.
+ * @param[in]  store_type      Store Number
+ * @return     TRUE if success, otherwise FALSE.
+ */
+static mtp_bool __add_store_to_device(store_type_t store_type)
+{
+       mtp_char *storage_path = NULL;
+       mtp_uint32 store_id = 0;
+       file_attr_t attrs = { 0, };
+
+       switch (store_type) {
+       case MTP_STORAGE_INTERNAL:
+               storage_path = MTP_STORE_PATH_CHAR;
+               store_id = MTP_INTERNAL_STORE_ID;
+               break;
+       case MTP_STORAGE_EXTERNAL:
+               storage_path = MTP_EXTERNAL_PATH_CHAR;
+               store_id = MTP_EXTERNAL_STORE_ID;
+               break;
+       default:
+               ERR("Unknown Storage [%d]\n", store_id);
+               return FALSE;
+       }
+
+       if (FALSE == _util_get_file_attrs(storage_path, &attrs)) {
+               ERR("_util_get_file_attrs() Fail");
+               return FALSE;
+       }
+
+       if (MTP_FILE_ATTR_INVALID == attrs.attribute ||
+                       !(attrs.attribute & MTP_FILE_ATTR_MODE_DIR)) {
+               ERR("attribute [0x%x], dir[0x%x]\n",
+                               attrs.attribute, MTP_FILE_ATTR_MODE_DIR);
+               ERR("Storage [%d]\n", store_id);
+               return FALSE;
+       }
+
+
+       if (g_device.num_stores + 1 > MAX_NUM_DEVICE_STORES) {
+               ERR("reached to max [%d]\n", MAX_NUM_DEVICE_STORES);
+               return FALSE;
+       }
+
+       if (FALSE == _entity_init_mtp_store(&(g_device.store_list[g_device.num_stores]),
+                               store_id, storage_path)) {
+               ERR("_entity_init_mtp_store() Fail");
+               return FALSE;
+       }
+
+       g_device.num_stores++;
+       g_device.is_mounted[store_type] = TRUE;
+
+       return TRUE;
+}
+
+/*
+ * static mtp_bool _device_remove_store(store_type_t store_type)
+ * This function will remove the store from the device.
+ * @param[in]  store_type      Store type
+ * @return     TRUE if success, otherwise FALSE.
+ */
+static mtp_bool __remove_store_from_device(store_type_t store_type)
+{
+       mtp_int32 ii = 0;
+       mtp_device_t *device = &g_device;
+       mtp_store_t *store = NULL;
+       mtp_uint32 store_id = 0;
+
+       switch (store_type) {
+       case MTP_STORAGE_INTERNAL:
+               store_id = MTP_INTERNAL_STORE_ID;
+               break;
+       case MTP_STORAGE_EXTERNAL:
+               store_id = MTP_EXTERNAL_STORE_ID;
+               break;
+       default:
+               ERR("Unknown Storage [%d]\n", store_type);
+               return FALSE;
+       }
+
+       for (ii = 0; ii < device->num_stores; ii++) {
+               store = &(device->store_list[ii]);
+               if (store->store_id == store_id) {
+                       __clear_store_data(store->store_id);
+                       device->is_mounted[store_type] = FALSE;
+                       break;
+               }
+       }
+
+       return TRUE;
+}
+
+mtp_bool _device_is_store_mounted(mtp_int32 store_type)
+{
+       if (store_type < MTP_STORAGE_INTERNAL ||
+                       store_type >= MTP_STORAGE_ALL) {
+               ERR("unknown storage(%d)\n", store_type);
+               return FALSE;
+       }
+
+       return g_device.is_mounted[store_type];
+}
+
+mtp_bool _device_install_storage(mtp_int32 type)
+{
+       mtp_int32 int_status = TRUE;
+       mtp_int32 ext_status = TRUE;
+       mtp_bool mounted;
+
+       switch (type) {
+       case MTP_ADDREM_AUTO:
+               DBG(" case MTP_ADDREM_AUTO:");
+               int_status = _device_is_store_mounted(MTP_STORAGE_INTERNAL);
+               if (int_status == FALSE)
+                       __add_store_to_device(MTP_STORAGE_INTERNAL);
+
+               mounted = _util_get_local_mmc_status();
+               if (mounted == MTP_PHONE_MMC_INSERTED) {
+
+                       ext_status =
+                               _device_is_store_mounted(MTP_STORAGE_EXTERNAL);
+                       if (ext_status == FALSE)
+                               __add_store_to_device(MTP_STORAGE_EXTERNAL);
+               }
+               break;
+
+       case MTP_ADDREM_INTERNAL:
+               DBG("case MTP_ADDREM_INTERNAL:");
+               if (FALSE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
+                       __add_store_to_device(MTP_STORAGE_INTERNAL);
+               break;
+
+       case MTP_ADDREM_EXTERNAL:
+               DBG(" case MTP_ADDREM_EXTERNAL:");
+               if (MTP_PHONE_MMC_INSERTED != _util_get_local_mmc_status())
+                       break;
+               mounted = _device_is_store_mounted(MTP_STORAGE_EXTERNAL);
+               if (mounted == FALSE) {
+                       if (__add_store_to_device(MTP_STORAGE_EXTERNAL)== FALSE) {
+                               ERR("__add_store_to_device() Fail");
+                               return FALSE;
+                       }
+               }
+               break;
+
+       case MTP_ADDREM_ALL:
+               DBG(" case MTP_ADDREM_ALL:");
+               __add_store_to_device(MTP_STORAGE_INTERNAL);
+               __add_store_to_device(MTP_STORAGE_EXTERNAL);
+               break;
+
+       default:
+               ERR("_device_install_storage : unknown type [%d]\n", type);
+               break;
+       }
+
+       return TRUE;
+}
+
+mtp_bool _device_uninstall_storage(mtp_int32 type)
+{
+       switch (type) {
+       case MTP_ADDREM_AUTO:
+               if (TRUE == _device_is_store_mounted(MTP_STORAGE_EXTERNAL))
+                       __remove_store_from_device(MTP_STORAGE_EXTERNAL);
+               if (TRUE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
+                       __remove_store_from_device(MTP_STORAGE_INTERNAL);
+               break;
+       case MTP_ADDREM_INTERNAL:
+               if (TRUE == _device_is_store_mounted(MTP_STORAGE_INTERNAL))
+                       __remove_store_from_device(MTP_STORAGE_INTERNAL);
+               break;
+       case MTP_ADDREM_EXTERNAL:
+               if (TRUE == _device_is_store_mounted(MTP_STORAGE_EXTERNAL))
+                       __remove_store_from_device(MTP_STORAGE_EXTERNAL);
+               break;
+       case MTP_ADDREM_ALL:
+               __remove_store_from_device(MTP_STORAGE_INTERNAL);
+               __remove_store_from_device(MTP_STORAGE_EXTERNAL);
+               break;
+       default:
+               ERR("unknown mode [%d]\n", type);
+               break;
+       }
+
+       return TRUE;
+}
+
+/*
+ * static mtp_err_t __device_clear_store_data(mtp_uint32 store_id)
+ * This function removes the storage entry.
+ * @param[in]  store_id        Specifies the storage id to remove
+ * @return     This function returns MTP_ERROR_NONE on success
+ *             ERROR number on failure.
+ */
+static mtp_err_t __clear_store_data(mtp_uint32 store_id)
+{
+       mtp_uint16 idx = 0;
+       mtp_store_t *store = NULL;
+       mtp_uint32 count = g_device.num_stores;
+
+       for (idx = 0; idx < count; idx++) {
+               if (g_device.store_list[idx].store_id == store_id) {
+
+                       _entity_destroy_mtp_store(&(g_device.store_list[idx]));
+
+                       store = &(g_device.store_list[idx]);
+                       store->store_id = 0;
+                       store->is_hidden = FALSE;
+                       g_free(store->root_path);
+                       store->root_path = NULL;
+
+                       for (; idx < count - 1; idx++) {
+                               _entity_copy_store_data(&(g_device.store_list[idx]),
+                                               &(g_device.store_list[idx + 1]));
+                       }
+
+                       g_device.store_list[count - 1].store_id = 0;
+                       g_device.store_list[count - 1].root_path = NULL;
+                       g_device.store_list[count - 1].is_hidden = FALSE;
+                       _util_init_list(&(g_device.store_list[count - 1].obj_list));
+
+                       /*Initialize the destroyed store*/
+                       g_device.num_stores--;
+                       return MTP_ERROR_NONE;
+               }
+       }
+       return MTP_ERROR_GENERAL;
+}
+
+mtp_store_t *_device_get_store(mtp_uint32 store_id)
+{
+       mtp_int32 ii = 0;
+       mtp_store_t *store = NULL;
+
+       for (ii = 0; ii < g_device.num_stores; ii++) {
+
+               store = &(g_device.store_list[ii]);
+               if (store->store_id == store_id)
+                       return store;
+       }
+       return NULL;
+}
+
+mtp_uint32 _device_get_store_ids(ptp_array_t *store_ids)
+{
+       mtp_store_t *store = NULL;
+       mtp_int32 ii = 0;
+
+       for (ii = g_device.num_stores - 1; ii >= 0; ii--) {
+
+               store = &(g_device.store_list[ii]);
+               if ((store != NULL) && (FALSE == store->is_hidden))
+                       _prop_append_ele_ptparray(store_ids, store->store_id);
+       }
+       return store_ids->num_ele;
+}
+
+mtp_uint32 _device_get_num_objects(mtp_uint32 store_id)
+{
+       mtp_uint32 num_objs = 0;
+       mtp_store_t *store = NULL;
+       mtp_uint32 ii = 0;
+
+       for (ii = 0; ii < g_device.num_stores; ii++) {
+
+               store = &(g_device.store_list[ii]);
+               if ((store->store_id == store_id) ||
+                               (store_id == PTP_STORAGEID_ALL)) {
+                       num_objs += store->obj_list.nnodes;
+               }
+       }
+
+       return num_objs;
+}
+
+mtp_uint32 _device_get_num_objects_with_format(mtp_uint32 store_id,
+               mtp_uint32 format)
+{
+       mtp_uint32 num_objs = 0;
+       mtp_store_t *store = NULL;
+       mtp_uint32 ii = 0;
+
+       for (ii = 0; ii < g_device.num_stores; ii++) {
+
+               store = &(g_device.store_list[ii]);
+               if ((store->store_id != store_id) &&
+                               (store_id != PTP_STORAGEID_ALL)) {
+                       continue;
+               }
+               num_objs += _entity_get_num_object_with_same_format(store,
+                               format);
+       }
+
+       return num_objs;
+}
+
+mtp_obj_t *_device_get_object_with_handle(mtp_uint32 obj_handle)
+{
+       mtp_int32 ii = 0;
+       mtp_obj_t *obj = NULL;
+       mtp_store_t *store = NULL;
+
+       for (ii = 0; ii < g_device.num_stores; ii++) {
+
+               store = &(g_device.store_list[ii]);
+               obj = _entity_get_object_from_store(store, obj_handle);
+               if (obj == NULL)
+                       continue;
+               break;
+       }
+       return obj;
+}
+
+mtp_obj_t* _device_get_object_with_path(mtp_char *full_path)
+{
+       mtp_int32 i = 0;
+       mtp_obj_t *obj = NULL;
+       mtp_store_t *store = NULL;
+
+       retv_if(NULL == full_path, NULL);
+
+       for (i = 0; i < g_device.num_stores; i++) {
+               store = &(g_device.store_list[i]);
+               obj = _entity_get_object_from_store_by_path(store, full_path);
+               if (obj == NULL)
+                       continue;
+               break;
+       }
+       return obj;
+}
+
+mtp_uint16 _device_delete_object(mtp_uint32 obj_handle, mtp_uint32 fmt)
+{
+       mtp_uint32 ii = 0;
+       mtp_uint16 response = PTP_RESPONSE_OK;
+       mtp_store_t *store = NULL;
+       mtp_bool all_del = TRUE;
+       mtp_bool atlst_one = FALSE;
+
+       if (PTP_OBJECTHANDLE_ALL != obj_handle) {
+               store = _device_get_store_containing_obj(obj_handle);
+               if (store == NULL) {
+                       response = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               } else {
+                       response = _entity_delete_obj_mtp_store(store,
+                                       obj_handle, fmt, TRUE);
+               }
+               return response;
+       }
+
+       for (ii = 0; ii < g_device.num_stores; ii++) {
+               store = &(g_device.store_list[ii]);
+               response = _entity_delete_obj_mtp_store(store, obj_handle,
+                               fmt, TRUE);
+               switch (response) {
+               case PTP_RESPONSE_STORE_READONLY:
+                       all_del = FALSE;
+                       break;
+               case PTP_RESPONSE_PARTIAL_DELETION:
+                       all_del = FALSE;
+                       atlst_one = TRUE;
+                       break;
+               case PTP_RESPONSE_OBJ_WRITEPROTECTED:
+               case PTP_RESPONSE_ACCESSDENIED:
+                       all_del = FALSE;
+                       break;
+               case PTP_RESPONSE_OK:
+               default:
+                       atlst_one = TRUE;
+                       break;
+               }
+       }
+
+       if (all_del)
+               response = PTP_RESPONSE_OK;
+       else if (atlst_one)
+               response = PTP_RESPONSE_PARTIAL_DELETION;
+
+       return response;
+}
+
+mtp_store_t *_device_get_store_containing_obj(mtp_uint32 obj_handle)
+{
+       mtp_uint32 ii = 0;
+       mtp_obj_t *obj = NULL;
+       mtp_store_t *store = NULL;
+
+       for (ii = 0; ii < g_device.num_stores; ii++) {
+               store = &(g_device.store_list[ii]);
+               obj = _entity_get_object_from_store(store, obj_handle);
+               if (obj != NULL)
+                       return store;
+       }
+       return NULL;
+}
+
+mtp_store_t *_device_get_store_at_index(mtp_uint32 index)
+{
+       if (index >= g_device.num_stores) {
+               ERR("Index not valid");
+               return NULL;
+       }
+
+       return &(g_device.store_list[index]);
+}
+
+device_prop_desc_t *_device_get_ref_prop_list(void)
+{
+       return g_device.device_prop_list;
+}
+
+mtp_bool _device_get_playback_obj(mtp_uint32 *playback_obj)
+{
+       device_prop_desc_t *device_prop = NULL;
+
+       device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
+       if (NULL == device_prop) {
+               ERR("device_prop is NULL");
+               return FALSE;
+       }
+       memcpy(playback_obj, device_prop->current_val.integer,
+                       sizeof(mtp_uint32));
+
+       return TRUE;
+}
+
+mtp_bool _device_set_playback_obj(mtp_uint32 playback_obj)
+{
+       device_prop_desc_t *device_prop = NULL;
+       cmd_container_t event = { 0, };
+
+       device_prop = _device_get_device_property(MTP_PROPERTYCODE_PLAYBACK_OBJECT);
+       if (device_prop == NULL) {
+               ERR("device_prop is NULL");
+               return FALSE;
+       }
+       _prop_set_current_integer(device_prop, playback_obj);
+       _hdlr_init_event_container(&event,
+                       PTP_EVENTCODE_DEVICEPROPCHANGED, 0, 0, 0);
+       _hdlr_send_event_container(&event);
+       return TRUE;
+}
+
+void _device_get_serial(mtp_char *serial_no, mtp_uint32 len)
+{
+       ret_if(serial_no == NULL);
+
+       _util_utf16_to_utf8(serial_no, len,
+                       g_device.device_info.serial_no.str);
+       return;
+}
+
+void _device_set_phase(device_phase_t phase)
+{
+       DBG("Devie phase is set [%d]\n", phase);
+       g_device.phase = phase;
+       return;
+}
+
+device_phase_t _device_get_phase(void)
+{
+       return g_device.phase;
+}
+
+mtp_uint32 _device_get_default_store_id(void)
+{
+       return g_device.default_store_id;
+}
+
+mtp_uint32 _device_get_default_parent_handle(void)
+{
+       return g_device.default_hparent;
+}
+
+mtp_uint32 _device_get_num_stores(void)
+{
+       return g_device.num_stores;
+}
+
+device_status_t _device_get_status(void)
+{
+       return g_device.status;
+}
+
+mtp_char *_device_get_device_name(void)
+{
+       return g_strdup(g_device.device_name);
+}
+
+void _device_set_device_name(mtp_char *dev_name)
+{
+       ret_if(dev_name == NULL);
+
+       g_strlcpy(g_device.device_name, dev_name, sizeof(g_device.device_name));
+       return;
+}
+
+mtp_char *_device_get_sync_partner(void)
+{
+       return g_strdup(g_device.sync_partner);
+}
+
+void _device_set_sync_partner(mtp_char *sync_ptr)
+{
+       ret_if(sync_ptr == NULL);
+
+       g_strlcpy(g_device.sync_partner, sync_ptr,
+                       sizeof(g_device.sync_partner));
+       return;
+}
diff --git a/src/entity/mtp_object.c b/src/entity/mtp_object.c
new file mode 100755 (executable)
index 0000000..1cc13bf
--- /dev/null
@@ -0,0 +1,755 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <glib.h>
+#include "mtp_fs.h"
+#include "mtp_support.h"
+#include "mtp_util.h"
+#include "mtp_device.h"
+
+
+extern mtp_bool g_is_full_enum;
+
+
+mtp_bool _entity_get_file_times(mtp_obj_t *obj, ptp_time_string_t *create_tm,
+               ptp_time_string_t *modify_tm)
+{
+       file_attr_t attrs = {0};
+       system_time_t local_time = {0};
+       struct tm new_time = {0};
+
+       if (FALSE == _util_get_file_attrs(obj->file_path, &attrs)) {
+               ERR("_util_get_file_attrs Fail");
+               return FALSE;
+       }
+
+       if (NULL != localtime_r((time_t*)&attrs.ctime, &new_time)) {
+               local_time.year = new_time.tm_year + 1900;
+               local_time.month = new_time.tm_mon + 1;
+               local_time.day = new_time.tm_mday;
+               local_time.hour = new_time.tm_hour;
+               local_time.minute = new_time.tm_min;
+               local_time.second = new_time.tm_sec;
+               local_time.day_of_week = 0;
+               local_time.millisecond = 0;
+       } else {
+               ERR("localtime_r returned NULL");
+               _util_print_error();
+               return FALSE;
+       }
+       _prop_copy_time_to_ptptimestring(create_tm, &local_time);
+
+       if (NULL != localtime_r((time_t*)&attrs.mtime, &new_time)) {
+               local_time.year = new_time.tm_year + 1900;
+               local_time.month = new_time.tm_mon + 1;
+               local_time.day = new_time.tm_mday;
+               local_time.hour = new_time.tm_hour;
+               local_time.minute = new_time.tm_min;
+               local_time.second = new_time.tm_sec;
+               local_time.day_of_week = 0;
+               local_time.millisecond = 0;
+       } else {
+               ERR("localtime_r returned NULL");
+               _util_print_error();
+               return FALSE;
+       }
+       _prop_copy_time_to_ptptimestring(modify_tm, &local_time);
+
+       return TRUE;
+}
+
+obj_info_t *_entity_alloc_object_info(void)
+{
+       obj_info_t *info = NULL;
+
+       info = (obj_info_t *)g_malloc(sizeof(obj_info_t));
+       if (NULL == info) {
+               ERR("Memory allocation Fail");
+               return NULL;
+       }
+
+       _entity_init_object_info(info);
+
+       return info;
+}
+
+void _entity_init_object_info(obj_info_t *info)
+{
+       ret_if(info == NULL);
+
+       memset(info, 0, sizeof(obj_info_t));
+}
+
+mtp_uint32 _entity_get_object_info_size(mtp_obj_t *obj, ptp_string_t *file_name)
+{
+       int ret;
+       ptp_string_t keywords;
+       ptp_time_string_t create_time_str = {0};
+       ptp_time_string_t modify_time_str = {0};
+       mtp_uint32 size = FIXED_LENGTH_MEMBERS_SIZE;
+
+       retv_if(obj == NULL, 0);
+
+       ret = _entity_get_file_times(obj, &create_time_str, &modify_time_str);
+       if (FALSE == ret) {
+               ERR("_entity_get_file_times() Fail");
+               return 0;
+       }
+
+       _prop_copy_char_to_ptpstring(&keywords, (mtp_wchar *)"", WCHAR_TYPE);
+
+       size += _prop_size_ptpstring(file_name);
+       size += _prop_size_ptptimestring(&create_time_str);
+       size += _prop_size_ptptimestring(&modify_time_str);
+       size += _prop_size_ptpstring(&keywords);
+
+       return (size);
+}
+
+void _entity_init_object_info_params(obj_info_t *info, mtp_uint32 store_id,
+               mtp_uint32 parent_handle, mtp_char *file_name, dir_entry_t *dir)
+{
+       mtp_char extn[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+       _entity_init_object_info(info);
+
+       info->store_id = store_id;
+       info->h_parent = parent_handle;
+
+       _util_get_file_extn(file_name, extn);
+
+       if (dir->attrs.attribute == MTP_FILE_ATTR_INVALID) {
+               ERR("File attribute invalid");
+               return;
+       }
+#ifndef MTP_SUPPORT_SET_PROTECTION
+       info->protcn_status = PTP_PROTECTIONSTATUS_NOPROTECTION;
+#else /* MTP_SUPPORT_SET_PROTECTION */
+       info->protcn_status = (dir->attrs.attribute &
+                       MTP_FILE_ATTR_MODE_READ_ONLY) ?
+               PTP_PROTECTIONSTATUS_READONLY :
+               PTP_PROTECTIONSTATUS_NOPROTECTION;
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+
+       if (dir->attrs.attribute & MTP_FILE_ATTR_MODE_DIR) {
+               info->obj_fmt = PTP_FMT_ASSOCIATION;
+               info->association_type = PTP_ASSOCIATIONTYPE_FOLDER;
+               return;
+       }
+
+       info->file_size = dir->attrs.fsize;
+       info->obj_fmt = _util_get_fmtcode(extn);
+
+       return;
+}
+
+mtp_uint32 _entity_parse_raw_obj_info(mtp_uchar *buf, mtp_uint32 buf_sz,
+               obj_info_t *info, mtp_char *file_name, mtp_uint16 fname_len)
+{
+       mtp_uchar *temp = buf;
+       ptp_string_t str = {0};
+       mtp_uint32 bytes_parsed = 0;
+
+       retv_if(buf == NULL, 0);
+       retvm_if(buf_sz < FIXED_LENGTH_MEMBERS_SIZE, 0, "buf_sz[%d] is less", buf_sz);
+
+       /* Copy Obj Props from store_id till file_size */
+       memcpy(&(info->store_id), temp, (sizeof(mtp_uint16) * 2 + sizeof(mtp_uint32) * 2));
+       temp += (sizeof(mtp_uint16) * 2 + sizeof(mtp_uint32) * 2);
+
+       /* Skip ObjProp:thumb format .No need to store ,the prop has
+        * a default value.
+        */
+       temp += sizeof(mtp_uint16);
+
+       memcpy(&(info->thumb_file_size), temp, sizeof(mtp_uint32));
+       temp += sizeof(mtp_uint32);
+
+       /* Skip ObjProps:ThumbPixWidth,ThumbPixHeight,ImagePixWidth,
+        * ImagePixHeight,ImageBitDepth.No need to store,they have default value
+        */
+       temp += sizeof(mtp_uint32) * 5;
+
+       memcpy(&(info->h_parent), temp, sizeof(mtp_uint32));
+       temp += sizeof(mtp_uint32);
+
+       memcpy(&(info->association_type), temp, sizeof(mtp_uint16));
+       temp += sizeof(mtp_uint16);
+
+       /* Skip ObjProps:association_desc, sequence_desc */
+       temp += sizeof(mtp_uint32) * 2;
+
+#ifdef __BIG_ENDIAN__
+       /* Byte swap the structure elements if needed.
+        * This works since the data elements will have the same size,
+        * the only difference is the byte order.
+        */
+       _util_conv_byte_order(&(info->store_id), sizeof(info->store_id));
+       _util_conv_byte_order(&(info->obj_fmt), sizeof(info->obj_fmt));
+       _util_conv_byte_order(&(info->protcn_status),
+                       sizeof(info->protcn_status));
+       _util_conv_byte_order(&(info->file_size), sizeof(info->file_size));
+       _util_conv_byte_order(&(info->thumb_file_size),
+                       sizeof(info->thumb_file_size));
+       _util_conv_byte_order(&(info->h_parent), sizeof(info->h_parent));
+       _util_conv_byte_order(&(info->association_type),
+                       sizeof(info->association_type));
+#endif /*__BIG_ENDIAN__*/
+
+       ptp_string_t fname = { 0 };
+       bytes_parsed = _prop_parse_rawstring(&fname, temp, buf_sz);
+       temp += bytes_parsed;
+
+       _util_utf16_to_utf8(file_name, fname_len, fname.str);
+
+       /* Skip ObjProps: datecreated/datemodified/keywords.
+        * The values are retrieved using stat.
+        */
+       memcpy(&(str.num_chars), temp, sizeof(mtp_uchar));
+       temp += _prop_size_ptpstring(&str);
+
+       memcpy(&(str.num_chars), temp, sizeof(mtp_uchar));
+       temp += _prop_size_ptpstring(&str);
+
+       memcpy(&(str.num_chars), temp, sizeof(mtp_uchar));
+       temp += _prop_size_ptpstring(&str);
+
+       return (mtp_uint32)(temp - buf);
+}
+
+void _entity_copy_obj_info(obj_info_t *dst, obj_info_t *src)
+{
+       memcpy(&(dst->store_id), &(src->store_id), (2 * sizeof(mtp_uint16) +
+                               sizeof(mtp_uint32) + sizeof(mtp_uint64)));
+
+       /* Copy Object Props:thumb_file_size,h_parent, association_type */
+       memcpy(&(dst->thumb_file_size), &(src->thumb_file_size),
+                       (2 * sizeof(mtp_uint32) + sizeof(mtp_uint16)));
+
+       return;
+}
+
+mtp_uint32 _entity_pack_obj_info(mtp_obj_t *obj, ptp_string_t *file_name,
+               mtp_uchar *buf, mtp_uint32 buf_sz)
+{
+       int ret;
+       mtp_uint32 num_bytes = 0;
+       mtp_uint32 objSize = 0;
+       mtp_uint16 thumb_fmt = 0;
+       mtp_uint32 thumb_width = 0;
+       mtp_uint32 thumb_height = 0;
+       obj_info_t *info = obj->obj_info;
+       ptp_time_string_t create_time_str = { 0 };
+       ptp_time_string_t modify_time_str = { 0 };
+       ptp_string_t keywords;
+
+       retv_if(buf == NULL, 0);
+       retv_if(obj == NULL, 0);
+
+       ret = _entity_get_file_times(obj, &create_time_str, &modify_time_str);
+       if (FALSE == ret) {
+               ERR("_entity_get_file_times() Fail");
+               return 0;
+       }
+
+       _prop_copy_char_to_ptpstring(&keywords, (mtp_wchar *)"", WCHAR_TYPE);
+
+       if (buf_sz < _entity_get_object_info_size(obj, file_name)) {
+               ERR("Buffer size is less than object info size");
+               return 0;
+       }
+
+       /* As per Spec ObjectCompressedSize field in ObjectInfo dataset is
+        * 4 bytes. In case file size greater than 4Gb, value 0xFFFFFFFF is sent
+        */
+       objSize = (info->file_size >= MTP_FILESIZE_4GB) ?
+               0xFFFFFFFF : (mtp_uint32)info->file_size;
+
+#ifdef __BIG_ENDIAN__
+       memcpy(&(buf[num_bytes]), &(info->store_id), sizeof(mtp_uint32));
+       _util_conv_byte_order(buf, sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       memcpy(&(buf[num_bytes]), &(info->obj_fmt), sizeof(mtp_uint16));
+       _util_conv_byte_order(buf, sizeof(mtp_uint16));
+       num_bytes += sizeof(mtp_uint16);
+
+       memcpy(&(buf[num_bytes]), &(info->protcn_status), sizeof(mtp_uint16));
+       _util_conv_byte_order(buf, sizeof(mtp_uint16));
+       num_bytes += sizeof(mtp_uint16);
+
+       memcpy(&(buf[num_bytes]), &objSize, sizeof(mtp_uint32));
+       _util_conv_byte_order(buf, sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       /* Thumb format has a constant value of 2 bytes */
+       memset(&(buf[num_bytes]), &thumb_fmt, sizeof(mtp_uint16));
+       _util_conv_byte_order(buf, sizeof(mtp_uint16));
+       num_bytes += sizeof(mtp_uint16);
+
+       memcpy(&(buf[num_bytes]), &(info->thumb_file_size), sizeof(mtp_uint32));
+       _util_conv_byte_order(buf, sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       memcpy(&(buf[num_bytes]), &thumb_width, sizeof(mtp_uint32));
+       _util_conv_byte_order(buf, sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       memcpy(&(buf[num_bytes]), &thumb_height, sizeof(mtp_uint32));
+       _util_conv_byte_order(buf, sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       /* ObjProps:image_width, image_height, image_bit_depth values
+        * currently are always 0 for any type of FILE/FOLDER
+        */
+       memset(&(buf[num_bytes]), 0, sizeof(mtp_uint32) * 3);
+       _util_conv_byte_order(buf, sizeof(mtp_uint32) * 3);
+       num_bytes += (sizeof(mtp_uint32) * 3);
+
+       memcpy(&(buf[num_bytes]), &(info->h_parent), sizeof(mtp_uint32));
+       _util_conv_byte_order(buf, sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       memcpy(&(buf[num_bytes]),
+                       &(info->association_type), sizeof(mtp_uint16));
+       _util_conv_byte_order(buf, sizeof(mtp_uint16));
+       num_bytes += sizeof(mtp_uint16);
+
+       /* ObjProps:association desc,sequence number values are always 0 */
+       memset(&(buf[num_bytes]), 0, sizeof(mtp_uint32) * 2);
+       _util_conv_byte_order(buf, sizeof(mtp_uint32) * 2);
+       num_bytes += (sizeof(mtp_uint32) * 2);
+
+#else /* __BIG_ENDIAN__ */
+
+       /* ObjProps:store_id, obj_format, protection status */
+       memcpy(buf, &(info->store_id),
+                       (sizeof(mtp_uint32) + sizeof(mtp_uint16) * 2));
+       num_bytes += (sizeof(mtp_uint32) + sizeof(mtp_uint16) * 2);
+
+       memcpy(&buf[num_bytes], &objSize, sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       /* ObjProp:thumb format */
+       memcpy(&buf[num_bytes], &thumb_fmt, sizeof(mtp_uint16));
+       num_bytes += sizeof(mtp_uint16);
+
+       /* ObjProp: thumb file size */
+       memcpy(&buf[num_bytes], &(info->thumb_file_size), sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       /* ObjProp:thumb_width */
+       memcpy(&buf[num_bytes], &thumb_width, sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       /* ObjProp:thumb_height */
+       memcpy(&buf[num_bytes], &thumb_height, sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       /* ObjProp:image_width, image_height,
+        * image_bit_depth values currently are always 0
+        */
+       memset(&(buf[num_bytes]), 0, sizeof(mtp_uint32) * 3);
+       num_bytes +=  (sizeof(mtp_uint32) * 3);
+
+       /* ObjProp:parent_handle */
+       memcpy(&buf[num_bytes], &(info->h_parent), sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint32);
+
+       /* ObjProp:association_type */
+       memcpy(&buf[num_bytes], &(info->association_type), sizeof(mtp_uint16));
+       num_bytes += sizeof(mtp_uint16);
+
+       /* ObjProp:association_desc,sequence Number values are always 0 */
+       memset(&buf[num_bytes], 0, sizeof(mtp_uint32) * 2);
+       num_bytes += sizeof(mtp_uint32) * 2;
+#endif /* __BIG_ENDIAN__ */
+
+       num_bytes += _prop_pack_ptpstring(file_name, buf + num_bytes,
+                       _prop_size_ptpstring(file_name));
+
+       num_bytes += _prop_pack_ptptimestring(&create_time_str,
+                       buf + num_bytes,
+                       _prop_size_ptptimestring(&create_time_str));
+
+       num_bytes += _prop_pack_ptptimestring(&modify_time_str,
+                       buf + num_bytes,
+                       _prop_size_ptptimestring(&modify_time_str));
+
+       num_bytes += _prop_pack_ptpstring(&keywords,
+                       buf + num_bytes,
+                       _prop_size_ptpstring(&keywords));
+
+       DBG("number of bytes for objectinfo :[%d]\n", num_bytes);
+       return num_bytes;
+}
+
+void _entity_dealloc_obj_info(obj_info_t *info)
+{
+       g_free(info);
+       info = NULL;
+       return;
+}
+
+mtp_obj_t *_entity_alloc_mtp_object(void)
+{
+       return ((mtp_obj_t *)g_malloc(sizeof(mtp_obj_t)));
+}
+
+mtp_bool _entity_init_mtp_object_params(
+               mtp_obj_t *obj,
+               mtp_uint32 store_id,
+               mtp_uint32 h_parent,
+               mtp_char *file_path,
+               mtp_char *file_name,
+               dir_entry_t *file_info)
+{
+       retv_if(obj == NULL, FALSE);
+
+       obj->obj_handle = 0;
+       obj->obj_info = NULL;
+       obj->file_path = NULL;
+       obj->obj_handle = _entity_generate_next_obj_handle();
+       _entity_set_object_file_path(obj, file_path, CHAR_TYPE);
+       obj->obj_info = _entity_alloc_object_info();
+
+       if (NULL == obj->obj_info) {
+               g_free(obj->file_path);
+               return FALSE;
+       }
+       _entity_init_object_info_params(obj->obj_info, store_id, h_parent,
+                       file_name, file_info);
+
+       _util_init_list(&(obj->propval_list));
+       memset(&(obj->child_array), 0, sizeof(ptp_array_t));
+       obj->child_array.type = UINT32_TYPE;
+
+       return TRUE;
+}
+
+mtp_bool _entity_set_object_file_path(mtp_obj_t *obj, void *file_path,
+               char_mode_t char_type)
+{
+       mtp_char temp[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+       if (char_type == WCHAR_TYPE) {
+               _util_utf16_to_utf8(temp, sizeof(temp), (mtp_wchar *)file_path);
+               g_free(obj->file_path);
+               obj->file_path = g_strdup(temp);
+       } else {
+               g_free(obj->file_path);
+               obj->file_path = g_strdup((char *)file_path);
+       }
+       return TRUE;
+}
+
+mtp_bool _entity_check_child_obj_path(mtp_obj_t *obj,
+               mtp_char *src_path, mtp_char *dest_path)
+{
+       mtp_uint16 idx = 0;
+       mtp_char *ptr = NULL;
+       mtp_obj_t *child_obj = NULL;
+       ptp_array_t child_arr = { 0 };
+       mtp_store_t *src_store = NULL;
+       mtp_char dest_chld_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char temp_chld_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_wchar dest_chld_wpath[MTP_MAX_PATHNAME_SIZE * 2 + 1] = { 0 };
+       mtp_wchar temp_chld_wpath[MTP_MAX_PATHNAME_SIZE * 2 + 1] = { 0 };
+
+       retv_if(obj == NULL, FALSE);
+
+       if (strlen(dest_path) > MTP_MAX_PATHNAME_SIZE - 1) {
+               ERR("dest_path is too long[%d]\n", strlen(dest_path));
+               return FALSE;
+       }
+
+       if (strlen(src_path) > MTP_MAX_PATHNAME_SIZE - 1) {
+               ERR("src_path is too long[%d]\n", strlen(src_path));
+               return FALSE;
+       }
+
+       src_store = _device_get_store_containing_obj(obj->obj_handle);
+       if (NULL == src_store) {
+               ERR("Object not present in store");
+               return FALSE;
+       }
+
+       _prop_init_ptparray(&child_arr, UINT32_TYPE);
+       _entity_get_child_handles(src_store, obj->obj_handle, &child_arr);
+
+       DBG("obj_handle[%d], src_path[%s], dest_path[%s], num elements[%ld]\n",
+                       obj->obj_handle, src_path, dest_path, child_arr.num_ele);
+
+       for (idx = 0; idx < child_arr.num_ele; idx++) {
+               mtp_uint32 *ptr32 = child_arr.array_entry;
+
+               child_obj = _entity_get_object_from_store(src_store, ptr32[idx]);
+               if (NULL == child_obj) {
+                       continue;
+               }
+
+               if (_util_is_file_opened(child_obj->file_path) == TRUE) {
+                       ERR_SECURE("File [%s] is already opened\n",
+                                       child_obj->file_path);
+                       return FALSE;
+               }
+
+               g_strlcpy(temp_chld_path, child_obj->file_path,
+                               MTP_MAX_PATHNAME_SIZE + 1);
+               _util_utf8_to_utf16(temp_chld_wpath,
+                               sizeof(temp_chld_wpath) / WCHAR_SIZ, temp_chld_path);
+               if (_util_wchar_len(temp_chld_wpath) >
+                               MTP_MAX_PATHNAME_SIZE - 1) {
+                       ERR("Child Object Full Path is too long[%d]\n",
+                                       strlen(child_obj->file_path));
+                       _prop_deinit_ptparray(&child_arr);
+                       return FALSE;
+               }
+
+               ptr = strstr(child_obj->file_path, src_path);
+               if (NULL == ptr) {
+                       continue;
+               }
+
+               _util_utf8_to_utf16(dest_chld_wpath,
+                               sizeof(dest_chld_wpath) / WCHAR_SIZ, src_path);
+
+               if (_util_wchar_len(dest_chld_wpath) <
+                               MTP_MAX_PATHNAME_SIZE - 1) {
+                       g_strlcpy(dest_chld_path, dest_path,
+                                       MTP_MAX_PATHNAME_SIZE + 1);
+               } else {
+                       ERR("dest_chld_wpath is too long[%d]\n",
+                                       strlen(dest_path));
+                       _prop_deinit_ptparray(&child_arr);
+                       return FALSE;
+               }
+
+               ptr += strlen(src_path);
+               if ((strlen(dest_chld_path) + strlen(ptr)) <
+                               MTP_MAX_PATHNAME_SIZE) {
+                       g_strlcat(dest_chld_path, ptr,
+                                       MTP_MAX_PATHNAME_SIZE + 1);
+               } else {
+                       ERR("dest_chld_path + ptr is too long[%d]\n",
+                                       (strlen(ptr) + strlen(ptr)));
+                       _prop_deinit_ptparray(&child_arr);
+                       return FALSE;
+               }
+               DBG("dest_chld_path[%s], ptr[%s]\n", dest_chld_path, ptr);
+
+               if (_entity_check_child_obj_path(child_obj,
+                                       temp_chld_path, dest_chld_path) == FALSE) {
+                       ERR("set full path Fail");
+                       _prop_deinit_ptparray(&child_arr);
+                       return FALSE;
+               }
+       }
+
+       _prop_deinit_ptparray(&child_arr);
+       return TRUE;
+}
+
+mtp_bool _entity_set_child_object_path(mtp_obj_t *obj, mtp_char *src_path,
+               mtp_char *dest_path)
+{
+       mtp_uint16 idx = 0;
+       mtp_char *ptr = NULL;
+       ptp_array_t child_arr = {0};
+       mtp_obj_t *child_obj = NULL;
+       mtp_store_t *src_store = NULL;
+       mtp_uint32 *child_handle_arr = NULL;
+       mtp_char dest_child_path[MTP_MAX_PATHNAME_SIZE + 1] = {0};
+       mtp_char temp_child_path[MTP_MAX_PATHNAME_SIZE + 1] = {0};
+
+       retv_if(NULL == obj, FALSE);
+       retv_if(NULL == src_path, FALSE);
+       retv_if(NULL == dest_path, FALSE);
+
+       src_store = _device_get_store_containing_obj(obj->obj_handle);
+       if (NULL == src_store) {
+               ERR("Object not present in store");
+               return FALSE;
+       }
+
+       _prop_init_ptparray(&child_arr, UINT32_TYPE);
+       _entity_get_child_handles(src_store, obj->obj_handle, &child_arr);
+       DBG("Object handle[%ld], src_path[%s], dest_path[%s], Numchild[%ld]\n",
+                       obj->obj_handle, src_path, dest_path, child_arr.num_ele);
+
+       for (idx = 0; idx < child_arr.num_ele; idx++) {
+               child_handle_arr = child_arr.array_entry;
+               child_obj = _entity_get_object_from_store(src_store, child_handle_arr[idx]);
+               if (NULL == child_obj)
+                       continue;
+               DBG_SECURE("obj_handle[%ld], full path[%s]\n", child_obj->obj_handle,
+                               child_obj->file_path);
+               g_strlcpy(temp_child_path, child_obj->file_path,
+                               sizeof(temp_child_path));
+
+               ptr = strstr(child_obj->file_path, src_path);
+               if (NULL == ptr)
+                       continue;
+
+               g_strlcpy(dest_child_path, dest_path, sizeof(dest_child_path));
+
+               ptr += strlen(src_path);
+               if (g_strlcat(dest_child_path, ptr, sizeof(dest_child_path)) >=
+                               sizeof(dest_child_path)) {
+                       ERR("g_strlcat truncation occured,failed to create\
+                                       dest_child_path");
+                       _entity_remove_reference_child_array(obj,
+                                       child_obj->obj_handle);
+                       _entity_dealloc_mtp_obj(child_obj);
+                       continue;
+               }
+               _util_delete_file_from_db(child_obj->file_path);
+
+               if (_entity_set_object_file_path(child_obj, dest_child_path,
+                                       CHAR_TYPE) == FALSE) {
+                       ERR("Failed to set full path!!");
+                       _entity_remove_reference_child_array(obj,
+                                       child_obj->obj_handle);
+                       _entity_dealloc_mtp_obj(child_obj);
+                       continue;
+               }
+
+               if (child_obj->obj_info == NULL) {
+                       ERR("obj_info is NULL");
+                       continue;
+               }
+
+               if ((child_obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION)) {
+                       if (_entity_set_child_object_path(child_obj, temp_child_path,
+                                               dest_child_path) == FALSE) {
+                               ERR("Fail to set the full path!!");
+                               _entity_remove_reference_child_array(obj,
+                                               child_obj->obj_handle);
+                               _entity_dealloc_mtp_obj(child_obj);
+                               continue;
+                       }
+               }
+       }
+
+       _prop_deinit_ptparray(&child_arr);
+       return TRUE;
+}
+
+mtp_bool _entity_add_reference_child_array(mtp_obj_t *obj, mtp_uint32 handle)
+{
+       if (_prop_find_ele_ptparray(&(obj->child_array), handle) ==
+                       ELEMENT_NOT_FOUND) {
+               return (_prop_append_ele_ptparray(&(obj->child_array), handle));
+       }
+
+       return TRUE;
+}
+
+ptp_array_t *_entity_get_reference_child_array(mtp_obj_t *obj)
+{
+       return &(obj->child_array);
+}
+
+mtp_bool _entity_set_reference_child_array(mtp_obj_t *obj, mtp_uchar *buf,
+               mtp_uint32 buf_sz)
+{
+       mtp_uint32 i = 0;
+       mtp_uint32 no_ref = 0;
+       mtp_uint32 ref_handle = 0;
+
+       retv_if(NULL == buf, FALSE);
+
+       /*Retrieve the number of references*/
+       no_ref = buf_sz;
+
+       /*Clean up the reference array*/
+       _entity_remove_reference_child_array(obj, PTP_OBJECTHANDLE_ALL);
+
+       /* Grow the array to accommodate all references*/
+       if (_prop_grow_ptparray(&(obj->child_array), no_ref) == FALSE) {
+               ERR("grow ptp Array Fail");
+               return FALSE;
+       }
+
+       ref_handle = 0;
+       for (i = 0; i < no_ref; i++) {
+               memcpy(&ref_handle, buf, sizeof(mtp_uint32));
+               buf += sizeof(mtp_uint32);
+               _prop_append_ele_ptparray(&(obj->child_array), ref_handle);
+       }
+
+       return TRUE;
+}
+
+void _entity_copy_mtp_object(mtp_obj_t *dst, mtp_obj_t *src)
+{
+       /*Copy same information*/
+       dst->obj_info = _entity_alloc_object_info();
+       if (dst->obj_info == NULL) {
+               ERR("Object info allocation Fail.");
+               return;
+       }
+       _entity_copy_obj_info(dst->obj_info, src->obj_info);
+       dst->obj_handle = 0;
+       dst->file_path = NULL;
+
+#ifndef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+       _prop_update_property_values_list(dst);
+#endif /* MTP_USE_RUNTIME_GETOBJECTPROPVALUE */
+       return;
+}
+
+mtp_bool _entity_remove_reference_child_array(mtp_obj_t *obj, mtp_uint32 handle)
+{
+       if (handle == PTP_OBJECTHANDLE_ALL) {
+               _prop_deinit_ptparray(&(obj->child_array));
+               return TRUE;
+       }
+       return _prop_rem_elem_ptparray(&(obj->child_array), handle);
+}
+
+void _entity_dealloc_mtp_obj(mtp_obj_t *obj)
+{
+       mtp_uint16 ii = 0;
+       slist_node_t *node = NULL;
+       slist_node_t *next_node = NULL;
+
+       ret_if(NULL == obj);
+
+       if (obj->obj_info) {
+               _entity_dealloc_obj_info(obj->obj_info);
+               obj->obj_info = NULL;
+       }
+
+       _entity_remove_reference_child_array(obj, PTP_OBJECTHANDLE_ALL);
+
+       for (ii = 0, next_node = obj->propval_list.start;
+                       ii < obj->propval_list.nnodes; ii++) {
+               node = next_node;
+               next_node = node->link;
+               _prop_destroy_obj_propval((obj_prop_val_t *)node->value);
+               g_free(node);
+       }
+
+       g_free(obj->file_path);
+       g_free(obj);
+       obj = NULL;
+       return;
+}
diff --git a/src/entity/mtp_property.c b/src/entity/mtp_property.c
new file mode 100755 (executable)
index 0000000..37151d2
--- /dev/null
@@ -0,0 +1,4984 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <glib.h>
+#include "mtp_property.h"
+#include "mtp_media_info.h"
+#include "mtp_support.h"
+#include "mtp_transport.h"
+
+/*
+ * EXTERN AND GLOBAL VARIABLES
+ */
+obj_interdep_proplist_t interdep_proplist;
+/*
+ * STATIC VARIABLES
+ */
+static obj_prop_desc_t props_list_mp3[NUM_OBJECT_PROP_DESC_MP3];
+static obj_prop_desc_t props_list_wma[NUM_OBJECT_PROP_DESC_WMA];
+static obj_prop_desc_t props_list_wmv[NUM_OBJECT_PROP_DESC_WMV];
+static obj_prop_desc_t props_list_album[NUM_OBJECT_PROP_DESC_ALBUM];
+static obj_prop_desc_t props_list_default[NUM_OBJECT_PROP_DESC_DEFAULT];
+
+/*
+ * STATIC FUNCTIONS
+ */
+static mtp_uint16 __get_ptp_array_elem_size(data_type_t type);
+static mtp_bool __check_object_propcode(obj_prop_desc_t *prop,
+               mtp_uint32 propcode, mtp_uint32 group_code);
+static mtp_bool __create_prop_integer(mtp_obj_t *obj,
+               mtp_uint16 propcode, mtp_uint64 value);
+static mtp_bool __create_prop_string(mtp_obj_t *obj, mtp_uint16 propcode,
+               mtp_wchar *value);
+static mtp_bool __create_prop_array(mtp_obj_t *obj, mtp_uint16 propcode,
+               mtp_char *arr, mtp_uint32 size);
+#ifdef MTP_SUPPORT_PROPERTY_SAMPLE
+static mtp_bool __create_prop_sample(mtp_obj_t *obj);
+static void __build_supported_sample_props(mtp_uchar *count,
+               obj_prop_desc_t *prop);
+#endif /*MTP_SUPPORT_PROPERTY_SAMPLE*/
+static mtp_bool __update_prop_values_audio(mtp_obj_t *obj);
+static mtp_bool __update_prop_values_video(mtp_obj_t *obj);
+static mtp_bool __update_prop_values_image(mtp_obj_t *obj);
+static mtp_bool __prop_common_metadata(mtp_obj_t *obj,
+               common_meta_t *p_metata);
+static void __build_supported_common_props(mtp_uchar *count,
+               obj_prop_desc_t *prop);
+/* PtpString Functions */
+#ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
+static ptp_string_t *__alloc_ptpstring(void);
+#else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+static ptp_string_t *__alloc_ptpstring(mtp_uint32 size);
+#endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+static void __init_obj_propval(obj_prop_val_t *val, obj_prop_desc_t *prop);
+static void __init_ptptimestring(ptp_time_string_t *pstring);
+static mtp_uint32 __size_curval_device_prop(device_prop_desc_t *prop);
+static void __init_obj_prop_desc(obj_prop_desc_t *prop, mtp_uint16 propcode,
+               mtp_uint16 data_type, mtp_uchar get_set, mtp_uchar form_flag,
+               mtp_uint32 group_code);
+static mtp_uint32 __get_size_default_val_obj_prop_desc(obj_prop_desc_t *prop);
+static void __destroy_obj_prop_desc(obj_prop_desc_t *prop);
+static mtp_uint32 __count_obj_proplist(obj_proplist_t *plist);
+static mtp_bool __append_obj_proplist(obj_proplist_t *prop_list, mtp_uint32 obj_handle,
+               mtp_uint16 prop_code, mtp_uint32 data_type, mtp_uchar *val);
+#ifdef MTP_SUPPORT_INTERDEPENDENTPROP
+static mtp_bool __append_interdep_prop(interdep_prop_config_t *config,
+               obj_prop_desc_t *prop);
+#endif /* MTP_SUPPORT_INTERDEPENDENTPROP */
+static mtp_uint32 __count_interdep_proplist(obj_interdep_proplist_t *config_list,
+               mtp_uint32 format_code);
+/*
+ * FUNCTIONS
+ */
+static mtp_bool __check_object_propcode(obj_prop_desc_t *prop,
+               mtp_uint32 propcode, mtp_uint32 group_code)
+{
+       if ((prop->propinfo.prop_code == propcode) ||
+                       ((propcode == PTP_PROPERTY_ALL) &&
+                        !(prop->group_code & GROUP_CODE_SLOW)) ||
+                       ((propcode == PTP_PROPERTY_UNDEFINED) &&
+                        (prop->group_code & group_code))) {
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+static mtp_bool __create_prop_integer(mtp_obj_t *obj,
+               mtp_uint16 propcode, mtp_uint64 value)
+{
+       obj_prop_desc_t *prop = NULL;
+       obj_prop_val_t *prop_val = NULL;
+       mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
+
+       retv_if(obj == NULL, FALSE);
+       retv_if(obj->obj_info == NULL, FALSE);
+
+       prop = _prop_get_obj_prop_desc(fmt_code, propcode);
+       if (NULL == prop) {
+               ERR("Create property Fail.. Prop = [0x%X]\n", propcode);
+               return FALSE;
+       }
+
+       propvalue_alloc_and_check(prop_val);
+       _prop_set_current_integer_val(prop_val, value);
+       node_alloc_and_append();
+
+       return TRUE;
+}
+
+static mtp_bool __create_prop_string(mtp_obj_t *obj, mtp_uint16 propcode,
+               mtp_wchar *value)
+{
+       ptp_string_t ptp_str = {0};
+       obj_prop_desc_t *prop = NULL;
+       obj_prop_val_t *prop_val = NULL;
+       mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
+
+       retv_if(obj == NULL, FALSE);
+       retv_if(obj->obj_info == NULL, FALSE);
+
+       prop = _prop_get_obj_prop_desc(fmt_code, propcode);
+       if (NULL == prop) {
+               ERR("Create property Fail.. Prop = [0x%X]\n", propcode);
+               return FALSE;
+       }
+
+       propvalue_alloc_and_check(prop_val);
+       _prop_copy_char_to_ptpstring(&ptp_str, value, WCHAR_TYPE);
+       _prop_set_current_string_val(prop_val, &ptp_str);
+       node_alloc_and_append();
+
+       return TRUE;
+}
+
+static mtp_bool __create_prop_timestring(mtp_obj_t *obj,
+       mtp_uint32 propcode, ptp_time_string_t *value)
+{
+       obj_prop_desc_t *prop  = NULL;
+       obj_prop_val_t *prop_val= NULL;
+       mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
+
+       retv_if(obj == NULL, FALSE);
+       retv_if(obj->obj_info == NULL, FALSE);
+
+       prop = _prop_get_obj_prop_desc(fmt_code, propcode);
+       if (NULL == prop) {
+               ERR("Create property Fail.. Prop = [0x%X]\n", propcode);
+               return FALSE;
+       }
+
+       propvalue_alloc_and_check(prop_val);
+       _prop_set_current_string_val(prop_val, (ptp_string_t *)value);
+       node_alloc_and_append();
+
+       return TRUE;
+}
+
+static mtp_bool __create_prop_array(mtp_obj_t *obj, mtp_uint16 propcode,
+               mtp_char *arr, mtp_uint32 size)
+{
+       obj_prop_desc_t *prop = NULL;
+       obj_prop_val_t *prop_val = NULL;
+       mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
+
+       retv_if(obj == NULL, FALSE);
+       retv_if(obj->obj_info == NULL, FALSE);
+
+       prop = _prop_get_obj_prop_desc(fmt_code, propcode);
+       if (NULL == prop) {
+               ERR("Create property Fail.. Prop = [0x%X]\n", propcode);
+               return FALSE;
+       }
+
+       propvalue_alloc_and_check(prop_val);
+       _prop_set_current_array_val(prop_val, (mtp_uchar *)arr, size);
+       node_alloc_and_append();
+
+       return TRUE;
+}
+
+static mtp_bool __update_prop_values_audio(mtp_obj_t *obj)
+{
+       mtp_bool success = TRUE;
+       mtp_int32 converted_rating = 0;
+       comp_audio_meta_t audio_data = {{0}, {0}};
+
+       retv_if(obj == NULL, FALSE);
+       retv_if(obj->obj_info == NULL, FALSE);
+
+       if (_util_get_audio_metadata(obj->file_path, &audio_data) == FALSE) {
+               if (_util_get_audio_meta_from_extractor(obj->file_path,
+                                       &audio_data) == FALSE) {
+                       success = FALSE;
+                       goto DONE;
+               }
+       }
+
+       /*Update common metadata information*/
+       if (FALSE == __prop_common_metadata(obj,
+                               &(audio_data.commonmeta))) {
+               ERR("Common  metadata update Fail");
+               success = FALSE;
+               goto DONE;
+       }
+
+
+       /*--------------TRACK--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_TRACK, audio_data.audiometa.track)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*--------------USER RATING--------------*/
+       /* DCM rating -> MTP (WMP) rating */
+       switch (audio_data.commonmeta.rating) {
+       case 1:
+               converted_rating = 1;   /* 1-12 */
+               break;
+       case 2:
+               converted_rating = 25;  /* 13-37 */
+               break;
+       case 3:
+               converted_rating = 50;  /* 37-62 */
+               break;
+       case 4:
+               converted_rating = 75;  /* 63-86 */
+               break;
+       case 5:
+               converted_rating = 99;  /* 87-100 */
+               break;
+       default:
+               converted_rating = 0;   /* otherwise */
+               break;
+       }
+
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_USERRATING, converted_rating)) {
+               success = FALSE;
+               goto DONE;
+
+       }
+
+       /*-------------AUDIOWAVECODEC--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC,
+                               MTP_WAVEFORMAT_UNKNOWN)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+DONE:
+       _util_free_common_meta(&(audio_data.commonmeta));
+       return success;
+}
+
+static mtp_bool __update_prop_values_video(mtp_obj_t *obj)
+{
+       mtp_bool success = TRUE;
+       mtp_int32 converted_rating = 0;
+       comp_video_meta_t video_data = { {0,}, {0,} };
+       video_meta_t *viddata = &(video_data.videometa);
+       mtp_wchar buf[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+       retv_if(obj == NULL, FALSE);
+       retv_if(obj->obj_info == NULL, FALSE);
+       retv_if(obj->file_path == NULL, FALSE);
+
+       if (_util_get_video_metadata(obj->file_path, &video_data) == FALSE) {
+               if (_util_get_video_meta_from_extractor(obj->file_path,
+                                       &video_data) == FALSE) {
+                       success = FALSE;
+                       goto DONE;
+               }
+       }
+
+       /*Update common metadata information*/
+       if (FALSE == __prop_common_metadata(obj,
+                               &(video_data.commonmeta))) {
+               ERR("Common  metadata update Fail");
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*--------------TRACK--------------*/
+       if ((viddata->track != NULL) && strlen(viddata->track) > 0) {
+               if (FALSE == __create_prop_integer(obj,
+                                       MTP_OBJ_PROPERTYCODE_TRACK,
+                                       atoi(viddata->track))) {
+                       success = FALSE;
+                       goto DONE;
+               }
+       }
+
+       /*--------------AUDIO WAVE CODEC--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC, 0)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*--------------VIDEO CODEC--------------*/
+       /*
+        * Conversion needs to be decided from audio_codec to
+        * exact format by spec
+        */
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_VIDEOFOURCCCODEC, 0)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*--------------VIDEO FRAMES PER 1K SECONDS--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_FRAMESPER1KSECONDS,
+                               viddata->video_fps * 1000)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*--------------VIDEO BITRATE--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_VIDEOBITRATE,
+                               viddata->video_br)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*--------------VIDEO WIDTH--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_WIDTH, viddata->video_w)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*--------------VIDEO HEIGHT--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_HEIGHT, viddata->video_h)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*--------------USER RATING--------------*/
+       switch (video_data.commonmeta.rating) {
+       case 1:
+               converted_rating = 1;   /* 1-12 */
+               break;
+       case 2:
+               converted_rating = 25;  /* 13-37 */
+               break;
+       case 3:
+               converted_rating = 50;  /* 37-62 */
+               break;
+       case 4:
+               converted_rating = 75;  /* 63-86 */
+               break;
+       case 5:
+               converted_rating = 99;  /* 87-100 */
+               break;
+       default:
+               converted_rating = 0;   /* otherwise */
+               break;
+       }
+
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_USERRATING, converted_rating)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*----------ENCODING PROFILE----------*/
+       _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ, "");
+       if (FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO, buf)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*----------METAGENRE-----------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_METAGENRE, 0x00)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+       /*---------SCAN TYPE---------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_SCANTYPE, 0x00)) {
+               success = FALSE;
+               goto DONE;
+       }
+
+DONE:
+       _util_free_common_meta(&(video_data.commonmeta));
+       _util_free_video_meta(&(video_data.videometa));
+       return success;
+}
+
+static mtp_bool __update_prop_values_image(mtp_obj_t *obj)
+{
+       image_meta_t image_data;
+
+       retv_if(obj == NULL, FALSE);
+       retv_if(obj->obj_info == NULL, FALSE);
+
+       if (_util_get_image_ht_wt(obj->file_path, &image_data) == FALSE)
+               return FALSE;
+
+       /*--------------IMAGE WIDTH--------------*/
+       if (FALSE == __create_prop_integer(obj, MTP_OBJ_PROPERTYCODE_WIDTH,
+                               image_data.wt))
+               return FALSE;
+
+       /*--------------IMAGE HEIGHT--------------*/
+       if (FALSE == __create_prop_integer(obj, MTP_OBJ_PROPERTYCODE_HEIGHT,
+                               image_data.ht))
+               return FALSE;
+
+       return TRUE;
+}
+
+static mtp_bool __prop_common_metadata(mtp_obj_t *obj,
+               common_meta_t *p_metata)
+{
+       mtp_wchar buf[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+       /*--------------ARTIST--------------*/
+       if (p_metata->artist != NULL && strlen(p_metata->artist) > 0) {
+               _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
+                               p_metata->artist);
+       }
+#ifdef MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN
+       else {
+               DBG("got null artist");
+               _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
+                               MTP_UNKNOWN_METADATA);
+       }
+#endif /*MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN*/
+
+       if (FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_ARTIST, buf)) {
+               return FALSE;
+       }
+
+       /*--------------ALBUM--------------*/
+       if (p_metata->album != NULL && strlen(p_metata->album) > 0) {
+               _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
+                               p_metata->album);
+       }
+#ifdef MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN
+       else {
+               DBG("got null album");
+               _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
+                               MTP_UNKNOWN_METADATA);
+       }
+#endif /*MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN*/
+
+       if (FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_ALBUMNAME, buf)) {
+               return FALSE;
+       }
+
+       /*--------------GENRE--------------*/
+       if (p_metata->genre != NULL && strlen(p_metata->genre) > 0) {
+               _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
+                               p_metata->genre);
+       }
+#ifdef MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN
+       else {
+               DBG("got null genre");
+               _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
+                               MTP_UNKNOWN_METADATA);
+       }
+#endif /*MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN*/
+
+       if (FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_GENRE, buf)) {
+               return FALSE;
+       }
+
+       /*--------------AUTHOR--------------*/
+       if (p_metata->author != NULL && strlen(p_metata->author) > 0) {
+               _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
+                               p_metata->author);
+       }
+#ifdef MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN
+       else {
+               DBG("got null author");
+               _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ,
+                               MTP_UNKNOWN_METADATA);
+       }
+#endif /*MTP_USE_FILL_EMPTYMETADATA_WITH_UNKNOWN*/
+
+       if (FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_COMPOSER, buf)) {
+               return FALSE;
+       }
+
+       /*--------------COPYRIGHT--------------*/
+       if ((p_metata->copyright != NULL) && strlen(p_metata->copyright) > 0) {
+               _util_utf8_to_utf16(buf,
+                               sizeof(buf) / WCHAR_SIZ,
+                               p_metata->copyright);
+       } else {
+               _util_utf8_to_utf16(buf,
+                               sizeof(buf) / WCHAR_SIZ, "");
+       }
+
+       if (FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO, buf)) {
+               return FALSE;
+       }
+
+       /*--------------DURATION--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_DURATION, p_metata->duration)) {
+               return FALSE;
+       }
+
+       /*--------------AUDIO BITRATE--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_AUDIOBITRATE, p_metata->audio_bitrate)) {
+               return FALSE;
+       }
+
+       /*--------------RELEASE YEAR--------------*/
+       if ((p_metata->year != NULL) && strlen(p_metata->year) > 0) {
+               _util_utf8_to_utf16(buf,
+                               sizeof(buf) / WCHAR_SIZ,
+                               p_metata->year);
+       } else {
+               _util_utf8_to_utf16(buf,
+                               sizeof(buf) / WCHAR_SIZ, "");
+       }
+
+       if (FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_ORIGINALRELEASEDATE, buf)) {
+               return FALSE;
+       }
+
+       /*--------------DESCRIPTION--------------*/
+       if ((p_metata->description != NULL) &&
+                       strlen(p_metata->description) > 0) {
+               _util_utf8_to_utf16(buf,
+                               sizeof(buf) / WCHAR_SIZ,
+                               p_metata->description);
+       } else {
+               _util_utf8_to_utf16(buf,
+                               sizeof(buf) / WCHAR_SIZ, "");
+       }
+
+       if (FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_DESCRIPTION, buf)) {
+               return FALSE;
+       }
+
+       /*--------------SAMPLE RATE--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_SAMPLERATE, p_metata->sample_rate)) {
+               return FALSE;
+       }
+
+       /*-------------NUMBEROFCHANNELS--------------*/
+       if (FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS, p_metata->num_channel)) {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static void __build_supported_common_props(mtp_uchar *count,
+               obj_prop_desc_t *prop)
+{
+       mtp_uchar i = 0;
+       mtp_wchar str[MTP_MAX_REG_STRING + 1] = { 0 };
+       mtp_uint32 default_val;
+
+       _util_utf8_to_utf16(str, sizeof(str) / WCHAR_SIZ, "");
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_ARTIST (1)
+        */
+       __init_obj_prop_desc((prop + i),
+                       MTP_OBJ_PROPERTYCODE_ARTIST,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_OBJECT);
+       _prop_set_default_string(&(prop[i].propinfo), str);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_DURATION (2)
+        */
+       __init_obj_prop_desc((prop + i),
+                       MTP_OBJ_PROPERTYCODE_DURATION,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = 0x0;
+       _prop_set_range_integer(&(prop[i].propinfo), 0, 0xffffffff, 1L);
+       _prop_set_default_integer(&((prop[i].propinfo)), (mtp_uchar *) &default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_USERRATING (3)
+        */
+       __init_obj_prop_desc((prop + i),
+                       MTP_OBJ_PROPERTYCODE_USERRATING,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = 0x0;
+       _prop_set_range_integer(&(prop[i].propinfo), 0, 100, 1L);
+       _prop_set_default_integer(&(prop[i].propinfo),
+                       (mtp_uchar *) &default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_TRACK (4)
+        */
+       __init_obj_prop_desc((prop + i),
+                       MTP_OBJ_PROPERTYCODE_TRACK,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = 0x0;
+       _prop_set_default_integer(&(prop[i].propinfo),
+                       (mtp_uchar *) &default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_GENRE (5)
+        */
+       __init_obj_prop_desc((prop + i),
+                       MTP_OBJ_PROPERTYCODE_GENRE,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_OBJECT);
+       _prop_set_default_string(&(prop[i].propinfo), str);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_ORIGINALRELEASEDATE (6)
+        */
+       __init_obj_prop_desc((prop + i),
+                       MTP_OBJ_PROPERTYCODE_ORIGINALRELEASEDATE,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETONLY,
+                       DATE_TIME_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+       _prop_set_default_string(&(prop[i].propinfo), str);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_ALBUMNAME (7)
+        */
+       __init_obj_prop_desc((prop + i),
+                       MTP_OBJ_PROPERTYCODE_ALBUMNAME,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_OBJECT);
+       _prop_set_default_string(&(prop[i].propinfo), str);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_COMPOSER (8)
+        */
+       __init_obj_prop_desc((prop + i),
+                       MTP_OBJ_PROPERTYCODE_COMPOSER,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_OBJECT);
+       _prop_set_default_string(&(prop[i].propinfo), str);
+       i++;
+
+       *count += i;
+
+       return;
+}
+
+/* PTP Array Functions */
+void _prop_init_ptparray(ptp_array_t *parray, data_type_t type)
+{
+       mtp_uint16 size = 0;
+       parray->num_ele = 0;
+       parray->type = type;
+
+       size = __get_ptp_array_elem_size(type);
+       if (size == 0)
+               return;
+
+       parray->array_entry = g_malloc(size * INITIAL_ARRAY_SIZE);
+       if (parray->array_entry == NULL) {
+               parray->arr_size = 0;
+       } else {
+               parray->arr_size = INITIAL_ARRAY_SIZE;
+               memset(parray->array_entry, 0, size * INITIAL_ARRAY_SIZE);
+       }
+       return;
+}
+
+ptp_array_t *_prop_alloc_ptparray(data_type_t type)
+{
+       ptp_array_t *parray;
+       parray = (ptp_array_t *)g_malloc(sizeof(ptp_array_t));
+       if (parray != NULL) {
+               _prop_init_ptparray(parray, type);
+       }
+
+       return (parray);
+}
+
+mtp_uint32 _prop_get_size_ptparray(ptp_array_t *parray)
+{
+       mtp_uint16 size = 0;
+
+       if (parray == NULL) {
+               ERR("ptp_array_t is NULL");
+               return 0;
+       }
+
+       size = __get_ptp_array_elem_size(parray->type);
+       if (size == 0)
+               return 0;
+
+       return (sizeof(mtp_uint32) + (size *parray->num_ele));
+}
+
+mtp_uint32 _prop_get_size_ptparray_without_elemsize(ptp_array_t *parray)
+{
+       mtp_uint16 size = 0;
+
+       size = __get_ptp_array_elem_size(parray->type);
+       if (size == 0)
+               return 0;
+
+       return (size * parray->num_ele);
+}
+
+mtp_bool _prop_grow_ptparray(ptp_array_t *parray, mtp_uint32 new_size)
+{
+       mtp_uint16 size = 0;
+
+       size = __get_ptp_array_elem_size(parray->type);
+       if (size == 0)
+               return FALSE;
+
+       if (parray->arr_size == 0)
+               _prop_init_ptparray(parray, parray->type);
+
+       if (new_size < parray->arr_size)
+               return TRUE;
+
+       parray->array_entry =
+               g_realloc(parray->array_entry, size * new_size);
+       if (parray->array_entry == NULL) {
+               parray->arr_size = 0;
+               return FALSE;
+       }
+       parray->arr_size = new_size;
+
+       return TRUE;
+}
+
+mtp_int32 _prop_find_ele_ptparray(ptp_array_t *parray, mtp_uint32 element)
+{
+       mtp_uchar *ptr8 = NULL;
+       mtp_uint16 *ptr16 = NULL;
+       mtp_uint32 *ptr32 = NULL;
+       mtp_int32 ii;
+
+       retv_if(parray->array_entry == NULL, ELEMENT_NOT_FOUND);
+
+       switch (parray->type) {
+       case UINT8_TYPE:
+               ptr8 = parray->array_entry;
+               for (ii = 0; ii < parray->num_ele; ii++) {
+                       if (ptr8[ii] == (mtp_uchar) element) {
+                               return ii;
+                       }
+               }
+               break;
+
+       case UINT16_TYPE:
+               ptr16 = parray->array_entry;
+               for (ii = 0; ii < parray->num_ele; ii++) {
+                       if (ptr16[ii] == (mtp_uint16) element) {
+                               return ii;
+                       }
+               }
+               break;
+
+       case PTR_TYPE:
+       case UINT32_TYPE:
+               ptr32 = parray->array_entry;
+               for (ii = 0; ii < parray->num_ele; ii++) {
+                       if (ptr32[ii] == (mtp_uint32)element) {
+                               return ii;
+                       }
+               }
+               break;
+
+       default:
+               break;
+       }
+       return ELEMENT_NOT_FOUND;
+}
+
+mtp_bool _prop_get_ele_ptparray(ptp_array_t *parray, mtp_uint32 index, void *ele)
+{
+       mtp_uchar *ptr8 = NULL;
+       mtp_uint16 *ptr16 = NULL;
+       mtp_uint32 *ptr32 = NULL;
+
+       retv_if(parray->array_entry == NULL, FALSE);
+
+       if (index >= parray->num_ele)
+               return FALSE;
+
+       switch (parray->type) {
+       case UINT8_TYPE:
+               ptr8 = parray->array_entry;
+               *((mtp_uchar *)ele) = ptr8[index];
+               break;
+       case UINT16_TYPE:
+               ptr16 = parray->array_entry;
+               *((mtp_uint16 *)ele) = ptr16[index];
+               break;
+
+       case PTR_TYPE:
+       case UINT32_TYPE:
+               ptr32 = parray->array_entry;
+               *((mtp_uint32 *)ele) = ptr32[index];
+               break;
+       default:
+               return FALSE;
+       }
+       return TRUE;
+}
+
+mtp_bool _prop_append_ele_ptparray(ptp_array_t *parray, mtp_uint32 element)
+{
+
+       mtp_uchar *ptr8 = NULL;
+       mtp_uint16 *ptr16 = NULL;
+       mtp_uint32 *ptr32 = NULL;
+
+       if (parray->num_ele >= parray->arr_size) {
+               ERR("parray->num_ele [%d] is bigger than parray->arr_size [%d]\n",
+                               parray->num_ele, parray->arr_size);
+               if (FALSE == _prop_grow_ptparray(parray,
+                                       ((parray->arr_size * 3) >> 1) + 2))
+                       return FALSE;
+       }
+
+       switch (parray->type) {
+       case UINT8_TYPE:
+               ptr8 = parray->array_entry;
+               ptr8[parray->num_ele++] = (mtp_uchar)element;
+               break;
+
+       case UINT16_TYPE:
+               ptr16 = parray->array_entry;
+               ptr16[parray->num_ele++] = (mtp_uint16) element;
+               break;
+
+       case PTR_TYPE:
+       case UINT32_TYPE:
+               ptr32 = parray->array_entry;
+               ptr32[parray->num_ele++] = (mtp_uint32)element;
+               break;
+
+       default:
+               break;
+       }
+
+       return TRUE;
+}
+
+mtp_bool _prop_append_ele128_ptparray(ptp_array_t *parray, mtp_uint64 *element)
+{
+       mtp_uchar *ptr = NULL;
+       mtp_bool ret = FALSE;
+       if (parray->num_ele >= parray->arr_size) {
+               if (FALSE == _prop_grow_ptparray(parray,
+                                       ((parray->arr_size * 3) >> 1) + 2))
+                       return FALSE;
+       }
+
+       switch (parray->type) {
+       case UINT128_TYPE:
+               ptr = parray->array_entry;
+               memcpy(&(ptr[(parray->num_ele * 16)]), element,
+                               sizeof(mtp_uint64) * 2);
+               parray->num_ele++;
+               ret = TRUE;
+               break;
+
+       default:
+               break;
+       }
+
+       return ret;
+}
+
+mtp_bool _prop_copy_ptparray(ptp_array_t *dst, ptp_array_t *src)
+{
+       mtp_uchar *ptr8src = NULL;
+       mtp_uint16 *ptr16src = NULL;
+       mtp_uint32 *ptr32src = NULL;
+       mtp_uint32 ii;
+
+       dst->type = src->type;
+
+       switch (src->type) {
+       case UINT8_TYPE:
+               ptr8src = src->array_entry;
+               for (ii = 0; ii < src->num_ele; ii++)
+                       _prop_append_ele_ptparray(dst, ptr8src[ii]);
+               break;
+
+       case UINT16_TYPE:
+               ptr16src = src->array_entry;
+               for (ii = 0; ii < src->num_ele; ii++)
+                       _prop_append_ele_ptparray(dst, ptr16src[ii]);
+               break;
+
+       case PTR_TYPE:
+       case UINT32_TYPE:
+               ptr32src = src->array_entry;
+               for (ii = 0; ii < src->num_ele; ii++)
+                       _prop_append_ele_ptparray(dst, ptr32src[ii]);
+               break;
+
+       default:
+               return 0;
+       }
+       return TRUE;
+}
+
+mtp_uint32 _prop_pack_ptparray(ptp_array_t *parray, mtp_uchar *buf,
+               mtp_uint32 bufsize)
+{
+       if (parray == NULL || buf == NULL) {
+               ERR("pArray or buf is NULL");
+               return 0;
+       }
+
+       mtp_uint16 size = 1;
+
+       size = __get_ptp_array_elem_size(parray->type);
+       if (size == 0)
+               return 0;
+
+       if ((buf == NULL) || (bufsize < (sizeof(mtp_uint32) +
+                                       parray->num_ele * size)))
+               return 0;
+
+       memcpy(buf, &(parray->num_ele), sizeof(mtp_uint32));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(buf, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+
+       if (parray->num_ele != 0) {
+#ifdef __BIG_ENDIAN__
+               mtp_uint32 ii;
+               mtp_uchar *temp = buf + sizeof(mtp_uint32);
+               mtp_uchar *ptr_entry = parray->array_entry;
+
+               for (ii = 0; ii < parray->num_ele; ii++) {
+                       memcpy(temp, ptr_entry, size);
+                       _util_conv_byte_order(temp, size);
+                       temp += size;
+                       ptr_entry += size;
+               }
+#else /* __BIG_ENDIAN__ */
+               memcpy(buf + sizeof(mtp_uint32), parray->array_entry,
+                               parray->num_ele * size);
+#endif /* __BIG_ENDIAN__ */
+       }
+       return (sizeof(mtp_uint32) + parray->num_ele * size);
+}
+
+mtp_uint32 _prop_pack_ptparray_without_elemsize(ptp_array_t *parray,
+               mtp_uchar *buf, mtp_uint32 bufsize)
+{
+       mtp_uint16 size = 1;
+#ifdef __BIG_ENDIAN__
+       mtp_uchar *temp;
+       mtp_uint32 ii;
+#endif /* __BIG_ENDIAN__ */
+
+       size = __get_ptp_array_elem_size(parray->type);
+       if (size == 0)
+               return 0;
+
+       if ((buf == NULL) || (bufsize < (parray->num_ele * size)))
+               return 0;
+
+       if (parray->num_ele != 0)
+               memcpy(buf, parray->array_entry, parray->num_ele * size);
+
+#ifdef __BIG_ENDIAN__
+       /* Swap all the elements */
+       temp = buf;
+       for (ii = 0; ii < parray->num_ele; ii++) {
+               _util_conv_byte_order(temp, size);
+               temp += size;
+       }
+#endif /* __BIG_ENDIAN__ */
+
+       return (parray->num_ele * size);
+}
+
+mtp_bool _prop_rem_elem_ptparray(ptp_array_t *parray, mtp_uint32 element)
+{
+       mtp_uchar *ptr8 = NULL;
+       mtp_uint16 *ptr16 = NULL;
+       mtp_uint32 *ptr32 = NULL;
+       mtp_int32 ii;
+
+       ii = _prop_find_ele_ptparray(parray, element);
+
+       if (ii == ELEMENT_NOT_FOUND)
+               return FALSE;
+
+       switch (parray->type) {
+       case UINT8_TYPE:
+               ptr8 = parray->array_entry;
+               for (; ii < (parray->num_ele - 1); ii++)
+                       ptr8[ii] = ptr8[ii + 1];
+               break;
+
+       case UINT16_TYPE:
+               ptr16 = parray->array_entry;
+               for (; ii < (parray->num_ele - 1); ii++)
+                       ptr16[ii] = ptr16[ii + 1];
+               break;
+
+       case UINT32_TYPE:
+               ptr32 = parray->array_entry;
+               for (; ii < (parray->num_ele - 1); ii++)
+                       ptr32[ii] = ptr32[ii + 1];
+               break;
+
+       case PTR_TYPE:
+               ptr32 = parray->array_entry;
+               for (; ii < (parray->num_ele - 1); ii++)
+                       ptr32[ii] = ptr32[ii + 1];
+               break;
+
+       default:
+               break;
+       }
+
+       parray->num_ele--;
+
+       return TRUE;
+
+}
+
+void _prop_deinit_ptparray(ptp_array_t *parray)
+{
+       parray->num_ele = 0;
+       parray->arr_size = 0;
+       if (parray->array_entry) {
+               g_free(parray->array_entry);
+       }
+       parray->array_entry = NULL;
+       return;
+}
+
+void _prop_destroy_ptparray(ptp_array_t *parray)
+{
+       if (parray == NULL)
+               return;
+
+       if (parray->array_entry != NULL) {
+               g_free(parray->array_entry);
+       }
+       parray->arr_size = 0;
+       parray->num_ele = 0;
+       g_free(parray);
+       return;
+}
+
+mtp_uint16 __get_ptp_array_elem_size(data_type_t type)
+{
+       mtp_uint16 size = 0;
+
+       switch (type) {
+       case UINT8_TYPE:
+               size = 1;
+               break;
+       case UINT16_TYPE:
+               size = 2;
+               break;
+       case PTR_TYPE:
+       case UINT32_TYPE:
+               size = 4;
+               break;
+       case UINT128_TYPE:
+               size = 16;
+               break;
+       default:
+               size = 0;
+               break;
+       }
+
+       return size;
+}
+
+/* PtpString Functions */
+#ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
+static ptp_string_t *__alloc_ptpstring(void)
+{
+       ptp_string_t *pstring = NULL;
+
+       pstring = (ptp_string_t *)g_malloc(sizeof(ptp_string_t));
+       if (pstring != NULL) {
+               _prop_init_ptpstring(pstring);
+       }
+
+       return (pstring);
+}
+#else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+static ptp_string_t *__alloc_ptpstring(mtp_uint32 size)
+{
+       ptp_string_t *pstring = NULL;
+       mtp_int32 size_tmp = 0;
+       mtp_int32 alloc_size = 0;
+
+       size_tmp = sizeof(wchar_t) * size + sizeof(wchar_t) * 2;
+       alloc_size = ((size_tmp >> 5) + 1) << 5;        /* multiple of 32 */
+
+       pstring = (ptp_string_t *)g_malloc(alloc_size); /* for margin */
+       if (pstring != NULL) {
+               _prop_init_ptpstring(pstring);
+       }
+
+       return (pstring);
+}
+#endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+
+void _prop_init_ptpstring(ptp_string_t *pstring)
+{
+       pstring->num_chars = 0;
+       return;
+}
+
+static void __init_ptptimestring(ptp_time_string_t *pstring)
+{
+       pstring->num_chars = 0;
+}
+
+void _prop_copy_char_to_ptpstring(ptp_string_t *pstring, void *str,
+               char_mode_t cmode)
+{
+       if (pstring == NULL)
+               return;
+
+       mtp_char *pchar = NULL;
+       mtp_wchar *pwchar = NULL;
+       mtp_uchar i = 0;
+
+       pchar = (mtp_char *)str;
+       pwchar = (mtp_wchar *)str;
+
+       if (str == NULL) {
+               pstring->num_chars = 0;
+               return;
+       }
+
+       if (cmode == CHAR_TYPE) {
+               if (pchar[0] == 0) {
+                       pstring->num_chars = 0;
+                       return;
+               }
+               for (i = 0; i < MAX_PTP_STRING_CHARS && pchar[i]; i++) {
+                       pstring->str[i] = (mtp_wchar)pchar[i];
+               }
+       } else if (cmode == WCHAR_TYPE) {
+               if (pwchar[0] == 0) {
+                       pstring->num_chars = 0;
+                       return;
+               }
+               for (i = 0; i < MAX_PTP_STRING_CHARS && pwchar[i]; i++) {
+                       pstring->str[i] = pwchar[i];
+               }
+       } else {
+               ERR("Unknown character mode : %d\n", cmode);
+               pstring->num_chars = 0;
+               return;
+       }
+
+       if (i == MAX_PTP_STRING_CHARS)
+               pstring->num_chars = i;
+       else
+               pstring->num_chars = i + 1;
+
+       pstring->str[pstring->num_chars - 1] = (mtp_wchar)0;
+
+       return;
+}
+
+void _prop_copy_time_to_ptptimestring(ptp_time_string_t *pstring,
+               system_time_t *sys_time)
+{
+       char time[17] = { 0 };
+
+       if (sys_time == NULL) {
+               __init_ptptimestring(pstring);
+       } else {
+#if defined(NEED_TO_PORT)
+               _util_wchar_swprintf(pstring->str, sizeof(pstring->str) / WCHAR_SIZ,
+                               "%04d%02d%02dT%02d%02d%02d.%01d",
+                               sys_time->year, sys_time->month,
+                               sys_time->day, sys_time->hour,
+                               sys_time->minute, sys_time->second,
+                               (sys_time->millisecond) / 100);
+#else
+               g_snprintf(time, sizeof(time), "%04d%02d%02dT%02d%02d%02d.%01d",
+                               sys_time->year, sys_time->month, sys_time->day,
+                               sys_time->hour, sys_time->minute,
+                               sys_time->second, (sys_time->millisecond) / 100);
+
+               _util_utf8_to_utf16(pstring->str, sizeof(pstring->str) / WCHAR_SIZ, time);
+#endif
+               pstring->num_chars = 17;
+               pstring->str[17] = '\0';
+       }
+       return;
+}
+
+void _prop_copy_ptpstring(ptp_string_t *dst, ptp_string_t *src)
+{
+       mtp_uint16 ii;
+
+       dst->num_chars = src->num_chars;
+       for (ii = 0; ii < src->num_chars; ii++) {
+               dst->str[ii] = src->str[ii];
+       }
+       return;
+}
+
+void _prop_copy_ptptimestring(ptp_time_string_t *dst, ptp_time_string_t *src)
+{
+       mtp_uint16 ii;
+
+       dst->num_chars = src->num_chars;
+       for (ii = 0; ii < src->num_chars; ii++) {
+               dst->str[ii] = src->str[ii];
+       }
+       return;
+}
+
+mtp_bool _prop_is_equal_ptpstring(ptp_string_t *dst, ptp_string_t *src)
+{
+       mtp_uint16 ii;
+
+       if (dst->num_chars != src->num_chars)
+               return FALSE;
+
+       for (ii = 0; ii < dst->num_chars; ii++) {
+               if (dst->str[ii] != src->str[ii])
+                       return FALSE;
+       }
+       return TRUE;
+}
+
+mtp_uint32 _prop_size_ptpstring(ptp_string_t *pstring)
+{
+       if (pstring == NULL)
+               return 0;
+
+       return (pstring->num_chars * sizeof(mtp_wchar) + 1);
+}
+
+mtp_uint32 _prop_size_ptptimestring(ptp_time_string_t *pstring)
+{
+       if (pstring == NULL)
+               return 0;
+
+       return (pstring->num_chars * sizeof(mtp_wchar) + 1);
+}
+
+mtp_uint32 _prop_pack_ptpstring(ptp_string_t *pstring, mtp_uchar *buf,
+               mtp_uint32 size)
+{
+       mtp_uint32 bytes_written = 0;
+       mtp_uint32 ii;
+       mtp_uchar *pchar = NULL;
+#ifdef __BIG_ENDIAN__
+       mtp_wchar conv_str[MAX_PTP_STRING_CHARS];
+#endif /* __BIG_ENDIAN__ */
+
+       if ((buf == NULL) || (pstring == NULL) || (size == 0) ||
+                       (size < _prop_size_ptpstring(pstring))) {
+               return bytes_written;
+       }
+
+       if (pstring->num_chars == 0) {
+               buf[0] = 0;
+               bytes_written = 1;
+       } else {
+#ifdef __BIG_ENDIAN__
+               memcpy(conv_str, pstring->str,
+                               pstring->num_chars * sizeof(mtp_wchar));
+               _util_conv_byte_orderForWString(conv_str, pstring->num_chars);
+               pchar = (mtp_uchar *) conv_str;
+#else /* __BIG_ENDIAN__ */
+               pchar = (mtp_uchar *) pstring->str;
+#endif /* __BIG_ENDIAN__ */
+               buf[0] = pstring->num_chars;
+
+               bytes_written = _prop_size_ptpstring(pstring);
+               for (ii = 0; ii < (bytes_written - 1); ii++) {
+                       buf[ii + 1] = pchar[ii];
+               }
+       }
+       return bytes_written;
+}
+
+mtp_uint32 _prop_pack_ptptimestring(ptp_time_string_t *pstring, mtp_uchar *buf,
+               mtp_uint32 size)
+{
+       mtp_uint32 bytes_written = 0;
+       mtp_uchar *pchar = NULL;
+#ifdef __BIG_ENDIAN__
+       mtp_wchar conv_str[MAX_PTP_STRING_CHARS];
+#endif /* __BIG_ENDIAN__ */
+
+       if ((buf == NULL) || (pstring == NULL) || (size == 0) ||
+                       (size < _prop_size_ptptimestring(pstring))) {
+               return bytes_written;
+       }
+
+       if (pstring->num_chars == 0) {
+               buf[0] = 0;
+               bytes_written = 1;
+       } else {
+#ifdef __BIG_ENDIAN__
+               memcpy(conv_str, pstring->str,
+                               pstring->num_chars * sizeof(mtp_wchar));
+               _util_conv_byte_order_wstring(conv_str, pstring->num_chars);
+               pchar = (mtp_uchar *)conv_str;
+#else /* __BIG_ENDIAN__ */
+               pchar = (mtp_uchar *)pstring->str;
+#endif /* __BIG_ENDIAN__ */
+               buf[0] = pstring->num_chars;
+
+               bytes_written = _prop_size_ptptimestring(pstring);
+
+               memcpy(&buf[1], pchar, bytes_written - 1);
+
+       }
+       return bytes_written;
+}
+
+mtp_uint32 _prop_parse_rawstring(ptp_string_t *pstring, mtp_uchar *buf,
+               mtp_uint32 size)
+{
+       mtp_uint16 ii;
+
+       if (buf == NULL) {
+               return 0;
+       }
+
+       if (buf[0] == 0) {
+               pstring->num_chars = 0;
+               return 1;
+       } else {
+               pstring->num_chars = buf[0];
+               ii = (mtp_uint16) ((size - 1) / sizeof(mtp_wchar));
+               if (pstring->num_chars > ii) {
+                       pstring->num_chars = (mtp_uchar)ii;
+               }
+
+               for (ii = 1; ii <= pstring->num_chars; ii++) {
+#ifdef __BIG_ENDIAN__
+                       pstring->str[ii - 1] =
+                               buf[2 * ii] | (buf[2 * ii - 1] << 8);
+#else /* __BIG_ENDIAN__ */
+                       pstring->str[ii - 1] =
+                               buf[2 * ii - 1] | (buf[2 * ii] << 8);
+#endif /* __BIG_ENDIAN__ */
+               }
+               pstring->str[pstring->num_chars - 1] = (mtp_wchar) 0;
+               return _prop_size_ptpstring(pstring);
+       }
+}
+
+void _prop_destroy_ptpstring(ptp_string_t *pstring)
+{
+       if (pstring != NULL) {
+               g_free(pstring);
+       }
+       return;
+}
+
+mtp_bool _prop_is_valid_integer(prop_info_t *prop_info, mtp_uint64 value)
+{
+       if ((prop_info->data_type & PTP_DATATYPE_VALUEMASK) !=
+                       PTP_DATATYPE_VALUE) {
+               return FALSE;
+       }
+
+       if (prop_info->form_flag == RANGE_FORM) {
+               if ((value >= prop_info->range.min_val) &&
+                               (value <= prop_info->range.max_val)) {
+                       return TRUE;
+               } else {
+                       /* invalid value */
+                       return FALSE;
+               }
+       } else if (prop_info->form_flag == ENUM_FORM) {
+               slist_node_t *node = prop_info->supp_value_list.start;
+               mtp_uint32 ii;
+               for (ii = 0; ii < prop_info->supp_value_list.nnodes;
+                               ii++, node = node->link) {
+                       if (value == (mtp_uint32) node->value) {
+                               return TRUE;
+                       }
+               }
+
+               /* if it hits here, must be an invalid value */
+               return FALSE;
+       } else if (prop_info->form_flag == NONE) {
+               /* No restrictions */
+               return TRUE;
+       }
+
+       /* shouldn't be here */
+       return FALSE;
+}
+
+mtp_bool _prop_is_valid_string(prop_info_t *prop_info, ptp_string_t *pstring)
+{
+       if ((prop_info->data_type != PTP_DATATYPE_STRING) || (pstring == NULL)) {
+               return FALSE;
+       }
+
+       if (prop_info->form_flag == ENUM_FORM)
+       {
+               slist_node_t *node = NULL;
+               mtp_uint32 ii;
+               ptp_string_t *ele_str = NULL;
+
+               node = prop_info->supp_value_list.start;
+               for (ii = 0; ii < prop_info->supp_value_list.nnodes;
+                               ii++, node = node->link) {
+                       ele_str = (ptp_string_t *) node->value;
+                       if (ele_str != NULL) {
+                               if (_prop_is_equal_ptpstring(pstring, ele_str)) {
+                                       /* value found in the list of supported values */
+                                       return TRUE;
+                               }
+                       }
+               }
+               /* if it hits here, must be an invalid value */
+               return FALSE;
+       } else if (prop_info->form_flag == NONE) {
+               /* No restrictions */
+               return TRUE;
+       } else if (prop_info->form_flag == DATE_TIME_FORM) {
+               mtp_wchar *date_time = pstring->str;
+               if ((date_time[8] != L'T') && (pstring->num_chars > 9)) {
+                       ERR("invalid data time format");
+                       return FALSE;
+               }
+               return TRUE;
+       } else if (prop_info->form_flag == REGULAR_EXPRESSION_FORM) {
+               return TRUE;
+       }
+
+       return TRUE;
+}
+
+mtp_bool _prop_set_default_string(prop_info_t *prop_info, mtp_wchar *val)
+{
+       if (prop_info->data_type == PTP_DATATYPE_STRING) {
+               _prop_destroy_ptpstring(prop_info->default_val.str);
+#ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
+               prop_info->default_val.str = __alloc_ptpstring();
+#else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               prop_info->default_val.str = __alloc_ptpstring(_util_wchar_len(val));
+#endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               if (NULL == prop_info->default_val.str)
+                       return FALSE;
+
+               _prop_copy_char_to_ptpstring(prop_info->default_val.str,
+                               val, WCHAR_TYPE);
+               return TRUE;
+       }
+       else {
+               return FALSE;
+       }
+}
+
+mtp_bool _prop_set_default_integer(prop_info_t *prop_info, mtp_uchar *value)
+{
+       if ((prop_info->data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+               memcpy(prop_info->default_val.integer, value,
+                               prop_info->dts_size);
+               return TRUE;
+       } else {
+               return FALSE;
+       }
+}
+
+mtp_bool _prop_set_default_array(prop_info_t *prop_info, mtp_uchar *parray,
+               mtp_uint32 num_ele)
+{
+       /* Allocate memory for the PTP array */
+       if ((prop_info->data_type == PTP_DATATYPE_AUINT8) ||
+                       (prop_info->data_type == PTP_DATATYPE_AINT8))
+               prop_info->default_val.array = _prop_alloc_ptparray(UINT8_TYPE);
+       else if ((prop_info->data_type == PTP_DATATYPE_AUINT16) ||
+                       (prop_info->data_type == PTP_DATATYPE_AINT16))
+               prop_info->default_val.array = _prop_alloc_ptparray(UINT16_TYPE);
+       else if ((prop_info->data_type == PTP_DATATYPE_AUINT32) ||
+                       (prop_info->data_type == PTP_DATATYPE_AINT32))
+               prop_info->default_val.array = _prop_alloc_ptparray(UINT32_TYPE);
+       else
+               return FALSE;
+
+       if (prop_info->default_val.array == NULL)
+               return FALSE;
+
+       /* Copies the data into the PTP array */
+       if ((prop_info->default_val.array != NULL) && (num_ele != 0))
+       {
+               mtp_uchar *ptr8 = NULL;
+               mtp_uint16 *ptr16 = NULL;
+               mtp_uint32 *ptr32 = NULL;
+               mtp_uint32 ii;
+
+               _prop_grow_ptparray(prop_info->default_val.array, num_ele);
+
+               if ((prop_info->data_type == PTP_DATATYPE_AUINT8) ||
+                               (prop_info->data_type == PTP_DATATYPE_AINT8))
+               {
+                       ptr8 = (mtp_uchar *) parray;
+                       for (ii = 0; ii < num_ele; ii++)
+                               _prop_append_ele_ptparray(prop_info->default_val.array,
+                                               ptr8[ii]);
+
+               } else if ((prop_info->data_type == PTP_DATATYPE_AUINT16) ||
+                               (prop_info->data_type == PTP_DATATYPE_AINT16)) {
+
+                       ptr16 = (mtp_uint16 *) parray;
+                       for (ii = 0; ii < num_ele; ii++)
+                               _prop_append_ele_ptparray(prop_info->default_val.array,
+                                               ptr16[ii]);
+
+               } else if ((prop_info->data_type == PTP_DATATYPE_AUINT32) ||
+                               (prop_info->data_type == PTP_DATATYPE_AINT32)) {
+
+                       ptr32 = (mtp_uint32 *)parray;
+                       for (ii = 0; ii < num_ele; ii++)
+                               _prop_append_ele_ptparray(prop_info->default_val.array,
+                                               ptr32[ii]);
+               }
+               return TRUE;
+       }
+       return FALSE;
+}
+
+mtp_bool _prop_set_current_integer(device_prop_desc_t *prop, mtp_uint32 val)
+{
+       if (_prop_is_valid_integer(&(prop->propinfo), val)) {
+               mtp_int32 ii;
+               mtp_uchar *ptr;
+
+               ptr = (mtp_uchar *) &val;
+
+               for (ii = 0; ii < sizeof(mtp_uint32); ii++) {
+                       prop->current_val.integer[ii] = ptr[ii];
+               }
+
+               return TRUE;
+       } else {
+               /* setting invalid value */
+               return FALSE;
+       }
+}
+
+mtp_bool _prop_set_current_string(device_prop_desc_t *prop, ptp_string_t *str)
+{
+       if (_prop_is_valid_string(&(prop->propinfo), str))
+       {
+               _prop_destroy_ptpstring(prop->current_val.str);
+#ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
+               prop->current_val.str = __alloc_ptpstring();
+#else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               prop->current_val.str = __alloc_ptpstring(str->num_chars);
+#endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               if (prop->current_val.str != NULL) {
+                       _prop_copy_ptpstring(prop->current_val.str, str);
+                       return TRUE;
+               }
+               else {
+                       _prop_destroy_ptpstring(prop->current_val.str);
+                       return FALSE;
+               }
+       } else {
+               /* setting invalid value */
+               return FALSE;
+       }
+}
+
+mtp_bool _prop_set_current_array(device_prop_desc_t *prop, mtp_uchar *arr)
+{
+       mtp_uint32 num_ele = 0;
+       mtp_uchar *pval = NULL;
+       memcpy(&num_ele, arr, sizeof(mtp_uint32));
+       pval = arr + sizeof(mtp_uint32);
+
+#ifdef __BIG_ENDIAN__
+       /* Byte swap the number of elements */
+       _util_conv_byte_order(&num_ele, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+
+       /* Allocate memory for the PTP array */
+       if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT8) ||
+                       (prop->propinfo.data_type == PTP_DATATYPE_AINT8)) {
+               _prop_destroy_ptparray(prop->current_val.array);
+               prop->current_val.array = _prop_alloc_ptparray(UINT8_TYPE);
+
+       } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT16) ||
+                       (prop->propinfo.data_type == PTP_DATATYPE_AINT16)) {
+
+               _prop_destroy_ptparray(prop->current_val.array);
+               prop->current_val.array = _prop_alloc_ptparray(UINT16_TYPE);
+
+       } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT32) ||
+                       (prop->propinfo.data_type == PTP_DATATYPE_AINT32)) {
+
+               _prop_destroy_ptparray(prop->current_val.array);
+               prop->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
+
+       } else
+               return FALSE;
+
+       /* Copies the data into the PTP array */
+       if ((prop->current_val.array != NULL) && (num_ele != 0)) {
+               mtp_uchar *ptr8 = NULL;
+               mtp_uint16 *ptr16 = NULL;
+               mtp_uint32 *ptr32 = NULL;
+               mtp_uint32 ii;
+#ifdef __BIG_ENDIAN__
+               /* Some temporary variables for swapping the bytes */
+               mtp_uint16 swap16;
+               mtp_uint32 swap32;
+#endif /* __BIG_ENDIAN__ */
+
+               _prop_grow_ptparray(prop->current_val.array, num_ele);
+
+               if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT8) ||
+                               (prop->propinfo.data_type == PTP_DATATYPE_AINT8)) {
+
+                       ptr8 = (mtp_uchar *) pval;
+                       for (ii = 0; ii < num_ele; ii++)
+                               _prop_append_ele_ptparray(prop->current_val.array,
+                                               ptr8[ii]);
+
+               } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT16) ||
+                               (prop->propinfo.data_type == PTP_DATATYPE_AINT16)) {
+
+                       ptr16 = (mtp_uint16 *) pval;
+                       for (ii = 0; ii < num_ele; ii++) {
+#ifdef __BIG_ENDIAN__
+                               swap16 = ptr16[ii];
+                               _util_conv_byte_order(&swap16, sizeof(mtp_uint16));
+                               _prop_append_ele_ptparray(prop->current_val.array,
+                                               swap16);
+#else /* __BIG_ENDIAN__ */
+                               _prop_append_ele_ptparray(prop->current_val.array,
+                                               ptr16[ii]);
+#endif /* __BIG_ENDIAN__ */
+                       }
+               } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT32) ||
+                               (prop->propinfo.data_type == PTP_DATATYPE_AINT32)) {
+
+                       ptr32 = (mtp_uint32 *) pval;
+                       for (ii = 0; ii < num_ele; ii++) {
+#ifdef __BIG_ENDIAN__
+                               swap32 = ptr32[ii];
+                               _util_conv_byte_order(&swap32, sizeof(mtp_uint32));
+                               _prop_append_ele_ptparray(prop->current_val.array,
+                                               swap32);
+#else /* __BIG_ENDIAN__ */
+                               _prop_append_ele_ptparray(prop->current_val.array,
+                                               ptr32[ii]);
+#endif /* __BIG_ENDIAN__ */
+                       }
+               }
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+mtp_bool _prop_set_current_device_prop(device_prop_desc_t *prop, mtp_uchar *val,
+               mtp_uint32 size)
+{
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+               ptp_string_t str;
+               _prop_init_ptpstring(&str);
+               _prop_parse_rawstring(&str, val, size);
+               return _prop_set_current_string(prop, &str);
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               mtp_uint32 *ptr = (mtp_uint32 *) val;
+               if (size < sizeof(mtp_uint32)) {
+                       return FALSE;
+               }
+               if (size < sizeof(mtp_uint32) + ptr[0] * prop->propinfo.dts_size) {
+                       return FALSE;
+               }
+               return _prop_set_current_array(prop, val);
+
+       }
+       else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               if (prop->propinfo.dts_size > size) {
+                       return FALSE;
+               }
+
+               if ((prop->propinfo.data_type == PTP_DATATYPE_INT64) ||
+                               (prop->propinfo.data_type == PTP_DATATYPE_UINT64) ||
+                               (prop->propinfo.data_type == PTP_DATATYPE_INT128) ||
+                               (prop->propinfo.data_type == PTP_DATATYPE_UINT128)) {
+
+                       /* No validation at this time */
+                       memcpy(prop->current_val.integer, val,
+                                       prop->propinfo.dts_size);
+#ifdef __BIG_ENDIAN__
+                       _util_conv_byte_order(prop->current_val.integer,
+                                       prop->propinfo.dts_size);
+#endif /* __BIG_ENDIAN__ */
+                       return TRUE;
+               } else {
+                       /* avoid using new_val = *(ddword*)val; */
+                       mtp_uint32 new_val = (mtp_uint32)0;
+                       memcpy(&new_val, val, size);
+#ifdef __BIG_ENDIAN__
+                       _util_conv_byte_order(&new_val, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+                       return _prop_set_current_integer(prop, new_val);
+               }
+       }
+
+       return FALSE;
+}
+
+mtp_bool _prop_set_current_integer_val(obj_prop_val_t *pval, mtp_uint64 val)
+{
+       if (_prop_is_valid_integer(&(pval->prop->propinfo), val)) {
+               memset(pval->current_val.integer, 0,
+                               pval->prop->propinfo.dts_size * sizeof(mtp_byte));
+               memcpy(pval->current_val.integer, &val,
+                               pval->prop->propinfo.dts_size * sizeof(mtp_byte));
+               return TRUE;
+       } else {
+               /* setting invalid value */
+               return FALSE;
+       }
+}
+
+mtp_bool _prop_set_current_string_val(obj_prop_val_t *pval, ptp_string_t *str)
+{
+       if (_prop_is_valid_string(&(pval->prop->propinfo), str)) {
+               _prop_destroy_ptpstring(pval->current_val.str);
+#ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
+               pval->current_val.str = __alloc_ptpstring();
+#else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               pval->current_val.str = __alloc_ptpstring(str->num_chars);
+#endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               if (pval->current_val.str != NULL) {
+                       _prop_copy_ptpstring (pval->current_val.str, str);
+                       return TRUE;
+               } else
+                       return FALSE;
+       } else {
+               /* setting invalid value */
+               return FALSE;
+       }
+}
+
+mtp_bool _prop_set_current_array_val(obj_prop_val_t *pval, mtp_uchar *arr,
+               mtp_uint32 size)
+{
+       mtp_uint32 num_ele = 0;
+       mtp_uchar *value = NULL;
+       prop_info_t *propinfo = NULL;
+
+       propinfo = &(pval->prop->propinfo);
+
+       if (propinfo->data_type == PTP_DATATYPE_STRING) {
+               ptp_string_t str;
+               _prop_init_ptpstring(&str);
+               _prop_parse_rawstring(&str, arr, size);
+               return _prop_set_current_string_val(pval, &str);
+
+       } else if ((propinfo->data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               if (size < sizeof(mtp_uint32))
+                       return FALSE;
+
+               memcpy(&num_ele, arr, sizeof(mtp_uint32));
+               DBG("parsed array num [%d]\n", num_ele);
+
+               if (size < sizeof(mtp_uint32) +
+                               num_ele * (propinfo->dts_size)) {
+
+                       ERR("buffer size is not enough [%d]\n", size);
+                       return FALSE;
+               }
+
+               value = arr + sizeof(mtp_uint32);
+
+               if ((propinfo->data_type == PTP_DATATYPE_AUINT8) ||
+                               (propinfo->data_type == PTP_DATATYPE_AINT8)) {
+
+                       _prop_destroy_ptparray(pval->current_val.array);
+                       pval->current_val.array = _prop_alloc_ptparray(UINT8_TYPE);
+
+               } else if ((propinfo->data_type == PTP_DATATYPE_AUINT16) ||
+                               (propinfo->data_type == PTP_DATATYPE_AINT16)) {
+
+                       _prop_destroy_ptparray(pval->current_val.array);
+                       pval->current_val.array = _prop_alloc_ptparray(UINT16_TYPE);
+
+               } else if ((propinfo->data_type == PTP_DATATYPE_AUINT32) ||
+                               (propinfo->data_type == PTP_DATATYPE_AINT32)) {
+
+                       _prop_destroy_ptparray(pval->current_val.array);
+                       pval->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
+               }
+
+               /* Copies the data into the PTP array */
+               if ((pval->current_val.array != NULL) && (num_ele != 0)) {
+                       mtp_uchar *ptr8 = NULL;
+                       mtp_uint16 *ptr16 = NULL;
+                       mtp_uint32 *ptr32 = NULL;
+                       mtp_uint32 ii;
+
+                       _prop_grow_ptparray(pval->current_val.array, num_ele);
+
+                       if ((propinfo->data_type == PTP_DATATYPE_AUINT8) ||
+                                       (propinfo->data_type == PTP_DATATYPE_AINT8)) {
+
+                               ptr8 = (mtp_uchar *) value;
+                               for (ii = 0; ii < num_ele; ii++)
+                                       _prop_append_ele_ptparray(pval->current_val.array,
+                                                       ptr8[ii]);
+
+                       } else if ((propinfo->data_type == PTP_DATATYPE_AUINT16) ||
+                                       (propinfo->data_type == PTP_DATATYPE_AINT16)) {
+                               ptr16 = (mtp_uint16 *) value;
+                               for (ii = 0; ii < num_ele; ii++)
+                                       _prop_append_ele_ptparray(pval->current_val.array,
+                                                       ptr16[ii]);
+
+                       } else if ((propinfo->data_type == PTP_DATATYPE_AUINT32) ||
+                                       (propinfo->data_type == PTP_DATATYPE_AINT32)) {
+
+                               ptr32 = (mtp_uint32 *)value;
+                               for (ii = 0; ii < num_ele; ii++)
+                                       _prop_append_ele_ptparray(pval->current_val.array,
+                                                       ptr32[ii]);
+                       }
+               }
+               return TRUE;
+       } else if ((propinfo->data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               if (propinfo->dts_size > size)
+                       return FALSE;
+
+               if ((propinfo->data_type == PTP_DATATYPE_INT64) ||
+                               (propinfo->data_type == PTP_DATATYPE_UINT64) ||
+                               (propinfo->data_type == PTP_DATATYPE_INT128) ||
+                               (propinfo->data_type == PTP_DATATYPE_UINT128)) {
+
+                       if (propinfo->data_type == PTP_DATATYPE_UINT64) {
+                               memcpy(pval->current_val.integer, arr,
+                                               propinfo->dts_size);
+                       }
+                       memcpy(pval->current_val.integer, arr,
+                                       propinfo->dts_size);
+                       return TRUE;
+               } else {
+
+                       mtp_uint32 new_val = 0;
+                       memcpy(&new_val, arr, propinfo->dts_size);
+                       return _prop_set_current_integer_val(pval,
+                                       new_val);
+               }
+       }
+       return FALSE;
+}
+
+#ifdef __BIG_ENDIAN__
+mtp_bool _prop_set_current_array_val_usbrawdata(obj_prop_val_t *pval,
+               mtp_uchar *arr, mtp_uint32 size)
+{
+       mtp_uint32 num_ele = 0;
+       mtp_uchar *value = NULL;
+       prop_info_t *propinfo = NULL;
+
+       propinfo = &(pval->prop->propinfo);
+
+       if (propinfo->data_type == PTP_DATATYPE_STRING) {
+               ptp_string_t str;
+               _prop_init_ptpstring(&str);
+               _prop_parse_rawstring(&str, arr, size);
+               return _prop_set_current_string_val(pval, &str);
+
+       } else if ((propinfo->data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               if (size < sizeof(mtp_uint32))
+                       return FALSE;
+
+               memcpy(&num_ele, arr, sizeof(mtp_uint32));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(&num_ele, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+               if (size < sizeof(mtp_uint32) + num_ele * propinfo->dts_size)
+                       return FALSE;
+
+               value = arr + sizeof(mtp_uint32);
+
+               if ((propinfo->data_type == PTP_DATATYPE_AUINT8) ||
+                               (propinfo->data_type == PTP_DATATYPE_AINT8)) {
+
+                       _prop_destroy_ptparray(pval->current_val.array);
+                       pval->current_val.array = _prop_alloc_ptparray(UINT8_TYPE);
+
+               } else if ((propinfo->data_type == PTP_DATATYPE_AUINT16) ||
+                               (propinfo->data_type == PTP_DATATYPE_AINT16)) {
+
+                       _prop_destroy_ptparray(pval->current_val.array);
+                       pval->current_val.array = _prop_alloc_ptparray(UINT16_TYPE);
+
+               } else if ((propinfo->data_type == PTP_DATATYPE_AUINT32) ||
+                               (propinfo->data_type == PTP_DATATYPE_AINT32)) {
+
+                       _prop_destroy_ptparray(pval->current_val.array);
+                       pval->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
+
+               }
+
+               /* Copies the data into the PTP array */
+               if ((pval->current_val.array != NULL) && (num_ele != 0)) {
+
+                       mtp_uchar *ptr8 = NULL;
+                       mtp_uint16 *ptr16 = NULL;
+                       mtp_uint32 *ptr32 = NULL;
+                       mtp_uint32 ii;
+
+                       _prop_grow_ptparray(pval->current_val.array, num_ele);
+
+                       if ((propinfo->data_type == PTP_DATATYPE_AUINT8) ||
+                                       (propinfo->data_type == PTP_DATATYPE_AINT8)) {
+
+                               ptr8 = (mtp_uchar *) arr;
+                               for (ii = 0; ii < num_ele; ii++)
+                                       _prop_append_ele_ptparray(pval->current_val.array,
+                                                       ptr8[ii]);
+
+                       } else if ((propinfo->data_type == PTP_DATATYPE_AUINT16) ||
+                                       (propinfo->data_type ==
+                                        PTP_DATATYPE_AINT16)) {
+
+                               ptr16 = (mtp_uint16 *) arr;
+#ifdef __BIG_ENDIAN__
+                               _util_conv_byte_order_gen_str(ptr16,
+                                               num_ele, sizeof(mtp_uint16));
+#endif /* __BIG_ENDIAN__ */
+                               for (ii = 0; ii < num_ele; ii++)
+                                       _prop_append_ele_ptparray(pval->current_val.array,
+                                                       ptr16[ii]);
+
+                       } else if ((propinfo->data_type == PTP_DATATYPE_AUINT32) ||
+                                       (propinfo->data_type ==
+                                        PTP_DATATYPE_AINT32)) {
+
+                               ptr32 = (mtp_uint32 *) arr;
+#ifdef __BIG_ENDIAN__
+                               _util_conv_byte_order_gen_str(ptr32, num_ele,
+                                               sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+                               for (ii = 0; ii < num_ele; ii++)
+                                       _prop_append_ele_ptparray(pval->current_val.array,
+                                                       ptr32[ii]);
+                       }
+               }
+               return TRUE;
+       } else if ((propinfo->data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               if (propinfo->dts_size > size)
+                       return FALSE;
+
+               if ((propinfo->data_type == PTP_DATATYPE_INT64) ||
+                               (propinfo->data_type == PTP_DATATYPE_UINT64) ||
+                               (propinfo->data_type == PTP_DATATYPE_INT128) ||
+                               (propinfo->data_type == PTP_DATATYPE_UINT128)) {
+
+                       memcpy(pval->current_val.integer, arr,
+                                       propinfo->dts_size);
+#ifdef __BIG_ENDIAN__
+                       _util_conv_byte_order(pval->current_val.integer,
+                                       propinfo->dts_size);
+#endif /* __BIG_ENDIAN__ */
+                       return TRUE;
+               } else {
+                       mtp_uint32 new_val = 0;
+                       memcpy(&new_val, arr, propinfo->dts_size);
+                       return _prop_set_current_integer_val(pval, new_val);
+               }
+       }
+       return FALSE;
+}
+#endif /* __BIG_ENDIAN__ */
+
+mtp_bool _prop_set_range_integer(prop_info_t *prop_info, mtp_uint32 min,
+               mtp_uint32 max, mtp_uint32 step)
+{
+       if (((prop_info->data_type & PTP_DATATYPE_VALUEMASK) !=
+                               PTP_DATATYPE_VALUE) || (prop_info->form_flag != RANGE_FORM)) {
+               return FALSE;
+
+       } else {
+               prop_info->range.min_val = min;
+               prop_info->range.max_val = max;
+               prop_info->range.step_size = step;
+               return TRUE;
+       }
+}
+
+mtp_bool _prop_set_regexp(obj_prop_desc_t *prop, mtp_wchar *regex)
+{
+       ptp_string_t *str;
+
+       if ((prop->propinfo.data_type != PTP_DATATYPE_STRING) ||
+                       (prop->propinfo.form_flag != REGULAR_EXPRESSION_FORM)) {
+               return FALSE;
+       }
+#ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
+       str = __alloc_ptpstring();
+#else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+       str = __alloc_ptpstring(_util_wchar_len(regex));
+#endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+       if (str == NULL)
+               return FALSE;
+
+       _prop_copy_char_to_ptpstring(str, regex, WCHAR_TYPE);
+       prop->prop_forms.reg_exp = str;
+
+       return TRUE;
+}
+
+mtp_bool _prop_set_maxlen(obj_prop_desc_t *prop, mtp_uint32 max)
+{
+       if ((prop->propinfo.form_flag != BYTE_ARRAY_FORM) &&
+                       (prop->propinfo.form_flag != LONG_STRING_FORM)) {
+               return FALSE;
+       }
+
+       if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) !=
+                       PTP_DATATYPE_ARRAY) {
+               return FALSE;
+       }
+
+       prop->prop_forms.max_len = max;
+       return TRUE;
+
+}
+
+/* DeviceObjectPropDesc Functions */
+void _prop_init_device_property_desc(device_prop_desc_t *prop,
+               mtp_uint16 propcode, mtp_uint16 data_type, mtp_uchar get_set,
+               mtp_uchar form_flag)
+{
+       mtp_int32 ii;
+
+       prop->propinfo.prop_code = propcode;
+       prop->propinfo.data_type = data_type;
+       prop->propinfo.get_set = get_set;
+       prop->propinfo.default_val.str = NULL;
+       prop->current_val.str = NULL;
+       prop->propinfo.form_flag = form_flag;
+
+       for (ii = 0; ii < 16; ii++) {
+               prop->current_val.integer[ii] = 0;
+               prop->propinfo.default_val.integer[ii] = 0;
+       }
+
+       /* size of default value: DTS */
+       switch (prop->propinfo.data_type) {
+       case PTP_DATATYPE_UINT8:
+       case PTP_DATATYPE_INT8:
+       case PTP_DATATYPE_AINT8:
+       case PTP_DATATYPE_AUINT8:
+               prop->propinfo.dts_size = sizeof(mtp_uchar);
+               break;
+
+       case PTP_DATATYPE_UINT16:
+       case PTP_DATATYPE_INT16:
+       case PTP_DATATYPE_AINT16:
+       case PTP_DATATYPE_AUINT16:
+               prop->propinfo.dts_size = sizeof(mtp_uint16);
+               break;
+
+       case PTP_DATATYPE_UINT32:
+       case PTP_DATATYPE_INT32:
+       case PTP_DATATYPE_AINT32:
+       case PTP_DATATYPE_AUINT32:
+               prop->propinfo.dts_size = sizeof(mtp_uint32);
+               break;
+
+       case PTP_DATATYPE_UINT64:
+       case PTP_DATATYPE_INT64:
+       case PTP_DATATYPE_AINT64:
+       case PTP_DATATYPE_AUINT64:
+               prop->propinfo.dts_size = sizeof(mtp_int64);
+               break;
+
+       case PTP_DATATYPE_UINT128:
+       case PTP_DATATYPE_INT128:
+       case PTP_DATATYPE_AINT128:
+       case PTP_DATATYPE_AUINT128:
+               prop->propinfo.dts_size = 2 * sizeof(mtp_int64);
+               break;
+
+       case PTP_DATATYPE_STRING:
+       default:
+               /* don't know how to handle at this point (including PTP_DATATYPE_STRING) */
+               prop->propinfo.dts_size = 0;
+               break;
+       }
+
+       _util_init_list(&(prop->propinfo.supp_value_list));
+
+       return;
+}
+
+mtp_uint32 _prop_size_device_prop_desc(device_prop_desc_t *prop)
+{
+       /* size :PropCode,Datatype,Getset,formflag */
+       mtp_uint32 size = sizeof(mtp_uint16) + sizeof(mtp_uint16) +
+               sizeof(mtp_uchar) + sizeof(mtp_uchar);
+
+       /* size of default value: DTS */
+       /* size of current value: DTS */
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+               size += _prop_size_ptpstring(prop->propinfo.default_val.str);
+               size += _prop_size_ptpstring(prop->current_val.str);
+
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               size += _prop_get_size_ptparray(prop->propinfo.default_val.array);
+               size += _prop_get_size_ptparray(prop->current_val.array);
+
+       } else {
+               size += 2 * prop->propinfo.dts_size;
+       }
+
+       /* Add the size of the Form followed */
+       switch (prop->propinfo.form_flag) {
+       case NONE:
+               break;
+
+       case RANGE_FORM:
+               size += 3 * prop->propinfo.dts_size;
+               break;
+
+       case ENUM_FORM:
+               /* Number of Values */
+               size += sizeof(mtp_uint16);
+               if (prop->propinfo.data_type != PTP_DATATYPE_STRING) {
+
+                       size += prop->propinfo.supp_value_list.nnodes *
+                               prop->propinfo.dts_size;
+
+               } else {
+                       slist_node_t *node = NULL;
+                       mtp_uint16 ii;
+
+                       for (ii = 0, node = prop->propinfo.supp_value_list.start;
+                                       ii < prop->propinfo.supp_value_list.nnodes;
+                                       ii++, node = node->link) {
+
+                               size += _prop_size_ptpstring((ptp_string_t *) node->value);
+                       }
+               }
+               break;
+
+       default:
+               /* don't know how to handle */
+               break;
+
+       }
+
+       return size;
+}
+
+static mtp_uint32 __size_curval_device_prop(device_prop_desc_t *prop)
+{
+       mtp_uint32 size = 0;
+
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+               size = _prop_size_ptpstring(prop->current_val.str);
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               size = _prop_get_size_ptparray(prop->current_val.array);
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               size = prop->propinfo.dts_size;
+       }
+       return size;
+}
+
+mtp_uint32 _prop_pack_device_prop_desc(device_prop_desc_t *prop,
+               mtp_uchar *buf, mtp_uint32 size)
+{
+       mtp_uchar *temp = buf;
+       mtp_uint32 count = 0;
+       mtp_uint32 bytes_to_write = 0;
+       slist_node_t *node = NULL;
+       mtp_uint32 ii;
+
+       if (!buf || size < _prop_size_device_prop_desc(prop)) {
+               return 0;
+       }
+
+       /* Pack propcode, data_type, & get_set */
+       bytes_to_write = sizeof(mtp_uint16);
+       memcpy(temp, &(prop->propinfo.prop_code), bytes_to_write);
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(temp, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+       temp += bytes_to_write;
+
+       bytes_to_write = sizeof(mtp_uint16);
+       memcpy(temp, &(prop->propinfo.data_type), bytes_to_write);
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(temp, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+       temp += bytes_to_write;
+
+       bytes_to_write = sizeof(mtp_uchar);
+       memcpy(temp, &(prop->propinfo.get_set), bytes_to_write);
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(temp, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+       temp += bytes_to_write;
+
+       /* Pack Default/Current Value: DTS */
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+               bytes_to_write = _prop_size_ptpstring(prop->propinfo.default_val.str);
+               if (bytes_to_write !=
+                               _prop_pack_ptpstring(prop->propinfo.default_val.str,
+                                       temp, bytes_to_write)) {
+
+                       return (mtp_uint32)(temp - buf);
+               }
+               temp += bytes_to_write;
+
+               bytes_to_write = _prop_size_ptpstring(prop->current_val.str);
+               if (bytes_to_write !=
+                               _prop_pack_ptpstring(prop->current_val.str,
+                                       temp, bytes_to_write)) {
+
+                       return (mtp_uint32)(temp - buf);
+               }
+               temp += bytes_to_write;
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               bytes_to_write = _prop_get_size_ptparray(prop->propinfo.default_val.array);
+               if (bytes_to_write !=
+                               _prop_pack_ptparray(prop->propinfo.default_val.array,
+                                       temp, bytes_to_write)) {
+
+                       return (mtp_uint32)(temp - buf);
+               }
+               temp += bytes_to_write;
+
+               bytes_to_write = _prop_get_size_ptparray(prop->current_val.array);
+               if (bytes_to_write !=
+                               _prop_pack_ptparray(prop->current_val.array,
+                                       temp, bytes_to_write)) {
+
+                       return (mtp_uint32)(temp - buf);
+               }
+               temp += bytes_to_write;
+
+               /* Add support for other array data types */
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               bytes_to_write = prop->propinfo.dts_size;
+               memcpy(temp, prop->propinfo.default_val.integer, bytes_to_write);
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+               temp += bytes_to_write;
+
+               memcpy(temp, prop->current_val.integer, bytes_to_write);
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+               temp += bytes_to_write;
+       }
+
+
+       /* Now pack the FormFlag */
+       memcpy(temp, &(prop->propinfo.form_flag), sizeof(mtp_uchar));
+       temp += sizeof(mtp_uchar);
+
+       /* Finally pack the Form followed */
+       switch (prop->propinfo.form_flag) {
+       case NONE:
+               break;
+
+       case RANGE_FORM:
+               /* Min, Max, & Step */
+               memcpy(temp, &(prop->propinfo.range.min_val),
+                               prop->propinfo.dts_size);
+               temp += prop->propinfo.dts_size;
+               memcpy(temp, &(prop->propinfo.range.max_val),
+                               prop->propinfo.dts_size);
+               temp += prop->propinfo.dts_size;
+               memcpy(temp, &(prop->propinfo.range.step_size),
+                               prop->propinfo.dts_size);
+               temp += prop->propinfo.dts_size;
+               break;
+
+       case ENUM_FORM:
+
+               /* Pack Number of Values in this enumeration */
+               count = prop->propinfo.supp_value_list.nnodes;
+
+               memcpy(temp, &count, sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, sizeof(mtp_uint16));
+#endif /* __BIG_ENDIAN__ */
+               temp += sizeof(mtp_uint16);
+
+               if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+                       for (ii = 0, node = prop->propinfo.supp_value_list.start;
+                                       ii < prop->propinfo.supp_value_list.nnodes;
+                                       ii++, node = node->link) {
+
+                               bytes_to_write =
+                                       _prop_size_ptpstring((ptp_string_t *) node->value);
+                               if (bytes_to_write !=
+                                               _prop_pack_ptpstring((ptp_string_t *) node->value,
+                                                       temp, bytes_to_write)) {
+
+                                       return (mtp_uint32)(temp - buf);
+                               }
+                               temp += bytes_to_write;
+                       }
+
+               } else {
+                       mtp_uint32 value = 0;
+
+                       for (ii = 0, node = prop->propinfo.supp_value_list.start;
+                                       ii < prop->propinfo.supp_value_list.nnodes;
+                                       ii++, node = node->link) {
+
+                               value = (mtp_uint32)node->value;
+                               memcpy(temp, &value, prop->propinfo.dts_size);
+#ifdef __BIG_ENDIAN__
+                               _util_conv_byte_order(temp, prop->propinfo.dts_size);
+#endif /* __BIG_ENDIAN__ */
+                               temp += prop->propinfo.dts_size;
+                       }
+               }
+               break;
+
+       default:
+               /*don't know how to handle */
+               break;
+
+       }
+
+       return (mtp_uint32)(temp - buf);
+}
+
+mtp_uint32 _prop_pack_curval_device_prop_desc(device_prop_desc_t *prop,
+               mtp_uchar *buf, mtp_uint32 size)
+{
+       mtp_uint32 bytes_to_write;
+
+       bytes_to_write = __size_curval_device_prop(prop);
+
+       if ((!bytes_to_write) || (buf == NULL) || (size < bytes_to_write)) {
+               return 0;
+       }
+
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+               if (bytes_to_write != _prop_pack_ptpstring(prop->current_val.str,
+                                       buf, bytes_to_write)) {
+                       return 0;
+               }
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               if (bytes_to_write != _prop_pack_ptparray(prop->current_val.array,
+                                       buf, bytes_to_write)) {
+                       return 0;
+               }
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+               /* this property is of type UINT8, ... */
+               memcpy(buf, prop->current_val.integer, bytes_to_write);
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(buf, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+       } else {
+               return 0;
+       }
+
+       return bytes_to_write;
+}
+
+void _prop_reset_device_prop_desc(device_prop_desc_t *prop)
+{
+       ret_if(prop == NULL);
+
+       if (prop->propinfo.get_set == PTP_PROPGETSET_GETONLY)
+               return;
+
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+               _prop_destroy_ptpstring(prop->current_val.str);
+#ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
+               prop->current_val.str = __alloc_ptpstring();
+#else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               prop->current_val.str = __alloc_ptpstring(prop->propinfo.default_val.str->num_chars);
+#endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               if (NULL == prop->current_val.str)
+                       return;
+
+               _prop_copy_ptpstring (prop->current_val.str,
+                               prop->propinfo.default_val.str);
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               _prop_destroy_ptparray(prop->current_val.array);
+               prop->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
+               if (NULL == prop->current_val.array)
+                       return;
+
+               _prop_copy_ptparray(prop->current_val.array,
+                               prop->propinfo.default_val.array);
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               mtp_int32 ii;
+               for (ii = 0; ii < 16; ii++)
+                       prop->current_val.integer[ii] =
+                               prop->propinfo.default_val.integer[ii];
+       }
+}
+
+/* ObjectPropVal Functions */
+obj_prop_val_t * _prop_alloc_obj_propval(obj_prop_desc_t *prop)
+{
+       obj_prop_val_t *pval = NULL;
+       pval = (obj_prop_val_t *)g_malloc(sizeof(obj_prop_val_t));
+
+       if (pval != NULL) {
+               __init_obj_propval(pval, prop);
+       }
+
+       return pval;
+}
+
+static void __init_obj_propval(obj_prop_val_t *pval, obj_prop_desc_t *prop)
+{
+       mtp_int32 ii;
+
+       pval->prop = prop;
+
+       for (ii = 0; ii < 16; ii++) {
+               pval->current_val.integer[ii] = 0;
+       }
+
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+#ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
+               pval->current_val.str = __alloc_ptpstring();
+#else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               pval->current_val.str = __alloc_ptpstring(prop->propinfo.default_val.str->num_chars);
+#endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+               if (NULL == pval->current_val.str)
+                       return;
+               _prop_copy_ptpstring (pval->current_val.str,
+                               prop->propinfo.default_val.str);
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               memcpy(pval->current_val.integer,
+                               prop->propinfo.default_val.integer,
+                               prop->propinfo.dts_size);
+       } else {
+               if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT8) ||
+                               (prop->propinfo.data_type == PTP_DATATYPE_AINT8)) {
+
+                       pval->current_val.array = _prop_alloc_ptparray(UINT8_TYPE);
+                       if (NULL == pval->current_val.array)
+                               return;
+
+                       _prop_copy_ptparray(pval->current_val.array,
+                                       prop->propinfo.default_val.array);
+
+               } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT16) ||
+                               (prop->propinfo.data_type == PTP_DATATYPE_AINT16)) {
+
+                       pval->current_val.array = _prop_alloc_ptparray(UINT16_TYPE);
+                       if (NULL == pval->current_val.array)
+                               return;
+
+                       _prop_copy_ptparray(pval->current_val.array,
+                                       prop->propinfo.default_val.array);
+
+               } else if ((prop->propinfo.data_type == PTP_DATATYPE_AUINT32) ||
+                               (prop->propinfo.data_type == PTP_DATATYPE_AINT32)) {
+
+                       pval->current_val.array = _prop_alloc_ptparray(UINT32_TYPE);
+                       if (NULL == pval->current_val.array)
+                               return;
+
+                       _prop_copy_ptparray(pval->current_val.array,
+                                       prop->propinfo.default_val.array);
+               }
+
+               /* Add support for other array data types */
+       }
+       return;
+}
+
+obj_prop_val_t *_prop_get_prop_val(mtp_obj_t *obj, mtp_uint32 propcode)
+{
+       obj_prop_val_t *prop_val = NULL;
+       slist_node_t *node = NULL;
+       mtp_uint32 ii = 0;
+
+       /*Update the properties if count is zero*/
+       if (obj->propval_list.nnodes == 0)
+               _prop_update_property_values_list(obj);
+
+       for (ii = 0, node = obj->propval_list.start;
+                       ii < obj->propval_list.nnodes; ii++, node = node->link) {
+               if (node == NULL || node->value == NULL)
+                       goto ERROR_CATCH;
+
+               prop_val = (obj_prop_val_t *)node->value;
+               if (prop_val) {
+                       if (prop_val->prop->propinfo.prop_code == propcode) {
+                               return prop_val;
+                       }
+               }
+       }
+
+       return NULL;
+
+ERROR_CATCH:
+       /* update property and try again */
+       _prop_update_property_values_list(obj);
+
+       for (ii = 0, node = obj->propval_list.start;
+                       ii < obj->propval_list.nnodes;
+                       ii++, node = node->link) {
+               if (node == NULL || node->value == NULL)
+                       break;
+
+               prop_val = (obj_prop_val_t *)node->value;
+               if ((prop_val) && (prop_val->prop->propinfo.prop_code ==
+                                       propcode)) {
+                       return prop_val;
+               }
+       }
+       ERR("node or node->value is null. try again but not found");
+       return NULL;
+}
+
+mtp_uint32 _prop_pack_obj_propval(obj_prop_val_t *pval, mtp_uchar *buf,
+               mtp_uint32 size)
+{
+       mtp_uint32 bytes_to_write = _prop_size_obj_propval(pval);
+
+       if ((!bytes_to_write) || (buf == NULL) || (size < bytes_to_write)) {
+               return 0;
+       }
+
+       if (pval->prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+               if (bytes_to_write != _prop_pack_ptpstring(pval->current_val.str,
+                                       buf, bytes_to_write)) {
+                       return 0;
+               }
+       } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               if (bytes_to_write != _prop_pack_ptparray(pval->current_val.array,
+                                       buf, size)) {
+                       return 0;
+               }
+
+       } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               /* this property is of type UINT8, ... */
+               memcpy(buf, pval->current_val.integer, bytes_to_write);
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(buf, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+       } else {
+               return 0;
+       }
+
+       return bytes_to_write;
+}
+
+
+mtp_uint32 _prop_size_obj_propval(obj_prop_val_t *pval)
+{
+       mtp_uint32 size = 0;
+
+       if (pval == NULL || pval->prop == NULL)
+               return size;
+
+       if (pval->prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+               if (pval->current_val.str == NULL) {
+                       size = 0;
+               } else {
+                       size = _prop_size_ptpstring(pval->current_val.str);
+               }
+
+       } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+               size = _prop_get_size_ptparray(pval->current_val.array);
+
+       } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+               size = pval->prop->propinfo.dts_size;
+       }
+
+       return size;
+}
+
+void _prop_destroy_obj_propval(obj_prop_val_t *pval)
+{
+       if (pval == NULL) {
+               return;
+       }
+
+       if (pval->prop == NULL) {
+               g_free(pval);
+               pval = NULL;
+               return;
+       }
+
+       if (pval->prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+               if (pval->current_val.str) {
+                       _prop_destroy_ptpstring(pval->current_val.str);
+                       pval->current_val.str = NULL;
+               }
+       } else if ((pval->prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+               _prop_destroy_ptparray(pval->current_val.array);
+               pval->current_val.array = NULL;
+       }
+
+       if (pval != NULL) {
+               g_free(pval);
+               pval = NULL;
+       }
+
+       return;
+}
+
+static void __init_obj_prop_desc(obj_prop_desc_t *prop, mtp_uint16 propcode,
+               mtp_uint16 data_type, mtp_uchar get_set, mtp_uchar form_flag,
+               mtp_uint32 group_code)
+{
+       mtp_int32 ii;
+       prop->propinfo.prop_code = propcode;/*Property code for this property*/
+       prop->propinfo.data_type = data_type;   /* 2=byte, 4=word,
+                                                                                        * 6=dword, 0xFFFF=String)
+                                                                                        */
+       prop->propinfo.get_set = get_set;       /* 0=get-only, 1=get-set */
+       prop->propinfo.default_val.str = NULL; /* Default value for a String value type */
+
+       prop->propinfo.form_flag = form_flag;
+
+       if (prop->propinfo.form_flag == BYTE_ARRAY_FORM) {
+               prop->propinfo.data_type = PTP_DATATYPE_AUINT8;
+       } else if (prop->propinfo.form_flag == LONG_STRING_FORM) {
+               prop->propinfo.data_type = PTP_DATATYPE_AUINT16;
+       }
+
+       prop->group_code = group_code;
+
+       /* Zero out the integer byte array */
+       for (ii = 0; ii < 16; ii++)
+               prop->propinfo.default_val.integer[ii] = 0;
+
+       /* size of default value: DTS */
+       switch (prop->propinfo.data_type) {
+
+       case PTP_DATATYPE_UINT8:
+       case PTP_DATATYPE_INT8:
+       case PTP_DATATYPE_AINT8:
+       case PTP_DATATYPE_AUINT8:
+               prop->propinfo.dts_size = sizeof(mtp_uchar);
+               break;
+
+       case PTP_DATATYPE_UINT16:
+       case PTP_DATATYPE_INT16:
+       case PTP_DATATYPE_AINT16:
+       case PTP_DATATYPE_AUINT16:
+               prop->propinfo.dts_size = sizeof(mtp_uint16);
+               break;
+
+       case PTP_DATATYPE_UINT32:
+       case PTP_DATATYPE_INT32:
+       case PTP_DATATYPE_AINT32:
+       case PTP_DATATYPE_AUINT32:
+               prop->propinfo.dts_size = sizeof(mtp_uint32);
+               break;
+
+       case PTP_DATATYPE_UINT64:
+       case PTP_DATATYPE_INT64:
+       case PTP_DATATYPE_AINT64:
+       case PTP_DATATYPE_AUINT64:
+               prop->propinfo.dts_size = sizeof(mtp_int64);
+               break;
+
+       case PTP_DATATYPE_UINT128:
+       case PTP_DATATYPE_INT128:
+       case PTP_DATATYPE_AINT128:
+       case PTP_DATATYPE_AUINT128:
+               prop->propinfo.dts_size = 2 * sizeof(mtp_int64);
+               break;
+
+       case PTP_DATATYPE_STRING:
+       default:
+               prop->propinfo.dts_size = 0;
+               break;
+       }
+
+       _util_init_list(&(prop->propinfo.supp_value_list));
+
+       prop->prop_forms.reg_exp = NULL;
+       prop->prop_forms.max_len = 0;
+
+       return;
+}
+
+static mtp_uint32 __get_size_default_val_obj_prop_desc(obj_prop_desc_t *prop)
+{
+       mtp_uint32 size = 0;
+
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+               size = _prop_size_ptpstring(prop->propinfo.default_val.str);
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               size = _prop_get_size_ptparray(prop->propinfo.default_val.array);
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               size = prop->propinfo.dts_size;
+       }
+
+       return size;
+}
+
+mtp_uint32 _prop_size_obj_prop_desc(obj_prop_desc_t *prop)
+{
+       mtp_uint32 size =
+               sizeof(mtp_uint16) + sizeof(mtp_uint16) + sizeof(mtp_uchar) +
+               sizeof(mtp_uint32) + sizeof(mtp_uchar);
+
+       /* size of default value: DTS */
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+               size += _prop_size_ptpstring(prop->propinfo.default_val.str);
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               size += _prop_get_size_ptparray(prop->propinfo.default_val.array);
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               size += prop->propinfo.dts_size;
+       }
+
+       /* Add the size of the Form followed */
+       switch (prop->propinfo.form_flag) {
+       case NONE:
+               break;
+
+       case RANGE_FORM:
+               if (prop->propinfo.data_type != PTP_DATATYPE_STRING) {
+                       size += 3 * prop->propinfo.dts_size;/* Min,Max,Step */
+               }
+               break;
+
+       case ENUM_FORM:
+               /* Number of Values */
+               size += sizeof(mtp_uint16);
+               if (prop->propinfo.data_type != PTP_DATATYPE_STRING) {
+                       size += prop->propinfo.supp_value_list.nnodes *
+                               prop->propinfo.dts_size;
+               } else {
+                       slist_node_t *node = NULL;
+                       mtp_uint32 ii;
+
+                       for (ii = 0, node = prop->propinfo.supp_value_list.start;
+                                       ii < prop->propinfo.supp_value_list.nnodes;
+                                       ii++, node = node->link) {
+
+                               size += _prop_size_ptpstring((ptp_string_t *) node->value);
+                       }
+               }
+               break;
+
+       case DATE_TIME_FORM:
+               break;
+
+       case REGULAR_EXPRESSION_FORM:
+               size += _prop_size_ptpstring(prop->prop_forms.reg_exp);
+               break;
+
+       case BYTE_ARRAY_FORM:
+       case LONG_STRING_FORM:
+               size += sizeof(prop->prop_forms.max_len);
+               break;
+
+       default:
+               /*don't know how to handle */
+               break;
+
+       }
+
+       return size;
+}
+
+mtp_uint32 _prop_pack_obj_prop_desc(obj_prop_desc_t *prop, mtp_uchar *buf,
+               mtp_uint32 size)
+{
+       mtp_uchar *temp = buf;
+       mtp_uint32 count = 0;
+       mtp_uint32 bytes_to_write = 0;
+       slist_node_t *node = NULL;
+       mtp_uint16 ii;
+
+       if (!buf || size < _prop_size_obj_prop_desc(prop)) {
+               return 0;
+       }
+
+       /* Pack propcode, data_type, & get_set */
+       bytes_to_write = sizeof(mtp_uint16);
+       memcpy(temp, &(prop->propinfo.prop_code), bytes_to_write);
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(temp, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+       temp += bytes_to_write;
+
+       bytes_to_write = sizeof(mtp_uint16);
+       memcpy(temp, &(prop->propinfo.data_type), bytes_to_write);
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(temp, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+       temp += bytes_to_write;
+
+       bytes_to_write = sizeof(mtp_uchar);
+       memcpy(temp, &(prop->propinfo.get_set), bytes_to_write);
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(temp, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+       temp += bytes_to_write;
+
+       /* Pack Default Value: DTS */
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+               bytes_to_write =
+                       _prop_size_ptpstring(prop->propinfo.default_val.str);
+               if (bytes_to_write != _prop_pack_ptpstring(prop->propinfo.default_val.str,
+                                       temp, bytes_to_write)) {
+                       return (mtp_uint32)(temp - buf);
+               }
+               temp += bytes_to_write;
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               bytes_to_write = _prop_get_size_ptparray(prop->propinfo.default_val.array);
+               if (bytes_to_write != _prop_pack_ptparray(prop->propinfo.default_val.array,
+                                       temp, bytes_to_write)) {
+                       return (mtp_uint32)(temp - buf);
+               }
+               temp += bytes_to_write;
+
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+
+               bytes_to_write = prop->propinfo.dts_size;
+               memcpy(temp, prop->propinfo.default_val.integer, bytes_to_write);
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+               temp += bytes_to_write;
+       }
+
+       /* Pack group_code */
+       memcpy(temp, &(prop->group_code), sizeof(mtp_uint32));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(temp, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+       temp += sizeof(mtp_uint32);
+
+       /* Pack the FormFlag */
+       memcpy(temp, &(prop->propinfo.form_flag), sizeof(mtp_uchar));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(temp, sizeof(mtp_uchar));
+#endif /* __BIG_ENDIAN__ */
+       temp += sizeof(mtp_uchar);
+
+       /* Pack the Form Flag values */
+       switch (prop->propinfo.form_flag) {
+       case NONE:
+               break;
+
+       case RANGE_FORM:
+               /* Min, Max, & Step */
+               memcpy(temp, &(prop->propinfo.range.min_val),
+                               prop->propinfo.dts_size);
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, prop->propinfo.dts_size);
+#endif /* __BIG_ENDIAN__ */
+               temp += prop->propinfo.dts_size;
+               memcpy(temp, &(prop->propinfo.range.max_val),
+                               prop->propinfo.dts_size);
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, prop->propinfo.dts_size);
+#endif /* __BIG_ENDIAN__ */
+               temp += prop->propinfo.dts_size;
+               memcpy(temp, &(prop->propinfo.range.step_size),
+                               prop->propinfo.dts_size);
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, prop->propinfo.dts_size);
+#endif /* __BIG_ENDIAN__ */
+               temp += prop->propinfo.dts_size;
+               break;
+
+       case ENUM_FORM:
+
+               /* Pack Number of Values in this enumeration */
+               count = prop->propinfo.supp_value_list.nnodes;
+
+               memcpy(temp, &count, sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, sizeof(mtp_uint16));
+#endif /* __BIG_ENDIAN__ */
+               temp += sizeof(mtp_uint16);
+
+               if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+                       for (ii = 0, node = prop->propinfo.supp_value_list.start;
+                                       ii < prop->propinfo.supp_value_list.nnodes;
+                                       ii++, node = node->link) {
+
+                               bytes_to_write =
+                                       _prop_size_ptpstring((ptp_string_t *) node->value);
+                               if (bytes_to_write !=
+                                               _prop_pack_ptpstring((ptp_string_t *) node->value,
+                                                       temp, bytes_to_write)) {
+                                       return (mtp_uint32) (temp - buf);
+                               }
+                               temp += bytes_to_write;
+                       }
+               } else {
+                       mtp_uint32 value = 0;
+
+                       for (ii = 0, node = prop->propinfo.supp_value_list.start;
+                                       ii < prop->propinfo.supp_value_list.nnodes;
+                                       ii++, node = node->link) {
+
+                               value = (mtp_uint32)node->value;
+                               memcpy(temp, &value, prop->propinfo.dts_size);
+#ifdef __BIG_ENDIAN__
+                               _util_conv_byte_order(temp, prop->propinfo.dts_size);
+#endif /* __BIG_ENDIAN__ */
+                               temp += prop->propinfo.dts_size;
+                       }
+               }
+               break;
+
+       case DATE_TIME_FORM:
+               break;
+
+       case REGULAR_EXPRESSION_FORM:
+               bytes_to_write = _prop_size_ptpstring(prop->prop_forms.reg_exp);
+               if (bytes_to_write !=
+                               _prop_pack_ptpstring(prop->prop_forms.reg_exp,
+                                       temp, bytes_to_write)) {
+
+                       return (mtp_uint32)(temp - buf);
+               }
+               temp += bytes_to_write;
+               break;
+
+       case BYTE_ARRAY_FORM:
+       case LONG_STRING_FORM:
+               memcpy(temp, &prop->prop_forms.max_len,
+                               sizeof(prop->prop_forms.max_len));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, sizeof(prop->prop_forms.max_len));
+#endif /* __BIG_ENDIAN__ */
+               temp += sizeof(prop->prop_forms.max_len);
+               break;
+
+       default:
+               /*don't know how to handle */
+               break;
+
+       }
+
+       return (mtp_uint32)(temp - buf);
+}
+
+mtp_uint32 _prop_pack_default_val_obj_prop_desc(obj_prop_desc_t *prop,
+               mtp_uchar *buf, mtp_uint32 size)
+{
+       mtp_uint32 bytes_to_write;
+
+       bytes_to_write = __get_size_default_val_obj_prop_desc(prop);
+
+       if ((!bytes_to_write) || (buf == NULL) || (size < bytes_to_write)) {
+               return 0;
+       }
+
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+               if (bytes_to_write !=
+                               _prop_pack_ptpstring(prop->propinfo.default_val.str,
+                                       buf, bytes_to_write)) {
+                       return 0;
+               }
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+               if (bytes_to_write !=
+                               _prop_pack_ptparray(prop->propinfo.default_val.array,
+                                       buf, bytes_to_write)) {
+                       return 0;
+               }
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_VALUEMASK) ==
+                       PTP_DATATYPE_VALUE) {
+               /* this property is of type UINT8, ... */
+               memcpy(buf, prop->propinfo.default_val.integer, bytes_to_write);
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(buf, bytes_to_write);
+#endif /* __BIG_ENDIAN__ */
+       } else {
+               return 0;
+       }
+
+       return bytes_to_write;
+}
+
+obj_prop_desc_t *_prop_get_obj_prop_desc(mtp_uint32 format_code,
+               mtp_uint32 propcode)
+{
+       mtp_uint32 i = 0;
+       int num_default_obj_props = 0;
+
+       /*Default*/
+       if (_get_oma_drm_status() == TRUE) {
+               num_default_obj_props = NUM_OBJECT_PROP_DESC_DEFAULT;
+       } else {
+               num_default_obj_props = NUM_OBJECT_PROP_DESC_DEFAULT - 1;
+       }
+
+       for (i = 0; i < num_default_obj_props; i++) {
+               if (props_list_default[i].propinfo.prop_code == propcode) {
+                       return &(props_list_default[i]);
+               }
+       }
+
+       switch (format_code) {
+       case PTP_FMT_MP3:
+       case PTP_FMT_WAVE:
+               for (i = 0; i < NUM_OBJECT_PROP_DESC_MP3; i++) {
+                       if (props_list_mp3[i].propinfo.prop_code == propcode) {
+                               return &(props_list_mp3[i]);
+                       }
+               }
+               break;
+       case MTP_FMT_WMA:
+               for (i = 0; i < NUM_OBJECT_PROP_DESC_WMA; i++) {
+                       if (props_list_wma[i].propinfo.prop_code == propcode) {
+                               return &(props_list_wma[i]);
+                       }
+               }
+               break;
+       case MTP_FMT_WMV:
+       case PTP_FMT_ASF:
+       case MTP_FMT_MP4:
+       case PTP_FMT_AVI:
+       case PTP_FMT_MPEG:
+       case MTP_FMT_3GP:
+               for (i = 0; i < NUM_OBJECT_PROP_DESC_WMV; i++) {
+                       if (props_list_wmv[i].propinfo.prop_code == propcode) {
+                               return &(props_list_wmv[i]);
+                       }
+               }
+               break;
+       case MTP_FMT_ABSTRACT_AUDIO_ALBUM:
+       case PTP_FMT_IMG_EXIF:
+       case PTP_FMT_IMG_GIF:
+       case PTP_FMT_IMG_BMP:
+       case PTP_FMT_IMG_PNG:
+               for (i = 0; i < NUM_OBJECT_PROP_DESC_ALBUM; i++) {
+                       if (props_list_album[i].propinfo.prop_code == propcode) {
+                               return &(props_list_album[i]);
+                       }
+               }
+               break;
+
+       default:
+               break;
+       }
+
+       ERR("No matched property[0x%x], format[0x%x]!!\n", propcode,
+                       format_code);
+       return NULL;
+}
+
+static void __destroy_obj_prop_desc(obj_prop_desc_t *prop)
+{
+       slist_node_t *node = NULL;
+       slist_node_t *next_node = NULL;
+       mtp_uint32 ii;
+
+       if (prop->propinfo.data_type == PTP_DATATYPE_STRING) {
+
+               if (prop->propinfo.default_val.str) {
+
+                       _prop_destroy_ptpstring(prop->propinfo.default_val.str);
+                       prop->propinfo.default_val.str = NULL;
+               }
+
+               if (prop->propinfo.form_flag == ENUM_FORM) {
+
+                       for (node = prop->propinfo.supp_value_list.start, ii = 0;
+                                       ii < prop->propinfo.supp_value_list.nnodes;
+                                       node = node->link, ii++) {
+                               _prop_destroy_ptpstring((ptp_string_t *) node->value);
+                       }
+               }
+
+               if (prop->propinfo.form_flag == REGULAR_EXPRESSION_FORM) {
+
+                       if (prop->prop_forms.reg_exp != NULL) {
+                               _prop_destroy_ptpstring(prop->prop_forms.reg_exp);
+                               prop->prop_forms.reg_exp = NULL;
+                       }
+               }
+       } else if ((prop->propinfo.data_type & PTP_DATATYPE_ARRAYMASK) ==
+                       PTP_DATATYPE_ARRAY) {
+
+               if (prop->propinfo.default_val.array) {
+
+                       _prop_destroy_ptparray(prop->propinfo.default_val.array);
+                       prop->propinfo.default_val.array = NULL;
+               }
+       }
+
+       /* deallocate memory consumed by list elements  */
+       next_node = prop->propinfo.supp_value_list.start;
+       for (ii = 0; ii < prop->propinfo.supp_value_list.nnodes; ii++) {
+               node = next_node;
+               next_node = next_node->link;
+               g_free(node);
+       }
+       return;
+}
+
+/* Objectproplist functions */
+static mtp_uint32 __count_obj_proplist(obj_proplist_t *prop_list)
+{
+       return prop_list->prop_quad_list.nnodes;
+}
+
+mtp_uint32 _prop_size_obj_proplist(obj_proplist_t *prop_list)
+{
+       prop_quad_t *quad = NULL;
+       slist_node_t *node = NULL;
+       mtp_uint32 ii;
+       mtp_uint32 size;
+
+       /* for the NumberOfElements field in objpropvalList Dataset */
+       size = sizeof(mtp_uint32);
+
+       /* add all the fixed length members of the list */
+       size += prop_list->prop_quad_list.nnodes * (sizeof(mtp_uint32) +
+                       sizeof(mtp_uint16) + sizeof(mtp_uint16));
+       node = prop_list->prop_quad_list.start;
+       for (ii = 0; ii < prop_list->prop_quad_list.nnodes; ii++) {
+               quad = (prop_quad_t *) node->value;
+               if (quad) {
+                       size += quad->val_size;
+               }
+               node = node->link;
+       }
+       return size;
+}
+
+mtp_uint32 _prop_get_obj_proplist(mtp_obj_t *obj, mtp_uint32 propcode,
+               mtp_uint32 group_code, obj_proplist_t *prop_list)
+{
+       obj_prop_val_t *propval = NULL;
+       slist_node_t *node = NULL;
+       mtp_uint32 ii = 0;
+
+       if (obj->propval_list.nnodes == 0) {
+               if (FALSE == _prop_update_property_values_list(obj)) {
+                       ERR("update Property Values FAIL!!");
+                       return 0;
+               }
+       }
+       for (ii = 0, node = obj->propval_list.start;
+                       ii < obj->propval_list.nnodes;
+                       ii++, node = node->link) {
+               propval = (obj_prop_val_t *)node->value;
+
+               if (NULL == propval) {
+                       continue;
+               }
+
+               if (FALSE == __check_object_propcode(propval->prop,
+                                       propcode, group_code)) {
+                       continue;
+               }
+               __append_obj_proplist(prop_list, obj->obj_handle,
+                               propval->prop->propinfo.prop_code,
+                               propval->prop->propinfo.data_type,
+                               (mtp_uchar *)propval->current_val.integer);
+       }
+
+       return __count_obj_proplist(prop_list);
+}
+
+mtp_bool _prop_update_property_values_list(mtp_obj_t *obj)
+{
+       mtp_uint32 ii = 0;
+       mtp_char guid[16] = { 0 };
+       slist_node_t *node = NULL;
+       slist_node_t *next_node = NULL;
+       ptp_time_string_t create_tm, modify_tm;
+       mtp_uint32 fmt_code = obj->obj_info->obj_fmt;
+       mtp_wchar buf[MTP_MAX_PATHNAME_SIZE+1] = { 0 };
+       mtp_char file_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
+       mtp_wchar w_file_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
+       char filename_wo_extn[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_wchar object_fullpath[MTP_MAX_PATHNAME_SIZE * 2 + 1] = { 0 };
+
+       retv_if(obj == NULL, FALSE);
+       retv_if(obj->obj_info == NULL, FALSE);
+
+       if (obj->propval_list.nnodes > 0) {
+               /*
+                * Remove all the old property value,
+                * and ready to set up new list
+                */
+               for (ii = 0, next_node = obj->propval_list.start;
+                               ii < obj->propval_list.nnodes; ii++) {
+                       node = next_node;
+                       next_node = node->link;
+                       _prop_destroy_obj_propval((obj_prop_val_t *)
+                                       node->value);
+                       g_free(node);
+               }
+               obj->propval_list.start = NULL;
+               obj->propval_list.end = NULL;
+               obj->propval_list.nnodes = 0;
+               node = NULL;
+       }
+
+       /* Populate Object Info to Object properties */
+       if (obj->file_path == NULL || obj->file_path[0] != '/') {
+               ERR_SECURE("Path is not valid.. path = [%s]\n",
+                               obj->file_path);
+               return FALSE;
+       }
+
+       /*STORAGE ID*/
+       retv_if(FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_STORAGEID,
+                               obj->obj_info->store_id), FALSE);
+
+       /*OBJECT FORMAT*/
+       retv_if(FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_OBJECTFORMAT,
+                               obj->obj_info->obj_fmt), FALSE);
+
+       /*PROTECTION STATUS*/
+       retv_if(FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_PROTECTIONSTATUS,
+                               obj->obj_info->protcn_status), FALSE);
+
+       /*OBJECT SIZE*/
+       retv_if(FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_OBJECTSIZE,
+                               obj->obj_info->file_size), FALSE);
+
+       /*OBJECT FILENAME*/
+       _util_get_file_name(obj->file_path, file_name);
+       _util_utf8_to_utf16(w_file_name, sizeof(w_file_name) / WCHAR_SIZ, file_name);
+       retv_if(FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_OBJECTFILENAME, w_file_name), FALSE);
+
+       /*PARENT*/
+       retv_if(FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_PARENT, obj->obj_info->h_parent), FALSE);
+
+       /*PERSISTENT GUID*/
+       _util_utf8_to_utf16(object_fullpath,
+                       sizeof(object_fullpath) / WCHAR_SIZ, obj->file_path);
+       _util_conv_wstr_to_guid(object_fullpath, (mtp_uint64 *) guid);
+       retv_if((FALSE == __create_prop_array(obj,
+                                       MTP_OBJ_PROPERTYCODE_PERSISTENTGUID,
+                                       guid, sizeof(guid))), FALSE);
+
+       /*NON-CONSUMABLE*/
+       retv_if(FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_NONCONSUMABLE, 0), FALSE);
+
+       _entity_get_file_times(obj, &create_tm, &modify_tm);
+       /*DATE MODIFIED*/
+       retv_if(FALSE == __create_prop_timestring(obj, MTP_OBJ_PROPERTYCODE_DATEMODIFIED,
+               &modify_tm), FALSE);
+
+       /*DATE CREATED*/
+       retv_if(FALSE == __create_prop_timestring(obj, MTP_OBJ_PROPERTYCODE_DATECREATED,
+               &create_tm), FALSE);
+
+       /* NAME */
+       _util_get_file_name_wo_extn(obj->file_path,
+                       filename_wo_extn);
+       _util_utf8_to_utf16(buf, sizeof(buf) / WCHAR_SIZ, filename_wo_extn);
+       retv_if(FALSE == __create_prop_string(obj,
+                               MTP_OBJ_PROPERTYCODE_NAME, buf), FALSE);
+
+       /*ASSOCIATION TYPE*/
+       retv_if(FALSE == __create_prop_integer(obj,
+                               MTP_OBJ_PROPERTYCODE_ASSOCIATIONTYPE,
+                               obj->obj_info->association_type), FALSE);
+
+       /* OMADRM STATUS */
+       if (_get_oma_drm_status() == TRUE) {
+               retv_if(FALSE == __create_prop_integer(obj,
+                                       MTP_OBJ_PROPERTYCODE_OMADRMSTATUS, 0), FALSE);
+       }
+
+       /*Get DCM data*/
+       if (fmt_code == PTP_FMT_MP3 ||
+                       fmt_code == MTP_FMT_WMA ||
+                       fmt_code == PTP_FMT_WAVE ||
+                       fmt_code == MTP_FMT_FLAC) {
+               __update_prop_values_audio(obj);
+
+       } else if (fmt_code == MTP_FMT_WMV ||
+                       fmt_code == PTP_FMT_ASF ||
+                       fmt_code == MTP_FMT_MP4 ||
+                       fmt_code == PTP_FMT_AVI ||
+                       fmt_code == PTP_FMT_MPEG) {
+               __update_prop_values_video(obj);
+
+       } else if (fmt_code == PTP_FMT_IMG_EXIF ||
+                       fmt_code == PTP_FMT_IMG_BMP ||
+                       fmt_code == PTP_FMT_IMG_GIF ||
+                       fmt_code == PTP_FMT_IMG_PNG) {
+               __update_prop_values_image(obj);
+       }
+
+       return TRUE;
+}
+
+static mtp_bool __append_obj_proplist(obj_proplist_t *prop_list, mtp_uint32 obj_handle,
+               mtp_uint16 propcode, mtp_uint32 data_type, mtp_uchar *val)
+{
+       ptp_string_t *str = NULL;
+       prop_quad_t *quad = NULL;
+       ptp_array_t *arr_uint8;
+       ptp_array_t *arr_uint16;
+       ptp_array_t *arr_uint32;
+
+       quad = (prop_quad_t *)g_malloc(sizeof(prop_quad_t));
+       if (NULL == quad)
+               return FALSE;
+
+       quad->obj_handle = obj_handle;
+       quad->prop_code =  propcode;
+       quad->data_type =  data_type;
+       quad->pval = val;
+
+       switch (data_type) {
+       case PTP_DATATYPE_UINT8:
+       case PTP_DATATYPE_INT8:
+               quad->val_size = sizeof(mtp_uchar);
+               break;
+
+       case PTP_DATATYPE_UINT16:
+       case PTP_DATATYPE_INT16:
+               quad->val_size = sizeof(mtp_uint16);
+               break;
+
+       case PTP_DATATYPE_UINT32:
+       case PTP_DATATYPE_INT32:
+               quad->val_size = sizeof(mtp_uint32);
+               break;
+
+       case PTP_DATATYPE_UINT64:
+       case PTP_DATATYPE_INT64:
+               quad->val_size = sizeof(mtp_int64);
+               break;
+
+       case PTP_DATATYPE_UINT128:
+       case PTP_DATATYPE_INT128:
+               quad->val_size = 2 * sizeof(mtp_int64);
+               break;
+
+       case PTP_DATATYPE_AUINT8:
+       case PTP_DATATYPE_AINT8:
+               memcpy(&arr_uint8, val, sizeof(ptp_array_t *));
+               quad->val_size = (arr_uint8 != NULL) ?
+                       _prop_get_size_ptparray(arr_uint8) : 0;
+               quad->pval = (mtp_uchar *)arr_uint8;
+               break;
+
+       case PTP_DATATYPE_AUINT16:
+       case PTP_DATATYPE_AINT16:
+               memcpy(&arr_uint16, val, sizeof(ptp_array_t *));
+               quad->val_size = (arr_uint16 != NULL) ?
+                       _prop_get_size_ptparray(arr_uint16) : 0;
+               quad->pval = (mtp_uchar *)arr_uint16;
+               break;
+
+       case PTP_DATATYPE_AUINT32:
+       case PTP_DATATYPE_AINT32:
+               memcpy(&arr_uint32, val, sizeof(ptp_array_t *));
+               quad->val_size = (arr_uint32 != NULL) ? _prop_get_size_ptparray(arr_uint32) : 0;
+               quad->pval = (mtp_uchar *)arr_uint32;
+               break;
+
+       case PTP_DATATYPE_STRING:
+               memcpy(&str, val, sizeof(ptp_string_t *));
+               quad->val_size = (str != NULL) ? _prop_size_ptpstring(str) : 1;
+               quad->pval = (mtp_uchar *)str;
+               break;
+       default:
+               /* don't know  */
+               quad->val_size = 0;
+               break;
+       }
+
+       _util_add_node(&(prop_list->prop_quad_list), quad);
+       return TRUE;
+}
+
+mtp_uint32 _prop_pack_obj_proplist(obj_proplist_t *prop_list, mtp_uchar *buf,
+               mtp_uint32 size)
+{
+       mtp_uchar *temp = buf;
+       ptp_string_t *str = NULL;
+       prop_quad_t *quad = NULL;
+       mtp_uint32 ii;
+       slist_node_t *node = NULL;
+
+       if (!buf || size < _prop_size_obj_proplist(prop_list)) {
+               return 0;
+       }
+
+       *(mtp_uint32 *) buf = prop_list->prop_quad_list.nnodes;
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(temp, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+       temp += sizeof(mtp_uint32);
+
+       /* Pack the array elements */
+       node = prop_list->prop_quad_list.start;
+       for (ii = 0; ii < prop_list->prop_quad_list.nnodes; ii++) {
+               quad = (prop_quad_t *) node->value;
+               node = node->link;
+               /* pack the fixed length members */
+               memcpy(temp, &quad->obj_handle, sizeof(mtp_uint32));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+               temp += sizeof(mtp_uint32);
+
+               memcpy(temp, &quad->prop_code, sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+               temp += sizeof(mtp_uint16);
+
+               memcpy(temp, &quad->data_type, sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(temp, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+               temp += sizeof(mtp_uint16);
+
+               /* Pack property value */
+               if ((quad->data_type & PTP_DATATYPE_VALUEMASK) ==
+                               PTP_DATATYPE_VALUE) {
+
+                       memcpy(temp, quad->pval, quad->val_size);
+#ifdef __BIG_ENDIAN__
+                       _util_conv_byte_order(temp, quad->val_size);
+#endif /* __BIG_ENDIAN__ */
+                       temp += quad->val_size;
+
+               } else if (quad->data_type == PTP_DATATYPE_STRING) {
+
+                       str = (ptp_string_t *) quad->pval;
+                       if (str) {
+                               temp += _prop_pack_ptpstring(str, temp,
+                                               _prop_size_ptpstring (str));
+                       } else {
+                               /* Put in an empty string: NumOfChars = 0; */
+                               *temp++ = 0;
+                       }
+               } else if ((quad->data_type & PTP_DATATYPE_ARRAYMASK) ==
+                               PTP_DATATYPE_ARRAY) {
+
+                       if (quad->pval != NULL) {
+
+                               if (quad->val_size !=
+                                               _prop_pack_ptparray((ptp_array_t *)quad->pval,
+                                                       temp, quad->val_size)) {
+                                       return (mtp_uint32) (temp - buf);
+                               }
+                               temp += quad->val_size;
+                       } else {
+                               /* Fill in an empty array: mtp_uint32 */
+                               mtp_uint32 zero = 0;
+                               memcpy(temp, &zero, sizeof(mtp_uint32));
+                               temp += sizeof(mtp_uint32);
+                       }
+               }
+       }
+
+       return (mtp_uint32)(temp - buf);
+}
+
+void _prop_destroy_obj_proplist(obj_proplist_t *prop_list)
+{
+       slist_node_t *node = NULL;
+       slist_node_t *next_node = NULL;
+       mtp_uint32 ii;
+
+       for (ii = 0, node = prop_list->prop_quad_list.start;
+                       ii < prop_list->prop_quad_list.nnodes; ii++, node = node->link) {
+               g_free(node->value);
+       }
+
+       next_node = prop_list->prop_quad_list.start;
+
+       for (ii = 0; ii < prop_list->prop_quad_list.nnodes; ii++) {
+               node = next_node;
+               next_node = node->link;
+               g_free(node);
+       }
+       return;
+}
+
+mtp_bool _prop_add_supp_integer_val(prop_info_t *prop_info, mtp_uint32 value)
+{
+       if (((prop_info->data_type & PTP_DATATYPE_VALUEMASK) !=
+                               PTP_DATATYPE_VALUE) || (prop_info->form_flag != ENUM_FORM)) {
+               return FALSE;
+       }
+
+       /* Create the node and append it. */
+       _util_add_node(&(prop_info->supp_value_list), (void *)value);
+
+       return TRUE;
+}
+
+mtp_bool _prop_add_supp_string_val(prop_info_t *prop_info, mtp_wchar *val)
+{
+       ptp_string_t *str = NULL;
+       mtp_bool ret;
+
+       if ((prop_info->data_type != PTP_DATATYPE_STRING) ||
+                       (prop_info->form_flag != ENUM_FORM)) {
+               return FALSE;
+       }
+#ifndef MTP_USE_VARIABLE_PTP_STRING_MALLOC
+       str = __alloc_ptpstring();
+#else /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+       str = __alloc_ptpstring(_util_wchar_len(val));
+#endif /* MTP_USE_VARIABLE_PTP_STRING_MALLOC */
+
+       if (str != NULL) {
+               _prop_copy_char_to_ptpstring(str, val, WCHAR_TYPE);
+               ret = _util_add_node(&(prop_info->supp_value_list), (void *)str);
+               if (ret == FALSE) {
+                       ERR("List add Fail");
+                       g_free(str);
+                       return FALSE;
+               }
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/* ObjectProp Functions */
+mtp_uint32 _prop_get_supp_obj_props(mtp_uint32 format_code,
+               ptp_array_t *supp_props)
+{
+       mtp_uint32 i = 0;
+       mtp_uint32 num_default_obj_props = 0;
+
+       /*Default*/
+       if (_get_oma_drm_status() == TRUE) {
+               num_default_obj_props = NUM_OBJECT_PROP_DESC_DEFAULT;
+       } else {
+               num_default_obj_props = NUM_OBJECT_PROP_DESC_DEFAULT - 1;
+       }
+
+       for (i = 0; i < num_default_obj_props; i++) {
+               _prop_append_ele_ptparray(supp_props,
+                               props_list_default[i].propinfo.prop_code);
+       }
+
+       switch (format_code) {
+       case PTP_FMT_MP3:
+       case PTP_FMT_WAVE:
+               for (i = 0; i < NUM_OBJECT_PROP_DESC_MP3; i++) {
+                       _prop_append_ele_ptparray(supp_props,
+                                       props_list_mp3[i].propinfo.prop_code);
+               }
+               break;
+       case MTP_FMT_WMA:
+               for (i = 0; i < NUM_OBJECT_PROP_DESC_WMA; i++) {
+                       _prop_append_ele_ptparray(supp_props,
+                                       props_list_wma[i].propinfo.prop_code);
+               }
+               break;
+       case MTP_FMT_WMV:
+       case PTP_FMT_ASF:
+       case MTP_FMT_MP4:
+       case PTP_FMT_AVI:
+       case PTP_FMT_MPEG:
+       case MTP_FMT_3GP:
+               for (i = 0; i < NUM_OBJECT_PROP_DESC_WMV; i++) {
+                       _prop_append_ele_ptparray(supp_props,
+                                       props_list_wmv[i].propinfo.prop_code);
+               }
+               break;
+       case MTP_FMT_ABSTRACT_AUDIO_ALBUM:
+       case PTP_FMT_IMG_EXIF:
+       case PTP_FMT_IMG_GIF:
+       case PTP_FMT_IMG_BMP:
+       case PTP_FMT_IMG_PNG:
+               for (i = 0; i < NUM_OBJECT_PROP_DESC_ALBUM; i++) {
+                       _prop_append_ele_ptparray(supp_props,
+                                       props_list_album[i].propinfo.prop_code);
+               }
+               break;
+       default:
+               break;
+       }
+       DBG("getsupp_props : format [0x%x], supported list [%d]\n",
+                       format_code, supp_props->num_ele);
+       return supp_props->num_ele;
+}
+
+mtp_bool _prop_build_supp_props_default(void)
+{
+       mtp_wchar temp[MTP_MAX_REG_STRING + 1] = { 0 };
+       static mtp_bool initialized = FALSE;
+       mtp_uchar i = 0;
+       mtp_uint32 default_val;
+
+       if (initialized == TRUE) {
+               DBG("already supported list is in there. just return!!");
+               return TRUE;
+       }
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_STORAGEID (1)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_STORAGEID,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       default_val = 0x0;
+       _prop_set_default_integer(&(props_list_default[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_OBJECTFORMAT (2)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_OBJECTFORMAT,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       default_val = PTP_FMT_UNDEF;
+       _prop_set_default_integer(&(props_list_default[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_PROTECTIONSTATUS (3)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_PROTECTIONSTATUS,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       default_val = PTP_PROTECTIONSTATUS_NOPROTECTION;
+       _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
+                       PTP_PROTECTIONSTATUS_NOPROTECTION);
+       _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
+                       PTP_PROTECTIONSTATUS_READONLY);
+       _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
+                       MTP_PROTECTIONSTATUS_READONLY_DATA);
+       _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
+                       (mtp_uint32)MTP_PROTECTIONSTATUS_NONTRANSFERABLE_DATA);
+       _prop_set_default_integer(&(props_list_default[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_OBJECTSIZE (4)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_OBJECTSIZE,
+                       PTP_DATATYPE_UINT64,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 0x0);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_OBJECTFILENAME (5)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_OBJECTFILENAME,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETSET,
+                       REGULAR_EXPRESSION_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ,
+                       "[a-zA-Z!#\\$%&`\\(\\)\\-0-9@\\^_\\'\\{\\}\\~]{1,8}\\.[[a-zA-Z!#\\$%&`\\(\\)\\-0-9@\\^_\\'\\{\\}\\~]{1,3}]");
+       _prop_set_regexp(&(props_list_default[i]), temp);
+
+       _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, "");
+       _prop_set_default_string(&(props_list_default[i].propinfo), temp);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_PARENT (6)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_PARENT,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       default_val = 0x0;
+       _prop_set_default_integer(&(props_list_default[i].propinfo),
+                       (mtp_uchar *) &default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_PERSISTENTGUID (7)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_PERSISTENTGUID,
+                       PTP_DATATYPE_UINT128,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       {
+               mtp_uchar guid[16] = { 0 };
+               _prop_set_default_integer(&(props_list_default[i].propinfo),
+                               guid);
+       }
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_NONCONSUMABLE (8)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_NONCONSUMABLE,
+                       PTP_DATATYPE_UINT8,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       default_val = 0x0;
+       _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 0x0);
+       _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 0x1);
+       _prop_set_default_integer(&(props_list_default[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        *MTP_OBJ_PROPERTYCODE_DATEMODIFIED (9)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_DATEMODIFIED,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETONLY,
+                       DATE_TIME_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_set_default_string(&(props_list_default[i].propinfo), temp);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_DATECREATED (10)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_DATECREATED,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETONLY,
+                       DATE_TIME_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_set_default_string(&(props_list_default[i].propinfo), temp);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_NAME (11)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_NAME,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETONLY,
+                       NONE,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_set_default_string(&(props_list_default[i].propinfo), temp);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_ASSOCIATIONTYPE (12)
+        */
+       __init_obj_prop_desc(&(props_list_default[i]),
+                       MTP_OBJ_PROPERTYCODE_ASSOCIATIONTYPE,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETSET,
+                       ENUM_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       default_val = PTP_ASSOCIATIONTYPE_UNDEFINED;
+       _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
+                       PTP_ASSOCIATIONTYPE_UNDEFINED);
+       _prop_add_supp_integer_val(&(props_list_default[i].propinfo),
+                       PTP_ASSOCIATIONTYPE_FOLDER);
+       _prop_set_default_integer(&(props_list_default[i].propinfo),
+                       (mtp_uchar *)&default_val);
+
+       if (_get_oma_drm_status() == TRUE) {
+               /*
+                * MTP_OBJ_PROPERTYCODE_OMADRMSTATUS (13)
+                */
+               i++;
+               __init_obj_prop_desc(&(props_list_default[i]),
+                               MTP_OBJ_PROPERTYCODE_OMADRMSTATUS,
+                               PTP_DATATYPE_UINT8,
+                               PTP_PROPGETSET_GETONLY,
+                               ENUM_FORM,
+                               MTP_PROP_GROUPCODE_GENERAL);
+
+               default_val = 0;
+               _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 0);
+               _prop_add_supp_integer_val(&(props_list_default[i].propinfo), 1);
+               _prop_set_default_integer(&(props_list_default[i].propinfo),
+                               (mtp_uchar *)&default_val);
+       }
+
+       initialized = TRUE;
+
+       return TRUE;
+}
+
+mtp_bool _prop_build_supp_props_mp3(void)
+{
+       static mtp_bool initialized = FALSE;
+       mtp_uchar i = 0;
+       mtp_uint32 default_val;
+
+       if (initialized == TRUE) {
+               DBG("already supported list is in there. just return!!");
+               return TRUE;
+       }
+
+       /*Common properties 1 - 8 */
+       __build_supported_common_props(&i, &props_list_mp3[i]);
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_AUDIOBITRATE (9)
+        */
+       __init_obj_prop_desc(&(props_list_mp3[i]),
+                       MTP_OBJ_PROPERTYCODE_AUDIOBITRATE,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_AUDIO_BITRATE_UNKNOWN;
+       _prop_set_range_integer(&(props_list_mp3[i].propinfo),
+                       MTP_AUDIO_BITRATE_UNKNOWN, MTP_AUDIO_BITRATE_BLUERAY, 1L);
+       _prop_set_default_integer(&(props_list_mp3[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_SAMPLERATE (10)
+        */
+       __init_obj_prop_desc(&(props_list_mp3[i]),
+                       MTP_OBJ_PROPERTYCODE_SAMPLERATE,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_AUDIO_SAMPLERATE_UNKNOWN;
+       _prop_set_range_integer(&(props_list_mp3[i].propinfo),
+                       MTP_AUDIO_SAMPLERATE_8K, MTP_AUDIO_SAMPLERATE_48K, 1L);
+       _prop_set_default_integer(&(props_list_mp3[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS (11)
+        */
+       __init_obj_prop_desc(&(props_list_mp3[i]),
+                       MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_CHANNELS_MONO;
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_CHANNELS_NOT_USED);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_CHANNELS_MONO);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_CHANNELS_STEREO);
+       _prop_set_default_integer(&(props_list_mp3[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC (12)
+        */
+       __init_obj_prop_desc(&(props_list_mp3[i]),
+                       MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_WAVEFORMAT_UNKNOWN;
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_UNKNOWN);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_PCM);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_ADPCM);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_IEEEFLOAT);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_DTS);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_DRM);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_WMSP2);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_GSM610);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_MSNAUDIO);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_MPEG);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_MPEGLAYER3);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_MSAUDIO1);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_MSAUDIO2);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_MSAUDIO3);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_WMAUDIOLOSSLESS);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_WMASPDIF);
+       _prop_add_supp_integer_val(&(props_list_mp3[i].propinfo),
+                       MTP_WAVEFORMAT_AAC);
+       _prop_set_default_integer(&(props_list_mp3[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_DESCRIPTION (13)
+        */
+       __init_obj_prop_desc(&(props_list_mp3[i]),
+                       MTP_OBJ_PROPERTYCODE_DESCRIPTION,
+                       PTP_DATATYPE_AUINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       LONG_STRING_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_set_maxlen(&(props_list_mp3[i]), MAX_PTP_STRING_CHARS);
+       _prop_set_default_array(&(props_list_mp3[i].propinfo), NULL, 0);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO (14)
+        */
+       __init_obj_prop_desc(&(props_list_mp3[i]),
+                       MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO,
+                       PTP_DATATYPE_AUINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       LONG_STRING_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_set_maxlen(&(props_list_mp3[i]), MAX_PTP_STRING_CHARS);
+       _prop_set_default_array(&(props_list_mp3[i].propinfo), NULL, 0);
+
+       initialized = TRUE;
+       return TRUE;
+}
+
+mtp_bool _prop_build_supp_props_wma(void)
+{
+       static mtp_bool initialized = FALSE;
+       mtp_uchar i = 0;
+       mtp_uint32 default_val;
+
+       if (initialized == TRUE) {
+               DBG("already supported list is in there. just return!!");
+               return TRUE;
+       }
+
+       /*Common properties 1 - 8 */
+       __build_supported_common_props(&i, &props_list_wma[i]);
+       /*
+        * MTP_OBJ_PROPERTYCODE_AUDIOBITRATE (9)
+        */
+       __init_obj_prop_desc(&(props_list_wma[i]),
+                       MTP_OBJ_PROPERTYCODE_AUDIOBITRATE,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_AUDIO_BITRATE_UNKNOWN;
+       _prop_set_range_integer(&(props_list_wma[i].propinfo),
+                       MTP_AUDIO_BITRATE_UNKNOWN, MTP_AUDIO_BITRATE_BLUERAY, 1L);
+       _prop_set_default_integer(&(props_list_wma[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_SAMPLERATE (10)
+        */
+       __init_obj_prop_desc(&(props_list_wma[i]),
+                       MTP_OBJ_PROPERTYCODE_SAMPLERATE,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_AUDIO_SAMPLERATE_UNKNOWN;
+       _prop_set_range_integer(&(props_list_wma[i].propinfo),
+                       MTP_AUDIO_SAMPLERATE_8K, MTP_AUDIO_SAMPLERATE_48K, 1L);
+       _prop_set_default_integer(&(props_list_wma[i]).propinfo,
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS (11)
+        */
+       __init_obj_prop_desc(&(props_list_wma[i]),
+                       MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_CHANNELS_MONO;
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_CHANNELS_NOT_USED);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_CHANNELS_MONO);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_CHANNELS_STEREO);
+       _prop_set_default_integer(&(props_list_wma[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC (12)
+        */
+       __init_obj_prop_desc(&(props_list_wma[i]),
+                       MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM,
+                       MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_WAVEFORMAT_UNKNOWN;
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_UNKNOWN);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_PCM);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_ADPCM);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_IEEEFLOAT);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_DTS);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_DRM);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_WMSP2);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_GSM610);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_MSNAUDIO);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_MPEG);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_MPEGLAYER3);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_MSAUDIO1);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_MSAUDIO2);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_MSAUDIO3);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_WMAUDIOLOSSLESS);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_WMASPDIF);
+       _prop_add_supp_integer_val(&(props_list_wma[i].propinfo),
+                       MTP_WAVEFORMAT_AAC);
+       _prop_set_default_integer(&(props_list_wma[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_DESCRIPTION (13)
+        */
+       __init_obj_prop_desc(&(props_list_wma[i]),
+                       MTP_OBJ_PROPERTYCODE_DESCRIPTION,
+                       PTP_DATATYPE_AUINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       LONG_STRING_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_set_maxlen(&(props_list_wma[i]), MAX_PTP_STRING_CHARS);
+       _prop_set_default_array(&(props_list_wma[i].propinfo), NULL, 0);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO (14)
+        */
+       __init_obj_prop_desc(&(props_list_wma[i]),
+                       MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO,
+                       PTP_DATATYPE_AUINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       LONG_STRING_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_set_maxlen(&(props_list_wma[i]), MAX_PTP_STRING_CHARS);
+       _prop_set_default_array(&(props_list_wma[i].propinfo), NULL, 0);
+
+       /*-------------------------------------------------------------
+        * Valid Configurations for interdependent Object properties
+        *-------------------------------------------------------------
+        */
+#ifdef MTP_SUPPORT_INTERDEPENDENTPROP
+       {
+               interdep_prop_config_t *ptr_interdep_prop_cfg = NULL;
+               obj_prop_desc_t *prop = NULL;
+               mtp_uint32 default_val;
+
+               _util_init_list(&(interdep_proplist.plist));
+
+               prop = (obj_prop_desc_t *)g_malloc(sizeof(obj_prop_desc_t) * 4);
+               if (!prop) {
+                       ERR("prop g_malloc fail");
+                       return FALSE;
+               }
+               /* Valid config. 1 for Bit Rate and Sample Rate */
+               ptr_interdep_prop_cfg =
+                       (interdep_prop_config_t *)g_malloc(sizeof(interdep_prop_config_t));
+               if (!ptr_interdep_prop_cfg) {
+                       g_free(prop);
+                       ERR("ptr_interdep_prop_config g_malloc fail");
+                       return FALSE;
+               }
+
+               _util_init_list(&(ptr_interdep_prop_cfg->propdesc_list));
+               if (!ptr_interdep_prop_cfg) {
+                       g_free(prop);
+                       return FALSE;
+               }
+               ptr_interdep_prop_cfg->format_code = MTP_FMT_WMA;
+               i = 0;
+
+               __init_obj_prop_desc(&(prop[i]),
+                               MTP_OBJ_PROPERTYCODE_TOTALBITRATE,
+                               PTP_DATATYPE_UINT32,
+                               PTP_PROPGETSET_GETONLY,
+                               RANGE_FORM, MTP_PROP_GROUPCODE_GENERAL);
+
+               default_val = MTP_AUDIO_BITRATE_192K;
+               _prop_set_range_integer(&(prop[i].propinfo),
+                               MTP_AUDIO_BITRATE_192K,
+                               MTP_AUDIO_BITRATE_256K, 1000L);
+               _prop_set_default_integer(&(prop[i].propinfo),
+                               (mtp_uchar *)&default_val);
+               __append_interdep_prop(ptr_interdep_prop_cfg, &(prop[i]));
+               i++;
+
+               __init_obj_prop_desc(&(prop[i]),
+                               MTP_OBJ_PROPERTYCODE_SAMPLERATE,
+                               PTP_DATATYPE_UINT32,
+                               PTP_PROPGETSET_GETONLY,
+                               ENUM_FORM, MTP_PROP_GROUPCODE_GENERAL);
+
+               _prop_add_supp_integer_val(&(prop[i].propinfo),
+                               MTP_AUDIO_SAMPLERATE_DVD);
+               _prop_set_default_integer(&(prop[i].propinfo),
+                               (mtp_uchar *)MTP_AUDIO_SAMPLERATE_DVD);
+               __append_interdep_prop(ptr_interdep_prop_cfg, &(prop[i]));
+               i++;
+
+               /* Created one valid configuration */
+
+               mtp_bool ret;
+               ret = _util_add_node(&(interdep_proplist.plist),
+                               (void *)ptr_interdep_prop_cfg);
+               if (ret == FALSE) {
+                       g_free(prop);
+                       ERR("List add Fail");
+                       return FALSE;
+               }
+
+               /* Valid config. 2 for Bit Rate and Sample Rate */
+               ptr_interdep_prop_cfg =
+                       (interdep_prop_config_t *)g_malloc(sizeof(interdep_prop_config_t));
+               if (!ptr_interdep_prop_cfg) {
+                       g_free(prop);
+                       ERR("ptr_interdep_prop_cfg g_malloc fail");
+                       return FALSE;
+               }
+               _util_init_list(&(ptr_interdep_prop_cfg->propdesc_list));
+
+               if (!ptr_interdep_prop_cfg) {
+                       g_free(prop);
+                       return FALSE;
+               }
+               ptr_interdep_prop_cfg->format_code = MTP_FMT_WMA;
+
+               __init_obj_prop_desc(&(prop[i]),
+                               MTP_OBJ_PROPERTYCODE_TOTALBITRATE,
+                               PTP_DATATYPE_UINT32,
+                               PTP_PROPGETSET_GETONLY,
+                               RANGE_FORM, MTP_PROP_GROUPCODE_GENERAL);
+
+               default_val = 0x0;
+               _prop_set_range_integer(&(prop[i].propinfo),
+                               MTP_AUDIO_BITRATE_GSM,
+                               MTP_AUDIO_BITRATE_BLUERAY, 1L);
+               _prop_set_default_integer(&(prop[i].propinfo),
+                               (mtp_uchar *)&default_val);
+               __append_interdep_prop(ptr_interdep_prop_cfg, &(prop[i]));
+               i++;
+
+               __init_obj_prop_desc(&(prop[i]),
+                               MTP_OBJ_PROPERTYCODE_SAMPLERATE,
+                               PTP_DATATYPE_UINT32,
+                               PTP_PROPGETSET_GETONLY,
+                               ENUM_FORM, MTP_PROP_GROUPCODE_GENERAL);
+
+               default_val = MTP_AUDIO_SAMPLERATE_CD;
+               _prop_add_supp_integer_val(&(prop[i].propinfo),
+                               MTP_AUDIO_SAMPLERATE_32K);
+               _prop_add_supp_integer_val(&(prop[i].propinfo),
+                               MTP_AUDIO_SAMPLERATE_CD);
+               _prop_set_default_integer(&(prop[i].propinfo),
+                               (mtp_uchar *)&default_val);
+               __append_interdep_prop(ptr_interdep_prop_cfg, &(prop[i]));
+               i++;
+
+               /* Created one valid configuration */
+               ret = _util_add_node(&(interdep_proplist.plist),
+                               (void *)ptr_interdep_prop_cfg);
+               if (ret == FALSE) {
+                       g_free(prop);
+                       ERR("List add Fail");
+                       return FALSE;
+               }
+               g_free(prop);
+       }
+#endif /*MTP_SUPPORT_INTERDEPENDENTPROP*/
+
+       initialized = TRUE;
+
+       return TRUE;
+}
+
+mtp_bool _prop_build_supp_props_wmv(void)
+{
+       static mtp_bool initialized = FALSE;
+       mtp_wchar buff[3] = { 0 };
+       mtp_uchar i = 0;
+       mtp_uint32 default_val;
+
+       if (initialized == TRUE) {
+               DBG("already supported list is in there. just return!!");
+               return TRUE;
+       }
+       _util_utf8_to_utf16(buff, sizeof(buff) / WCHAR_SIZ, "");
+
+       /*Common properties 1 - 8 */
+       __build_supported_common_props(&i, &props_list_wmv[i]);
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_WIDTH (9)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_WIDTH,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = 0x0;
+       _prop_set_range_integer(&(props_list_wmv[i].propinfo),
+                       MTP_MIN_VIDEO_WIDTH, MTP_MAX_VIDEO_WIDTH,
+                       MTP_VIDEO_HEIGHT_WIDTH_INTERVAL);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_HEIGHT (10)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_HEIGHT,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = 0x0;
+       _prop_set_range_integer(&(props_list_wmv[i].propinfo),
+                       MTP_MIN_VIDEO_HEIGHT, MTP_MAX_VIDEO_HEIGHT,
+                       MTP_VIDEO_HEIGHT_WIDTH_INTERVAL);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_SAMPLERATE (11)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_SAMPLERATE,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_AUDIO_SAMPLERATE_8K;
+       _prop_set_range_integer(&(props_list_wmv[i]).propinfo,
+                       MTP_AUDIO_SAMPLERATE_8K,
+                       MTP_AUDIO_SAMPLERATE_DVD, MTP_AUDIO_SAMPLE_RATE_INTERVAL);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS (12)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_CHANNELS_MONO;
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_CHANNELS_NOT_USED);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_CHANNELS_MONO);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_CHANNELS_STEREO);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC (13)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_AUDIOWAVECODEC,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_WAVEFORMAT_UNKNOWN;
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_WAVEFORMAT_UNKNOWN);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_WAVEFORMAT_MPEGLAYER3);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_WAVEFORMAT_MSAUDIO1);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_WAVEFORMAT_MSAUDIO2);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_WAVEFORMAT_PCM);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_WAVEFORMAT_ADPCM);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_WAVEFORMAT_MSAUDIO3);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_WAVEFORMAT_RAW_AAC1);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_WAVEFORMAT_MPEG_HEAAC);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_AUDIOBITRATE (14)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_AUDIOBITRATE,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_AUDIO_BITRATE_UNKNOWN;
+       _prop_set_range_integer(&(props_list_wmv[i].propinfo),
+                       MTP_AUDIO_BITRATE_UNKNOWN,
+                       MTP_AUDIO_BITRATE_BLUERAY, 1L);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_VIDEOFOURCCCODEC (15)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_VIDEOFOURCCCODEC,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_VIDEOFOURCC_MP42;
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_UNKNOWN);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_H263);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_H264);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_MP42);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_MP43);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_WMV1);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_WMV2);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_WMV3);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_DIVX);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_XVID);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_M4S2);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_MP4V);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_AVC1);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_h264);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_X264);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_VIDEOFOURCC_N264);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_VIDEOBITRATE (16)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_VIDEOBITRATE,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_MIN_VIDEO_BITRATE;
+       _prop_set_range_integer(&(props_list_wmv[i].propinfo),
+                       MTP_MIN_VIDEO_BITRATE, MTP_MAX_VIDEO_BITRATE, 1L);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_FRAMESPER1KSECONDS (17)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_FRAMESPER1KSECONDS,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_MIN_VIDEO_FPS;
+       _prop_set_range_integer(&(props_list_wmv[i].propinfo), MTP_MIN_VIDEO_FPS,
+                       MTP_MAX_VIDEO_FPS, 1L);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_DESCRIPTION (18)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_DESCRIPTION,
+                       PTP_DATATYPE_AUINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       LONG_STRING_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_set_maxlen(&(props_list_wmv[i]), MAX_PTP_STRING_CHARS);
+       _prop_set_default_array(&(props_list_wmv[i].propinfo), NULL, 0);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO (19)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_COPYRIGHTINFO,
+                       PTP_DATATYPE_AUINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       LONG_STRING_FORM,
+                       MTP_PROP_GROUPCODE_GENERAL);
+
+       _prop_set_maxlen(&(props_list_wmv[i]), MAX_PTP_STRING_CHARS);
+       _prop_set_default_array(&(props_list_wmv[i].propinfo), NULL, 0);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_ENCODINGPROFILE (20)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_ENCODINGPROFILE,
+                       PTP_DATATYPE_STRING,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       _util_utf8_to_utf16(buff, sizeof(buff) / WCHAR_SIZ, "SP");
+       _prop_add_supp_string_val(&(props_list_wmv[i].propinfo), buff);
+       _util_utf8_to_utf16(buff, sizeof(buff) / WCHAR_SIZ, "MP");
+       _prop_add_supp_string_val(&(props_list_wmv[i].propinfo), buff);
+       _util_utf8_to_utf16(buff, sizeof(buff) / WCHAR_SIZ, "SP");
+       _prop_set_default_string(&(props_list_wmv[i].propinfo), buff);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_METAGENRE (21)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_METAGENRE,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_METAGENRE_NOT_USED;
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_NOT_USED);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_GENERIC_MUSIC_AUDIO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_GENERIC_NONMUSIC_AUDIO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_SPOKEN_WORD_AUDIO_BOOK_FILES);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_SPOKEN_WORD_NONAUDIO_BOOK_FILES);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_SPOKEN_WORD_NEWS);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_GENERIC_VIDEO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_NEWS_VIDEO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_MUSIC_VIDEO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_HOME_VIDEO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_FEATURE_FILM_VIDEO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_TV_SHOW_VIDEO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_TRAINING_VIDEO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_PHOTO_MONTAGE_VIDEO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_GENERIC_NONAUDIO_NONVIDEO_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_AUDIO_MEDIA_CAST_FILE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_METAGENRE_VIDEO_MEDIA_CAST_FILE);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_SCANTYPE (22)
+        */
+       __init_obj_prop_desc(&(props_list_wmv[i]),
+                       MTP_OBJ_PROPERTYCODE_SCANTYPE,
+                       PTP_DATATYPE_UINT16,
+                       PTP_PROPGETSET_GETONLY,
+                       ENUM_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = MTP_SCANTYPE_NOT_USED;
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_SCANTYPE_NOT_USED);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_SCANTYPE_PROGESSIVE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_SCANTYPE_FIELDINTERLEAVEDUPPERFIRST);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_SCANTYPE_FIELDINTERLEAVEDLOWERFIRST);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_SCANTYPE_FIELDSINGLEUPPERFIRST);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_SCANTYPE_FIELDSINGLELOWERFIRST);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_SCANTYPE_MIXEDINTERLACE);
+       _prop_add_supp_integer_val(&(props_list_wmv[i].propinfo),
+                       MTP_SCANTYPE_MIXEDINTERLACEANDPROGRESSIVE);
+       _prop_set_default_integer(&(props_list_wmv[i].propinfo),
+                       (mtp_uchar *)&default_val);
+
+#ifdef MTP_SUPPORT_PROPERTY_SAMPLE
+       __build_supported_sample_props(&i, &props_list_wmv[i]);
+#endif /*MTP_SUPPORT_PROPERTY_SAMPLE*/
+
+       initialized = TRUE;
+
+       return TRUE;
+}
+
+mtp_bool _prop_build_supp_props_album(void)
+{
+       static mtp_bool initialized = FALSE;
+       mtp_uchar i = 0;
+       mtp_uint32 default_val;
+
+       if (initialized == TRUE) {
+               DBG("already supported list is in there. just return!!");
+               return TRUE;
+       }
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_WIDTH (1)
+        */
+       __init_obj_prop_desc(&(props_list_album[i]),
+                       MTP_OBJ_PROPERTYCODE_WIDTH,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = 0x0;
+       _prop_set_range_integer(&(props_list_album[i].propinfo), 0,
+                       MTP_MAX_IMG_WIDTH, 1L);
+       _prop_set_default_integer(&(props_list_album[i].propinfo),
+                       (mtp_uchar *)&default_val);
+       i++;
+
+       /*
+        * MTP_OBJ_PROPERTYCODE_HEIGHT (2)
+        */
+       __init_obj_prop_desc(&(props_list_album[i]),
+                       MTP_OBJ_PROPERTYCODE_HEIGHT,
+                       PTP_DATATYPE_UINT32,
+                       PTP_PROPGETSET_GETONLY,
+                       RANGE_FORM, MTP_PROP_GROUPCODE_OBJECT);
+
+       default_val = 0x0;
+       _prop_set_range_integer(&(props_list_album[i].propinfo), 0,
+                       MTP_MAX_IMG_HEIGHT, 1L);
+       _prop_set_default_integer(&(props_list_album[i].propinfo),
+                       (mtp_uchar *)&default_val);
+
+       /*
+        * SAMPLE PROPERTIES (3-8)
+        */
+#ifdef MTP_SUPPORT_PROPERTY_SAMPLE
+       i++
+               __build_supported_sample_props(&i, &props_list_album[i]);
+#endif /*MTP_SUPPORT_PROPERTY_SAMPLE*/
+
+       initialized = TRUE;
+
+       return TRUE;
+}
+
+void _prop_destroy_supp_obj_props(void)
+{
+       mtp_uint32 i = 0;
+       int num_default_obj_prps = 0;
+
+       for (i = 0; i < NUM_OBJECT_PROP_DESC_MP3; i++) {
+               __destroy_obj_prop_desc(&(props_list_mp3[i]));
+       }
+
+       for (i = 0; i < NUM_OBJECT_PROP_DESC_WMA; i++) {
+               __destroy_obj_prop_desc(&(props_list_wma[i]));
+       }
+
+       for (i = 0; i < NUM_OBJECT_PROP_DESC_WMV; i++) {
+               __destroy_obj_prop_desc(&(props_list_wmv[i]));
+       }
+
+       for (i = 0; i < NUM_OBJECT_PROP_DESC_ALBUM; i++) {
+               __destroy_obj_prop_desc(&(props_list_album[i]));
+       }
+
+       if (_get_oma_drm_status() == TRUE) {
+               num_default_obj_prps = NUM_OBJECT_PROP_DESC_DEFAULT;
+       } else {
+               num_default_obj_prps = NUM_OBJECT_PROP_DESC_DEFAULT - 1;
+       }
+
+       for (i = 0; i < num_default_obj_prps; i++) {
+               __destroy_obj_prop_desc(&(props_list_default[i]));
+       }
+       return;
+}
+
+#ifdef MTP_SUPPORT_INTERDEPENDENTPROP
+static mtp_bool __append_interdep_prop(interdep_prop_config_t *prop_config,
+               obj_prop_desc_t *prop)
+{
+       mtp_bool ret;
+       if (prop != NULL) {
+               ret = _util_add_node(&(prop_config->propdesc_list),
+                               (void*)prop);
+               if (ret == FALSE) {
+                       ERR("list add Fail");
+                       return FALSE;
+               }
+               return TRUE;
+       }
+       return FALSE;
+}
+#endif /* MTP_SUPPORT_INTERDEPENDENTPROP */
+
+mtp_uint32 _prop_get_size_interdep_prop(interdep_prop_config_t *prop_config)
+{
+       obj_prop_desc_t *prop = NULL;
+       slist_node_t *node;
+       mtp_int32 ii;
+       mtp_uint32 size = sizeof(mtp_uint32);
+
+       node = prop_config->propdesc_list.start;
+       for (ii = 0; ii < prop_config->propdesc_list.nnodes; ii++) {
+               prop = node->value;
+               if (prop) {
+                       size += _prop_size_obj_prop_desc(prop);
+               }
+       }
+       return size;
+}
+
+mtp_uint32 _prop_pack_interdep_prop(interdep_prop_config_t *prop_config,
+               mtp_uchar *buf, mtp_uint32 size)
+{
+       mtp_uchar *temp = buf;
+       obj_prop_desc_t *prop = NULL;
+       slist_node_t *node;
+       mtp_uint32 ele_size = 0;
+       mtp_int32 ii;
+
+       if (!buf || size < _prop_get_size_interdep_prop(prop_config)) {
+               return 0;
+       }
+
+       *(mtp_uint32 *) buf = prop_config->propdesc_list.nnodes;
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(buf, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+       temp += sizeof(mtp_uint32);
+
+       node = prop_config->propdesc_list.start;
+       for (ii = 0; ii < prop_config->propdesc_list.nnodes; ii++) {
+               prop = node->value;
+
+               if (prop) {
+                       ele_size = _prop_size_obj_prop_desc(prop);
+                       _prop_pack_obj_prop_desc(prop, temp, ele_size);
+                       temp += ele_size;
+               }
+       }
+
+       return (mtp_uint32)(temp - buf);
+}
+
+static mtp_uint32 __count_interdep_proplist(obj_interdep_proplist_t *config_list,
+               mtp_uint32 format_code)
+{
+       mtp_uint32 count = 0;
+       interdep_prop_config_t *prop_config = NULL;
+       slist_node_t *node;
+       mtp_int32 ii;
+
+       node = config_list->plist.start;
+
+       for (ii = 0; ii < config_list->plist.nnodes; ii++) {
+               prop_config = node->value;
+               if ((prop_config->format_code == format_code) ||
+                               (prop_config->format_code == PTP_FORMATCODE_NOTUSED)) {
+                       count++;
+               }
+       }
+       return count;
+}
+
+mtp_uint32 _prop_get_size_interdep_proplist(obj_interdep_proplist_t *config_list,
+               mtp_uint32 format_code)
+{
+       mtp_uint32 size = sizeof(mtp_uint32);
+       interdep_prop_config_t *prop_config = NULL;
+       slist_node_t *node;
+       mtp_int32 ii;
+
+       node = config_list->plist.start;
+
+       for (ii = 0; ii < config_list->plist.nnodes; ii++) {
+               prop_config = node->value;
+               if ((prop_config->format_code == format_code) ||
+                               (prop_config->format_code == PTP_FORMATCODE_NOTUSED)) {
+
+                       size += _prop_get_size_interdep_prop(prop_config);
+               }
+       }
+       return size;
+}
+
+mtp_uint32 _prop_pack_interdep_proplist(obj_interdep_proplist_t *config_list,
+               mtp_uint32 format_code, mtp_uchar *buf, mtp_uint32 size)
+{
+       mtp_uchar *temp = buf;
+       interdep_prop_config_t *prop_config = NULL;
+       slist_node_t *node;
+       mtp_int32 ii;
+       mtp_uint32 ele_size = 0;
+
+       if (!buf ||
+                       size < _prop_get_size_interdep_proplist(config_list, format_code)) {
+               return 0;
+       }
+
+       *(mtp_uint32 *)buf = __count_interdep_proplist(config_list,
+                       format_code);
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(buf, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+       temp += sizeof(mtp_uint32);
+
+       node = config_list->plist.start;
+
+       for (ii = 0; ii < config_list->plist.nnodes; ii++) {
+
+               prop_config = node->value;
+               if ((prop_config->format_code == format_code) ||
+                               (prop_config->format_code == PTP_FORMATCODE_NOTUSED)) {
+
+                       ele_size = _prop_get_size_interdep_prop(prop_config);
+                       _prop_pack_interdep_prop(prop_config, temp, ele_size);
+                       temp += ele_size;
+               }
+       }
+
+       return (mtp_uint32)(temp - buf);
+}
+
+mtp_bool _get_oma_drm_status(void)
+{
+#ifdef MTP_SUPPORT_OMADRM_EXTENSION
+       return TRUE;
+#else /* MTP_SUPPORT_OMADRM_EXTENSION */
+       return FALSE;
+#endif /* MTP_SUPPORT_OMADRM_EXTENSION */
+}
diff --git a/src/entity/mtp_store.c b/src/entity/mtp_store.c
new file mode 100755 (executable)
index 0000000..dbf744e
--- /dev/null
@@ -0,0 +1,1233 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <glib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include "mtp_util.h"
+#include "mtp_support.h"
+#include "mtp_device.h"
+#include "mtp_media_info.h"
+#include "mtp_transport.h"
+#include "mtp_inoti_handler.h"
+
+
+extern mtp_char g_last_deleted[MTP_MAX_PATHNAME_SIZE + 1];
+static mtp_uint32 g_next_obj_handle = 1;
+
+
+static inline mtp_bool UTIL_CHECK_LIST_NEXT(slist_iterator *iter)
+{
+       return (iter && iter->node_ptr) ? TRUE : FALSE;
+}
+
+static void __init_store_info(store_info_t *info)
+{
+       ret_if(info == NULL);
+
+       memset(info, 0x00, sizeof(store_info_t));
+
+       info->store_type = PTP_STORAGETYPE_FIXEDRAM;
+       info->fs_type = PTP_FILESYSTEMTYPE_DCF;
+       info->access = PTP_STORAGEACCESS_RWD;
+
+       info->capacity = MTP_MAX_STORAGE;
+       info->free_space = MTP_MAX_STORAGE - 1;
+       info->free_space_in_objs = MTP_MAX_STORAGE_IN_OBJTS;
+
+       return;
+}
+
+static void __init_store_info_params(store_info_t *info,
+               mtp_uint64 capacity, mtp_uint16 store_type, mtp_uint16 fs_type,
+               mtp_uint16 access, mtp_wchar *store_desc, mtp_wchar *label)
+{
+       info->store_type = store_type;
+       info->fs_type = fs_type;
+       info->access = access;
+
+       info->capacity = capacity;
+       info->free_space = capacity;
+       info->free_space_in_objs = MTP_MAX_STORAGE_IN_OBJTS;
+
+       _prop_copy_char_to_ptpstring(&(info->store_desc), store_desc, WCHAR_TYPE);
+       _prop_copy_char_to_ptpstring(&(info->vol_label), label, WCHAR_TYPE);
+       return;
+}
+
+void _entity_update_store_info_run_time(store_info_t *info,
+               mtp_char *root_path)
+{
+       fs_info_t fs_info = { 0 };
+
+       ret_if(info == NULL);
+       ret_if(root_path == NULL);
+
+       if (FALSE == _util_get_filesystem_info(root_path, &fs_info)) {
+               ERR("_util_get_filesystem_info fail [%s]\n", root_path);
+               return;
+       }
+
+       info->capacity = fs_info.disk_size;
+       info->free_space = fs_info.avail_size;
+
+       return;
+}
+
+mtp_bool _entity_get_store_path_by_id(mtp_uint32 store_id, mtp_char *path)
+{
+       switch(store_id) {
+       case MTP_INTERNAL_STORE_ID :
+               g_strlcpy(path, MTP_STORE_PATH_CHAR,
+                               MTP_MAX_PATHNAME_SIZE + 1);
+               break;
+       case MTP_EXTERNAL_STORE_ID :
+               g_strlcpy(path, MTP_EXTERNAL_PATH_CHAR,
+                               MTP_MAX_PATHNAME_SIZE + 1);
+               break;
+       default :
+               ERR("No valid match for the store id [0x%x]\n", store_id);
+               return FALSE;
+
+       }
+       return TRUE;
+}
+
+mtp_uint32 _entity_get_store_info_size(store_info_t *info)
+{
+       mtp_uint32 size = FIXED_LENGTH_MEMBERS_MTPSTORE_SIZE;
+
+       size += _prop_size_ptpstring(&(info->store_desc));
+       size += _prop_size_ptpstring(&(info->vol_label));
+
+       return (size);
+}
+
+mtp_uint32 _entity_pack_store_info(store_info_t *info, mtp_uchar *buf,
+               mtp_uint32 buf_sz)
+{
+       mtp_uint32 num_bytes = 0;
+
+       retv_if(buf == NULL, 0);
+
+       if (buf_sz < _entity_get_store_info_size(info)) {
+               ERR("Buffer size is less [%u]\n", buf_sz);
+               return 0;
+       }
+#ifdef __BIG_ENDIAN__
+       memcpy(&(buf[num_bytes]), &(info->store_type),
+                       sizeof(info->StorageType));
+       _util_conv_byte_order(buf, sizeof(info->store_type));
+       num_bytes += sizeof(info->store_type);
+
+       memcpy(&(buf[num_bytes]), &(info->fs_type), sizeof(info->fs_type));
+       _util_conv_byte_order(buf, sizeof(info->fs_type));
+       num_bytes += sizeof(info->fs_type);
+
+       memcpy(&(buf[num_bytes]), &(info->access), sizeof(info->access));
+       _util_conv_byte_order(buf, sizeof(info->access));
+       num_bytes += sizeof(info->access);
+
+       memcpy(&(buf[num_bytes]), &(info->capacity), sizeof(info->capacity));
+       _util_conv_byte_order(buf, sizeof(info->capacity));
+       num_bytes += sizeof(info->capacity);
+
+       memcpy(&(buf[num_bytes]), &(info->free_space),
+                       sizeof(info->free_space));
+       _util_conv_byte_order(buf, sizeof(info->free_space));
+       num_bytes += sizeof(info->free_space);
+
+       memcpy(&(buf[num_bytes]), &(info->free_space_in_objs),
+                       sizeof(info->free_space_in_objs));
+       _util_conv_byte_order(buf, sizeof(info->free_space_in_objs));
+       num_bytes += sizeof(info->free_space_in_objs);
+#else /*__BIG_ENDIAN__*/
+       memcpy(buf, &(info->store_type), sizeof(mtp_uint16) *3);
+       num_bytes += sizeof(mtp_uint16) * 3;
+       memcpy(&(buf[num_bytes]), &(info->capacity),
+                       sizeof(mtp_uint64) * 2 + sizeof(mtp_uint32));
+       num_bytes += sizeof(mtp_uint64) * 2 + sizeof(mtp_uint32);
+#endif /*__BIG_ENDIAN__*/
+       num_bytes += _prop_pack_ptpstring(&(info->store_desc), buf + num_bytes,
+                       _prop_size_ptpstring(&(info->store_desc)));
+
+       num_bytes += _prop_pack_ptpstring(&(info->vol_label), buf + num_bytes,
+                       _prop_size_ptpstring(&(info->vol_label)));
+
+       return num_bytes;
+}
+
+mtp_uint32 _entity_get_store_id_by_path(const mtp_char *path_name)
+{
+       mtp_uint32 store_id = 0;
+
+       retv_if(NULL == path_name, FALSE);
+
+       if (!strncmp(path_name, MTP_STORE_PATH_CHAR,
+                               strlen(MTP_STORE_PATH_CHAR))) {
+               store_id = MTP_INTERNAL_STORE_ID;
+       } else if (!strncmp(path_name, MTP_EXTERNAL_PATH_CHAR,
+                               strlen(MTP_EXTERNAL_PATH_CHAR))) {
+               store_id = MTP_EXTERNAL_STORE_ID;
+       }
+
+       DBG_SECURE("Path : %s, store_id : 0x%x\n", path_name, store_id);
+
+       return store_id;
+}
+
+mtp_bool _entity_init_mtp_store(mtp_store_t *store, mtp_uint32 store_id,
+               mtp_char *store_path)
+{
+       mtp_char temp[MTP_SERIAL_LEN_MAX + 1] = { 0 };
+       mtp_wchar wtemp[MTP_MAX_REG_STRING + 1] = { 0 };
+       mtp_char serial[MTP_MAX_REG_STRING + 1] = { 0 };
+       mtp_wchar wserial[MTP_MAX_REG_STRING + 1] = { 0 };
+
+       retv_if(store == NULL, FALSE);
+
+       store->store_id = store_id;
+       store->root_path = g_strdup(store_path);
+
+       __init_store_info(&(store->store_info));
+       _entity_update_store_info_run_time(&(store->store_info),
+                       store->root_path);
+
+       _device_get_serial(temp, sizeof(temp));
+       g_snprintf(serial, sizeof(serial), "%s-%x", temp, store_id);
+       _util_utf8_to_utf16(wserial, sizeof(wserial) / WCHAR_SIZ, serial);
+
+       switch (store_id) {
+       case MTP_INTERNAL_STORE_ID:
+               store->is_hidden = FALSE;
+               _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ,
+                               MTP_STORAGE_DESC_INT);
+               __init_store_info_params(&(store->store_info),
+                               store->store_info.capacity, PTP_STORAGETYPE_FIXEDRAM,
+                               PTP_FILESYSTEMTYPE_HIERARCHICAL, PTP_STORAGEACCESS_RWD,
+                               wtemp, wserial);
+               break;
+
+       case MTP_EXTERNAL_STORE_ID:
+               store->is_hidden = FALSE;
+               _util_utf8_to_utf16(wtemp, sizeof(wtemp) / WCHAR_SIZ,
+                               MTP_STORAGE_DESC_EXT);
+               __init_store_info_params(&(store->store_info),
+                               store->store_info.capacity,
+                               PTP_STORAGETYPE_REMOVABLERAM,
+                               PTP_FILESYSTEMTYPE_HIERARCHICAL,
+                               PTP_STORAGEACCESS_RWD, wtemp, wserial);
+               break;
+
+       default:
+               ERR("store initialization Fail");
+               return FALSE;
+       }
+
+       _util_init_list(&(store->obj_list));
+
+       return TRUE;
+}
+
+mtp_obj_t *_entity_add_file_to_store(mtp_store_t *store, mtp_uint32 h_parent,
+               mtp_char *file_path, mtp_char *file_name, dir_entry_t *file_info)
+{
+       mtp_obj_t *obj = NULL;
+
+       retv_if(NULL == store, NULL);
+
+       obj = _entity_alloc_mtp_object();
+       if (NULL == obj) {
+               ERR("Memory allocation Fail");
+               return NULL;
+       }
+
+       if (_entity_init_mtp_object_params(obj, store->store_id, h_parent,
+                               file_path, file_name, file_info) == FALSE) {
+               ERR("_entity_init_mtp_object_params Fail");
+               g_free(obj);
+               return NULL;
+       }
+
+       _entity_add_object_to_store(store, obj);
+       return obj;
+}
+
+mtp_obj_t *_entity_add_folder_to_store(mtp_store_t *store, mtp_uint32 h_parent,
+               mtp_char *file_path, mtp_char *file_name, dir_entry_t *file_info)
+{
+       mtp_obj_t *obj = NULL;
+
+       retv_if(NULL == store, NULL);
+
+       obj = _entity_alloc_mtp_object();
+       if (NULL == obj) {
+               ERR("Memory allocation Fail");
+               return NULL;
+       }
+
+       if (_entity_init_mtp_object_params(obj, store->store_id, h_parent,
+                               file_path, file_name, file_info) == FALSE) {
+               ERR("_entity_init_mtp_object_params Fail");
+               g_free(obj);
+               return NULL;
+       }
+
+       _entity_add_object_to_store(store, obj);
+       return obj;
+}
+
+mtp_bool _entity_add_object_to_store(mtp_store_t *store, mtp_obj_t *obj)
+{
+       mtp_obj_t *par_obj = NULL;
+
+       retv_if(obj == NULL, FALSE);
+       retv_if(NULL == store, FALSE);
+       retv_if(obj->obj_info == NULL, FALSE);
+
+       if (_util_add_node(&(store->obj_list), obj) == FALSE) {
+               ERR("Node add to list Fail");
+               return FALSE;
+       }
+
+       /* references */
+       if (PTP_OBJECTHANDLE_ROOT != obj->obj_info->h_parent) {
+               par_obj = _entity_get_object_from_store(store, obj->obj_info->h_parent);
+               if (NULL != par_obj) {
+                       _entity_add_reference_child_array(par_obj, obj->obj_handle);
+               }
+       }
+
+       return TRUE;
+}
+
+mtp_obj_t *_entity_get_object_from_store(mtp_store_t *store, mtp_uint32 handle)
+{
+       mtp_obj_t *obj = NULL;
+       slist_iterator *iter = NULL;
+
+       retv_if(NULL == store, NULL);
+
+       iter = (slist_iterator *)_util_init_list_iterator(&(store->obj_list));
+       if (iter == NULL) {
+               ERR("Iterator init Fail, Store id = [0x%x]\n", store->store_id);
+               return NULL;
+       }
+
+       while(UTIL_CHECK_LIST_NEXT(iter) == TRUE) {
+               obj = (mtp_obj_t *)_util_get_list_next(iter);
+
+               if (obj && obj->obj_handle == handle) {
+                       _util_deinit_list_iterator(iter);
+                       return obj;
+               }
+       }
+
+       ERR("Object not found in the list handle [%d] in store[0x%x]\n", handle, store->store_id);
+       _util_deinit_list_iterator(iter);
+       return NULL;
+}
+
+mtp_obj_t *_entity_get_last_object_from_store(mtp_store_t *store,
+               mtp_uint32 handle)
+{
+       mtp_obj_t *obj = NULL;
+       mtp_obj_t *temp_obj = NULL;
+       slist_iterator *iter = NULL;
+
+       retv_if(NULL == store, NULL);
+
+       iter = (slist_iterator *)_util_init_list_iterator(&(store->obj_list));
+       if (iter == NULL) {
+               ERR("Iterator init Fail Store id = [0x%x]\n", store->store_id);
+               return NULL;
+       }
+
+       while(UTIL_CHECK_LIST_NEXT(iter) == TRUE) {
+
+               temp_obj = (mtp_obj_t *)_util_get_list_next(iter);
+               if (temp_obj && temp_obj->obj_handle == handle) {
+                       obj = temp_obj;
+               }
+       }
+
+       _util_deinit_list_iterator(iter);
+       return obj;
+}
+
+mtp_obj_t *_entity_get_object_from_store_by_path(mtp_store_t *store,
+               mtp_char *file_path)
+{
+       mtp_obj_t *obj = NULL;
+       slist_iterator *iter = NULL;
+
+       retv_if(NULL == store, NULL);
+
+       iter = (slist_iterator *)_util_init_list_iterator(&(store->obj_list));
+       if (iter == NULL) {
+               ERR("Iterator init Fail Store id = [0x%x]\n", store->store_id);
+               return NULL;
+       }
+
+       while(UTIL_CHECK_LIST_NEXT(iter) == TRUE) {
+               obj = (mtp_obj_t *)_util_get_list_next(iter);
+               if (obj == NULL) {
+                       ERR("Object is NULL");
+                       continue;
+               }
+
+               if (!g_strcmp0(file_path, obj->file_path)) {
+                       _util_deinit_list_iterator(iter);
+                       return obj;
+               }
+       }
+       ERR_SECURE("Object [%s] not found in the list\n", file_path);
+       _util_deinit_list_iterator(iter);
+       return NULL;
+}
+
+/*
+ * _entity_get_objects_from_store
+ * called in case of PTP_OBJECTHANDLE_ALL
+ * fills the obj_array with objects matching the format code
+ */
+mtp_uint32 _entity_get_objects_from_store(mtp_store_t *store,
+               mtp_uint32 obj_handle, mtp_uint32 fmt, ptp_array_t *obj_arr)
+{
+       mtp_obj_t *obj = NULL;
+       slist_iterator *iter = NULL;
+
+       retv_if(store == NULL, 0);
+       retv_if(obj_arr == NULL, 0);
+
+       if (obj_handle != PTP_OBJECTHANDLE_ALL) {
+               ERR("Object Handle is not PTP_OBJECTHANDLE_ALL");
+               return 0;
+       }
+
+       iter = (slist_iterator *)_util_init_list_iterator(&(store->obj_list));
+       if (iter == NULL) {
+               ERR("Iterator init Fail Store id = [0x%x]\n", store->store_id);
+               return 0;
+       }
+
+       while(UTIL_CHECK_LIST_NEXT(iter) == TRUE) {
+
+               obj = (mtp_obj_t *)_util_get_list_next(iter);
+               if (obj == NULL) {
+                       ERR("Object is NULL");
+                       continue;
+               }
+               if ((fmt == obj->obj_info->obj_fmt) ||
+                               (fmt == PTP_FORMATCODE_ALL) ||
+                               (fmt == PTP_FORMATCODE_NOTUSED)) {
+                       _prop_append_ele_ptparray(obj_arr, (mtp_uint32)obj);
+               }
+       }
+       _util_deinit_list_iterator(iter);
+       return obj_arr->num_ele;
+}
+
+mtp_uint32 _entity_get_objects_from_store_till_depth(mtp_store_t *store,
+               mtp_uint32 obj_handle, mtp_uint32 fmt_code, mtp_uint32 depth,
+               ptp_array_t *obj_arr)
+{
+       mtp_obj_t *obj = NULL;
+
+       retv_if(store == NULL, 0);
+       retv_if(obj_arr == NULL, 0);
+
+       if (PTP_OBJECTHANDLE_ALL == obj_handle) {
+               _entity_get_objects_from_store(store, obj_handle, fmt_code,
+                               obj_arr);
+               DBG("Number of object filled [%u]\n", obj_arr->num_ele);
+               return obj_arr->num_ele;
+       }
+
+       if (PTP_OBJECTHANDLE_ROOT != obj_handle) {
+               obj = _entity_get_object_from_store(store, obj_handle);
+               if (obj) {
+                       _prop_append_ele_ptparray(obj_arr, (mtp_uint32)obj);
+               }
+       }
+       if (depth > 0) {
+               ptp_array_t *child_arr = NULL;
+               mtp_uint32 *ptr = NULL;
+               mtp_uint32 ii = 0;
+
+               child_arr = _prop_alloc_ptparray(UINT32_TYPE);
+               if (child_arr == NULL || child_arr->array_entry == NULL)
+                       return 0;
+
+               depth--;
+
+               _entity_get_child_handles_with_same_format(store, obj_handle,
+                               fmt_code, child_arr);
+               ptr = child_arr->array_entry;
+
+               for (ii = 0; ii < child_arr->num_ele; ii++) {
+                       _entity_get_objects_from_store_till_depth(store,
+                                       ptr[ii], fmt_code, depth, obj_arr);
+               }
+               _prop_destroy_ptparray(child_arr);
+       }
+
+       DBG("Handle[%u] : array count [%u]!!\n", obj_handle,
+                       obj_arr->num_ele);
+       return obj_arr->num_ele;
+}
+
+mtp_uint32 _entity_get_objects_from_store_by_format(mtp_store_t *store,
+               mtp_uint32 format, ptp_array_t *obj_arr)
+{
+       mtp_obj_t *obj = NULL;
+       slist_iterator *iter = NULL;
+
+       retv_if(store == NULL, 0);
+       retv_if(obj_arr == NULL, 0);
+
+       iter = (slist_iterator *)_util_init_list_iterator(&(store->obj_list));
+       if (iter == NULL) {
+               ERR("Iterator init Fail Store id = [0x%x]\n", store->store_id);
+               return 0;
+       }
+
+       while(UTIL_CHECK_LIST_NEXT(iter) == TRUE) {
+
+               obj = (mtp_obj_t *)_util_get_list_next(iter);
+               if (obj == NULL || obj->obj_info == NULL)
+                       continue;
+               if ((format == PTP_FORMATCODE_NOTUSED) ||
+                               (format == obj->obj_info->obj_fmt) ||
+                               ((format == PTP_FORMATCODE_ALL) &&
+                                (obj->obj_info->obj_fmt !=
+                                 PTP_FMT_ASSOCIATION))) {
+                       _prop_append_ele_ptparray(obj_arr,
+                                       (mtp_uint32)obj->obj_handle);
+               }
+
+       }
+
+       _util_deinit_list_iterator(iter);
+       return (obj_arr->num_ele);
+}
+
+mtp_uint32 _entity_get_num_object_with_same_format(mtp_store_t *store,
+               mtp_uint32 format)
+{
+       mtp_uint32 count = 0;
+       mtp_obj_t *obj = NULL;
+       slist_iterator *iter = NULL;
+
+       retv_if(store == NULL, 0);
+
+       if (PTP_FORMATCODE_NOTUSED == format) {
+               return store->obj_list.nnodes;
+       }
+
+       iter = (slist_iterator *)_util_init_list_iterator(&(store->obj_list));
+       if (iter == NULL) {
+               ERR("Iterator init Fail, store id = [0x%x]\n", store->store_id);
+               return 0;
+       }
+
+       while(UTIL_CHECK_LIST_NEXT(iter) == TRUE) {
+
+               obj = (mtp_obj_t *)_util_get_list_next(iter);
+               if (obj == NULL || obj->obj_info == NULL)
+                       continue;
+
+               if ((obj->obj_info->obj_fmt == format) ||
+                               (obj->obj_info->obj_fmt != PTP_FMT_ASSOCIATION &&
+                                PTP_FORMATCODE_ALL == format)) {
+                       count++;
+               }
+       }
+
+       _util_deinit_list_iterator(iter);
+       return count;
+}
+
+mtp_uint32 _entity_get_num_children(mtp_store_t *store, mtp_uint32 h_parent,
+               mtp_uint32 format)
+{
+       mtp_uint32 count = 0;
+       mtp_obj_t *obj = NULL;
+       slist_iterator *iter = NULL;
+
+       retv_if(store == NULL, 0);
+
+       iter = (slist_iterator *)_util_init_list_iterator(&(store->obj_list));
+       if (iter == NULL) {
+               ERR("Iterator init Fail Store id = [0x%x]\n", store->store_id);
+               return 0;
+       }
+
+       while(UTIL_CHECK_LIST_NEXT(iter) == TRUE) {
+
+               obj = (mtp_obj_t *)_util_get_list_next(iter);
+               if (obj == NULL || obj->obj_info == NULL)
+                       continue;
+
+               if ((obj->obj_info->h_parent == h_parent) &&
+                               ((format == obj->obj_info->obj_fmt) ||
+                                (format == PTP_FORMATCODE_NOTUSED) ||
+                                ((format == PTP_FORMATCODE_ALL) &&
+                                 (obj->obj_info->obj_fmt !=
+                                  PTP_FMT_ASSOCIATION)))) {
+                       count++;
+               }
+       }
+
+       _util_deinit_list_iterator(iter);
+       return count;
+}
+
+mtp_uint32 _entity_get_child_handles(mtp_store_t *store, mtp_uint32 h_parent,
+               ptp_array_t *child_arr)
+{
+       mtp_obj_t *obj = NULL;
+       slist_iterator *iter = NULL;
+       mtp_obj_t *parent_obj = NULL;
+
+       retv_if(store == NULL, 0);
+       retv_if(child_arr == NULL, 0);
+
+       parent_obj = _entity_get_object_from_store(store, h_parent);
+
+       if (NULL == parent_obj) {
+               ERR("parent object is NULL");
+               return FALSE;
+       }
+
+       iter = (slist_iterator *)_util_init_list_iterator(&(store->obj_list));
+       if (iter == NULL) {
+               ERR("Iterator init Fail Store id = [0x%x]\n", store->store_id);
+               return 0;
+       }
+
+       while(UTIL_CHECK_LIST_NEXT(iter) == TRUE) {
+
+               obj = (mtp_obj_t *)_util_get_list_next(iter);
+               if (obj == NULL || obj->obj_info == NULL)
+                       continue;
+
+               if (obj->obj_info->h_parent == h_parent) {
+                       _prop_append_ele_ptparray(child_arr, obj->obj_handle);
+               }
+       }
+
+       _util_deinit_list_iterator(iter);
+       return child_arr->num_ele;
+}
+
+mtp_uint32 _entity_get_child_handles_with_same_format(mtp_store_t *store,
+               mtp_uint32 h_parent, mtp_uint32 format, ptp_array_t *child_arr)
+{
+       mtp_obj_t *obj = NULL;
+       slist_iterator *iter = NULL;
+
+       retv_if(store == NULL, 0);
+       retv_if(child_arr == NULL, 0);
+
+       iter = (slist_iterator *)_util_init_list_iterator(&(store->obj_list));
+       if (iter == NULL) {
+               ERR("Iterator init Fail Store id = [0x%x]\n", store->store_id);
+               return 0;
+       }
+
+       while(UTIL_CHECK_LIST_NEXT(iter) == TRUE) {
+
+               obj = (mtp_obj_t *)_util_get_list_next(iter);
+               if (obj == NULL || obj->obj_info == NULL)
+                       continue;
+
+               if ((obj->obj_info->h_parent == h_parent) &&
+                               ((obj->obj_info->obj_fmt == format) ||
+                                (format == PTP_FORMATCODE_NOTUSED))) {
+
+                       _prop_append_ele_ptparray(child_arr, obj->obj_handle);
+               }
+
+       }
+
+       _util_deinit_list_iterator(iter);
+       return child_arr->num_ele;
+}
+
+mtp_bool _entity_remove_object_mtp_store(mtp_store_t *store, mtp_obj_t *obj,
+               mtp_uint32 format, mtp_uint16 *response, mtp_bool *atleast_one,
+               mtp_bool read_only)
+{
+       mtp_uint64 size = 0;
+       mtp_bool all_del = TRUE;
+       mtp_uint32 h_parent = 0;
+       obj_info_t *objinfo = NULL;
+       mtp_int32 ret = MTP_ERROR_NONE;
+
+       retv_if(store == NULL, 0);
+
+       if (TRUE == _transport_get_cancel_initialization() ||
+                       TRUE == _transport_get_usb_discon_state()) {
+               ERR("Delete operation cancelled or USB is disconnected");
+               *response = PTP_RESPONSE_PARTIAL_DELETION;
+               return FALSE;
+       }
+
+       if (NULL == obj || NULL == obj->obj_info || NULL == store) {
+               *response = PTP_RESPONSE_UNDEFINED;
+               return FALSE;
+       }
+
+       objinfo = obj->obj_info;
+
+       if ((objinfo->obj_fmt != format) && (format != PTP_FORMATCODE_ALL) &&
+                       (format != PTP_FORMATCODE_NOTUSED)) {
+               *response = PTP_RESPONSE_UNDEFINED;
+               return FALSE;
+       }
+
+       if ((PTP_FORMATCODE_ALL == format) &&
+                       (PTP_FMT_ASSOCIATION == objinfo->obj_fmt)) {
+
+               *response = PTP_RESPONSE_UNDEFINED;
+               return FALSE;
+       }
+
+#ifdef MTP_SUPPORT_SET_PROTECTION
+       /* Delete readonly files/folder */
+       if (!read_only)
+               objinfo->protcn_status = PTP_PROTECTIONSTATUS_NOPROTECTION;
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+
+       if (PTP_FMT_ASSOCIATION == objinfo->obj_fmt) {
+               /* If this is an association, delete children first
+                * the reference list contain all the children handle
+                * or find a child each time;
+                */
+
+               mtp_uint32 i = 0;
+               ptp_array_t child_arr = { 0 };
+               mtp_obj_t *child_obj = NULL;
+
+               _prop_init_ptparray(&child_arr, UINT32_TYPE);
+               _entity_get_child_handles(store, obj->obj_handle, &child_arr);
+
+               if (child_arr.num_ele) {
+
+                       for (i = 0; i < child_arr.num_ele; i++) {
+                               mtp_uint32 *ptr32 = child_arr.array_entry;
+                               /*check cancel transaction*/
+                               if (_transport_get_cancel_initialization() == TRUE ||
+                                               _transport_get_usb_discon_state() == TRUE) {
+                                       ERR("child handle. USB is disconnected \
+                                                       format operation is cancelled.");
+                                       *response =
+                                               PTP_RESPONSE_PARTIAL_DELETION;
+                                       return FALSE;
+                               }
+
+                               child_obj = _entity_get_object_from_store(store,
+                                               ptr32[i]);
+                               if (NULL == child_obj) {
+                                       continue;
+                               }
+                               if (_entity_remove_object_mtp_store(store, child_obj,
+                                                       format, response, atleast_one,
+                                                       read_only)) {
+                                       slist_node_t *node;
+                                       node = _util_delete_node(&(store->obj_list),
+                                                       child_obj);
+                                       g_free(node);
+                                       *atleast_one = TRUE;
+                                       _entity_dealloc_mtp_obj(child_obj);
+                               } else {
+                                       all_del = FALSE;
+                                       /*check cancel transaction*/
+                                       if (TRUE == _transport_get_cancel_initialization() ||
+                                                       TRUE == _transport_get_usb_discon_state()) {
+                                               ERR("USB is disconnected format\
+                                                               operation is cancelled.");
+                                               *response =
+                                                       PTP_RESPONSE_PARTIAL_DELETION;
+                                               return FALSE;
+                                       }
+                               }
+
+                       }
+                       _prop_deinit_ptparray(&child_arr);
+
+               } else {
+                       /* Non-Enumerated Folder */
+                       mtp_uint32 num_of_deleted_file = 0;
+                       mtp_uint32 num_of_file = 0;
+
+                       ret = _util_remove_dir_children_recursive(obj->file_path,
+                                       &num_of_deleted_file, &num_of_file, read_only);
+                       if (MTP_ERROR_GENERAL == ret ||
+                                       MTP_ERROR_ACCESS_DENIED == ret) {
+                               ERR_SECURE("directory children deletion Fail [%s]\n",
+                                               obj->file_path);
+                               *response = PTP_RESPONSE_GEN_ERROR;
+                               if (MTP_ERROR_ACCESS_DENIED == ret)
+                                       *response =
+                                               PTP_RESPONSE_ACCESSDENIED;
+                               return FALSE;
+                       }
+                       if (num_of_file == 0)
+                               DBG_SECURE("Folder[%s] is empty\n", obj->file_path);
+                       else if (num_of_deleted_file == 0) {
+                               DBG_SECURE("Folder[%s] contains only read-only files\n",
+                                               obj->file_path);
+                               all_del = FALSE;
+                       } else if (num_of_deleted_file < num_of_file){
+                               DBG("num of files[%d] is present in folder[%s]\
+                                               and number of deleted files[%d]\n",
+                                               num_of_file, obj->file_path,
+                                               num_of_deleted_file);
+                               *atleast_one = TRUE;
+                               all_del = FALSE;
+                       }
+               }
+               _util_scan_folder_contents_in_db(obj->file_path);
+               if (all_del) {
+                       g_snprintf(g_last_deleted,
+                                       MTP_MAX_PATHNAME_SIZE + 1, "%s",
+                                       obj->file_path);
+
+                       if (rmdir(obj->file_path) < 0) {
+                               memset(g_last_deleted, 0,
+                                               MTP_MAX_PATHNAME_SIZE + 1);
+                               *response = PTP_RESPONSE_GEN_ERROR;
+                               if (EACCES == errno)
+                                       *response =
+                                               PTP_RESPONSE_ACCESSDENIED;
+                               return FALSE;
+                       }
+               } else {
+                       ERR("all member in this folder is not deleted.");
+               }
+       } else {
+#ifdef MTP_SUPPORT_SET_PROTECTION
+               size = objinfo->file_size;
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+
+               if (objinfo->protcn_status ==
+                               PTP_PROTECTIONSTATUS_READONLY ||
+                               objinfo->protcn_status ==
+                               MTP_PROTECTIONSTATUS_READONLY_DATA) {
+                       *response = PTP_RESPONSE_OBJ_WRITEPROTECTED;
+                       return FALSE;
+               }
+
+               /* delete the real file */
+               g_snprintf(g_last_deleted, MTP_MAX_PATHNAME_SIZE + 1,
+                               "%s", obj->file_path);
+               if (remove(obj->file_path) < 0) {
+                       memset(g_last_deleted, 0,
+                                       MTP_MAX_PATHNAME_SIZE + 1);
+                       *response = PTP_RESPONSE_GEN_ERROR;
+                       if (EACCES == errno)
+                               *response = PTP_RESPONSE_ACCESSDENIED;
+                       return FALSE;
+               }
+               *atleast_one = TRUE;
+
+               /* Upate store's available space */
+               store->store_info.free_space += size;
+       }
+
+       if (all_del) {
+               *response = PTP_RESPONSE_OK;
+               /* delete references;*/
+               h_parent = objinfo->h_parent;
+               if (h_parent != PTP_OBJECTHANDLE_ROOT) {
+                       mtp_obj_t *parent_obj =
+                               _entity_get_object_from_store(store, h_parent);
+                       if (NULL != parent_obj) {
+                               _entity_remove_reference_child_array(parent_obj,
+                                               obj->obj_handle);
+                       }
+               }
+       } else if(*atleast_one) {
+               *response = PTP_RESPONSE_PARTIAL_DELETION;
+               return FALSE;
+       } else {
+               *response = PTP_RESPONSE_OBJ_WRITEPROTECTED;
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+mtp_uint16 _entity_delete_obj_mtp_store(mtp_store_t *store,
+               mtp_uint32 obj_handle, mtp_uint32 fmt, mtp_bool read_only)
+{
+       mtp_uint16 response;
+       mtp_obj_t *obj = NULL;
+       mtp_bool all_del = TRUE;
+       mtp_bool atleas_one = FALSE;
+
+       retv_if(store == NULL, PTP_RESPONSE_GEN_ERROR);
+
+       if (PTP_STORAGEACCESS_R == store->store_info.access) {
+               ERR("Read only store");
+               return PTP_RESPONSE_STORE_READONLY;
+       }
+
+       if (PTP_OBJECTHANDLE_ALL == obj_handle) {
+               slist_node_t *node = NULL;
+               node = store->obj_list.start;
+               while (NULL != node) {
+                       if (TRUE == _transport_get_cancel_initialization() ||
+                                       TRUE == _transport_get_usb_discon_state()) {
+                               ERR("USB is disconnected format\
+                                               operation is cancelled.");
+                               response = PTP_RESPONSE_GEN_ERROR;
+                               return response;
+                       }
+                       /* protect from disconnect USB */
+                       if (NULL == store || NULL == node ||
+                                       NULL == node->value) {
+                               response = PTP_RESPONSE_GEN_ERROR;
+                               return response;
+                       }
+
+                       obj = (mtp_obj_t *)node->value;
+                       if (_entity_remove_object_mtp_store(store, obj,
+                                               fmt, &response, &atleas_one, read_only)) {
+
+                               slist_node_t *temp = NULL;
+
+                               node = node->link;
+                               temp = _util_delete_node(&(store->obj_list), obj);
+                               g_free(temp);
+                               _util_delete_file_from_db(obj->file_path);
+                               _entity_dealloc_mtp_obj(obj);
+                       } else {
+                               node = node->link;
+                       }
+
+                       switch (response) {
+                       case PTP_RESPONSE_PARTIAL_DELETION:
+                               all_del = FALSE;
+                               break;
+                       case PTP_RESPONSE_OBJ_WRITEPROTECTED:
+                       case PTP_RESPONSE_ACCESSDENIED:
+                               all_del = FALSE;
+                               break;
+                       case PTP_RESPONSE_UNDEFINED:
+                       default:
+                               break;
+                       }
+
+               }
+       } else {
+               DBG("object handle is not PTP_OBJECTHANDLE_ALL. [%ld]\n",
+                               obj_handle);
+               obj = _entity_get_object_from_store(store, obj_handle);
+               if (_entity_remove_object_mtp_store(store, obj, PTP_FORMATCODE_NOTUSED,
+                                       &response, &atleas_one, read_only)) {
+                       slist_node_t *temp = NULL;
+
+                       temp = _util_delete_node(&(store->obj_list), obj);
+                       g_free(temp);
+                       _util_delete_file_from_db(obj->file_path);
+                       _entity_dealloc_mtp_obj(obj);
+               } else {
+                       switch (response) {
+                       case PTP_RESPONSE_PARTIAL_DELETION:
+                               all_del = FALSE;
+                               break;
+                       case PTP_RESPONSE_OBJ_WRITEPROTECTED:
+                       case PTP_RESPONSE_ACCESSDENIED:
+                               all_del = FALSE;
+                               break;
+                       case PTP_RESPONSE_UNDEFINED:
+                       default:
+                               /* do nothing */
+                               break;
+                       }
+               }
+       }
+
+       if (all_del) {
+               response = PTP_RESPONSE_OK;
+       } else if (atleas_one)
+               response = PTP_RESPONSE_PARTIAL_DELETION;
+
+       return response;
+}
+
+mtp_uint32 _entity_get_object_tree_size(mtp_store_t *store, mtp_obj_t *obj)
+{
+       mtp_uint32 i = 0;
+       mtp_uint64 size = 0;
+
+       retv_if(store == NULL, 0);
+       retv_if(obj == NULL, 0);
+
+       if (obj->obj_info->obj_fmt != PTP_FMT_ASSOCIATION) {
+               size = obj->obj_info->file_size;
+       } else {
+               ptp_array_t child_arr = { 0 };
+               mtp_obj_t *child_obj = NULL;
+
+               _prop_init_ptparray(&child_arr, UINT32_TYPE);
+
+               _entity_get_child_handles(store, obj->obj_handle, &child_arr);
+
+               for (i = 0; i < child_arr.num_ele; i++) {
+                       mtp_uint32 *ptr32 = child_arr.array_entry;
+                       child_obj = _entity_get_object_from_store(store,
+                                       ptr32[i]);
+                       size += _entity_get_object_tree_size(store, child_obj);
+               }
+               _prop_deinit_ptparray(&child_arr);
+       }
+
+       return size;
+}
+
+mtp_bool _entity_check_if_B_parent_of_A(mtp_store_t *store,
+               mtp_uint32 handleA, mtp_uint32 handleB)
+{
+       mtp_uint32 i = 0;
+       mtp_obj_t *obj = NULL;
+       ptp_array_t child_arr = {0};
+
+       retv_if(store == NULL, FALSE);
+
+       _prop_init_ptparray(&child_arr, UINT32_TYPE);
+       _entity_get_child_handles(store, handleB, &child_arr);
+
+       for (i = 0; i < child_arr.num_ele; i++) {
+               mtp_uint32 *ptr32 = child_arr.array_entry;
+               if (handleA == ptr32[i]) {
+                       _prop_deinit_ptparray(&child_arr);
+                       return TRUE;
+               }
+
+               obj = _entity_get_object_from_store(store, ptr32[i]);
+               if (obj == NULL || obj->obj_info == NULL ||
+                               obj->obj_info->obj_fmt ==
+                               PTP_FMT_ASSOCIATION) {
+                       continue;
+               }
+               if (_entity_check_if_B_parent_of_A(store, handleA, ptr32[i])) {
+                       _prop_deinit_ptparray(&child_arr);
+                       return TRUE;
+               }
+       }
+       _prop_deinit_ptparray(&child_arr);
+       return FALSE;
+}
+
+mtp_uint32 _entity_generate_next_obj_handle(void)
+{
+       return g_next_obj_handle++;
+}
+
+mtp_uint16 _entity_format_store(mtp_store_t *store, mtp_uint32 fs_format)
+{
+       mtp_uint16 response;
+
+       retv_if(store == NULL, PTP_RESPONSE_GEN_ERROR);
+
+       /* Is store ready only? */
+       if (store->store_info.access == PTP_STORAGEACCESS_R) {
+               ERR("Read only storage");
+               return PTP_RESPONSE_STORE_READONLY;
+       }
+
+       /* Is FilesystemFormat supported? */
+       if ((fs_format != PTP_FILESYSTEMTYPE_UNDEFINED) &&
+                       (fs_format != PTP_FILESYSTEMTYPE_FLAT) &&
+                       (fs_format != PTP_FILESYSTEMTYPE_HIERARCHICAL) &&
+                       (fs_format != PTP_FILESYSTEMTYPE_DCF)) {
+               ERR("File system type not supported");
+               return PTP_RESPONSE_INVALIDPARAM;
+       }
+
+       /* check cancel transaction */
+       if (TRUE == _transport_get_cancel_initialization() ||
+                       TRUE == _transport_get_usb_discon_state()) {
+               ERR("USB is disconnected format operation is cancelled.");
+               return PTP_RESPONSE_GEN_ERROR;
+       }
+
+       response = _entity_delete_obj_mtp_store(store, PTP_OBJECTHANDLE_ALL,
+                       PTP_FORMATCODE_NOTUSED, TRUE);
+
+       if (PTP_RESPONSE_OK != response) {
+               ERR("format is not completed [0x%X].\n", response);
+               return response;
+       }
+
+       return PTP_RESPONSE_OK;
+}
+
+void _entity_destroy_mtp_store(mtp_store_t *store)
+{
+       mtp_uint32 ii = 0;
+       slist_node_t *node = NULL;
+       slist_node_t *next_node = NULL;
+
+       ret_if(store == NULL);
+
+       for (ii = 0, next_node = store->obj_list.start;
+                       ii < store->obj_list.nnodes; ii++) {
+
+               node = next_node;
+               next_node = node->link;
+               _entity_dealloc_mtp_obj((mtp_obj_t *)node->value);
+               g_free(node);
+       }
+
+       _util_init_list(&(store->obj_list));
+       return;
+}
+
+void _entity_store_recursive_enum_folder_objects(mtp_store_t *store,
+               mtp_obj_t *pobj)
+{
+       DIR *h_dir = 0;
+       mtp_char file_name[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_bool status = FALSE;
+       mtp_obj_t *obj = NULL;
+       dir_entry_t entry = { { 0 }, 0 };
+       mtp_char *folder_name;
+       mtp_uint32 h_parent;
+
+       ret_if(NULL == store);
+
+       if (!pobj) {
+               folder_name = store->root_path;
+               h_parent = PTP_OBJECTHANDLE_ROOT;
+       } else {
+               folder_name = pobj->file_path;
+               h_parent = pobj->obj_handle;
+       }
+
+       if (folder_name == NULL || folder_name[0] != '/') {
+               ERR("foldername has no root slash!!");
+               return;
+       }
+
+       if (FALSE == _util_ifind_first(folder_name, &h_dir, &entry)) {
+               DBG("No more files");
+               return;
+       }
+
+       do {
+               if (TRUE == _transport_get_usb_discon_state()) {
+                       DBG("USB is disconnected");
+                       if (closedir(h_dir) < 0) {
+                               ERR("Close directory Fail");
+                       }
+                       return;
+               }
+
+               _util_get_file_name(entry.filename, file_name);
+               if (0 == strlen(file_name)) {
+                       ERR("szFilename size is 0");
+                       goto NEXT;
+               }
+
+               if (file_name[0] == '.') {
+                       DBG_SECURE("Hidden file [%s]\n", entry.filename);
+               } else if (entry.type == MTP_DIR_TYPE) {
+                       obj = _entity_add_folder_to_store(store, h_parent,
+                                       entry.filename, file_name, &entry);
+
+                       if (NULL == obj) {
+                               ERR("pObject is NULL");
+                               goto NEXT;
+                       }
+
+                       _entity_store_recursive_enum_folder_objects(store, obj);
+               } else if (entry.type == MTP_FILE_TYPE) {
+                       _entity_add_file_to_store(store, h_parent,
+                                       entry.filename, file_name, &entry);
+               } else {
+                       DBG("UNKNOWN TYPE");
+               }
+NEXT:
+               status = (mtp_bool)_util_ifind_next(folder_name, h_dir,
+                               &entry);
+       } while (status);
+
+       if (closedir(h_dir) < 0) {
+               ERR("close directory fail");
+       }
+#ifdef MTP_SUPPORT_OBJECTADDDELETE_EVENT
+       _inoti_add_watch_for_fs_events(folder_name);
+#endif /*MTP_SUPPORT_OBJECTADDDELETE_EVENT*/
+
+       return;
+}
+
+void _entity_list_modified_files(mtp_uint32 minutes)
+{
+       if (minutes == 0)
+               return;
+       mtp_int32 ret;
+       mtp_char command[FIND_CMD_LEN] = { 0 };
+
+       if (TRUE == _device_is_store_mounted(MTP_STORAGE_INTERNAL)) {
+               g_snprintf(command, FIND_CMD_LEN, FIND_CMD,
+                               MTP_STORE_PATH_CHAR, minutes,
+                               MTP_FILES_MODIFIED_FILES);
+               DBG("find query is [%s]\n", command);
+               ret = system(command);
+               if (WIFSIGNALED(ret) &&
+                               (WTERMSIG(ret) == SIGINT ||
+                                WTERMSIG(ret) == SIGQUIT)) {
+                       ERR("SYSTEM Fail");
+                       return;
+               }
+       }
+       if (TRUE == _device_is_store_mounted(MTP_STORAGE_EXTERNAL)) {
+               g_snprintf(command, FIND_CMD_LEN, FIND_CMD,
+                               MTP_EXTERNAL_PATH_CHAR, minutes,
+                               MTP_FILES_MODIFIED_FILES);
+               DBG("find query is [%s]\n", command);
+               ret = system(command);
+               if (WIFSIGNALED(ret) &&
+                               (WTERMSIG(ret) == SIGINT ||
+                                WTERMSIG(ret) == SIGQUIT)) {
+                       ERR("SYSTEM Fail");
+                       return;
+               }
+       }
+
+       return;
+}
+
+void _entity_copy_store_data(mtp_store_t *dst, mtp_store_t *src)
+{
+       dst->store_id = src->store_id;
+       dst->root_path = src->root_path;
+       dst->is_hidden = src->is_hidden;
+
+       memcpy(&(dst->obj_list), &(src->obj_list), sizeof(slist_t));
+       _entity_update_store_info_run_time(&(dst->store_info), dst->root_path);
+       _prop_copy_ptpstring(&(dst->store_info.store_desc), &(src->store_info.store_desc));
+       _prop_copy_ptpstring(&(dst->store_info.vol_label), &(src->store_info.vol_label));
+
+       return;
+}
diff --git a/src/mtp_cmd_handler.c b/src/mtp_cmd_handler.c
new file mode 100755 (executable)
index 0000000..48908fc
--- /dev/null
@@ -0,0 +1,3387 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <sys/vfs.h>
+#include <linux/magic.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <vconf.h>
+#include "mtp_support.h"
+#include "ptp_datacodes.h"
+#include "mtp_media_info.h"
+#include "mtp_usb_driver.h"
+#include "mtp_cmd_handler.h"
+#include "mtp_cmd_handler_util.h"
+#include "mtp_transport.h"
+#include "mtp_thread.h"
+
+/*
+ * GLOBAL AND EXTERN VARIABLES
+ */
+extern mtp_mgr_t g_mtp_mgr;
+extern mtp_bool g_is_full_enum;
+extern pthread_mutex_t g_cmd_inoti_mutex;
+extern mtp_config_t g_conf;
+
+mtp_bool g_is_sync_estab = FALSE;
+
+/*
+ * STATIC VARIABLES
+ */
+static mtp_mgr_t *g_mgr = &g_mtp_mgr;
+static mtp_bool g_has_round_trip = FALSE;
+#ifdef MTP_USE_SKIP_CONTINUOUS_OPENSESSION
+static mtp_uint16 g_count_open_session = 0;
+static mtp_uint32 g_old_open_session_time = 0;
+#endif/*MTP_USE_SKIP_CONTINUOUS_OPENSESSION*/
+
+/*
+ * STATIC FUNCTIONS
+ */
+static void __process_commands(mtp_handler_t *hdlr, cmd_blk_t *cmd);
+static void __open_session(mtp_handler_t *hdlr);
+static void __get_device_info(mtp_handler_t *hdlr);
+static void __get_storage_ids(mtp_handler_t *hdlr);
+static void __get_storage_info(mtp_handler_t *hdlr);
+static void __get_num_objects(mtp_handler_t *hdlr);
+static void __get_object_handles(mtp_handler_t *hdlr);
+static void __get_object_info(mtp_handler_t *hdlr);
+static void __get_object(mtp_handler_t *hdlr);
+static void __send_object_info(mtp_handler_t *hdlr);
+static void __send_object(mtp_handler_t *hdlr);
+static void __delete_object(mtp_handler_t *hdlr);
+static void __format_store(mtp_handler_t *hdlr);
+static void __reset_device(mtp_handler_t *hdlr);
+static void __get_device_prop_desc(mtp_handler_t *hdlr);
+static void __get_device_prop_value(mtp_handler_t *hdlr);
+static void __set_device_prop_value(mtp_handler_t *hdlr);
+static void __get_partial_object(mtp_handler_t *hdlr);
+static void __get_object_references(mtp_handler_t *hdlr);
+static void __set_object_references(mtp_handler_t *hdlr);
+static void __get_object_prop_desc(mtp_handler_t *hdlr);
+static void __get_object_prop_supported(mtp_handler_t *hdlr);
+static void __get_object_prop_value(mtp_handler_t *hdlr);
+static void __set_object_prop_value(mtp_handler_t *hdlr);
+static void __get_object_prop_list(mtp_handler_t *hdlr);
+static void __set_object_prop_list(mtp_handler_t *hdlr);
+static void __report_acquired_content(mtp_handler_t *hdlr);
+static void __send_playback_skip(mtp_handler_t *hdlr);
+#ifndef PMP_VER
+static void __self_test(mtp_handler_t *hdlr);
+#ifdef MTP_SUPPORT_SET_PROTECTION
+static void __set_object_protection(mtp_handler_t *hdlr);
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+static void __power_down(mtp_handler_t *hdlr);
+static void __move_object(mtp_handler_t *hdlr);
+static void __copy_object(mtp_handler_t *hdlr);
+static void __reset_device_prop_value(mtp_handler_t *hdlr);
+static void __vendor_command1(mtp_handler_t *hdlr);
+static void __get_interdep_prop_desc(mtp_handler_t *hdlr);
+static void __send_object_prop_list(mtp_handler_t *hdlr);
+#endif /* PMP_VER */
+static void __close_session(mtp_handler_t *hdlr);
+#ifdef MTP_SUPPORT_PRINT_COMMAND
+static void __print_command(mtp_uint16 code);
+#endif /* MTP_SUPPORT_PRINT_COMMAND */
+static void __enum_store_not_enumerated(mtp_uint32 obj_handle,
+               mtp_uint32 fmt, mtp_uint32 depth);
+static mtp_bool __receive_temp_file_first_packet(mtp_char *data,
+               mtp_int32 data_len);
+static mtp_bool __receive_temp_file_next_packets(mtp_char *data,
+               mtp_int32 data_len);
+static void __finish_receiving_file_packets(mtp_char *data, mtp_int32 data_len);
+
+/*
+ * FUNCTIONS
+ */
+void _cmd_hdlr_reset_cmd(mtp_handler_t *hdlr)
+{
+       if (hdlr->data4_send_obj.obj != NULL) {
+               _entity_dealloc_mtp_obj(hdlr->data4_send_obj.obj);
+       }
+
+       memset(hdlr, 0x00, sizeof(mtp_handler_t));
+
+#ifdef MTP_USE_SKIP_CONTINUOUS_OPENSESSION
+       /* reset open session count */
+       g_count_open_session = 0;
+       g_old_open_session_time = 0;
+#endif /* MTP_USE_SKIP_CONTINUOUS_OPENSESSION */
+}
+
+static void __process_commands(mtp_handler_t *hdlr, cmd_blk_t *cmd)
+{
+       mtp_store_t *store = NULL;
+
+       /* Keep a local copy for this command */
+       _hdlr_copy_cmd_container(cmd, &(hdlr->usb_cmd));
+
+       if (hdlr->usb_cmd.code == PTP_OPCODE_GETDEVICEINFO) {
+               DBG("COMMAND CODE = [0x%4x]!!\n", hdlr->usb_cmd.code);
+#ifdef MTP_SUPPORT_PRINT_COMMAND
+               __print_command(hdlr->usb_cmd.code);
+#endif /*MTP_SUPPORT_PRINT_COMMAND*/
+               __get_device_info(hdlr);
+               goto DONE;
+       }
+
+       /*  Process OpenSession Command */
+       if (hdlr->usb_cmd.code == PTP_OPCODE_OPENSESSION) {
+               DBG("COMMAND CODE = [0x%4X]!!\n", hdlr->usb_cmd.code);
+#ifdef MTP_SUPPORT_PRINT_COMMAND
+               __print_command(hdlr->usb_cmd.code);
+#endif /*MTP_SUPPORT_PRINT_COMMAND*/
+#ifdef MTP_USE_SKIP_CONTINUOUS_OPENSESSION
+               time_t t;
+               mtp_uint32 cur_time = 0;
+               time(&t);
+               cur_time = (mtp_uint32)t;
+               /*first opensession*/
+               if (g_count_open_session == 0) {
+                       g_old_open_session_time = cur_time;
+               } else if (cur_time <= g_old_open_session_time + 1) {
+                       /*under 1 sec. it might be skipped*/
+                       ERR("skip continuous OPEN session");
+                       goto DONE;
+               }
+               ++g_count_open_session;
+
+#endif /* MTP_USE_SKIP_CONTINUOUS_OPENSESSION */
+               __open_session(hdlr);
+               goto DONE;
+       }
+#ifdef MTP_USE_SKIP_CONTINUOUS_OPENSESSION
+       g_count_open_session = 0;
+#endif /* MTP_USE_SKIP_CONTINUOUS_OPENSESSION */
+
+       /* Check if session is open or not, if not respond */
+       if (hdlr->session_id == 0) {
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_SESSIONNOTOPEN);
+               _device_set_phase(DEVICE_PHASE_IDLE);
+               goto DONE;
+       }
+       DBG("COMMAND CODE = [0x%4x]!!\n", hdlr->usb_cmd.code);
+#ifdef MTP_SUPPORT_PRINT_COMMAND
+       __print_command(hdlr->usb_cmd.code);
+#endif /* MTP_SUPPORT_PRINT_COMMAND */
+
+       switch (hdlr->usb_cmd.code) {
+       case PTP_OPCODE_CLOSESESSION:
+               __close_session(hdlr);
+               break;
+       case PTP_OPCODE_GETSTORAGEIDS:
+               __get_storage_ids(hdlr);
+               break;
+       case PTP_OPCODE_GETSTORAGEINFO:
+               __get_storage_info(hdlr);
+               break;
+       case PTP_OPCODE_GETNUMOBJECTS:
+               __get_num_objects(hdlr);
+               break;
+       case PTP_OPCODE_GETOBJECTHANDLES:
+               __get_object_handles(hdlr);
+               break;
+       case PTP_OPCODE_GETOBJECTINFO:
+               __get_object_info(hdlr);
+               break;
+       case PTP_OPCODE_GETOBJECT:
+               _eh_send_event_req_to_eh_thread(EVENT_START_DATAIN, 0, 0, NULL);
+               __get_object(hdlr);
+               _eh_send_event_req_to_eh_thread(EVENT_DONE_DATAIN, 0, 0, NULL);
+               break;
+       case PTP_OPCODE_DELETEOBJECT:
+               __delete_object(hdlr);
+               break;
+       case PTP_OPCODE_FORMATSTORE:
+               __format_store(hdlr);
+               break;
+       case PTP_OPCODE_GETDEVICEPROPDESC:
+               __get_device_prop_desc(hdlr);
+               break;
+       case PTP_OPCODE_GETDEVICEPROPVALUE:
+               __get_device_prop_value(hdlr);
+               break;
+       case PTP_OPCODE_GETPARTIALOBJECT:
+               __get_partial_object(hdlr);
+               break;
+       case MTP_OPCODE_GETOBJECTREFERENCES:
+               __get_object_references(hdlr);
+               break;
+       case MTP_OPCODE_GETOBJECTPROPDESC:
+               __get_object_prop_desc(hdlr);
+               break;
+       case MTP_OPCODE_GETOBJECTPROPSUPPORTED:
+               __get_object_prop_supported(hdlr);
+               break;
+       case MTP_OPCODE_GETOBJECTPROPVALUE:
+               __get_object_prop_value(hdlr);
+               break;
+       case MTP_OPCODE_GETOBJECTPROPLIST:
+               __get_object_prop_list(hdlr);
+               break;
+#ifndef PMP_VER
+       case PTP_OPCODE_RESETDEVICE:
+               __reset_device(hdlr);
+               break;
+       case PTP_OPCODE_SELFTEST:
+               __self_test(hdlr);
+               break;
+#ifdef MTP_SUPPORT_SET_PROTECTION
+       case PTP_OPCODE_SETOBJECTPROTECTION:
+               __set_object_protection(hdlr);
+               break;
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+       case PTP_OPCODE_POWERDOWN:
+               __power_down(hdlr);
+               break;
+       case PTP_OPCODE_RESETDEVICEPROPVALUE:
+               __reset_device_prop_value(hdlr);
+               break;
+       case PTP_OPCODE_MOVEOBJECT:
+               __move_object(hdlr);
+               break;
+       case PTP_OPCODE_COPYOBJECT:
+               __copy_object(hdlr);
+               break;
+       case MTP_OPCODE_GETINTERDEPPROPDESC:
+               __get_interdep_prop_desc(hdlr);
+               break;
+       case PTP_CODE_VENDOR_OP1:       /* Vendor-specific operations */
+               __vendor_command1(hdlr);
+               break;
+#endif /* PMP_VER */
+       case MTP_OPCODE_PLAYBACK_SKIP:  /* Playback control */
+               __send_playback_skip(hdlr);
+               break;
+
+       case MTP_OPCODE_WMP_REPORTACQUIREDCONTENT:
+               /* Windows Media 11 extension*/
+               __report_acquired_content(hdlr);
+               break;
+       case PTP_OPCODE_SENDOBJECTINFO:
+       case PTP_OPCODE_SENDOBJECT:
+       case PTP_OPCODE_SETDEVICEPROPVALUE:
+       case MTP_OPCODE_SETOBJECTREFERENCES:
+       case MTP_OPCODE_SETOBJECTPROPVALUE:
+       case MTP_OPCODE_SETOBJECTPROPLIST:
+#ifndef PMP_VER
+       case MTP_OPCODE_SENDOBJECTPROPLIST:
+#endif /* PMP_VER */
+               /* DATA_HANDLE_PHASE: Send operation will be blocked
+                * until data packet is received
+                */
+               if (_device_get_phase() == DEVICE_PHASE_IDLE) {
+                       DBG("DATAOUT COMMAND PHASE!!");
+                       if (hdlr->usb_cmd.code == PTP_OPCODE_SENDOBJECT)
+                               _eh_send_event_req_to_eh_thread(EVENT_START_DATAOUT,
+                                               0, 0, NULL);
+                       _device_set_phase(DEVICE_PHASE_DATAOUT);
+                       return; /* in command phase, just return and wait next data */
+               }
+               switch (hdlr->usb_cmd.code) {
+               case PTP_OPCODE_SENDOBJECTINFO:
+                       __send_object_info(hdlr);
+                       break;
+               case PTP_OPCODE_SENDOBJECT:
+                       __send_object(hdlr);
+                       _eh_send_event_req_to_eh_thread(EVENT_DONE_DATAOUT,
+                                       0, 0, NULL);
+                       break;
+               case PTP_OPCODE_SETDEVICEPROPVALUE:
+                       __set_device_prop_value(hdlr);
+                       break;
+               case MTP_OPCODE_SETOBJECTREFERENCES:
+                       __set_object_references(hdlr);
+                       break;
+               case MTP_OPCODE_SETOBJECTPROPVALUE:
+                       __set_object_prop_value(hdlr);
+                       break;
+               case MTP_OPCODE_SETOBJECTPROPLIST:
+                       __set_object_prop_list(hdlr);
+                       break;
+#ifndef PMP_VER
+               case MTP_OPCODE_SENDOBJECTPROPLIST:
+                       __send_object_prop_list(hdlr);
+                       break;
+#endif /* PMP_VER */
+               }
+               break;
+
+       default:
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_OP_NOT_SUPPORTED);
+               DBG("Unsupported COMMAND[%d]\n", hdlr->usb_cmd.code);
+               break;
+       }
+DONE:
+       if (((hdlr->last_opcode == PTP_OPCODE_SENDOBJECTINFO) ||
+                               (hdlr->last_opcode == MTP_OPCODE_SENDOBJECTPROPLIST)) &&
+                       ((hdlr->last_fmt_code != PTP_FMT_ASSOCIATION) &&
+                        (hdlr->last_fmt_code != PTP_FMT_UNDEF))) {
+               DBG("Processed, last_opcode[0x%x], last_fmt_code[%d]\n",
+                               hdlr->last_opcode, hdlr->last_fmt_code);
+
+               if ((hdlr->usb_cmd.code != PTP_OPCODE_SENDOBJECT) &&
+                               hdlr->data4_send_obj.is_valid &&
+                               hdlr->data4_send_obj.is_data_sent) {
+
+                       DBG("Processed, COMMAND[0x%x]!!\n", hdlr->usb_cmd.code);
+                       store = _device_get_store(hdlr->data4_send_obj.store_id);
+                       if (store != NULL) {
+                               /*Restore reserved space*/
+                               store->store_info.free_space +=
+                                       hdlr->data4_send_obj.file_size;
+                       }
+
+                       if (hdlr->data4_send_obj.obj) {
+                               _entity_dealloc_mtp_obj(hdlr->data4_send_obj.obj);
+                               hdlr->data4_send_obj.obj = NULL;
+                       }
+                       memset(&(hdlr->data4_send_obj), 0x00,
+                                       sizeof(hdlr->data4_send_obj));
+               }
+       }
+       hdlr->last_opcode = hdlr->usb_cmd.code; /* Last operation code*/
+}
+
+static void __open_session(mtp_handler_t *hdlr)
+{
+       mtp_uint32 session_id;
+       /*Check the parameters*/
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               /*Unknown parameters*/
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+       /* Validate parameters*/
+       session_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+
+       if (session_id == 0 || (hdlr->usb_cmd.tid != 0)) {
+               /*Session Id cannot be zero, while TransactionId must be zero.*/
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_INVALIDPARAM);
+               return;
+       }
+
+       if (hdlr->session_id) { /*Session already open*/
+               _cmd_hdlr_send_response(hdlr,
+                               PTP_RESPONSE_SESSIONALREADYOPENED, 1,
+                               (mtp_uint32 *)&(hdlr->session_id));
+       } else {        /*Save the Session ID*/
+               hdlr->session_id = session_id;
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+       }
+}
+
+static void __get_device_info(mtp_handler_t *hdlr)
+{
+       /* Check the parameters*/
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               /* Unknown parameters*/
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       /* When used outside a session, both the SessionID and TransactionID
+        * in the Operation Request dataset must be 0;
+        */
+
+       if ((hdlr->session_id == 0) &&
+                       (hdlr->usb_cmd.tid != 0)) {     /*INVALIDPARAMETER*/
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               ERR("Invalid Session ID[%u], Transaction ID[%u]\n",
+                               hdlr->session_id, hdlr->usb_cmd.tid);
+               return;
+       }
+
+       /*Build the data block for device info.*/
+       data_blk_t blk = { 0 };
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *buf_ptr = NULL;
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       num_bytes = _get_device_info_size();
+       buf_ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+       if (num_bytes == _pack_device_info(buf_ptr, num_bytes)) {
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+               if (_hdlr_send_data_container(&blk)) {
+                       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+               } else {
+                       /* Host Cancelled data-in transfer */
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+                       DBG("Device phase is set to DEVICE_PHASE_NOTREADY");
+               }
+       } else {
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+       }
+
+       g_free(blk.data);
+}
+
+static void __get_storage_ids(mtp_handler_t *hdlr)
+{
+       data_blk_t blk = { 0 };
+       ptp_array_t ids = { 0 };
+       mtp_uint32 resp = PTP_RESPONSE_GEN_ERROR;
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *ptr = NULL;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       _prop_init_ptparray(&ids, UINT32_TYPE);
+
+       if (_hutil_get_storage_ids(&ids) == MTP_ERROR_NONE)
+       {
+               _hdlr_init_data_container(&blk, hdlr->usb_cmd.code,
+                               hdlr->usb_cmd.tid);
+               num_bytes = _prop_get_size_ptparray(&ids);
+               ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+               if (NULL != ptr) {
+                       /*Pack storage IDs*/
+                       _prop_pack_ptparray(&ids, ptr, num_bytes);
+                       _device_set_phase(DEVICE_PHASE_DATAIN);
+                       /*Send the data block*/
+                       if (FALSE == _hdlr_send_data_container(&blk)) {
+                               /*Host Cancelled data-in transfer*/
+                               _device_set_phase(DEVICE_PHASE_NOTREADY);
+                               DBG("DEVICE_PHASE_NOTREADY!!");
+                       } else {
+                               resp = PTP_RESPONSE_OK;
+                       }
+               }
+               g_free(blk.data);
+       }
+       _prop_deinit_ptparray(&ids);
+       _cmd_hdlr_send_response_code(hdlr, (mtp_uint16) resp);
+}
+
+static void __get_storage_info(mtp_handler_t *hdlr)
+{
+       mtp_uint32 store_id = 0;
+       store_info_t store_info = { 0 };
+       mtp_uint32 pkt_sz = 0;
+       data_blk_t blk = { 0 };
+       mtp_uchar *ptr = NULL;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               /*Unknown parameters*/
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+
+       if (_hutil_get_storage_entry(store_id, &store_info) != MTP_ERROR_NONE) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_INVALID_STORE_ID);
+               return;
+       }
+
+       /* Build the data block for StorageInfo Dataset.*/
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       pkt_sz = _hutil_get_storage_info_size(&store_info);
+       ptr = _hdlr_alloc_buf_data_container(&blk, pkt_sz, pkt_sz);
+
+       if (pkt_sz == _entity_pack_store_info(&store_info, ptr, pkt_sz)) {
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+               if (_hdlr_send_data_container(&blk)) {
+                       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+               } else {
+                       /*Host Cancelled data-in transfer*/
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+                       DBG("DEVICE_PHASE_NOTREADY!!");
+               }
+       } else {
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+       }
+
+       g_free(blk.data);
+}
+
+static void __get_num_objects(mtp_handler_t *hdlr)
+{
+       mtp_uint16 resp = 0;
+       mtp_uint32 store_id = 0;
+       mtp_uint32 h_parent = 0;
+       mtp_uint32 fmt = 0;
+       mtp_uint32 num_obj = 0;
+
+       store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
+
+       switch (_hutil_get_num_objects(store_id, h_parent, fmt,
+                               (mtp_uint32 *)(&num_obj))) {
+       case MTP_ERROR_INVALID_STORE:
+               resp = PTP_RESPONSE_INVALID_STORE_ID;
+               break;
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       case MTP_ERROR_INVALID_PARENT:
+               resp = PTP_RESPONSE_INVALIDPARENT;
+               break;
+       case MTP_ERROR_STORE_NOT_AVAILABLE:
+               resp = PTP_RESPONSE_STORENOTAVAILABLE;
+               break;
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               break;
+       default:
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       if (resp == PTP_RESPONSE_OK) {
+               _cmd_hdlr_send_response(hdlr, resp, 1, (mtp_uint32 *)&num_obj);
+       } else {
+               _cmd_hdlr_send_response_code(hdlr, resp);
+       }
+}
+
+static void __get_object_handles(mtp_handler_t *hdlr)
+{
+       mtp_uint32 store_id = 0;
+       mtp_uint32 fmt = 0;
+       mtp_uint32 h_parent = 0;
+       ptp_array_t handle_arr = { 0 };
+       data_blk_t blk = { 0 };
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *ptr = NULL;
+       mtp_uint16 resp = 0;
+
+       _prop_init_ptparray(&handle_arr, UINT32_TYPE);
+
+       store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
+
+       DBG("store_id = [0x%x], Format Code = [0x%x], parent handle = [0x%x]\n",
+                       store_id, fmt, h_parent);
+       switch (_hutil_get_object_handles(store_id, fmt, h_parent,
+                               &handle_arr)) {
+       case MTP_ERROR_INVALID_STORE:
+               resp = PTP_RESPONSE_INVALID_STORE_ID;
+               break;
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       case MTP_ERROR_INVALID_PARENT:
+               resp = PTP_RESPONSE_INVALIDPARENT;
+               break;
+       case MTP_ERROR_STORE_NOT_AVAILABLE:
+               resp = PTP_RESPONSE_STORENOTAVAILABLE;
+               break;
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               break;
+       default:
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       if (resp != PTP_RESPONSE_OK) {
+               _prop_deinit_ptparray(&handle_arr);
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+       }
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       num_bytes = _prop_get_size_ptparray(&handle_arr);
+       ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+       if (NULL != ptr) {
+               _prop_pack_ptparray(&handle_arr, ptr, num_bytes);
+               _prop_deinit_ptparray(&handle_arr);
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+               if (_hdlr_send_data_container(&blk)) {
+                       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+               } else {
+                       /*Host Cancelled data-in transfer.*/
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+                       DBG("DEVICE_PHASE_NOTREADY!!");
+               }
+       } else {
+               _prop_deinit_ptparray(&handle_arr);
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+       }
+
+       g_free(blk.data);
+}
+
+static void __get_object_info(mtp_handler_t *hdlr)
+{
+       mtp_uint32 obj_handle = 0;
+       data_blk_t blk = { 0 };
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *ptr = NULL;
+       mtp_obj_t *obj = NULL;
+       mtp_char f_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
+       mtp_wchar wf_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
+       ptp_string_t ptp_string = { 0 };
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+       obj_handle = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       if (MTP_ERROR_NONE != _hutil_get_object_entry(obj_handle, &obj)) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_INVALID_OBJ_HANDLE);
+               return;
+       }
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+
+       _util_get_file_name(obj->file_path, f_name);
+       _util_utf8_to_utf16(wf_name, sizeof(wf_name) / WCHAR_SIZ, f_name);
+       _prop_copy_char_to_ptpstring(&ptp_string, wf_name, WCHAR_TYPE);
+
+       num_bytes = _entity_get_object_info_size(obj, &ptp_string);
+       ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+       if (num_bytes == _entity_pack_obj_info(obj, &ptp_string, ptr,
+                               num_bytes)) {
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+               if (_hdlr_send_data_container(&blk)) {
+                       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+               } else {
+                       /* Host Cancelled data-in transfer*/
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+                       DBG("DEVICE_PHASE_NOTREADY!!");
+               }
+       } else {
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+       }
+
+       g_free(blk.data);
+}
+
+static void __get_object(mtp_handler_t *hdlr)
+{
+       mtp_uint32 obj_handle;
+       mtp_obj_t *obj;
+       mtp_uchar *ptr;
+       data_blk_t blk;
+       mtp_char *path;
+       mtp_uint64 num_bytes;
+       mtp_uint64 total_len;
+       mtp_uint64 sent = 0;
+       mtp_uint16 resp = PTP_RESPONSE_OK;
+       mtp_uint32 packet_len;
+       mtp_uint32 read_len = 0;
+       mtp_uint32 h_file = INVALID_FILE;
+       mtp_int32 error = 0;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       obj_handle = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       obj = _device_get_object_with_handle(obj_handle);
+       if (obj == NULL) {
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+       }
+
+#ifdef MTP_SUPPORT_SET_PROTECTION
+       /* Check to see if the data is non-transferable */
+       if (obj->obj_info->protcn_status ==
+                       MTP_PROTECTIONSTATUS_NONTRANSFERABLE_DATA) {
+               resp = PTP_RESPONSE_ACCESSDENIED;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+       }
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+
+       path = obj->file_path;
+       num_bytes = obj->obj_info->file_size;
+       total_len = num_bytes + sizeof(header_container_t);
+       packet_len = total_len < g_conf.read_file_size ? num_bytes :
+               (g_conf.read_file_size - sizeof(header_container_t));
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       ptr = _hdlr_alloc_buf_data_container(&blk, packet_len, num_bytes);
+       if (NULL == ptr) {
+               ERR("_hdlr_alloc_buf_data_container() Fail");
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+               return;
+       }
+
+       _device_set_phase(DEVICE_PHASE_DATAIN);
+       h_file = _util_file_open(path, MTP_FILE_READ, &error);
+       if (h_file == INVALID_FILE) {
+               ERR("_util_file_open() Fail");
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+               if (EACCES == error) {
+                       _cmd_hdlr_send_response_code(hdlr,
+                                       PTP_RESPONSE_ACCESSDENIED);
+                       return;
+               }
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+               return;
+       }
+
+       _util_file_read(h_file, ptr, packet_len, &read_len);
+       if (0 == read_len) {
+               ERR("_util_file_read() Fail");
+               ERR_SECURE("filename[%s]", path);
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+               resp = PTP_RESPONSE_INCOMPLETETRANSFER;
+               goto Done;
+       }
+
+       /* First Packet with Header */
+       if (PTP_EVENTCODE_CANCELTRANSACTION == _transport_get_control_event() ||
+                       FALSE == _hdlr_send_bulk_data(blk.data, blk.len)) {
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+               resp = PTP_RESPONSE_INCOMPLETETRANSFER;
+               ERR("First Packet send Fail");
+               ERR_SECURE("filename[%s]\n", path);
+               goto Done;
+       }
+
+       sent = sizeof(header_container_t) + read_len;
+       ptr = blk.data;
+
+       while (sent < total_len) {
+               _util_file_read(h_file, ptr, g_conf.read_file_size, &read_len);
+               if (0 == read_len) {
+                       ERR("_util_file_read() Fail");
+                       ERR_SECURE("filename[%s]\n", path);
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+                       resp = PTP_RESPONSE_INCOMPLETETRANSFER;
+                       goto Done;
+               }
+
+               if (PTP_EVENTCODE_CANCELTRANSACTION == _transport_get_control_event() ||
+                               FALSE == _hdlr_send_bulk_data(ptr, read_len)) {
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+                       resp = PTP_RESPONSE_INCOMPLETETRANSFER;
+                       ERR("Packet send Fail");
+                       ERR_SECURE("filename[%s]\n", path);
+                       goto Done;
+               }
+
+               sent += read_len;
+       }
+
+       if (total_len % ((mtp_uint64)_transport_get_usb_packet_len()) == 0) {
+               _transport_send_zlp();
+       }
+
+Done:
+       _util_file_close(h_file);
+
+       g_free(blk.data);
+       _cmd_hdlr_send_response_code(hdlr, resp);
+}
+
+static void __send_object_info(mtp_handler_t *hdlr)
+{
+       mtp_uint16 resp = PTP_RESPONSE_UNDEFINED;
+       mtp_uint32 store_id = 0;
+       mtp_uint32 h_parent = 0;
+       mtp_uint32 num_bytes = 0;
+       data_blk_t blk = { 0 };
+       mtp_uint32 resp_param[3] = { 0 };
+       mtp_obj_t *obj = NULL;
+       mtp_err_t ret = 0;
+       obj_data_t obdata = { 0 };
+
+       store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       if (store_id == 0) {
+               store_id = _device_get_default_store_id();
+       }
+       h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
+               if (_device_get_phase() != DEVICE_PHASE_NOTREADY) {
+                       _cmd_hdlr_send_response_code(hdlr, resp);
+               }
+               return;
+       }
+
+       _device_set_phase(DEVICE_PHASE_DATAOUT);
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       num_bytes = MAX_SIZE_IN_BYTES_OF_OBJECT_INFO;
+       if (_hdlr_rcv_data_container(&blk, num_bytes) == FALSE) {
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+       } else {
+               if (TRUE == hdlr->data4_send_obj.is_valid) {
+                       obdata.store_id = hdlr->data4_send_obj.store_id;
+                       obdata.obj_size = hdlr->data4_send_obj.file_size;
+                       obdata.obj = hdlr->data4_send_obj.obj;
+                       hdlr->data4_send_obj.obj = NULL;
+               }
+               ret = _hutil_construct_object_entry(store_id, h_parent,
+                               ((hdlr->data4_send_obj.is_valid == TRUE) ? (&obdata)
+                                : (NULL)), &obj, _hdlr_get_payload_data(&blk),
+                               _hdlr_get_payload_size(&blk));
+               hdlr->data4_send_obj.is_valid = FALSE;
+               switch (ret) {
+               case MTP_ERROR_NONE:
+                       if (obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION) {
+                               hdlr->data4_send_obj.obj = NULL;
+                               hdlr->data4_send_obj.is_valid = FALSE;
+                               hdlr->data4_send_obj.obj_handle = obj->obj_handle;
+                               hdlr->data4_send_obj.h_parent = h_parent;
+                               hdlr->data4_send_obj.store_id = store_id;
+                       }
+#ifdef MTP_USE_SELFMAKE_ABSTRACTION
+                       else if (obj->obj_info->file_size == 0 &&
+                                       obj->obj_info->obj_fmt > MTP_FMT_UNDEFINED_COLLECTION &&
+                                       obj->obj_info->obj_fmt < MTP_FMT_UNDEFINED_DOC) {
+                               hdlr->data4_send_obj.obj = NULL;
+                               hdlr->data4_send_obj.is_valid = FALSE;
+                               hdlr->data4_send_obj.obj_handle = obj->obj_handle;
+                               hdlr->data4_send_obj.h_parent = h_parent;
+                               hdlr->data4_send_obj.store_id = store_id;
+                       }
+#endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
+                       else {
+                               hdlr->data4_send_obj.is_valid = TRUE;
+                               hdlr->data4_send_obj.obj_handle = obj->obj_handle;
+                               hdlr->data4_send_obj.h_parent = h_parent;
+                               hdlr->data4_send_obj.store_id = store_id;
+                               hdlr->data4_send_obj.obj = obj;
+                               hdlr->data4_send_obj.file_size =
+                                       obj->obj_info->file_size;
+                       }
+                       resp = PTP_RESPONSE_OK;
+                       break;
+               case MTP_ERROR_STORE_NOT_AVAILABLE:
+                       resp = PTP_RESPONSE_STORENOTAVAILABLE;
+                       DBG("PTP_RESPONSE_STORENOTAVAILABLE");
+                       break;
+               case MTP_ERROR_INVALID_PARAM:
+                       resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
+                       DBG("PTP_RESPONSE_PARAM_NOTSUPPORTED");
+                       break;
+               case MTP_ERROR_INVALID_STORE:
+                       resp = PTP_RESPONSE_INVALID_STORE_ID;
+                       DBG("PTP_RESPONSE_INVALID_STORE_ID");
+                       break;
+               case MTP_ERROR_STORE_READ_ONLY:
+                       resp = PTP_RESPONSE_STORE_READONLY;
+                       break;
+               case MTP_ERROR_STORE_FULL:
+                       resp = PTP_RESPONSE_STOREFULL;
+                       DBG("PTP_RESPONSE_STOREFULL");
+                       break;
+               case MTP_ERROR_GENERAL:
+                       resp = PTP_RESPONSE_GEN_ERROR;
+                       DBG("PTP_RESPONSE_GEN_ERROR");
+                       break;
+               case MTP_ERROR_INVALID_OBJECT_INFO:
+                       resp = MTP_RESPONSECODE_INVALIDDATASET;
+                       DBG("MTP_RESPONSECODE_INVALIDDATASET");
+                       break;
+               case MTP_ERROR_INVALID_OBJECTHANDLE:
+                       resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+                       DBG("PTP_RESPONSE_INVALID_OBJ_HANDLE");
+                       break;
+               case MTP_ERROR_INVALID_PARENT:
+                       resp = PTP_RESPONSE_INVALIDPARENT;
+                       DBG("PTP_RESPONSE_INVALIDPARENT");
+                       break;
+               case MTP_ERROR_ACCESS_DENIED:
+                       resp = PTP_RESPONSE_ACCESSDENIED;
+                       DBG("PTP_RESPONSE_ACCESSDENIED");
+                       break;
+               default:
+                       resp = PTP_RESPONSE_GEN_ERROR;
+                       DBG("PTP_RESPONSE_GEN_ERROR");
+                       break;
+               }
+       }
+
+       g_free(blk.data);
+       if (_device_get_phase() != DEVICE_PHASE_NOTREADY) {
+               if (resp == PTP_RESPONSE_OK) {
+                       hdlr->last_fmt_code = obj->obj_info->obj_fmt;
+                       resp_param[0] = hdlr->data4_send_obj.store_id;
+
+                       /* PTP spec here requires that 0xFFFFFFFF be sent if root is the parent object,
+                        * while in some situations(e.g. MoveObject, CopyObject), 0x00000000 (as
+                        * PTP_OBJECTHANDLE_ROOT is defined) represents the root.
+                        */
+                       resp_param[1] = (hdlr->data4_send_obj.h_parent
+                                       != PTP_OBJECTHANDLE_ROOT) ?
+                               hdlr->data4_send_obj.h_parent :
+                               0xFFFFFFFF;
+                       resp_param[2] = hdlr->data4_send_obj.obj_handle;
+                       _cmd_hdlr_send_response(hdlr, resp, 3, resp_param);
+               } else {
+                       _cmd_hdlr_send_response_code(hdlr, resp);
+               }
+       }
+}
+
+static void __send_object(mtp_handler_t *hdlr)
+{
+       data_blk_t blk = { 0 };
+       mtp_uint16 resp = PTP_RESPONSE_OK;
+       mtp_char temp_fpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+
+               ERR("unsupported parameter");
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_INVALIDPARAM);
+               return;
+       }
+#ifndef MTP_USE_SELFMAKE_ABSTRACTION
+       if (hdlr->data4_send_obj.is_valid != TRUE) {
+               DBG("invalide object info");
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+               return;
+       }
+#endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
+
+       _device_set_phase(DEVICE_PHASE_DATAOUT);
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+
+       if (_hdlr_rcv_file_in_data_container(&blk, temp_fpath,
+                               MTP_MAX_PATHNAME_SIZE + 1) == FALSE) {
+               _device_set_phase(DEVICE_PHASE_IDLE);
+
+               ERR("_hdlr_rcv_file_in_data_container() Fail");
+               g_free(blk.data);
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+               return;
+       }
+
+       switch (_hutil_write_file_data(hdlr->data4_send_obj.store_id,
+                               hdlr->data4_send_obj.obj, temp_fpath)) {
+
+       case MTP_ERROR_INVALID_OBJECT_INFO:
+               resp = PTP_RESPONSE_NOVALID_OBJINFO;
+               DBG("PTP_RESPONSE_NOVALID_OBJINFO");
+               break;
+#ifdef MTP_USE_SELFMAKE_ABSTRACTION
+       case MTP_ERROR_INVALID_PARAM:   /* association file*/
+#endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               DBG("PTP_RESPONSE_OK");
+               break;
+       case MTP_ERROR_STORE_FULL:
+               resp = PTP_RESPONSE_STOREFULL;
+               DBG("PTP_RESPONSE_STOREFULL");
+               break;
+       default:
+               resp = PTP_RESPONSE_GEN_ERROR;
+               DBG("PTP_RESPONSE_GEN_ERROR");
+       }
+       _cmd_hdlr_send_response_code(hdlr, resp);
+
+       /* This object info has been consumed.*/
+       hdlr->data4_send_obj.obj = NULL;
+       hdlr->data4_send_obj.is_valid = FALSE;
+
+       g_free(blk.data);
+}
+
+static void __delete_object(mtp_handler_t *hdlr)
+{
+       mtp_uint32 obj_handle = 0;
+       mtp_uint32 fmt = 0;
+       mtp_uint16 resp = 0;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+
+               ERR("Parameters not supported");
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       obj_handle = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       if ((PTP_FORMATCODE_NOTUSED != fmt) &&
+                       (obj_handle != PTP_OBJECTHANDLE_ALL)) {
+               ERR("Invalid object format");
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_INVALID_OBJ_FMTCODE);
+               return;
+       }
+
+       _transport_set_mtp_operation_state(MTP_STATE_DATA_PROCESSING);
+
+       switch (_hutil_remove_object_entry(obj_handle, fmt)) {
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               break;
+       case MTP_ERROR_STORE_READ_ONLY:
+               resp = PTP_RESPONSE_STORE_READONLY;
+               break;
+       case MTP_ERROR_PARTIAL_DELETION:
+               resp = PTP_RESPONSE_PARTIAL_DELETION;
+               break;
+       case MTP_ERROR_OBJECT_WRITE_PROTECTED:
+               resp = PTP_RESPONSE_OBJ_WRITEPROTECTED;
+               break;
+       case MTP_ERROR_ACCESS_DENIED:
+               resp = PTP_RESPONSE_ACCESSDENIED;
+               break;
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       default:
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
+       _cmd_hdlr_send_response_code(hdlr, resp);
+}
+
+static void __format_store(mtp_handler_t *hdlr)
+{
+       mtp_uint32 store_id = 0;
+       mtp_uint32 fs_fmt = 0;
+       mtp_uint16 ret = 0;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       fs_fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+
+       ret = _hutil_format_storage(store_id, fs_fmt);
+       
+       /* although there is remain file, send OK */
+       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+}
+
+static void __reset_device(mtp_handler_t *hdlr)
+{
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+}
+
+static void __get_device_prop_desc(mtp_handler_t *hdlr)
+{
+       device_prop_desc_t dev_prop = { { 0 }, };
+       device_prop_desc_t *prop_ptr = NULL;
+       ptp_string_t ptp_str = { 0, { 0 } };
+       data_blk_t blk = { 0 };
+       mtp_uint32 prop_id = 0;
+       mtp_uint32 resp = 0;
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *ptr = NULL;
+       mtp_wchar temp[MTP_MAX_REG_STRING + 1] = { 0 };
+
+       prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       switch (prop_id) {
+#ifdef MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL
+       case PTP_PROPERTYCODE_BATTERYLEVEL:
+               {
+                       mtp_int32 batt = 0;
+
+                       prop_ptr = _device_get_device_property(prop_id);
+                       if (NULL == prop_ptr) {
+                               ERR("prop_ptr is NULL!");
+                               break;
+                       }
+
+                       batt = _util_get_battery_level();
+                       if (FALSE == _prop_set_current_integer(prop_ptr, batt))
+                               ERR("_util_get_battery_level() Fail");
+                       break;
+               }
+#endif /* MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL */
+
+       case MTP_PROPERTYCODE_DEVICEFRIENDLYNAME:
+               {
+                       mtp_char *dev_name = _device_get_device_name();
+                       if (dev_name == NULL) {
+                               ERR("_device_get_device_name() Fail");
+                               break;
+                       }
+
+                       prop_ptr = _device_get_device_property(prop_id);
+                       if (NULL == prop_ptr) {
+                               ERR("prop_ptr is Null");
+                               g_free(dev_name);
+                               break;
+                       }
+                       _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, dev_name);
+                       _prop_copy_char_to_ptpstring(&ptp_str, temp, WCHAR_TYPE);
+                       _prop_set_current_string(prop_ptr, &ptp_str);
+                       g_free(dev_name);
+                       break;
+               }
+
+       case MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER:
+               {
+                       mtp_char *sync_ptr = _device_get_sync_partner();
+                       if (NULL == sync_ptr) {
+                               ERR("_device_get_sync_partner() Fail");
+                               break;
+                       }
+                       prop_ptr = _device_get_device_property(prop_id);
+                       if (NULL == prop_ptr) {
+                               ERR("prop_ptr is Null");
+                               g_free(sync_ptr);
+                               break;
+                       }
+
+                       _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, sync_ptr);
+                       _prop_copy_char_to_ptpstring(&ptp_str, temp, WCHAR_TYPE);
+                       _prop_set_current_string(prop_ptr, &ptp_str);
+                       g_free(sync_ptr);
+                       break;
+               }
+       case MTP_PROPERTYCODE_DEVICEICON:
+               {
+                       mtp_uint32 h_file;
+                       mtp_uint32 bytes_read = 0;
+                       mtp_uint32 file_size = 0;
+                       struct stat buf;
+                       mtp_uchar *data = NULL;
+                       mtp_int32 err = 0;
+
+                       prop_ptr = _device_get_device_property(prop_id);
+                       if (NULL == prop_ptr) {
+                               ERR("prop_ptr is Null");
+                               break;
+                       }
+
+                       h_file = _util_file_open(MTP_DEVICE_ICON, MTP_FILE_READ, &err);
+                       if (h_file == INVALID_FILE) {
+                               ERR("file handle is not valid");
+                               _cmd_hdlr_send_response_code(hdlr,
+                                               PTP_RESPONSE_GEN_ERROR);
+                               return;
+                       }
+                       if (fstat(fileno((FILE *)h_file), &buf) != 0) {
+                               _util_file_close(h_file);
+                               _cmd_hdlr_send_response_code(hdlr,
+                                               PTP_RESPONSE_GEN_ERROR);
+                               return;
+                       }
+                       file_size = buf.st_size;
+                       data = (mtp_uchar *)g_malloc(file_size + sizeof(mtp_uint32));
+                       if (data == NULL) {
+                               ERR("g_malloc() Fail");
+                               _util_file_close(h_file);
+                               _cmd_hdlr_send_response_code(hdlr,
+                                               PTP_RESPONSE_GEN_ERROR);
+                               return;
+                       }
+                       memcpy(data, &file_size, sizeof(mtp_uint32));
+                       _util_file_read(h_file, &data[sizeof(mtp_uint32)], file_size,
+                                       &bytes_read);
+                       if (bytes_read != file_size) {
+                               ERR("Number of read bytes less than requested");
+                               _util_file_close(h_file);
+                               g_free(data);
+                               _cmd_hdlr_send_response_code(hdlr,
+                                               PTP_RESPONSE_GEN_ERROR);
+                               return;
+                       }
+
+                       _prop_set_current_array(prop_ptr, data);
+                       _prop_set_default_array(&(prop_ptr->propinfo),
+                                       (mtp_uchar *)&data[sizeof(mtp_uint32)], bytes_read);
+                       g_free(data);
+                       _util_file_close(h_file);
+                       break;
+               }
+
+       default:
+               ERR("Unknown PropId : [0x%x]\n", prop_id);
+               break;
+       }
+
+       if (_hutil_get_device_property(prop_id, &dev_prop) != MTP_ERROR_NONE) {
+               ERR("_hutil_get_device_property returned error");
+               resp = PTP_RESPONSE_PROP_NOTSUPPORTED;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+       }
+       num_bytes = _prop_size_device_prop_desc(&dev_prop);
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+       if (ptr == NULL) {
+               resp = PTP_RESPONSE_GEN_ERROR;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+       }
+
+       if (_prop_pack_device_prop_desc(&dev_prop, ptr, num_bytes) != num_bytes) {
+               resp = PTP_RESPONSE_GEN_ERROR;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               g_free(blk.data);
+               return;
+       }
+
+       _device_set_phase(DEVICE_PHASE_DATAIN);
+       if (_hdlr_send_data_container(&blk))
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+       else {
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+       }
+
+       g_free(blk.data);
+       return;
+}
+
+static void __get_device_prop_value(mtp_handler_t *hdlr)
+{
+
+       ptp_string_t ptp_str = { 0, { 0 } };
+       data_blk_t blk = { 0 };
+       mtp_uint32 prop_id = 0;
+       mtp_uint32 no_bytes = 0;
+       mtp_uchar *ptr = NULL;
+       mtp_wchar temp[MTP_MAX_REG_STRING + 1] = { 0 };
+
+       prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+
+       switch(prop_id) {
+#ifdef MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL
+       case PTP_PROPERTYCODE_BATTERYLEVEL: {
+                                                                                       mtp_int32 batt = 0;
+
+                                                                                       batt = _util_get_battery_level();
+                                                                                       no_bytes = sizeof(batt);
+
+                                                                                       ptr = _hdlr_alloc_buf_data_container(&blk, no_bytes, no_bytes);
+                                                                                       if (ptr == NULL) {
+                                                                                               _cmd_hdlr_send_response_code(hdlr,
+                                                                                                               PTP_RESPONSE_GEN_ERROR);
+                                                                                               return;
+                                                                                       }
+                                                                                       memcpy(ptr, &batt, no_bytes);
+#ifdef __BIG_ENDIAN__
+                                                                                       _util_conv_byte_order(ptr, no_bytes);
+#endif /*__BIG_ENDIAN__*/
+                                                                                       break;
+                                                                               }
+#endif /* MTP_SUPPORT_DEVICEPROP_BATTERYLEVEL */
+
+       case MTP_PROPERTYCODE_DEVICEFRIENDLYNAME:
+               {
+
+                                                                                                 mtp_char *device = _device_get_device_name();
+                                                                                                 if (device == NULL) {
+                                                                                                         ERR("_device_get_device_name() Fail");
+                                                                                                         _cmd_hdlr_send_response_code(hdlr,
+                                                                                                                         PTP_RESPONSE_GEN_ERROR);
+                                                                                                         return;
+                                                                                                 }
+
+                                                                                                 _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, device);
+                                                                                                 _prop_copy_char_to_ptpstring(&ptp_str, temp, WCHAR_TYPE);
+                                                                                                 no_bytes = _prop_size_ptpstring(&ptp_str);
+                                                                                                 g_free(device);
+
+                                                                                                 ptr = _hdlr_alloc_buf_data_container(&blk, no_bytes, no_bytes);
+                                                                                                 if (ptr == NULL) {
+                                                                                                         _cmd_hdlr_send_response_code(hdlr,
+                                                                                                                         PTP_RESPONSE_GEN_ERROR);
+                                                                                                         return;
+                                                                                                 }
+
+                                                                                                 if (_prop_pack_ptpstring(&ptp_str, ptr, no_bytes) != no_bytes) {
+                                                                                                         _cmd_hdlr_send_response_code(hdlr,
+                                                                                                                         PTP_RESPONSE_GEN_ERROR);
+                                                                                                         g_free(blk.data);
+                                                                                                         return;
+                                                                                                 }
+                                                                                                 break;
+                                                                                         }
+
+       case MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER:
+               {
+
+                                                                                                         mtp_char *sync_ptr = _device_get_sync_partner();
+                                                                                                         if (sync_ptr == NULL) {
+                                                                                                                 ERR("_device_get_sync_partner() Fail");
+                                                                                                                 _cmd_hdlr_send_response_code(hdlr,
+                                                                                                                                 PTP_RESPONSE_GEN_ERROR);
+                                                                                                                 return;
+                                                                                                         }
+                                                                                                         _util_utf8_to_utf16(temp, sizeof(temp) / WCHAR_SIZ, sync_ptr);
+                                                                                                         g_free(sync_ptr);
+
+                                                                                                         _prop_copy_char_to_ptpstring(&ptp_str, temp, WCHAR_TYPE);
+                                                                                                         no_bytes = _prop_size_ptpstring(&ptp_str);
+
+                                                                                                         ptr = _hdlr_alloc_buf_data_container(&blk, no_bytes, no_bytes);
+                                                                                                         if (ptr == NULL) {
+                                                                                                                 _cmd_hdlr_send_response_code(hdlr,
+                                                                                                                                 PTP_RESPONSE_GEN_ERROR);
+                                                                                                                 return;
+                                                                                                         }
+
+                                                                                                         if (_prop_pack_ptpstring(&ptp_str, ptr, no_bytes) != no_bytes) {
+                                                                                                                 _cmd_hdlr_send_response_code(hdlr,
+                                                                                                                                 PTP_RESPONSE_GEN_ERROR);
+                                                                                                                 g_free(blk.data);
+                                                                                                                 return;
+                                                                                                         }
+                                                                                                         break;
+                                                                                                 }
+
+       case MTP_PROPERTYCODE_DEVICEICON:
+               {
+
+                                                                                 mtp_uint32 h_file;
+                                                                                 mtp_uint32 read_bytes = 0;
+                                                                                 mtp_uint32 file_size = 0;
+                                                                                 struct stat buf;
+                                                                                 mtp_uchar *data = NULL;
+                                                                                 mtp_int32 err = 0;
+                                                                                 ptp_array_t val_arr = { 0 };
+                                                                                 mtp_uint32 ii;
+
+                                                                                 h_file = _util_file_open(MTP_DEVICE_ICON, MTP_FILE_READ, &err);
+                                                                                 if (h_file == INVALID_FILE) {
+                                                                                         ERR("file handle is not valid");
+                                                                                         _cmd_hdlr_send_response_code(hdlr,
+                                                                                                         PTP_RESPONSE_GEN_ERROR);
+                                                                                         return;
+                                                                                 }
+                                                                                 if (fstat(fileno((FILE *)h_file), &buf) != 0) {
+                                                                                         _util_file_close(h_file);
+                                                                                         _cmd_hdlr_send_response_code(hdlr,
+                                                                                                         PTP_RESPONSE_GEN_ERROR);
+                                                                                         return;
+                                                                                 }
+
+                                                                                 file_size = buf.st_size;
+                                                                                 data = (mtp_uchar *)g_malloc(file_size);
+                                                                                 if (data == NULL) {
+                                                                                         ERR("g_malloc() Fail");
+                                                                                         _util_file_close(h_file);
+                                                                                         _cmd_hdlr_send_response_code(hdlr,
+                                                                                                         PTP_RESPONSE_GEN_ERROR);
+                                                                                         return;
+                                                                                 }
+
+                                                                                 _util_file_read(h_file, &data, file_size, &read_bytes);
+                                                                                 if (read_bytes != file_size) {
+                                                                                         ERR("Number of read bytes less than requested");
+                                                                                         _util_file_close(h_file);
+                                                                                         g_free(data);
+                                                                                         _cmd_hdlr_send_response_code(hdlr,
+                                                                                                         PTP_RESPONSE_GEN_ERROR);
+                                                                                         return;
+                                                                                 }
+
+                                                                                 _prop_init_ptparray(&val_arr, UINT8_TYPE);
+                                                                                 _prop_grow_ptparray(&val_arr, read_bytes);
+                                                                                 for (ii = 0; ii < read_bytes; ii++) {
+                                                                                         _prop_append_ele_ptparray(&val_arr, data[ii]);
+                                                                                 }
+
+                                                                                 no_bytes = _prop_get_size_ptparray(&val_arr);
+                                                                                 ptr = _hdlr_alloc_buf_data_container(&blk, no_bytes, no_bytes);
+                                                                                 if (ptr == NULL) {
+                                                                                         _cmd_hdlr_send_response_code(hdlr,
+                                                                                                         PTP_RESPONSE_GEN_ERROR);
+                                                                                         g_free(data);
+                                                                                         _util_file_close(h_file);
+                                                                                         _prop_deinit_ptparray(&val_arr);
+                                                                                         return;
+                                                                                 }
+                                                                                 if (_prop_pack_ptparray(&val_arr, ptr, no_bytes) != no_bytes) {
+                                                                                         _cmd_hdlr_send_response_code(hdlr,
+                                                                                                         PTP_RESPONSE_GEN_ERROR);
+                                                                                         g_free(blk.data);
+                                                                                         g_free(data);
+                                                                                         _prop_deinit_ptparray(&val_arr);
+                                                                                         _util_file_close(h_file);
+                                                                                         return;
+                                                                                 }
+
+                                                                                 g_free(data);
+                                                                                 _prop_deinit_ptparray(&val_arr);
+                                                                                 _util_file_close(h_file);
+
+                                                                                 break;
+                                                                         }
+
+       default:
+                                                                         ERR("Unknown PropId : [0x%x]\n", prop_id);
+                                                                         _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+                                                                         return;
+       }
+
+       _device_set_phase(DEVICE_PHASE_DATAIN);
+       if (_hdlr_send_data_container(&blk)) {
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+       } else {
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_INCOMPLETETRANSFER);
+       }
+       g_free(blk.data);
+       return;
+}
+
+static void __set_device_prop_value(mtp_handler_t *hdlr)
+{
+       mtp_uint32 prop_id = 0;
+       data_blk_t blk = { 0 };
+       mtp_uint32 max_bytes = 0;
+       mtp_uint16 resp = PTP_RESPONSE_OK;
+       mtp_err_t ret = 0;
+       mtp_char *d_raw = NULL;
+
+       prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       _device_set_phase(DEVICE_PHASE_DATAOUT);
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       max_bytes = MAX_SIZE_IN_BYTES_OF_PROP_VALUE;
+
+       if (FALSE == _hdlr_rcv_data_container(&blk, max_bytes)) {
+               ERR("_hdlr_rcv_data_container() Fail");
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+               return;
+       }
+
+       d_raw = (mtp_char *)_hdlr_get_payload_data(&blk);
+       if (NULL != d_raw) {
+               ret = _hutil_set_device_property(prop_id, d_raw,
+                               _hdlr_get_payload_size(&blk));
+       } else {
+               ret = MTP_ERROR_INVALID_OBJ_PROP_CODE;
+       }
+
+       switch (ret) {
+       case MTP_ERROR_NONE: {
+#ifdef MTP_USE_INFORMATION_REGISTRY
+
+                                                        mtp_char temp[MTP_MAX_REG_STRING * 3 + 1] = { 0 };
+                                                        mtp_wchar parsed_buf[MTP_MAX_REG_STRING + 1] = { 0 };
+                                                        mtp_uchar parse_sz = 0;
+
+                                                        if (MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER == prop_id) {
+                                                                parse_sz = d_raw[0];
+                                                                _util_wchar_ncpy(parsed_buf, (mtp_wchar *)&d_raw[1],
+                                                                                parse_sz > MTP_MAX_REG_STRING ?
+                                                                                MTP_MAX_REG_STRING : parse_sz);
+                                                                _util_utf16_to_utf8(temp, sizeof(temp), parsed_buf);
+                                                                _device_set_sync_partner(temp);
+                                                                if (!g_strcmp0(temp,
+                                                                                        MTP_DEV_PROPERTY_NULL_SYNCPARTNER)) {
+                                                                        vconf_set_str(VCONFKEY_MTP_SYNC_PARTNER_STR,
+                                                                                        "");
+                                                                } else {
+                                                                        vconf_set_str(VCONFKEY_MTP_SYNC_PARTNER_STR,
+                                                                                        temp);
+                                                                }
+                                                        }
+#endif /*MTP_USE_INFORMATION_REGISTRY*/
+                                                }
+                                                resp = PTP_RESPONSE_OK;
+                                                break;
+       case MTP_ERROR_ACCESS_DENIED:
+                                                resp = PTP_RESPONSE_ACCESSDENIED;
+                                                break;
+       case MTP_ERROR_INVALID_OBJ_PROP_VALUE:
+                                                resp = PTP_RESPONSE_INVALIDPROPVALUE;
+                                                break;
+       default:
+                                                resp = PTP_RESPONSE_PROP_NOTSUPPORTED;
+       }
+
+       _cmd_hdlr_send_response_code(hdlr, resp);
+
+       g_free(blk.data);
+       return;
+}
+
+static void __get_partial_object(mtp_handler_t *hdlr)
+{
+       mtp_uint32 h_obj = 0;
+       off_t offset = 0;
+       mtp_uint32 data_sz = 0;
+       mtp_uint32 send_bytes = 0;
+       data_blk_t blk = { 0 };
+       mtp_uchar *ptr = NULL;
+       mtp_uint16 resp = 0;
+       mtp_uint64 f_size = 0;
+       mtp_uint64 total_sz = 0;
+
+       offset = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       data_sz = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
+       h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+
+       switch (_hutil_get_object_entry_size(h_obj, &f_size)) {
+
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       case MTP_ERROR_NONE:
+               if (data_sz > (f_size - offset))
+                       send_bytes = f_size - offset;
+               else
+                       send_bytes = data_sz;
+               resp = PTP_RESPONSE_OK;
+               break;
+       default:
+               resp = PTP_RESPONSE_GEN_ERROR;
+               break;
+       }
+
+       if (PTP_RESPONSE_OK != resp) {
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+       }
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       ptr = _hdlr_alloc_buf_data_container(&blk, send_bytes, send_bytes);
+
+       if (NULL != ptr) {
+               switch (_hutil_read_file_data_from_offset(h_obj, offset, ptr, &send_bytes)) {
+               case MTP_ERROR_NONE:
+                       resp = PTP_RESPONSE_OK;
+                       break;
+               case MTP_ERROR_INVALID_OBJECTHANDLE:
+                       resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+                       break;
+               default:
+                       resp = PTP_RESPONSE_GEN_ERROR;
+               }
+       } else {
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       if (PTP_RESPONSE_OK == resp) {
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+               if (_hdlr_send_data_container(&blk)) {
+                       total_sz = send_bytes + sizeof(header_container_t);
+                       if (total_sz % _transport_get_usb_packet_len() == 0)
+                               _transport_send_zlp();
+                       _cmd_hdlr_send_response(hdlr, resp, 1, &send_bytes);
+                       g_free(blk.data);
+                       return;
+               }
+
+               /*Host Cancelled data-in transfer*/
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+               g_free(blk.data);
+               return;
+       }
+
+       _cmd_hdlr_send_response_code(hdlr, resp);
+
+       g_free(blk.data);
+       return;
+}
+
+static void __get_object_references(mtp_handler_t *hdlr)
+{
+       mtp_uint32 h_obj = 0;
+       ptp_array_t ref_arr = { 0 };
+       data_blk_t blk = { 0 };
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *ptr = NULL;
+       mtp_uint32 num_ele = 0;
+       mtp_uint16 resp = 0;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+
+               ERR("Unsupported Parameters");
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+
+       switch (_hutil_get_object_references(h_obj, &ref_arr, &num_ele)) {
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               break;
+       default :
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       if (resp != PTP_RESPONSE_OK) {
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+       }
+
+       if (resp == PTP_RESPONSE_OK && num_ele == 0) {
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+       }
+
+       num_bytes = _prop_get_size_ptparray(&ref_arr);
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+
+       ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+       if (num_bytes == _prop_pack_ptparray(&ref_arr, ptr, num_bytes)) {
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+               if (_hdlr_send_data_container(&blk)) {
+                       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+               } else {
+                       /* Host Cancelled data-in transfer*/
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+               }
+       } else {
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+       }
+
+       _prop_deinit_ptparray(&ref_arr);
+       g_free(blk.data);
+
+       return;
+}
+
+static void __set_object_references(mtp_handler_t *hdlr)
+{
+       mtp_uint32 h_obj = 0;
+       data_blk_t blk = { 0 };
+       mtp_uint32 max_bytes = 0;
+       mtp_uint16 resp = PTP_RESPONSE_OK;
+       mtp_uint32 num_ref = 0;
+       mtp_uint32 idx = 0;
+       mtp_uint32 *ref_ptr = NULL;
+       mtp_uchar *ptr = NULL;
+       mtp_uint32 ref_handle = 0;
+
+       h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+
+               resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+       }
+
+       _device_set_phase(DEVICE_PHASE_DATAOUT);
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+
+       /* temporarily set a big number for data size received */
+
+       max_bytes = MTP_MAX_REFDB_ROWCNT * sizeof(mtp_uint32);
+       if (_hdlr_rcv_data_container(&blk, max_bytes) == FALSE) {
+               DBG("_hdlr_rcv_data_container() Fail");
+               _device_set_phase(DEVICE_PHASE_IDLE);
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       if (PTP_RESPONSE_OK != resp) {
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               g_free(blk.data);
+               return;
+       }
+
+       ptr = _hdlr_get_payload_data(&blk);
+       if (ptr == NULL) {
+               return;
+       }
+
+       memcpy(&num_ref, ptr, sizeof(mtp_uint32));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(&num_ref, sizeof(DWORD));
+#endif /* __BIG_ENDIAN__ */
+
+       ptr += sizeof(mtp_uint32);
+       if (_hdlr_get_payload_size(&blk) < (num_ref + 1) * sizeof(mtp_uint32)) {
+
+               resp = PTP_RESPONSE_GEN_ERROR;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               g_free(blk.data);
+               return;
+       }
+
+       ref_ptr = (mtp_uint32 *)ptr;
+       if (MTP_ERROR_NONE != _hutil_remove_object_reference(h_obj,
+                               PTP_OBJECTHANDLE_ALL)) {
+               resp = PTP_RESPONSE_GEN_ERROR;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               g_free(blk.data);
+       }
+
+       for (idx = 0; idx < num_ref; idx++) {
+               ref_handle = ref_ptr[idx];
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(&ref_handle, sizeof(mtp_uint32));
+#endif /*__BIG_ENDIAN__*/
+               _device_get_object_with_handle(ref_handle);
+       }
+
+       _hutil_add_object_references_enhanced(h_obj, (mtp_uchar *)ref_ptr,
+                       num_ref);
+       _cmd_hdlr_send_response_code(hdlr, resp);
+
+       g_free(blk.data);
+       return;
+}
+
+static void __get_object_prop_desc(mtp_handler_t *hdlr)
+{
+       mtp_uint32 prop_id = 0;
+       mtp_uint32 fmt = 0;
+       obj_prop_desc_t prop = { { 0 }, };
+       data_blk_t blk = { 0, };
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *ptr = NULL;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+
+       if (MTP_ERROR_NONE != _hutil_get_prop_desc(fmt, prop_id, &prop)) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PROP_NOTSUPPORTED);
+               return;
+       }
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       num_bytes = _prop_size_obj_prop_desc(&prop);
+       ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+
+       if (num_bytes == _prop_pack_obj_prop_desc(&prop, ptr, num_bytes)) {
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+               if (_hdlr_send_data_container(&blk)) {
+                       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+               } else {
+                       /* Host Cancelled data-in transfer */
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+               }
+       } else {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_GEN_ERROR);
+       }
+
+       g_free(blk.data);
+       return;
+}
+
+static void __get_object_prop_supported(mtp_handler_t *hdlr)
+{
+       mtp_uint32 fmt = 0;
+       data_blk_t blk = { 0 };
+       ptp_array_t props_supported = { 0 };
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *ptr = NULL;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       _prop_init_ptparray(&props_supported, UINT16_TYPE);
+
+       if (MTP_ERROR_NONE != _hutil_get_object_prop_supported(fmt,
+                               &props_supported)) {
+               _prop_deinit_ptparray(&props_supported);
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+               return;
+       }
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       num_bytes = _prop_get_size_ptparray(&props_supported);
+       ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+
+       if (NULL != ptr) {
+               _prop_pack_ptparray(&props_supported, ptr, num_bytes);
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+               if (_hdlr_send_data_container(&blk)) {
+                       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+               } else {
+                       /* Host Cancelled data-in transfer */
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+               }
+       } else {
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+       }
+
+       _prop_deinit_ptparray(&props_supported);
+
+       g_free(blk.data);
+       return;
+}
+
+static void __get_object_prop_value(mtp_handler_t *hdlr)
+{
+       mtp_uint32 h_obj = 0;
+       mtp_uint32 prop_id = 0;
+       mtp_uchar *ptr = NULL;
+       mtp_uint32 num_bytes = 0;
+       data_blk_t blk = { 0 };
+       obj_prop_val_t prop_val = { 0 };
+       mtp_err_t ret = 0;
+       mtp_obj_t *obj = NULL;
+#ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+       slist_node_t *node = NULL;
+       slist_node_t *next_node = NULL;
+       mtp_uint32 ii = 0;
+#endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       ret = _hutil_get_object_prop_value(h_obj, prop_id, &prop_val, &obj);
+
+       if (MTP_ERROR_NONE == ret) {
+               num_bytes = _prop_size_obj_propval(&prop_val);
+               _hdlr_init_data_container(&blk, hdlr->usb_cmd.code,
+                               hdlr->usb_cmd.tid);
+               ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes,
+                               num_bytes);
+               if (num_bytes ==
+                               _prop_pack_obj_propval(&prop_val, ptr, num_bytes)) {
+
+                       _device_set_phase(DEVICE_PHASE_DATAIN);
+                       if (_hdlr_send_data_container(&blk)) {
+                               _cmd_hdlr_send_response_code(hdlr,
+                                               PTP_RESPONSE_OK);
+                       } else {
+                               /* Host Cancelled data-in transfer */
+                               _device_set_phase(DEVICE_PHASE_NOTREADY);
+                       }
+               } else {
+                       _cmd_hdlr_send_response_code(hdlr,
+                                       PTP_RESPONSE_GEN_ERROR);
+               }
+
+               g_free(blk.data);
+
+       } else if (ret == MTP_ERROR_INVALID_OBJECTHANDLE) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_INVALID_OBJ_HANDLE);
+       } else {
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+       }
+
+#ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+       if (NULL == obj) {
+               ERR("Invalid object");
+               return;
+       }
+
+       for (ii = 0, next_node = obj->propval_list.start;
+                       ii < obj->propval_list.nnodes; ii++) {
+               node = next_node;
+               next_node = node->link;
+               _prop_destroy_obj_propval((obj_prop_val_t *)node->value);
+               g_free(node);
+       }
+       obj->propval_list.start = NULL;
+       obj->propval_list.end = NULL;
+       obj->propval_list.nnodes = 0;
+#endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+
+       return;
+}
+
+static void __set_object_prop_value(mtp_handler_t *hdlr)
+{
+       mtp_uint32 h_obj = 0;
+       mtp_uint32 prop_id = 0;
+       mtp_uint16 resp = PTP_RESPONSE_OK;
+       data_blk_t blk = { 0 };
+       mtp_uint32 max_bytes = 0;
+       mtp_err_t ret = 0;
+
+       h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               ERR("Unsupported parameters");
+               resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+       }
+
+       _device_set_phase(DEVICE_PHASE_DATAOUT);
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       max_bytes = MTP_MAX_PROP_DATASIZE;
+
+       if (_hdlr_rcv_data_container(&blk, max_bytes) == FALSE) {
+               ERR("_hdlr_rcv_data_container() Fail");
+               _device_set_phase(DEVICE_PHASE_IDLE);
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_INVALIDPROPVALUE);
+               g_free(blk.data);
+               return;
+       }
+
+       ret = _hutil_update_object_property(h_obj, prop_id, NULL,
+                       _hdlr_get_payload_data(&blk),
+                       _hdlr_get_payload_size(&blk), NULL);
+       switch (ret) {
+       case MTP_ERROR_ACCESS_DENIED:
+               resp = PTP_RESPONSE_ACCESSDENIED;
+               break;
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       case MTP_ERROR_INVALID_OBJ_PROP_CODE:
+               resp = PTP_RESPONSE_PROP_NOTSUPPORTED;
+               break;
+       case MTP_ERROR_GENERAL:
+               resp = PTP_RESPONSE_GEN_ERROR;
+               break;
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               break;
+       default:
+               resp = PTP_RESPONSE_INVALIDPROPVALUE;
+               break;
+       }
+
+       _cmd_hdlr_send_response_code(hdlr, resp);
+
+       g_free(blk.data);
+       return;
+}
+
+static void __get_object_prop_list(mtp_handler_t *hdlr)
+{
+       mtp_uint32 h_obj = 0;
+       mtp_uint32 fmt = 0;
+       mtp_uint32 prop_id = 0;
+       mtp_uint32 group_code = 0;
+       mtp_uint32 depth = 0;
+       mtp_err_t ret = 0;
+       mtp_uint16 resp = 0;
+       obj_proplist_t prop_list = { { 0 } };
+       data_blk_t blk = { 0 };
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *ptr = NULL;
+#ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+       ptp_array_t obj_arr = { 0 };
+       slist_node_t *node = NULL;
+       slist_node_t *next_node = NULL;
+       mtp_uint32 ii = 0;
+       mtp_uint32 jj = 0;
+       mtp_obj_t **ptr_array = NULL;
+       mtp_obj_t *obj = NULL;
+#endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+
+       h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
+       group_code = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 3);
+       depth = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 4);
+
+       __enum_store_not_enumerated(h_obj, fmt, depth);
+
+#ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+       ret = _hutil_get_object_prop_list(h_obj, fmt, prop_id, group_code,
+                       depth, &prop_list, &obj_arr);
+#else /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+       ret = _hutil_get_object_prop_list(h_obj, fmt, prop_id, group_code,
+                       depth, &prop_list);
+#endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+
+       switch (ret) {
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               break;
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       case MTP_ERROR_INVALID_PARAM:
+               resp = PTP_RESPONSE_INVALIDPARAM;
+               break;
+       case MTP_ERROR_NO_SPEC_BY_FORMAT:
+               resp = PTP_RESPONSE_NOSPECIFICATIONBYFORMAT;
+               break;
+       case MTP_ERROR_GENERAL:
+       default:
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       if (PTP_RESPONSE_OK != resp) {
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               _prop_deinit_ptparray(&obj_arr);
+               return;
+       }
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       num_bytes = _prop_size_obj_proplist(&prop_list);
+       ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+       if (num_bytes == _prop_pack_obj_proplist(&prop_list, ptr, num_bytes)) {
+
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+               if (_hdlr_send_data_container(&blk)) {
+                       _cmd_hdlr_send_response_code(hdlr, resp);
+               } else {
+                       /* Host Cancelled data-in transfer*/
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+               }
+       }
+
+       _prop_destroy_obj_proplist(&prop_list);
+       g_free(blk.data);
+
+#ifdef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+       if (resp == PTP_RESPONSE_OK && obj_arr.array_entry) {
+               ptr_array = obj_arr.array_entry;
+
+               for (ii = 0; ii < obj_arr.num_ele; ii++) {
+                       obj = ptr_array[ii];
+                       if (NULL == obj || obj->propval_list.nnodes == 0) {
+                               continue;
+                       }
+                       /*Remove all the old property value, and ready to set up new */
+                       for (jj = 0, next_node = obj->propval_list.start;
+                                       jj < obj->propval_list.nnodes; jj++) {
+                               node = next_node;
+                               next_node = node->link;
+                               _prop_destroy_obj_propval
+                                       ((obj_prop_val_t *)node->value);
+                               g_free(node);
+                       }
+                       obj->propval_list.start = NULL;
+                       obj->propval_list.end = NULL;
+                       obj->propval_list.nnodes = 0;
+                       node = NULL;
+               }
+       }
+       _prop_deinit_ptparray(&obj_arr);
+#endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+       return;
+}
+
+static void __set_object_prop_list(mtp_handler_t *hdlr)
+{
+       mtp_uint32 i = 0;
+       mtp_uint16 resp = PTP_RESPONSE_OK;
+       data_blk_t blk = { 0 };
+       mtp_uint32 max_num_obj = 0;
+       mtp_uint32 max_bytes = 0;
+       mtp_uint32 h_obj = 0;
+       mtp_uint32 prop_id = 0;
+       mtp_uint32 data_type = 0;
+       mtp_uchar *temp = NULL;
+       mtp_int32 bytes_left = 0;
+       mtp_uint32 prop_val_sz = 0;
+       mtp_uint32 num_elem = 0;
+       mtp_err_t ret = 0;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 3) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 4)) {
+               resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
+       }
+
+       _device_set_phase(DEVICE_PHASE_DATAOUT);
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+
+       /* Gestimate the amount of data we will be receiving */
+       _hutil_get_number_of_objects(PTP_STORAGEID_ALL, &max_num_obj);
+       max_bytes = max_num_obj * 1000;
+
+       /* If Host sent more data than we could receive, a device stall happens,
+        * which cancels the data transfer
+        */
+       if (max_bytes > 1000000) {
+               max_bytes = 1000000;
+               ERR("max_bytes is overflowed");
+       }
+       if (FALSE == _hdlr_rcv_data_container(&blk, max_bytes)) {
+               ERR("_hdlr_rcv_data_container() Fail");
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       if (PTP_RESPONSE_OK != resp) {
+               _cmd_hdlr_send_response(hdlr, resp, 1, &i);
+               g_free(blk.data);
+               return;
+       }
+
+       temp = _hdlr_get_payload_data(&blk);
+       bytes_left = (mtp_int32)_hdlr_get_payload_size(&blk);
+       if (bytes_left < sizeof(mtp_uint32)) {
+
+               resp = MTP_RESPONSE_INVALIDOBJPROPFORMAT;
+               _cmd_hdlr_send_response(hdlr, resp, 1, &i);
+               g_free(blk.data);
+
+               ERR("invalid object format, bytes_left [%d]:[%u]\n", bytes_left,
+                               sizeof(mtp_uint32));
+               return;
+       }
+
+       num_elem = 0;
+       memcpy(&num_elem, temp, sizeof(mtp_uint32));
+       temp += sizeof(mtp_uint32);
+       bytes_left -= sizeof(mtp_uint32);
+
+       for (i = 0; i < num_elem; i++) {
+               if (bytes_left < 0)
+                       break;
+
+               /*Get object handle*/
+               memcpy(&h_obj, temp, sizeof(mtp_uint32));
+               temp += sizeof(mtp_uint32);
+               bytes_left -= sizeof(mtp_uint32);
+               if (bytes_left < 0)
+                       break;
+
+               /* Get property code */
+               memcpy(&prop_id, temp, sizeof(mtp_uint16));
+               temp += sizeof(mtp_uint16);
+               bytes_left -= sizeof(mtp_uint16);
+               if (bytes_left < 0)
+                       break;
+
+               /* Get data type*/
+               memcpy(&data_type, temp, sizeof(mtp_uint16));
+               temp += sizeof(mtp_uint16);
+               bytes_left -= sizeof(mtp_uint16);
+               if (bytes_left < 0)
+                       break;
+
+               /* Update property*/
+               ret = _hutil_update_object_property(h_obj, prop_id,
+                               (mtp_uint16 *)&data_type, temp, bytes_left,
+                               &prop_val_sz);
+
+               switch (ret) {
+               case MTP_ERROR_INVALID_OBJECT_PROP_FORMAT:
+                       resp = MTP_RESPONSE_INVALIDOBJPROPFORMAT;
+                       _cmd_hdlr_send_response(hdlr, resp, 1, &i);
+                       g_free(blk.data);
+                       ERR("invalid object format");
+                       return;
+                       break;
+               case MTP_ERROR_ACCESS_DENIED:
+                       resp = PTP_RESPONSE_ACCESSDENIED;
+                       _cmd_hdlr_send_response(hdlr, resp, 1, &i);
+                       g_free(blk.data);
+                       ERR("access denied");
+                       return;
+                       break;
+               case MTP_ERROR_INVALID_OBJECTHANDLE:
+                       resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+                       _cmd_hdlr_send_response(hdlr, resp, 1, &i);
+                       g_free(blk.data);
+                       ERR("invalid object handle");
+                       return;
+                       break;
+               case MTP_ERROR_INVALID_OBJ_PROP_CODE:
+                       resp = PTP_RESPONSE_PROP_NOTSUPPORTED;
+                       _cmd_hdlr_send_response(hdlr, resp, 1, &i);
+                       g_free(blk.data);
+                       ERR("property not supported");
+                       return;
+                       break;
+               case MTP_ERROR_NONE:
+                       temp += prop_val_sz;
+                       bytes_left -= prop_val_sz;
+                       break;
+               default:
+                       resp = PTP_RESPONSE_INVALIDPROPVALUE;
+                       _cmd_hdlr_send_response(hdlr, resp, 1, &i);
+                       g_free(blk.data);
+                       ERR("invalid property value");
+                       return;
+                       break;
+               }
+       }
+       i = 0;
+       resp = PTP_RESPONSE_OK;
+       _cmd_hdlr_send_response(hdlr, resp, 1, &i);
+       g_free(blk.data);
+       return;
+}
+
+static void __report_acquired_content(mtp_handler_t *hdlr)
+{
+       mtp_uint32 tid = 0;
+       mtp_uint32 start_idx = 0;
+       mtp_uint32 max_size = 0;
+       mtp_uint16 resp = PTP_RESPONSE_OK;
+       mtp_uint32 resp_param[3] = { 0 };
+       data_blk_t blk = { 0 };
+       mtp_uchar *ptr = NULL;
+       ptp_array_t guid_arr = { 0 };
+       mtp_uint32 num_mod = 0;
+       mtp_uint32 num_bytes = 0;
+       mtp_uint32 num_lines = 0;
+       mtp_uint32 rem_modified = 0;
+       mtp_uint32 h_file;
+       time_t cur_time;
+       time_t l_time;
+       mtp_int32 diff_time;
+       mtp_int32 err = 0;
+       mtp_int32 ret = 0;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 3)) {
+
+               ERR("Unsupported parameters");
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       tid = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       start_idx = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       max_size = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
+
+       if (tid == 0) {
+
+               if (access(MTP_FILES_MODIFIED_FILES, F_OK) == 0)
+                       if (remove(MTP_FILES_MODIFIED_FILES) < 0) {
+                               ERR("remove(%s) Fail", MTP_FILES_MODIFIED_FILES);
+                       }
+               resp = PTP_RESPONSE_OK;
+               _prop_grow_ptparray(&guid_arr, 1);
+               _prop_append_ele_ptparray(&guid_arr, 0);
+               goto DONE;
+       }
+
+       g_is_sync_estab = TRUE;
+
+       if (!g_has_round_trip && start_idx == 0) {
+               time(&cur_time);
+               ret = vconf_get_int(VCONFKEY_MTP_SYNC_TIME_INT, (int *)&l_time);
+               if (ret == -1) {
+                       ERR("Error to get key value at [%s] path\n",
+                                       VCONFKEY_MTP_SYNC_TIME_INT);
+                       resp = PTP_RESPONSE_OK;
+                       _prop_grow_ptparray(&guid_arr, 1);
+                       _prop_append_ele_ptparray(&guid_arr, 0);
+                       goto DONE;
+               }
+               diff_time = (cur_time - l_time) / 60;
+               if (diff_time < 0) {
+                       resp = PTP_RESPONSE_GEN_ERROR;
+                       _prop_init_ptparray(&guid_arr, UINT32_TYPE);
+                       _prop_append_ele_ptparray(&guid_arr, 0);
+                       goto DONE;
+               }
+               _entity_list_modified_files(diff_time);
+       }
+
+       h_file = _util_file_open(MTP_FILES_MODIFIED_FILES, MTP_FILE_READ, &err);
+       if (h_file == INVALID_FILE) {
+               resp = PTP_RESPONSE_GEN_ERROR;
+               _prop_init_ptparray(&guid_arr, UINT32_TYPE);
+               _prop_append_ele_ptparray(&guid_arr, 0);
+               goto DONE;
+       }
+
+       if (!g_has_round_trip && start_idx == 0) {
+               _util_count_num_lines(h_file, &g_mgr->meta_info.mod);
+               _util_file_seek(h_file, 0, SEEK_SET);
+       }
+       num_lines = g_mgr->meta_info.mod;
+       num_mod = ((num_lines - start_idx) > max_size) ?
+               max_size : num_lines - start_idx;
+
+       rem_modified = (num_lines - start_idx > max_size) ?
+               (num_lines - start_idx- max_size) : 0;
+
+       g_has_round_trip = FALSE;
+       _prop_init_ptparray(&guid_arr, UINT32_TYPE);
+       _prop_grow_ptparray(&guid_arr, (num_mod * sizeof(mtp_uint32)) + 1);
+       _prop_append_ele_ptparray(&guid_arr, num_mod);
+       _util_fill_guid_array(&guid_arr, start_idx, h_file, num_mod);
+
+       _util_file_close(h_file);
+       if (rem_modified == 0) {
+               if (remove(MTP_FILES_MODIFIED_FILES) < 0) {
+                       ERR("remove(%s) Fail", MTP_FILES_MODIFIED_FILES);
+               }
+               g_mgr->meta_info.mod = 0;
+       }
+
+DONE:
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       num_bytes = _prop_get_size_ptparray_without_elemsize(&guid_arr);
+       ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+
+       if (NULL != ptr) {
+               _prop_pack_ptparray_without_elemsize(&guid_arr, ptr, num_bytes);
+               _device_set_phase(DEVICE_PHASE_DATAIN);
+       }
+
+       if (_hdlr_send_data_container(&blk)) {
+               resp = PTP_RESPONSE_OK;
+       } else {
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       _prop_deinit_ptparray(&guid_arr);
+       g_free(blk.data);
+
+       if (PTP_RESPONSE_OK == resp) {
+
+               resp_param[0] = hdlr->usb_cmd.tid;
+               resp_param[1] = rem_modified;
+               resp_param[2] = 0;
+               _cmd_hdlr_send_response(hdlr, resp, 3, resp_param);
+       } else {
+               _cmd_hdlr_send_response_code(hdlr, resp);
+       }
+       return;
+}
+
+static void __send_playback_skip(mtp_handler_t *hdlr)
+{
+       mtp_int32 skip = 0;
+       mtp_uint16 resp = PTP_RESPONSE_INVALIDPARAM;
+
+       skip = (mtp_int32) _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       if (MTP_ERROR_NONE == _hutil_get_playback_skip(skip)) {
+               resp = PTP_RESPONSE_OK;
+       }
+       _cmd_hdlr_send_response_code(hdlr, resp);
+       return;
+}
+
+#ifndef PMP_VER
+static void __self_test(mtp_handler_t *hdlr)
+{
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               ERR("Unsupported parameters");
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       /* Do device-specific tests */
+       /* After the test */
+       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+       return;
+}
+
+#ifdef MTP_SUPPORT_SET_PROTECTION
+static void __set_object_protection(mtp_handler_t *hdlr)
+{
+       mtp_uint32 h_obj = 0;
+       mtp_uint16 protcn_status = 0;
+       mtp_uint16 resp = 0;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               ERR("Unsupported parameter");
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       protcn_status = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+
+       if ((protcn_status != PTP_PROTECTIONSTATUS_NOPROTECTION) &&
+                       (protcn_status != PTP_PROTECTIONSTATUS_READONLY) &&
+                       (protcn_status != MTP_PROTECTIONSTATUS_READONLY_DATA) &&
+                       (protcn_status != MTP_PROTECTIONSTATUS_NONTRANSFERABLE_DATA)) {
+
+               resp = PTP_RESPONSE_INVALIDPARAM;
+               _cmd_hdlr_send_response_code(hdlr, resp);
+               return;
+
+       }
+       switch (_hutil_set_protection(h_obj, protcn_status)) {
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       case MTP_ERROR_OBJECT_WRITE_PROTECTED:
+               resp = PTP_RESPONSE_OBJ_WRITEPROTECTED;
+               break;
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               break;
+       case MTP_ERROR_OPERATION_NOT_SUPPORTED:
+               resp = PTP_RESPONSE_OP_NOT_SUPPORTED;
+               break;
+       default:
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       _cmd_hdlr_send_response_code(hdlr, resp);
+       return;
+}
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+
+static void __power_down(mtp_handler_t *hdlr)
+{
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               ERR("Unsupported Parameter");
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+       usleep(1000);
+       _cmd_hdlr_reset_cmd(hdlr);
+       return;
+}
+
+static void __move_object(mtp_handler_t *hdlr)
+{
+       mtp_uint32 store_id = 0;
+       mtp_uint32 obj_handle = 0;
+       mtp_uint32 h_parent = 0;
+       mtp_uint32 resp = 0;
+
+       obj_handle = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
+
+       _transport_set_mtp_operation_state(MTP_STATE_DATA_PROCESSING);
+
+       switch (_hutil_move_object_entry(store_id, h_parent, obj_handle)) {
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               break;
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       case MTP_ERROR_OBJECT_WRITE_PROTECTED:
+               resp = PTP_RESPONSE_OBJ_WRITEPROTECTED;
+               break;
+       case MTP_ERROR_ACCESS_DENIED:
+               resp = PTP_RESPONSE_ACCESSDENIED;
+               break;
+       case MTP_ERROR_STORE_NOT_AVAILABLE:
+               resp = PTP_RESPONSE_STORENOTAVAILABLE;
+               break;
+       case MTP_ERROR_INVALID_PARENT:
+               resp = PTP_RESPONSE_INVALIDPARENT;
+               break;
+       case MTP_ERROR_INVALID_PARAM:
+               resp = PTP_RESPONSE_INVALIDPARAM;
+               break;
+       case MTP_ERROR_STORE_FULL:
+               resp = PTP_RESPONSE_STOREFULL;
+               break;
+       default:
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
+       _cmd_hdlr_send_response_code(hdlr, resp);
+       return;
+}
+
+static void __copy_object(mtp_handler_t *hdlr)
+{
+       mtp_uint32 store_id = 0;
+       mtp_uint32 h_obj = 0;
+       mtp_uint32 h_parent = 0;
+       mtp_uint32 new_handle = 0;
+       mtp_uint16 resp = 0;
+
+       h_obj = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
+
+       _transport_set_mtp_operation_state(MTP_STATE_DATA_PROCESSING);
+
+       switch (_hutil_duplicate_object_entry(store_id, h_parent, h_obj,
+                               &new_handle)) {
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+               break;
+       case MTP_ERROR_OBJECT_WRITE_PROTECTED:
+               resp = PTP_RESPONSE_OBJ_WRITEPROTECTED;
+               break;
+       case MTP_ERROR_STORE_NOT_AVAILABLE:
+               resp = PTP_RESPONSE_STORENOTAVAILABLE;
+               break;
+       case MTP_ERROR_STORE_READ_ONLY:
+               resp = PTP_RESPONSE_STORE_READONLY;
+               break;
+       case MTP_ERROR_INVALID_PARENT:
+               resp = PTP_RESPONSE_INVALIDPARENT;
+               break;
+       case MTP_ERROR_INVALID_PARAM:
+               resp = PTP_RESPONSE_INVALIDPARAM;
+               break;
+       case MTP_ERROR_STORE_FULL:
+               resp = PTP_RESPONSE_STOREFULL;
+               break;
+       case MTP_ERROR_NONE:
+               resp = PTP_RESPONSE_OK;
+               break;
+       case MTP_ERROR_ACCESS_DENIED:
+               resp = PTP_RESPONSE_ACCESSDENIED;
+               break;
+       default:
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+       _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
+
+       if (resp == PTP_RESPONSE_OK) {
+               _cmd_hdlr_send_response(hdlr, resp, 1, &new_handle);
+       } else {
+               _cmd_hdlr_send_response_code(hdlr, resp);
+       }
+
+       return;
+}
+
+static void __reset_device_prop_value(mtp_handler_t *hdlr)
+{
+       mtp_uint32 prop_id = 0;
+       device_prop_desc_t *prop = NULL;
+       mtp_char temp[MTP_MAX_REG_STRING * 3 + 1] = { 0 };
+
+       prop_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+
+       if (MTP_ERROR_NONE != _hutil_reset_device_entry(prop_id)) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PROP_NOTSUPPORTED);
+               return;
+       }
+
+       if (MTP_PROPERTYCODE_DEVICEFRIENDLYNAME == prop_id) {
+               prop = _device_get_device_property(prop_id);
+               if (prop == NULL) {
+                       _cmd_hdlr_send_response_code(hdlr,
+                                       PTP_RESPONSE_PROP_NOTSUPPORTED);
+                       return;
+               }
+
+               _util_utf16_to_utf8(temp, sizeof(temp),
+                               prop->current_val.str->str);
+               _device_set_device_name(temp);
+
+       } else if (MTP_PROPERTYCODE_SYNCHRONIZATIONPARTNER == prop_id) {
+               prop = _device_get_device_property(prop_id);
+               if (NULL == prop) {
+                       _cmd_hdlr_send_response_code(hdlr,
+                                       PTP_RESPONSE_PROP_NOTSUPPORTED);
+                       return;
+               }
+
+               _util_utf16_to_utf8(temp, sizeof(temp),
+                               prop->current_val.str->str);
+               _device_set_sync_partner(temp);
+
+               if (!g_strcmp0(temp, MTP_DEV_PROPERTY_NULL_SYNCPARTNER)) {
+                       vconf_set_str(VCONFKEY_MTP_SYNC_PARTNER_STR, "");
+               } else {
+                       vconf_set_str(VCONFKEY_MTP_SYNC_PARTNER_STR, temp);
+               }
+       }
+       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+
+       return;
+}
+
+/* Vendor-specific operations */
+#define GET_DEVICEPC_NAME      1
+static void __vendor_command1(mtp_handler_t *hdlr)
+{
+       switch (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0)) {
+       case GET_DEVICEPC_NAME:
+               break;
+       default:
+               break;
+       }
+       /* Vendor command not properly handled*/
+       _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+       return;
+}
+
+static void __get_interdep_prop_desc(mtp_handler_t *hdlr)
+{
+       mtp_uint32 fmt = 0;
+       data_blk_t blk = { 0 };
+       mtp_uint32 num_bytes = 0;
+       mtp_uchar *ptr = NULL;
+
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+               return;
+       }
+
+       fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       if (0x0 == fmt || 0xFFFFFFFF == fmt) {
+               ERR("Invalid format code");
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_INVALIDCODEFORMAT);
+               return;
+       }
+
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+       _hutil_get_interdep_prop_config_list_size(&num_bytes, fmt);
+       ptr = _hdlr_alloc_buf_data_container(&blk, num_bytes, num_bytes);
+
+       if (MTP_ERROR_NONE != _hutil_get_interdep_prop_config_list_data(ptr,
+                               num_bytes, fmt)) {
+               ERR("_hutil_get_interdep_prop_config_list_data() Fail");
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_GEN_ERROR);
+               return;
+       }
+
+       _device_set_phase(DEVICE_PHASE_DATAIN);
+       if (_hdlr_send_data_container(&blk)) {
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+       } else {
+               /*Host Cancelled data-in transfer*/
+               _device_set_phase(DEVICE_PHASE_NOTREADY);
+       }
+
+       g_free(blk.data);
+       return;
+}
+
+/*
+ * void __cmd_hdlr_send_object_prop_list(mtp_handler_t *hdlr)
+ * This function is used as an alternative first operation when the initiator
+ * wants to send an object to the responder. This operation sends a
+ * modified ObjectPropList dataset from the initiator to the Responder.
+ *@param[in]           hdlr
+ *@return              none
+ */
+static void __send_object_prop_list(mtp_handler_t *hdlr)
+{
+       mtp_uint32 idx = 0;
+       mtp_uint16 resp = PTP_RESPONSE_OK;
+       mtp_uint32 resp_param[MAX_MTP_PARAMS] = { 0 };
+       mtp_obj_t *obj = NULL;
+       mtp_uint16 fmt = 0;
+       mtp_uint64 f_size = 0;
+       mtp_uint64 fsize_hbits = 0;
+       mtp_uint32 store_id;
+       mtp_uint32 h_parent;
+       data_blk_t blk = { 0 };
+       mtp_uint32 max_bytes = 0;
+       mtp_err_t ret = 0;
+       obj_data_t objdata = { 0 };
+
+       store_id = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0);
+       h_parent = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1);
+       fmt = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2);
+       fsize_hbits = _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 3);
+
+       f_size = (fsize_hbits << 32) + _hdlr_get_param_cmd_container
+               (&(hdlr->usb_cmd), 4);
+
+       _device_set_phase(DEVICE_PHASE_DATAOUT);
+       _hdlr_init_data_container(&blk, hdlr->usb_cmd.code, hdlr->usb_cmd.tid);
+
+       max_bytes = MTP_MAX_METADATA;
+       if (FALSE == _hdlr_rcv_data_container(&blk, max_bytes)) {
+               _device_set_phase(DEVICE_PHASE_IDLE);
+               ERR("_hdlr_rcv_data_container() Fail");
+               resp = PTP_RESPONSE_GEN_ERROR;
+       }
+
+       idx = 0;
+       if (store_id) {
+               if (!h_parent) {
+                       h_parent = _device_get_default_parent_handle();
+               } else if (h_parent == 0xFFFFFFFF) {
+                       h_parent = PTP_OBJECTHANDLE_ROOT;
+               }
+       } else {
+               store_id = _device_get_default_store_id();
+               if (!store_id)
+                       resp = PTP_RESPONSE_STORENOTAVAILABLE;
+               if (h_parent)
+                       /* If the second parameter is used, the first must
+                        * also be used
+                        * */
+                       resp = PTP_RESPONSE_PARAM_NOTSUPPORTED;
+               else
+                       h_parent = _device_get_default_parent_handle();
+       }
+
+       if (f_size >= MTP_FILESIZE_4GB) {
+
+               mtp_store_t *store = NULL;
+               struct statfs buf = { 0 };
+               mtp_int32 ret = 0;
+
+               store = _device_get_store(store_id);
+               if (store == NULL) {
+                       ERR("Store Not Available");
+                       resp = PTP_RESPONSE_STORENOTAVAILABLE;
+               } else {
+                       DBG("StorePath = [%s]\n", store->root_path);
+                       ret = statfs(store->root_path, &buf);
+                       if (ret < 0 || buf.f_type == MSDOS_SUPER_MAGIC) {
+                               ERR("File System does not support files over 4gb");
+                               resp = MTP_RESPONSE_OBJECT_TOO_LARGE;
+                       }
+               }
+       }
+
+       if (PTP_RESPONSE_OK == resp) {
+
+               mtp_uchar *data = NULL;
+
+               if (TRUE == hdlr->data4_send_obj.is_valid) {
+
+                       objdata.store_id = hdlr->data4_send_obj.store_id;
+                       objdata.obj_size = hdlr->data4_send_obj.file_size;
+                       objdata.obj = hdlr->data4_send_obj.obj;
+                       hdlr->data4_send_obj.obj = NULL;
+               }
+
+               data = _hdlr_get_payload_data(&blk);
+               if (data == NULL)
+                       return;
+
+               ret = _hutil_construct_object_entry_prop_list(store_id, h_parent,
+                               fmt, f_size, ((hdlr->data4_send_obj.is_valid == TRUE) ?
+                                       (&objdata) : (NULL)), &obj, data,
+                               _hdlr_get_payload_size(&blk), &idx);
+               hdlr->data4_send_obj.is_valid = FALSE;
+
+               switch (ret) {
+               case MTP_ERROR_INVALID_STORE:
+                       resp = PTP_RESPONSE_INVALID_STORE_ID;
+                       break;
+               case MTP_ERROR_STORE_READ_ONLY:
+                       resp = PTP_RESPONSE_STORE_READONLY;
+                       break;
+               case MTP_ERROR_STORE_FULL:
+                       resp = PTP_RESPONSE_STOREFULL;
+                       break;
+               case MTP_ERROR_GENERAL:
+                       resp = PTP_RESPONSE_GEN_ERROR;
+                       break;
+               case MTP_ERROR_INVALID_DATASET:
+                       resp = MTP_RESPONSECODE_INVALIDDATASET;
+                       break;
+               case MTP_ERROR_INVALID_OBJECTHANDLE:
+                       resp = PTP_RESPONSE_INVALID_OBJ_HANDLE;
+                       break;
+               case MTP_ERROR_INVALID_OBJ_PROP_CODE:
+                       resp = MTP_RESPONSE_INVALIDOBJPROPCODE;
+                       break;
+               case MTP_ERROR_INVALID_OBJECT_PROP_FORMAT:
+                       resp = MTP_RESPONSE_INVALIDOBJPROPFORMAT;
+                       break;
+               case MTP_ERROR_INVALID_OBJ_PROP_VALUE:
+                       resp = MTP_RESPONSE_INVALIDOBJPROPVALUE;
+                       break;
+               case MTP_ERROR_INVALID_PARENT:
+                       resp = PTP_RESPONSE_INVALIDPARENT;
+                       break;
+               case MTP_ERROR_ACCESS_DENIED:
+                       resp = PTP_RESPONSE_ACCESSDENIED;
+                       break;
+               case MTP_ERROR_NONE:
+#ifdef MTP_USE_SELFMAKE_ABSTRACTION
+                       if ((obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION) ||
+                                       (obj->obj_info->file_size == 0 &&
+                                        obj->obj_info->obj_fmt >
+                                        MTP_FMT_UNDEFINED_COLLECTION &&
+                                        obj->obj_info->obj_fmt <
+                                        MTP_FMT_UNDEFINED_DOC))
+#else /*MTP_USE_SELFMAKE_ABSTRACTION*/
+                               if (obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION)
+#endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
+                               {
+                                       hdlr->data4_send_obj.obj = NULL;
+                                       hdlr->data4_send_obj.is_valid = FALSE;
+                                       hdlr->data4_send_obj.obj_handle = obj->obj_handle;
+                                       hdlr->data4_send_obj.h_parent = h_parent;
+                                       hdlr->data4_send_obj.store_id = store_id;
+                                       hdlr->data4_send_obj.file_size = 0;
+                               } else {
+                                       hdlr->data4_send_obj.is_valid = TRUE;
+                                       hdlr->data4_send_obj.obj_handle = obj->obj_handle;
+                                       hdlr->data4_send_obj.h_parent = h_parent;
+                                       hdlr->data4_send_obj.store_id = store_id;
+                                       hdlr->data4_send_obj.obj = obj;
+                                       hdlr->data4_send_obj.file_size =
+                                               obj->obj_info->file_size;
+                               }
+                       resp = PTP_RESPONSE_OK;
+                       break;
+               default:
+                       resp = PTP_RESPONSE_GEN_ERROR;
+               }
+       }
+
+       if (PTP_RESPONSE_OK != resp) {
+               if (hdlr->data4_send_obj.obj) {
+                       _entity_dealloc_mtp_obj(hdlr->data4_send_obj.obj);
+               }
+
+               hdlr->data4_send_obj.obj = NULL;
+               hdlr->data4_send_obj.is_valid = FALSE;
+               resp_param[3] = idx;
+       } else {
+               resp_param[0] = hdlr->data4_send_obj.store_id;
+
+               /* PTP spec here requires that 0xFFFFFFFF be sent if root is the parent,
+                * while in some situations (e.g. Move Object, Copy Object), 0x00000000
+                *(as PTP_OBJECTHANDLE_ROOT is defined) represents the root
+                */
+               resp_param[1] = (hdlr->data4_send_obj.h_parent !=
+                               PTP_OBJECTHANDLE_ROOT) ? hdlr->data4_send_obj.h_parent
+                       : 0xFFFFFFFF;
+               resp_param[2] = hdlr->data4_send_obj.obj_handle;
+               resp_param[3] = 0;
+       }
+
+       _cmd_hdlr_send_response(hdlr, resp, 4, resp_param);
+
+       g_free(blk.data);
+       return;
+}
+#endif /*PMP_VER*/
+
+void __close_session(mtp_handler_t *hdlr)
+{
+       if (_hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 0) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 1) ||
+                       _hdlr_get_param_cmd_container(&(hdlr->usb_cmd), 2)) {
+
+               ERR("PTP_RESPONSE_PARAM_NOTSUPPORTED");
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_PARAM_NOTSUPPORTED);
+
+               return;
+       }
+
+       if (hdlr->session_id) {
+               hdlr->session_id = 0;
+               _cmd_hdlr_send_response_code(hdlr, PTP_RESPONSE_OK);
+       } else {
+               _cmd_hdlr_send_response_code(hdlr,
+                               PTP_RESPONSE_SESSIONNOTOPEN);
+               ERR("PTP_RESPONSE_SESSIONNOTOPEN");
+       }
+       return;
+}
+
+mtp_bool _cmd_hdlr_send_response(mtp_handler_t *hdlr, mtp_uint16 resp,
+               mtp_uint32 num_param, mtp_uint32 *params)
+{
+       mtp_bool ret = FALSE;
+       resp_blk_t blk = { 0 };
+
+       _hdlr_resp_container_init(&blk, resp, hdlr->usb_cmd.tid);
+
+       ret = _hdlr_add_param_resp_container(&blk, num_param, params);
+
+       _device_set_phase(DEVICE_PHASE_RESPONSE);
+       ret = _hdlr_send_resp_container(&blk);
+       _device_set_phase(DEVICE_PHASE_IDLE);
+
+       if ((resp == PTP_RESPONSE_OK) && (ret == TRUE)) {
+               DBG("[%s], Opcode[0x%4x], ResponseCode[0x%4x], NumParams[%d]\n",
+                               "SUCCESS", hdlr->usb_cmd.code, resp, num_param);
+       } else {
+               ERR("[%s], Opcode = [0x%4x] ResponseCode[0x%4x], NumParams[%u]\n",
+                               "FAIL", hdlr->usb_cmd.code, resp, num_param);
+       }
+       return ret;
+}
+
+mtp_bool _cmd_hdlr_send_response_code(mtp_handler_t *hdlr, mtp_uint16 resp)
+{
+       return _cmd_hdlr_send_response(hdlr, resp, 0, NULL);
+}
+
+#ifdef MTP_SUPPORT_PRINT_COMMAND
+static void __print_command(mtp_uint16 code)
+{
+       switch(code) {
+       case PTP_OPCODE_GETDEVICEINFO :
+               DBG("COMMAND ======== GET DEVICE INFO===========");
+               break;
+       case PTP_OPCODE_OPENSESSION :
+               DBG("COMMAND ======== OPEN SESSION ===========");
+               break;
+       case PTP_OPCODE_CLOSESESSION :
+               DBG("COMMAND ======== CLOSE SESSION ===========");
+               break;
+       case PTP_OPCODE_GETSTORAGEIDS :
+               DBG("COMMAND ======== GET STORAGE IDS ===========");
+               break;
+       case PTP_OPCODE_GETSTORAGEINFO :
+               DBG("COMMAND ======== GET STORAGE INFO ===========");
+               break;
+       case PTP_OPCODE_GETNUMOBJECTS :
+               DBG("COMMAND ======== GET NUM OBJECTS ===========");
+               break;
+       case PTP_OPCODE_GETOBJECTHANDLES :
+               DBG("COMMAND ======== GET OBJECT HANDLES ===========");
+               break;
+       case PTP_OPCODE_GETOBJECTINFO :
+               DBG("COMMAND ======== GET OBJECT INFO ===========");
+               break;
+       case PTP_OPCODE_GETOBJECT :
+               DBG("COMMAND ======== GET OBJECT ===========");
+               break;
+       case PTP_OPCODE_DELETEOBJECT :
+               DBG("COMMAND ======== DELETE OBJECT ===========");
+               break;
+       case PTP_OPCODE_SENDOBJECTINFO :
+               DBG("COMMAND ======== SEND OBJECT INFO ===========");
+               break;
+       case PTP_OPCODE_SENDOBJECT :
+               DBG("COMMAND ======== SEND OBJECT ===========");
+               break;
+       case PTP_OPCODE_INITIATECAPTURE :
+               DBG("COMMAND ======== INITIATE CAPTURE ===========");
+               break;
+       case PTP_OPCODE_FORMATSTORE :
+               DBG("COMMAND ======== FORMAT STORE ===========");
+               break;
+       case PTP_OPCODE_RESETDEVICE :
+               DBG("COMMAND ======== RESET DEVICE ===========");
+               break;
+       case PTP_OPCODE_SELFTEST :
+               DBG("COMMAND ======== SELF TEST ===========");
+               break;
+       case PTP_OPCODE_SETOBJECTPROTECTION :
+               DBG("COMMAND ======== SET OBJECT PROTECTION ===========");
+               break;
+       case PTP_OPCODE_POWERDOWN :
+               DBG("COMMAND ======== POWER DOWN ===========");
+               break;
+       case PTP_OPCODE_GETDEVICEPROPDESC :
+               DBG("COMMAND ======== GET DEVICE PROP DESC ===========");
+               break;
+       case PTP_OPCODE_GETDEVICEPROPVALUE :
+               DBG("COMMAND ======== GET DEVICE PROP VALUE ===========");
+               break;
+       case PTP_OPCODE_SETDEVICEPROPVALUE :
+               DBG("COMMAND ======== SET DEVICE PROP VALUE ===========");
+               break;
+       case PTP_OPCODE_RESETDEVICEPROPVALUE :
+               DBG("COMMAND ======== RESET DEVICE PROP VALUE ===========");
+               break;
+       case PTP_OPCODE_TERMINATECAPTURE :
+               DBG("COMMAND ======== TERMINATE CAPTURE ===========");
+               break;
+       case PTP_OPCODE_MOVEOBJECT :
+               DBG("COMMAND ======== MOVE OBJECT ===========");
+               break;
+       case PTP_OPCODE_COPYOBJECT :
+               DBG("COMMAND ======== COPY OBJECT ===========");
+               break;
+       case PTP_OPCODE_GETPARTIALOBJECT :
+               DBG("COMMAND ======== GET PARTIAL OBJECT ===========");
+               break;
+       case PTP_OPCODE_INITIATEOPENCAPTURE :
+               DBG("COMMAND ======== INITIATE OPEN CAPTURE ===========");
+               break;
+       case MTP_OPCODE_WMP_UNDEFINED :
+               DBG("COMMAND ======== WMP UNDEFINED ==========");
+               break;
+       case MTP_OPCODE_WMP_REPORTACQUIREDCONTENT :
+               DBG("COMMAND ======= REPORT ACQUIRED CONTENT =========");
+               break;
+       case MTP_OPCODE_GETOBJECTPROPSUPPORTED :
+               DBG("COMMAND ======= GET OBJECT PROP SUPPORTED ========");
+               break;
+       case MTP_OPCODE_GETOBJECTPROPDESC :
+               DBG("COMMAND ======== GET OBJECT PROP DESC ==========");
+               break;
+       case MTP_OPCODE_GETOBJECTPROPVALUE :
+               DBG("COMMAND ======== GET OBJECT PROP VALUE ==========");
+               break;
+       case MTP_OPCODE_SETOBJECTPROPVALUE :
+               DBG("COMMAND ======== SET OBJECT PROP VALUE ==========");
+               break;
+       case MTP_OPCODE_GETOBJECTPROPLIST :
+               DBG("COMMAND ======== GET OBJECT PROP LIST ==========");
+               break;
+       case MTP_OPCODE_SETOBJECTPROPLIST :
+               DBG("COMMAND ======== SET OBJECT PROP LIST ==========");
+               break;
+       case MTP_OPCODE_GETINTERDEPPROPDESC :
+               DBG("COMMAND ======== GET INTERDEP PROP DESC ==========");
+               break;
+       case MTP_OPCODE_SENDOBJECTPROPLIST :
+               DBG("COMMAND ======== SEND OBJECT PROP LIST ==========");
+               break;
+       case MTP_OPCODE_GETOBJECTREFERENCES :
+               DBG("COMMAND ======== GET OBJECT REFERENCES ==========");
+               break;
+       case MTP_OPCODE_SETOBJECTREFERENCES :
+               DBG("COMMAND ======== SET OBJECT REFERENCES ==========");
+               break;
+       case MTP_OPCODE_PLAYBACK_SKIP :
+               DBG("COMMAND ======== PLAYBACK SKIP ==========");
+               break;
+       default :
+               DBG("======== UNKNOWN COMMAND ==========");
+               break;
+       }
+
+       return;
+}
+#endif /*MTP_SUPPORT_PRINT_COMMAND*/
+
+static void __enum_store_not_enumerated(mtp_uint32 obj_handle,
+               mtp_uint32 fmt, mtp_uint32 depth)
+{
+       mtp_uint32 ii;
+       mtp_store_t *store = NULL;
+       mtp_obj_t *obj = NULL;
+
+       if (TRUE == g_is_full_enum) {
+               DBG("Full Enumeration has been already done");
+               return;
+       }
+
+       DBG("obj_handle = [%u], format =[ %u], depth = [%u]\n", obj_handle,
+                       fmt, depth);
+       if (obj_handle == PTP_OBJECTHANDLE_ALL || obj_handle == PTP_OBJECTHANDLE_ROOT) {
+               for (ii = 0; ii < _device_get_num_stores(); ii++) {
+                       store = _device_get_store_at_index(ii);
+                       if (store && store->obj_list.nnodes == 0)
+                               _entity_store_recursive_enum_folder_objects(store, NULL);
+               }
+               g_is_full_enum = TRUE;
+       } else if (obj_handle != PTP_OBJECTHANDLE_ROOT) {
+               store = _device_get_store_containing_obj(obj_handle);
+               obj = _entity_get_object_from_store(store, obj_handle);
+               if (obj == NULL) {
+                       ERR("pObject is NULL");
+                       return;
+               }
+               _entity_store_recursive_enum_folder_objects(store, obj);
+       }
+       return;
+}
+
+void _receive_mq_data_cb(mtp_char *buffer, mtp_int32 buf_len)
+{
+       cmd_blk_t cmd = { 0 };
+       mtp_uint32 rx_size = _get_rx_pkt_size();
+
+       if (_transport_get_mtp_operation_state() < MTP_STATE_READY_SERVICE) {
+               ERR("MTP is stopped or initializing. ignore all");
+               return;
+       }
+
+#ifdef MTP_SUPPORT_CONTROL_REQUEST
+       /* process control request */
+       switch (_transport_get_control_event()) {
+       case PTP_EVENTCODE_CANCELTRANSACTION:
+               DBG("PTP_EVENTCODE_CANCELTRANSACTION, just change state to IDLE");
+               _transport_set_control_event(PTP_EVENTCODE_CANCELTRANSACTION);
+               _device_set_phase(DEVICE_PHASE_IDLE);
+               if ((buf_len == rx_size) ||
+                               (buf_len < sizeof(header_container_t))) {
+                       DBG("Cancelling Transaction. data length [%d]\n",
+                                       buf_len);
+                       _transport_set_control_event(PTP_EVENTCODE_CANCELTRANSACTION);
+                       return;
+               }
+
+               mtp_int32 i = 0;
+               cmd_container_t *tmp;
+               mtp_dword len = 0;
+               mtp_word type = 0;
+               mtp_word code = 0;
+               mtp_dword trid = 0;
+
+               for (i = 0; i < MAX_MTP_PARAMS; i++) {  /* check size */
+                       /* check number of parameter */
+                       tmp = (cmd_container_t *)&buffer[buf_len -
+                               sizeof(header_container_t) -
+                               sizeof(mtp_dword) * i];
+
+                       len = tmp->len;
+                       type = tmp->type;
+
+                       if ((len == sizeof(header_container_t)
+                                               + sizeof(mtp_dword) * i) &&
+                                       (type == CONTAINER_CMD_BLK)) {
+                               DBG("Found Command in remaining data");
+                               memcpy(buffer, tmp, len);
+                               buf_len = len;
+                               break;
+                       }
+                       DBG("Not found command, length[%lu]\n", len);
+               }
+
+               len = tmp->len;
+               type = tmp->type;
+               code = tmp->code;
+               trid = tmp->tid;
+
+               DBG("len[%ld], type[0x%x], code [0x%x], trid[0x%x]\n",
+                               len, type, code, trid);
+
+               if (_hdlr_validate_cmd_container((mtp_byte *)tmp, len)
+                               == FALSE) {
+                       ERR("Cancelling Transaction, invalid header, but last packet");
+               } else {        /*another command, cancelling is finished*/
+                       DBG("Cancelling Transaction, Finished.");
+               }
+
+               _transport_set_control_event(0);
+               _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
+               if (g_mgr->ftemp_st.fhandle != INVALID_FILE) {
+                       DBG("In Cancel Transaction fclose ");
+                       _util_file_close(g_mgr->ftemp_st.fhandle);
+                       g_mgr->ftemp_st.fhandle = INVALID_FILE;
+                       DBG("In Cancel Transaction, remove ");
+                       if (remove(g_mgr->ftemp_st.filepath) < 0) {
+                               ERR_SECURE("remove(%s) Fail", g_mgr->ftemp_st.filepath);
+                       }
+               } else {
+                       DBG("g_mgr->ftemp_st.fhandle is not valid, return");
+               }
+               break;
+
+       case PTP_EVENTCODE_DEVICERESET:
+               DBG("Implement later, PTP_EVENTCODE_DEVICERESET");
+               _device_set_phase(DEVICE_PHASE_IDLE);
+               /* do close session, just skip save reference
+                * mtp_save_object_references_mtp_device(MtpHandler.pDevice);
+                */
+               g_mgr->hdlr.session_id = 0;
+               _transport_set_control_event(0);
+               _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
+               break;
+
+       default:
+               break;
+       }
+#endif/* MTP_SUPPORT_CONTROL_REQUEST */
+
+       /* main processing */
+       if (_device_get_phase() == DEVICE_PHASE_IDLE) {
+               if (_hdlr_validate_cmd_container((mtp_uchar *)buffer, buf_len)
+                               == FALSE) {
+                       _device_set_phase(DEVICE_PHASE_NOTREADY);
+                       ERR("MTP device phase NOT READY, invalid Command block");
+                       return;
+               }
+
+               _transport_save_cmd_buffer(buffer, buf_len);
+               _hdlr_copy_cmd_container_unknown_params((cmd_container_t *)buffer,
+                               &cmd);
+#ifdef __BIG_ENDIAN__
+               _hdlr_conv_cmd_container_byte_order(&cmd);
+#endif /* __BIG_ENDIAN__ */
+
+               UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
+               __process_commands(&g_mtp_mgr.hdlr, &cmd);
+               UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
+       } else if (_device_get_phase() == DEVICE_PHASE_DATAOUT) {
+               if (g_mgr->ftemp_st.data_count == 0)
+                       __receive_temp_file_first_packet(buffer, buf_len);
+               else
+                       __receive_temp_file_next_packets(buffer, buf_len);
+               return;
+       } else {
+               /* ignore other case */
+               ERR("MTP device phase[%d], unknown device PHASE\n",
+                               _device_get_phase());
+               ERR("PhaseUnknown-> pData[0x%x], length=[%d]", buffer, buf_len);
+               _device_set_phase(DEVICE_PHASE_IDLE);
+               _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
+       }
+       return;
+}
+
+static mtp_bool __receive_temp_file_first_packet(mtp_char *data,
+               mtp_int32 data_len)
+{
+       mtp_char *filepath = g_mgr->ftemp_st.filepath;
+       mtp_uint32 *fhandle = &g_mgr->ftemp_st.fhandle;
+       mtp_int32 error = 0;
+       mtp_uint32 *data_sz = &g_mgr->ftemp_st.data_size;
+       mtp_char *buffer = g_mgr->ftemp_st.temp_buff;
+
+       _transport_set_mtp_operation_state(MTP_STATE_DATA_TRANSFER_DL);
+       if (access(filepath, F_OK) == 0) {
+               if (*fhandle != INVALID_FILE) {
+                       _util_file_close(*fhandle);
+                       *fhandle = INVALID_FILE;        /* initialize */
+               }
+
+               if (remove(filepath) < 0) {
+                       ERR_SECURE("remove(%s) Fail", filepath);
+                       __finish_receiving_file_packets(data, data_len);
+                       return FALSE;
+               }
+       }
+
+       *fhandle = _util_file_open(filepath, MTP_FILE_WRITE, &error);
+       if (*fhandle == INVALID_FILE) {
+               ERR("First file handle is invalid!!");
+               __finish_receiving_file_packets(data, data_len);
+               return FALSE;
+       }
+       /* consider header size */
+       memcpy(&g_mgr->ftemp_st.header_buf, data, sizeof(header_container_t));
+
+       g_mgr->ftemp_st.file_size = ((header_container_t *)data)->len -
+               sizeof(header_container_t);
+       *data_sz = data_len - sizeof(header_container_t);
+
+       /* check whether last data packet */
+       if (*data_sz == g_mgr->ftemp_st.file_size) {
+               if (_util_file_write(*fhandle, &data[sizeof(header_container_t)],
+                                       data_len - sizeof(header_container_t)) !=
+                               data_len - sizeof(header_container_t)) {
+                       ERR("fwrite error!");
+               }
+               *data_sz = 0;
+               _util_file_close(*fhandle);
+               *fhandle = INVALID_FILE;        /* initialize */
+               __finish_receiving_file_packets(data, data_len);
+       } else {
+               g_mgr->ftemp_st.data_count++;
+               g_mgr->ftemp_st.size_remaining = *data_sz;
+
+               memcpy(buffer, data + sizeof(header_container_t), *data_sz);
+       }
+       return TRUE;
+}
+
+static mtp_bool __receive_temp_file_next_packets(mtp_char *data,
+               mtp_int32 data_len)
+{
+       mtp_uint32 rx_size = _get_rx_pkt_size();
+       mtp_uint32 *data_sz = &g_mgr->ftemp_st.data_size;
+       mtp_char *buffer = g_mgr->ftemp_st.temp_buff;
+       mtp_uint32 *fhandle = &g_mgr->ftemp_st.fhandle;
+
+       g_mgr->ftemp_st.data_count++;
+       g_mgr->ftemp_st.size_remaining += data_len;
+
+       if ((*data_sz + (mtp_uint32)data_len) > g_conf.write_file_size) {
+               /* copy oversized packet to temp file */
+               if (_util_file_write(*fhandle, buffer, *data_sz) != *data_sz)
+                       ERR("fwrite error writeSize=[%u]\n", *data_sz);
+
+               *data_sz = 0;
+       }
+
+       memcpy(&buffer[*data_sz], data, data_len);
+       *data_sz += data_len;
+
+       /*Complete file is recieved, so close the file*/
+       if (data_len < rx_size ||
+                       g_mgr->ftemp_st.size_remaining == g_mgr->ftemp_st.file_size) {
+
+               if (_util_file_write(*fhandle, buffer, *data_sz) != *data_sz) {
+                       ERR("fwrite error write size=[%u]\n", *data_sz);
+               }
+               *data_sz = 0;
+               _util_file_close(*fhandle);
+               *fhandle = INVALID_FILE;        /* initialize */
+               __finish_receiving_file_packets(data, data_len);
+       }
+       return TRUE;
+}
+
+static void __finish_receiving_file_packets(mtp_char *data, mtp_int32 data_len)
+{
+       cmd_blk_t cmd = { 0 };
+       mtp_uchar *cmd_buf = NULL;
+
+       g_mgr->ftemp_st.data_count = 0;
+       cmd_buf = (mtp_uchar *)data;
+
+       if (!_hdlr_validate_cmd_container(cmd_buf, (mtp_uint32)data_len)) {
+               cmd_buf = (mtp_uchar *)g_mgr->ftemp_st.cmd_buf;
+               if (!_hdlr_validate_cmd_container(cmd_buf,
+                                       g_mgr->ftemp_st.cmd_size)) {
+                       _device_set_phase(DEVICE_PHASE_IDLE);
+                       ERR("DATA PROCESS, device phase[%d], invalid Command\
+                                       block\n", _device_get_phase());
+                       return;
+               }
+       }
+
+       _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
+       _hdlr_copy_cmd_container_unknown_params((cmd_container_t *)cmd_buf,
+                       &cmd);
+
+#ifdef __BIG_ENDIAN__
+       _hdlr_conv_cmd_container_byte_order(&cmd);
+#endif /* __BIG_ENDIAN__ */
+
+       UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
+       __process_commands(&g_mtp_mgr.hdlr, &cmd);
+       UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
+
+       DBG("MTP device phase[%d], processing Command is complete\n",
+                       _device_get_phase());
+
+       return;
+}
diff --git a/src/mtp_cmd_handler_util.c b/src/mtp_cmd_handler_util.c
new file mode 100755 (executable)
index 0000000..5b1b7c5
--- /dev/null
@@ -0,0 +1,2418 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <unistd.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include "mtp_cmd_handler.h"
+#include "mtp_cmd_handler_util.h"
+#include "mtp_support.h"
+#include "mtp_media_info.h"
+#include "mtp_transport.h"
+
+/*
+ * GLOBAL AND EXTERN VARIABLES
+ */
+mtp_bool g_is_full_enum = FALSE;
+extern mtp_mgr_t g_mtp_mgr;
+extern obj_interdep_proplist_t interdep_proplist;
+extern mtp_char g_last_created_dir[MTP_MAX_PATHNAME_SIZE + 1];
+extern mtp_char g_last_moved[MTP_MAX_PATHNAME_SIZE + 1];
+extern mtp_char g_last_copied[MTP_MAX_PATHNAME_SIZE + 1];
+extern mtp_char g_last_deleted[MTP_MAX_PATHNAME_SIZE + 1];
+
+/*
+ * STATIC VARIABLES
+ */
+static mtp_mgr_t *g_mgr = &g_mtp_mgr;
+
+/*
+ * FUNCTIONS
+ */
+
+/*
+ * This function gets the storage entry.
+ * @param[in]  store_id        Specifies the storage id to get.
+ * @param[in]  info            Points the storage info structure
+ * @return     This function returns MTP_ERROR_NONE on success or
+ *             ERROR_No on failure.
+ */
+mtp_err_t _hutil_get_storage_entry(mtp_uint32 store_id, store_info_t *info)
+{
+       mtp_store_t *store = NULL;
+
+       store = _device_get_store(store_id);
+       if (store == NULL) {
+               ERR("Not able to retrieve store");
+               return MTP_ERROR_GENERAL;
+       }
+       _entity_update_store_info_run_time(&(store->store_info),
+                       store->root_path);
+
+       _prop_copy_ptpstring(&(info->store_desc), &(store->store_info.store_desc));
+       _prop_copy_ptpstring(&(info->vol_label), &(store->store_info.vol_label));
+       info->access = store->store_info.access;
+       info->fs_type = store->store_info.fs_type;
+       info->free_space = store->store_info.free_space;
+       info->capacity = store->store_info.capacity;
+       info->store_type = store->store_info.store_type;
+       info->free_space_in_objs = store->store_info.free_space_in_objs;
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_get_storage_ids(ptp_array_t *store_ids)
+{
+       mtp_uint32 num_elem = 0;
+       mtp_uint32 num_stores = 0;
+
+       num_elem = _device_get_store_ids(store_ids);
+       num_stores = _device_get_num_stores();
+       if (num_elem == num_stores) {
+               return MTP_ERROR_NONE;
+       }
+
+       ERR("get storage id Fail. num_elem[%d], num_stores[%d]\n",
+                       num_elem, num_stores);
+       return MTP_ERROR_GENERAL;
+}
+
+/*
+ * This function gets the device property.
+ * @param[in]  prop_id         Specifies the property id to retrieve
+ * @param[in]  dev_prop        Points the device prop structure
+ * @return     This function returns MTP_ERROR_NONE on success,
+ *             or ERROR_NO on failure.
+ */
+mtp_err_t _hutil_get_device_property(mtp_uint32 prop_id,
+               device_prop_desc_t* dev_prop)
+{
+       device_prop_desc_t *prop = NULL;
+
+       prop = _device_get_device_property(prop_id);
+       if (prop == NULL)
+               return MTP_ERROR_GENERAL;
+
+       memcpy(dev_prop, prop, sizeof(device_prop_desc_t));
+       return MTP_ERROR_NONE;
+}
+
+/*
+ * This function sets the device property.
+ * @param[in]  prop_id         Specifies the property id to retrieve.
+ * @param[in]  data            Points the associated data buffer.
+ * @param[in]  data_sz         Specifies the data size of property.
+ * @return     This function returns MTP_ERROR_NONE on success or
+ *             appropriate error on failure.
+ */
+mtp_err_t _hutil_set_device_property(mtp_uint32 prop_id, void *data,
+               mtp_uint32 data_sz)
+{
+       device_prop_desc_t *prop = NULL;
+
+       prop = _device_get_device_property(prop_id);
+       if (prop == NULL)
+               return MTP_ERROR_GENERAL;
+
+       if (prop->propinfo.get_set == PTP_PROPGETSET_GETONLY)
+               return MTP_ERROR_ACCESS_DENIED;
+
+       if (FALSE == _prop_set_current_device_prop(prop, data, data_sz))
+               return MTP_ERROR_INVALID_OBJ_PROP_VALUE;
+
+       return MTP_ERROR_NONE;
+}
+
+/*
+ * This function resets the device property.
+ * @param[in]  prop_id         Specifies the property id to retrieve.
+ * @return     This function returns MTP_ERROR_NONE on success,
+ *             appropriate error on failure.
+ */
+mtp_err_t _hutil_reset_device_entry(mtp_uint32 prop_id)
+{
+       device_prop_desc_t *prop = NULL;
+       mtp_uint16 ii = 0;
+
+       if (prop_id == 0xFFFFFFFF) {
+
+               prop = _device_get_ref_prop_list();
+               if (prop == NULL) {
+                       ERR("property reference is NULL");
+                       return MTP_ERROR_GENERAL;
+               }
+               for (ii = 0; ii < NUM_DEVICE_PROPERTIES; ii++) {
+                       _prop_reset_device_prop_desc(&prop[ii]);
+               }
+       } else {
+               prop = _device_get_device_property(prop_id);
+               if (prop == NULL)
+                       return MTP_ERROR_GENERAL;
+
+               _prop_reset_device_prop_desc(prop);
+       }
+
+       return MTP_ERROR_NONE;
+}
+
+/*
+ * This function adds the object entry.
+ * @param[in]  obj_info        Points the objectinfo.
+ * @param[in]  file_name       Points the file name of the object.
+ * @param[out] new_obj         Points to the new object added.
+ * @return     This function returns MTP_ERROR_NONE on success or
+ *             appropriate error on failure.
+ */
+mtp_err_t _hutil_add_object_entry(obj_info_t *obj_info, mtp_char *file_name,
+               mtp_obj_t **new_obj)
+{
+       mtp_obj_t *obj = NULL;
+       mtp_obj_t *par_obj = NULL;
+       mtp_store_t *store = NULL;
+       mtp_wchar temp_wfname[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char utf8_temp[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char new_f_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_int32 i = 0;
+       mtp_int32 error;
+       mtp_bool is_made_by_mtp = FALSE;
+       mtp_wchar w_file_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
+
+       if (obj_info->h_parent != PTP_OBJECTHANDLE_ROOT) {
+               par_obj = _device_get_object_with_handle(obj_info->h_parent);
+               if (par_obj == NULL) {
+                       ERR("parent is not existed.");
+                       _entity_dealloc_obj_info(obj_info);
+                       return MTP_ERROR_INVALID_OBJECTHANDLE;
+               }
+
+               if (par_obj->obj_info->obj_fmt != PTP_FMT_ASSOCIATION) {
+                       ERR("parent handle is not association format[0x%x]\
+                                       handle[%d]\n", par_obj->obj_info->obj_fmt,
+                                       par_obj->obj_info->h_parent);
+                       _entity_dealloc_obj_info(obj_info);
+                       return MTP_ERROR_INVALID_PARENT;
+               }
+       }
+
+       store = _device_get_store(obj_info->store_id);
+       if (store == NULL) {
+               ERR("store is null");
+               _entity_dealloc_obj_info(obj_info);
+               return MTP_ERROR_GENERAL;
+       }
+
+       if (store->store_info.free_space < obj_info->file_size) {
+               ERR("free space is not enough [%ld] bytes, object size[%ld]\n",
+                               store->store_info.free_space, obj_info->file_size);
+               _entity_dealloc_obj_info(obj_info);
+               return MTP_ERROR_STORE_FULL;
+       }
+
+       obj = _entity_alloc_mtp_object();
+       if (obj == NULL) {
+               ERR("allocation memory Fail");
+               _entity_dealloc_obj_info(obj_info);
+               return MTP_ERROR_GENERAL;
+       }
+
+       memset(obj, 0, sizeof(mtp_obj_t));
+       obj->child_array.type = UINT32_TYPE;
+       obj->obj_handle = _entity_generate_next_obj_handle();
+       obj->obj_info = obj_info;
+
+       /* For PC->MMC read-only file/folder transfer
+        * and for PC->Phone read-only folder transfer
+        * store PTP_PROTECTIONSTATUS_NOPROTECTION in
+        * the field obj_info->ProtectionStatus
+        */
+       if (MTP_EXTERNAL_STORE_ID == obj_info->store_id ||
+                       obj_info->obj_fmt == PTP_FMT_ASSOCIATION) {
+               obj_info->protcn_status = PTP_PROTECTIONSTATUS_NOPROTECTION;
+       }
+
+       if (strlen(file_name) == 0) {
+               /* Generate a filename in 8.3 format for this object */
+               g_snprintf(utf8_temp, MTP_MAX_PATHNAME_SIZE + 1,
+                               "Tmp_%04u.dat", obj->obj_handle);
+               _util_utf8_to_utf16(temp_wfname,
+                               sizeof(temp_wfname) / WCHAR_SIZ, utf8_temp);
+       } else {
+               _util_utf8_to_utf16(temp_wfname,
+                               sizeof(temp_wfname) / WCHAR_SIZ, file_name);
+       }
+
+       /* Does this path/filename already exist ? */
+       for (i = 0; ; i++) {
+               mtp_bool file_exist = FALSE;
+               mtp_uint32 path_len = 0;
+
+               /* Get/Generate the Full Path for the new Object; */
+               if (obj_info->h_parent == PTP_OBJECTHANDLE_ROOT) {
+                       _util_utf16_to_utf8(utf8_temp, sizeof(utf8_temp),
+                                       temp_wfname);
+
+                       if (_util_create_path(new_f_path, sizeof(new_f_path),
+                                               store->root_path, utf8_temp) == FALSE) {
+                               _entity_dealloc_mtp_obj(obj);
+                               return MTP_ERROR_GENERAL;
+                       }
+#ifdef MTP_SUPPORT_HIDE_WMPINFO_XML
+                       /* WMPInfo.xml and DevLogo.fil.*/
+                       /* find WMPInfo.xml and add file mtp store */
+                       {
+                               mtp_char wmp_info_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+                               mtp_char wmp_hidden_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+                               if (obj_info->store_id == MTP_INTERNAL_STORE_ID) {
+                                       g_snprintf(wmp_hidden_path,
+                                                       MTP_MAX_PATHNAME_SIZE + 1,
+                                                       "%s/%s/%s", MTP_USER_DIRECTORY,
+                                                       MTP_HIDDEN_PHONE,
+                                                       MTP_FILE_NAME_WMPINFO_XML);
+                                       g_snprintf(wmp_info_path,
+                                                       MTP_MAX_PATHNAME_SIZE + 1,
+                                                       "%s/%s", MTP_STORE_PATH_CHAR,
+                                                       MTP_FILE_NAME_WMPINFO_XML);
+                               } else {
+                                       g_snprintf(wmp_hidden_path,
+                                                       MTP_MAX_PATHNAME_SIZE + 1,
+                                                       "%s/%s/%s", MTP_USER_DIRECTORY,
+                                                       MTP_HIDDEN_CARD,
+                                                       MTP_FILE_NAME_WMPINFO_XML);
+                                       g_snprintf(wmp_info_path,
+                                                       MTP_MAX_PATHNAME_SIZE + 1,
+                                                       "%s/%s", MTP_EXTERNAL_PATH_CHAR,
+                                                       MTP_FILE_NAME_WMPINFO_XML);
+                               }
+
+                               if (!strcasecmp(wmp_info_path, new_f_path)) {
+                                       DBG("substitute file[%s]-->[%s]\n",
+                                                       wmp_info_path, wmp_hidden_path);
+
+                                       g_strlcpy(new_f_path, wmp_hidden_path,
+                                                       sizeof(new_f_path));
+
+                                       if (obj_info->store_id ==
+                                                       MTP_INTERNAL_STORE_ID) {
+                                               obj->obj_handle =
+                                                       MTP_MAX_INT_OBJECT_NUM -
+                                                       MTPSTORE_WMPINFO_PHONE;
+                                       } else {
+                                               obj->obj_handle =
+                                                       MTP_MAX_INT_OBJECT_NUM -
+                                                       MTPSTORE_WMPINFO_CARD;
+                                       }
+                               }
+                       }
+#endif /*MTP_SUPPORT_HIDE_WMPINFO_XML*/
+               } else {
+                       _util_utf16_to_utf8(utf8_temp, sizeof(utf8_temp),
+                                       temp_wfname);
+                       if (_util_create_path(new_f_path, sizeof(new_f_path),
+                                               par_obj->file_path, utf8_temp) == FALSE) {
+                               _entity_dealloc_mtp_obj(obj);
+                               return MTP_ERROR_GENERAL;
+                       }
+               }
+
+               /*
+                * g_mgr->ftemp_st.filepath was allocated g_strdup("/tmp/.mtptemp.tmp");
+                * So if we need to change the path we need to allocate sufficient memory
+                * otherwise memory corruption may happen
+                */
+
+               path_len = strlen(store->root_path) + strlen(MTP_TEMP_FILE) + 2;
+               g_mgr->ftemp_st.filepath = g_realloc(g_mgr->ftemp_st.filepath, path_len);
+               if (g_mgr->ftemp_st.filepath == NULL) {
+                       ERR("g_realloc Fail");
+                       _entity_dealloc_mtp_obj(obj);
+                       return MTP_ERROR_GENERAL;
+               }
+
+               if (_util_create_path(g_mgr->ftemp_st.filepath, path_len,
+                                       store->root_path, MTP_TEMP_FILE) == FALSE) {
+                       ERR("Tempfile fullPath is too long");
+                       _entity_dealloc_mtp_obj(obj);
+                       return MTP_ERROR_GENERAL;
+               }
+
+               DBG_SECURE("Temp file path [%s]\n", g_mgr->ftemp_st.filepath);
+
+
+#ifdef MTP_SUPPORT_ALBUM_ART
+               if (access(new_f_path, F_OK) == 0) {
+                       file_exist = TRUE;
+                       /* if file is album, overwrite it. */
+                       mtp_char alb_buf[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+                       mtp_char alb_ext[MTP_MAX_PATHNAME_SIZE + 1] =   { 0 };
+
+                       /* find extension, if album or pla, overwrite that. */
+                       _util_utf16_to_utf8(alb_buf, sizeof(alb_buf), temp_wfname);
+
+                       if (obj_info->obj_fmt != PTP_FMT_ASSOCIATION ||
+                                       (obj_info->obj_fmt == PTP_FMT_ASSOCIATION &&
+                                        obj_info->association_type !=
+                                        PTP_ASSOCIATIONTYPE_UNDEFINED &&
+                                        obj_info->association_type !=
+                                        PTP_ASSOCIATIONTYPE_FOLDER)) {
+
+                               _util_get_file_extn(alb_buf, alb_ext);
+                               if (!strcasecmp(alb_ext, "alb")) {
+                                       if (remove(new_f_path) == 0) {
+                                               file_exist = FALSE;
+                                               DBG("[%s] file is found. Delete\
+                                                               old and make new one\n",
+                                                               alb_ext);
+                                       } else
+                                               ERR("[%s] file is found. but \
+                                                               cannot delete it\n",
+                                                               alb_ext);
+                               }
+                       }
+               }
+#endif /*MTP_SUPPORT_ALBUM_ART*/
+
+               if (file_exist == FALSE) {
+                       DBG_SECURE("Found a unique file name for the incoming object\
+                                       [%s]\n", temp_wfname);
+                       break;
+               }
+
+#ifdef MTP_USE_SELFMAKE_ABSTRACTION
+               is_made_by_mtp = obj_info->file_size == 0 &&
+                       obj_info->obj_fmt > MTP_FMT_UNDEFINED_COLLECTION &&
+                       obj_info->obj_fmt < MTP_FMT_UNDEFINED_DOC;
+#endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
+               if (obj_info->obj_fmt == PTP_FMT_ASSOCIATION ||
+                               is_made_by_mtp) {
+                       *new_obj = _device_get_object_with_path(new_f_path);
+                       if (*new_obj) {
+                               _entity_dealloc_mtp_obj(obj);
+                               return MTP_ERROR_NONE;
+                       } else {
+                               DBG("+ not found object. [%s]\n", new_f_path);
+                               break;
+                       }
+               }
+
+               /* Rename the Filename for this object */
+               memset(temp_wfname, 0, (MTP_MAX_PATHNAME_SIZE + 1) * 2);
+               _util_utf8_to_utf16(w_file_name, sizeof(w_file_name) / WCHAR_SIZ,
+                               file_name);
+               _util_wchar_swprintf(temp_wfname,
+                               MTP_MAX_PATHNAME_SIZE + 1, "COPY%d_%s", i, w_file_name);
+       }
+
+       /* Save the full path to this object */
+       _entity_set_object_file_path(obj, new_f_path, CHAR_TYPE);
+
+       /*
+        * Is this an association (or folder)?
+        * Associations are fully qualified by the ObjectInfo Dataset.
+        */
+#ifdef MTP_USE_SELFMAKE_ABSTRACTION
+       is_made_by_mtp = (obj_info->file_size == 0 &&
+                       obj_info->obj_fmt > MTP_FMT_UNDEFINED_COLLECTION &&
+                       obj_info->obj_fmt < MTP_FMT_UNDEFINED_DOC);
+#endif /*MTP_USE_SELFMAKE_ABSTRACTION*/
+
+       if (obj_info->obj_fmt == PTP_FMT_ASSOCIATION || is_made_by_mtp) {
+               /* Create the new object */
+               DBG("[normal] create association file/folder[%s][0x%x]\n",
+                               new_f_path, obj_info->association_type);
+
+               if ((obj_info->association_type !=
+                                       PTP_ASSOCIATIONTYPE_UNDEFINED &&
+                                       obj_info->association_type !=
+                                       PTP_ASSOCIATIONTYPE_FOLDER) ||
+                               is_made_by_mtp) {
+                       mtp_uint32 h_abs_file = INVALID_FILE;
+                       h_abs_file = _util_file_open(new_f_path,
+                                       MTP_FILE_WRITE, &error);
+                       if (h_abs_file == INVALID_FILE) {
+                               ERR("create file fail!!");
+                               _entity_dealloc_mtp_obj(obj);
+                               return MTP_ERROR_GENERAL;
+                       }
+                       _util_file_close(h_abs_file);
+               } else {
+                       g_snprintf(g_last_created_dir,
+                                       MTP_MAX_PATHNAME_SIZE + 1, "%s", new_f_path);
+                       if (_util_dir_create(new_f_path, &error) == FALSE) {
+                               /* We failed to create the folder */
+                               ERR("create directory Fail");
+                               memset(g_last_created_dir, 0,
+                                               sizeof(g_last_created_dir));
+                               _entity_dealloc_mtp_obj(obj);
+                               return MTP_ERROR_GENERAL;
+                       }
+               }
+
+               _entity_set_object_file_path(obj, new_f_path, CHAR_TYPE);
+               if (_entity_add_object_to_store(store, obj) == FALSE) {
+                       ERR("_entity_add_object_to_store Fail");
+                       _entity_dealloc_mtp_obj(obj);
+                       return MTP_ERROR_STORE_FULL;
+               }
+       } else {
+               /* Reserve space for the object: Object itself, and probably
+                * some Filesystem-specific overhead
+                */
+               store->store_info.free_space -= obj_info->file_size;
+       }
+
+       *new_obj = obj;
+
+       return MTP_ERROR_NONE;
+}
+
+/*
+ * This function removes the object entry.
+ * @param[in]  obj_handle      Specifies the object to remove.
+ * @param[in]  format          Specifies the format code.
+ * @return     This function returns MTP_ERROR_NONE on success or
+ *             appropriate error on failure.
+ */
+mtp_err_t _hutil_remove_object_entry(mtp_uint32 obj_handle, mtp_uint32 format)
+{
+       mtp_err_t resp = MTP_ERROR_GENERAL;
+       mtp_uint16 ret = 0;
+
+#ifdef MTP_SUPPORT_SET_PROTECTION
+       /* this will check to see if the protection is set */
+       mtp_obj_t *obj = NULL;
+       if (obj_handle != 0xFFFFFFFF) {
+               obj = _device_get_object_with_handle(obj_handle);
+               if (obj != NULL) {
+                       if ((obj->obj_info->protcn_status ==
+                                               MTP_PROTECTIONSTATUS_READONLY_DATA) ||
+                                       (obj->obj_info->protcn_status ==
+                                        PTP_PROTECTIONSTATUS_READONLY)) {
+                               ERR("Protection status is [0x%x]\n",
+                                               obj->obj_info->protcn_status);
+                               return MTP_ERROR_OBJECT_WRITE_PROTECTED;
+                       }
+               }
+       }
+#endif /*MTP_SUPPORT_SET_PROTECTION*/
+
+       ret = _device_delete_object(obj_handle, format);
+       switch (ret) {
+       case PTP_RESPONSE_OK:
+               resp = MTP_ERROR_NONE;
+               break;
+       case PTP_RESPONSE_STORE_READONLY:
+               resp = MTP_ERROR_STORE_READ_ONLY;
+               break;
+       case PTP_RESPONSE_PARTIAL_DELETION:
+               resp = MTP_ERROR_PARTIAL_DELETION;
+               break;
+       case PTP_RESPONSE_OBJ_WRITEPROTECTED:
+               resp = MTP_ERROR_OBJECT_WRITE_PROTECTED;
+               break;
+       case PTP_RESPONSE_ACCESSDENIED:
+               resp = MTP_ERROR_ACCESS_DENIED;
+               break;
+       case PTP_RESPONSE_INVALID_OBJ_HANDLE:
+               resp =MTP_ERROR_INVALID_OBJECTHANDLE;
+               break;
+       default:
+               break;
+       }
+
+       return resp;
+}
+
+/*
+ * This function gets the object entry.
+ * @param[in]  obj_handle      Specifies the object to get.
+ * @param[out] obj_ptr         Points to object found.
+ * @return     This function returns MTP_ERROR_NONE on success
+ *             or appropriate error on failure.
+ */
+mtp_err_t _hutil_get_object_entry(mtp_uint32 obj_handle, mtp_obj_t **obj_ptr)
+{
+       mtp_obj_t *obj = NULL;
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (NULL == obj || NULL == obj->obj_info) {
+               return MTP_ERROR_GENERAL;
+       }
+
+       *obj_ptr = obj;
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_copy_object_entries(mtp_uint32 dst_store_id,
+               mtp_uint32 src_store_id, mtp_uint32 h_parent, mtp_uint32 obj_handle,
+               mtp_uint32 *new_hobj, mtp_bool keep_handle)
+{
+       mtp_store_t *dst = NULL;
+       mtp_store_t *src = NULL;
+       mtp_obj_t *obj = NULL;
+       mtp_obj_t *par_obj = NULL;
+       mtp_obj_t *new_obj = NULL;
+       mtp_int32 error = 0;
+       mtp_char fpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char utf8_temp[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_err_t ret = MTP_ERROR_NONE;
+       mtp_uint32 num_of_deleted_file = 0;
+       mtp_uint32 num_of_file = 0;
+       ptp_array_t child_arr = { 0 };
+       mtp_obj_t *child_obj = NULL;
+       mtp_uint32 ii = 0;
+
+       src = _device_get_store(src_store_id);
+       dst = _device_get_store(dst_store_id);
+       obj = _device_get_object_with_handle(obj_handle);
+
+       if ((src == NULL) || (dst == NULL) || (obj == NULL)) {
+               ERR("NULL!!");
+               return MTP_ERROR_GENERAL;
+       }
+
+       if (h_parent > 0)       {
+               if (keep_handle) {
+                       /* two sam handle can occurs in folder copy case
+                        * (find last appended object in target storage)
+                        */
+                       par_obj = _entity_get_last_object_from_store(dst,
+                                       h_parent);
+               } else
+                       par_obj = _device_get_object_with_handle(h_parent);
+       } else {
+               par_obj = NULL;
+       }
+
+       _util_get_file_name(obj->file_path, utf8_temp);
+
+       if (par_obj == NULL) {
+               /* Parent is the root of this store */
+               if (_util_create_path(fpath, sizeof(fpath), dst->root_path,
+                                       utf8_temp) == FALSE) {
+                       ERR("new path is too LONG");
+                       return MTP_ERROR_GENERAL;
+               }
+       } else {
+               if (_util_create_path(fpath, sizeof(fpath), par_obj->file_path,
+                                       utf8_temp) == FALSE) {
+                       ERR("New path is too LONG!!");
+                       return MTP_ERROR_GENERAL;
+               }
+       }
+
+       if (!strcasecmp(fpath, obj->file_path)) {
+               ERR("Identical path of source and destination[%s]\n", fpath);
+               return MTP_ERROR_GENERAL;
+       }
+
+       new_obj = _entity_alloc_mtp_object();
+       if (new_obj == NULL) {
+               ERR("_entity_alloc_mtp_object Fail");
+               return MTP_ERROR_GENERAL;
+       }
+
+       memset(new_obj, 0, sizeof(mtp_obj_t));
+       new_obj->child_array.type = UINT32_TYPE;
+
+       _entity_copy_mtp_object(new_obj, obj);
+       if (new_obj->obj_info == NULL) {
+               _entity_dealloc_mtp_obj(new_obj);
+               return MTP_ERROR_GENERAL;
+       }
+
+       new_obj->obj_info->store_id = dst_store_id;
+       _entity_set_object_file_path(new_obj, fpath, CHAR_TYPE);
+
+       if (MTP_EXTERNAL_STORE_ID == new_obj->obj_info->store_id) {
+               new_obj->obj_info->protcn_status =
+                       PTP_PROTECTIONSTATUS_NOPROTECTION;
+       }
+
+       new_obj->obj_handle = (keep_handle) ? obj->obj_handle :
+               _entity_generate_next_obj_handle();
+       new_obj->obj_info->h_parent = (par_obj == NULL) ? PTP_OBJECTHANDLE_ROOT :
+               par_obj->obj_handle;
+
+       if (new_obj->obj_info->obj_fmt != PTP_FMT_ASSOCIATION) {
+               DBG("Non-association type!!");
+               g_snprintf(g_last_copied, MTP_MAX_PATHNAME_SIZE + 1, "%s",
+                               new_obj->file_path);
+               if (_util_file_copy(obj->file_path, new_obj->file_path,
+                                       &error) == FALSE) {
+                       memset(g_last_copied, 0, MTP_MAX_PATHNAME_SIZE + 1);
+                       ERR("Copy file Fail");
+                       _entity_dealloc_mtp_obj(new_obj);
+                       if (EACCES == error)
+                               return MTP_ERROR_ACCESS_DENIED;
+                       else if (ENOSPC == error)
+                               return MTP_ERROR_STORE_FULL;
+                       return MTP_ERROR_GENERAL;
+
+               }
+#ifdef MTP_SUPPORT_SET_PROTECTION
+               file_attr_t attr = { 0 };
+               attr.attribute = MTP_FILE_ATTR_MODE_REG;
+               if (PTP_PROTECTIONSTATUS_READONLY ==
+                               new_obj->obj_info->protcn_status) {
+                       if (FALSE == _util_set_file_attrs(new_obj->file_path,
+                                               attr.attribute | MTP_FILE_ATTR_MODE_READ_ONLY))
+                               return MTP_ERROR_GENERAL;
+               }
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+
+               /* Update the storeinfo after successfully copy of the object */
+               dst->store_info.free_space -= obj->obj_info->file_size;
+
+               /* move case */
+               if (keep_handle) {
+                       _entity_add_object_to_store(dst, new_obj);
+                       /* Reference Copy */
+                       _prop_copy_ptparray(&(new_obj->child_array),
+                                       &(obj->child_array));
+               } else {
+                       _entity_add_object_to_store(dst, new_obj);
+               }
+
+               *new_hobj = new_obj->obj_handle;
+               return MTP_ERROR_NONE;
+       }
+
+       DBG("Association type!!");
+       if (access(new_obj->file_path, F_OK) == 0) {
+               if (TRUE == keep_handle) {
+                       /*generate unique_path*/
+                       mtp_char unique_fpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+                       if (FALSE == _util_get_unique_dir_path(new_obj->file_path,
+                                               unique_fpath, sizeof(unique_fpath))) {
+                               _entity_dealloc_mtp_obj(new_obj);
+                               return MTP_ERROR_GENERAL;
+                       }
+                       _entity_set_object_file_path(new_obj, unique_fpath, CHAR_TYPE);
+                       g_snprintf(g_last_created_dir, MTP_MAX_PATHNAME_SIZE + 1,
+                                       "%s", new_obj->file_path);
+                       if (_util_dir_create(new_obj->file_path, &error) == FALSE) {
+                               memset(g_last_created_dir, 0,
+                                               MTP_MAX_PATHNAME_SIZE + 1);
+                               ERR("Creating folder Fail!!");
+                               _entity_dealloc_mtp_obj(new_obj);
+                               if (ENOSPC == error)
+                                       return MTP_ERROR_STORE_FULL;
+                               return MTP_ERROR_GENERAL;
+                       }
+
+                       /* Add the new object to this store's object list */
+                       _entity_add_object_to_store(dst, new_obj);
+               } else {
+                       DBG("Already existed association type!!");
+                       _entity_dealloc_mtp_obj(new_obj);
+                       new_obj = _entity_get_object_from_store_by_path(dst, fpath);
+                       if (!new_obj) {
+                               ERR("But object is not registered!!");
+                               return MTP_ERROR_GENERAL;
+                       }
+               }
+       } else {
+               g_snprintf(g_last_created_dir, MTP_MAX_PATHNAME_SIZE + 1,
+                               "%s", new_obj->file_path);
+               if (_util_dir_create(new_obj->file_path, &error) == FALSE) {
+                       memset(g_last_created_dir, 0,
+                                       MTP_MAX_PATHNAME_SIZE + 1);
+                       ERR("Creating folder Fail!!");
+                       _entity_dealloc_mtp_obj(new_obj);
+                       if (ENOSPC == error)
+                               return MTP_ERROR_STORE_FULL;
+                       return MTP_ERROR_GENERAL;
+               }
+
+               /* Add the new object to this store's object list */
+               _entity_add_object_to_store(dst, new_obj);
+       }
+
+       /* Child addition to data structures is not required in Copy
+        * case as on demand enumeration is supported
+        */
+       if (FALSE == keep_handle) {
+               if (FALSE == _util_copy_dir_children_recursive(obj->file_path,
+                                       new_obj->file_path, &error)) {
+                       ERR_SECURE("Recursive copy Fail  [%s]->[%s]",
+                                       obj->file_path, new_obj->file_path);
+                       ret = MTP_ERROR_GENERAL;
+                       if (EACCES == error)
+                               ret = MTP_ERROR_ACCESS_DENIED;
+                       else if (ENOSPC == error)
+                               ret = MTP_ERROR_STORE_FULL;
+                       if (_util_remove_dir_children_recursive(new_obj->file_path,
+                                               &num_of_deleted_file, &num_of_file,
+                                               FALSE) == MTP_ERROR_NONE) {
+                               g_snprintf(g_last_deleted,
+                                               MTP_MAX_PATHNAME_SIZE + 1,
+                                               "%s", new_obj->file_path);
+                               if (rmdir(new_obj->file_path) < 0) {
+                                       memset(g_last_deleted, 0,
+                                                       MTP_MAX_PATHNAME_SIZE + 1);
+                               }
+                       }
+                       return ret;
+               }
+
+               *new_hobj = new_obj->obj_handle;
+
+               return MTP_ERROR_NONE;
+       }
+
+
+       /* Since this is an association, copy its children as well*/
+       _prop_init_ptparray(&child_arr, UINT32_TYPE);
+       _entity_get_child_handles(src, obj->obj_handle, &child_arr);
+
+       for (ii = 0; ii < child_arr.num_ele; ii++)      {
+               mtp_uint32 *ptr32 = child_arr.array_entry;
+
+               child_obj = _entity_get_object_from_store(src, ptr32[ii]);
+               if (child_obj == NULL) {
+                       continue;
+               }
+
+               ret = _hutil_copy_object_entries(dst_store_id, src_store_id,
+                               new_obj->obj_handle, child_obj->obj_handle,
+                               new_hobj, keep_handle);
+               if (ret != MTP_ERROR_NONE) {
+                       ERR("Copy file Fail");
+                       _prop_deinit_ptparray(&child_arr);
+                       return ret;
+               }
+       }
+
+       /* Recursive copy is required when folder is not enumerated so it may
+        * return 0 child handles
+        */
+       if (!((child_arr.num_ele > 0) ||
+                               _util_copy_dir_children_recursive(obj->file_path,
+                                       new_obj->file_path, &error))) {
+               ERR_SECURE("Recursive copy Fail [%d], [%s]->[%s]",
+                               child_arr.num_ele,
+                               obj->file_path, new_obj->file_path);
+               _prop_deinit_ptparray(&child_arr);
+               if (_util_remove_dir_children_recursive(new_obj->file_path,
+                                       &num_of_deleted_file, &num_of_file, FALSE) ==
+                               MTP_ERROR_NONE) {
+                       g_snprintf(g_last_deleted, MTP_MAX_PATHNAME_SIZE + 1,
+                                       "%s", new_obj->file_path);
+                       if (rmdir(new_obj->file_path) < 0) {
+                               memset(g_last_deleted, 0,
+                                               MTP_MAX_PATHNAME_SIZE + 1);
+                       }
+               }
+               if (error == ENOSPC)
+                       return MTP_ERROR_STORE_FULL;
+               return MTP_ERROR_GENERAL;
+       }
+
+       _prop_deinit_ptparray(&child_arr);
+       *new_hobj = new_obj->obj_handle;
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_move_object_entry(mtp_uint32 dst_store_id, mtp_uint32 h_parent,
+               mtp_uint32 obj_handle)
+{
+       mtp_store_t *src = NULL;
+       mtp_store_t *dst = NULL;
+       mtp_obj_t *obj = NULL;
+       mtp_obj_t *par_obj = NULL;
+       mtp_char str_buf[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char utf8_temp[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_uint32 new_handle = 0;
+       mtp_int32 error = 0;
+       mtp_err_t ret = MTP_ERROR_NONE;
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (NULL == obj) {
+               ERR("object is [%p]\n", obj);
+               return MTP_ERROR_INVALID_OBJECTHANDLE;
+       }
+       if (NULL == obj->obj_info) {
+               ERR("obj_info is [%p]\n", obj->obj_info);
+               return MTP_ERROR_GENERAL;
+       }
+
+       src = _device_get_store_containing_obj(obj_handle);
+       if (src == NULL) {
+               ERR("error retrieving source store");
+               return MTP_ERROR_STORE_NOT_AVAILABLE;
+       }
+
+       if (src->store_info.access == PTP_STORAGEACCESS_R) {
+               ERR("Store access is read only");
+               return MTP_ERROR_STORE_READ_ONLY;
+       }
+
+       dst = _device_get_store(dst_store_id);
+       if (dst == NULL) {
+               ERR("error retrieving destination store");
+               return MTP_ERROR_STORE_NOT_AVAILABLE;
+       }
+
+       if (dst->store_info.access != PTP_STORAGEACCESS_RWD) {
+               ERR("Write permission not there on target store");
+               return MTP_ERROR_STORE_READ_ONLY;
+       }
+
+       /* Get the Parent Object Handle */
+       if (h_parent > 0) {
+               par_obj = _device_get_object_with_handle(h_parent);
+
+               if (par_obj == NULL || par_obj->obj_info == NULL) {
+                       ERR("par_obj[%p] or par_obj->obj_info is NULL\n", par_obj);
+                       return MTP_ERROR_INVALID_PARENT;
+               } else if (PTP_FMT_ASSOCIATION != par_obj->obj_info->obj_fmt) {
+                       ERR("par obj fmt = [0x%x]\n", par_obj->obj_info->obj_fmt);
+                       return MTP_ERROR_INVALID_PARENT;
+               }
+
+               if (dst != _device_get_store_containing_obj(h_parent)) {
+                       ERR("parent is not on the destination store");
+                       return MTP_ERROR_INVALID_PARENT;
+               }
+
+               /* Parent must not be a descendant of the object to be moved */
+               if (dst->store_id == src->store_id) {
+                       if (_entity_check_if_B_parent_of_A(dst, h_parent,
+                                               obj_handle))
+                               return MTP_ERROR_INVALID_PARAM;
+               }
+       } else {
+               par_obj = NULL; /* Parent is the root */
+       }
+
+       /* Check if the source store is the target store */
+       if (dst->store_id == src->store_id) {
+
+               mtp_obj_t *old_par = NULL;
+               mtp_char new_fpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+               mtp_char dst_fpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+               mtp_char *parent_path = NULL;
+
+               DBG("same storage , type[0x%x]\n",
+                               obj->obj_info->association_type);
+               _util_get_file_name(obj->file_path, utf8_temp);
+
+               if (par_obj == NULL)
+                       parent_path = dst->root_path;
+               else
+                       parent_path = par_obj->file_path;
+
+               if (_util_create_path(dst_fpath, sizeof(dst_fpath), parent_path,
+                                       utf8_temp) == FALSE) {
+                       ERR("dst path is too LONG!!");
+                       return MTP_ERROR_GENERAL;
+               }
+
+               /* Do a real "Move" for the object in the same store: no need to
+                * check space available
+                */
+               g_strlcpy(str_buf, obj->file_path, sizeof(str_buf));
+
+               if (obj->obj_info != NULL && obj->obj_info->obj_fmt ==
+                               PTP_FMT_ASSOCIATION) {
+
+                       if (access(dst_fpath, F_OK) == 0) {
+                               if (FALSE == _util_get_unique_dir_path(dst_fpath,
+                                                       new_fpath, sizeof(new_fpath))) {
+                                       return MTP_ERROR_GENERAL;
+                               }
+                       } else {
+                               g_strlcpy(new_fpath, dst_fpath, sizeof(new_fpath));
+                       }
+
+                       g_snprintf(g_last_moved, MTP_MAX_PATHNAME_SIZE + 1,
+                                       "%s", str_buf);
+                       if (rename(str_buf, new_fpath) < 0) {
+                               /* Failed to move the object */
+                               error = errno;
+                               memset(g_last_moved, 0,
+                                               MTP_MAX_PATHNAME_SIZE + 1);
+                               ERR_SECURE("Directory rename fail in same storage\
+                                               [%s]->[%s]\n", str_buf, new_fpath);
+                               if (EACCES == error)
+                                       return MTP_ERROR_ACCESS_DENIED;
+                               else if (ENOSPC == error)
+                                       return MTP_ERROR_STORE_FULL;
+                               return MTP_ERROR_GENERAL;
+                       }
+
+                       _util_scan_folder_contents_in_db(str_buf);
+                       _entity_set_object_file_path(obj, new_fpath, CHAR_TYPE);
+                       _entity_set_child_object_path(obj, str_buf, new_fpath);
+                       _util_scan_folder_contents_in_db(new_fpath);
+               } else {
+                       g_snprintf(g_last_moved, MTP_MAX_PATHNAME_SIZE + 1,
+                                       "%s", str_buf);
+                       if (FALSE == _util_file_move(str_buf, dst_fpath,
+                                               &error)) {
+                               /* Failed to move the object */
+                               memset(g_last_moved, 0,
+                                               MTP_MAX_PATHNAME_SIZE + 1);
+                               ERR("move file Fail in same storage\
+                                               [%s]->[%s]\n", str_buf, dst_fpath);
+                               if (EACCES == error)
+                                       return MTP_ERROR_ACCESS_DENIED;
+                               else if (ENOSPC == error)
+                                       return MTP_ERROR_STORE_FULL;
+                               return MTP_ERROR_GENERAL;
+                       }
+
+                       _util_delete_file_from_db(obj->file_path);
+                       _entity_set_object_file_path(obj, dst_fpath, CHAR_TYPE);
+                       _util_add_file_to_db(obj->file_path);
+               }
+
+               if (obj->obj_info->h_parent != PTP_OBJECTHANDLE_ROOT) {
+                       old_par = _entity_get_object_from_store(src,
+                                       obj->obj_info->h_parent);
+                       if (old_par) {
+                               _entity_remove_reference_child_array(old_par,
+                                               obj->obj_handle);
+                       }
+               }
+
+               if (par_obj != NULL) {
+                       obj->obj_info->h_parent = par_obj->obj_handle;
+                       _entity_add_reference_child_array(par_obj,
+                                       obj->obj_handle);
+               } else {
+                       obj->obj_info->h_parent = PTP_OBJECTHANDLE_ROOT;
+               }
+
+               return MTP_ERROR_NONE;
+       } else {
+               /* Move is called between two stores */
+               /* Calculate the space required for the new object(s) */
+               mtp_obj_t *new_obj = NULL;
+               DBG("Different storage or a folder, type[0x%x]\n",
+                               obj->obj_info->association_type);
+
+               /* Simulate a Move operation: First copy the Object,
+                * then remove the old object
+                */
+               ret = _hutil_copy_object_entries(dst->store_id, src->store_id,
+                               (par_obj == NULL) ? 0 : (par_obj->obj_handle),
+                               obj->obj_handle, &new_handle, TRUE);
+               if (ret != MTP_ERROR_NONE) {
+                       _entity_delete_obj_mtp_store(dst, obj->obj_handle,
+                                       PTP_FORMATCODE_NOTUSED, FALSE);
+                       return ret;
+               }
+
+               _entity_delete_obj_mtp_store(src, obj->obj_handle,
+                               PTP_FORMATCODE_NOTUSED, FALSE);
+               new_obj = _device_get_object_with_handle(new_handle);
+               if (NULL == new_obj || NULL == new_obj->obj_info)
+                       return MTP_ERROR_GENERAL;
+
+               if (new_obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION)
+                       _util_scan_folder_contents_in_db(new_obj->file_path);
+               else
+                       _util_add_file_to_db(new_obj->file_path);
+
+               return MTP_ERROR_NONE;
+       }
+       return MTP_ERROR_GENERAL;
+}
+
+mtp_err_t _hutil_duplicate_object_entry(mtp_uint32 dst_store_id,
+               mtp_uint32 h_parent, mtp_uint32 obj_handle, mtp_uint32 *new_handle)
+{
+       mtp_store_t *src = NULL;
+       mtp_store_t *dst = NULL;
+       mtp_obj_t *obj = NULL;
+       mtp_obj_t *par_obj = NULL;
+       mtp_obj_t *new_obj = NULL;
+       mtp_uint32 space_req = 0;
+       mtp_err_t ret = MTP_ERROR_NONE;
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (NULL == obj) {
+               ERR("Object not found");
+               return MTP_ERROR_INVALID_OBJECTHANDLE;
+       }
+
+       src = _device_get_store_containing_obj(obj_handle);
+       if (NULL == src) {
+               ERR("Source store not found");
+               return MTP_ERROR_STORE_NOT_AVAILABLE;
+       }
+
+       dst = _device_get_store(dst_store_id);
+       if (NULL == dst) {
+               ERR("Destination store not found");
+               return MTP_ERROR_STORE_NOT_AVAILABLE;
+       }
+
+       if (dst->store_info.access != PTP_STORAGEACCESS_RWD) {
+               ERR("Store is read only");
+               return MTP_ERROR_STORE_READ_ONLY;
+       }
+
+       if (h_parent > 0) {
+               par_obj = _device_get_object_with_handle(h_parent);
+               if ((par_obj == NULL) || (par_obj->obj_info->obj_fmt !=
+                                       PTP_FMT_ASSOCIATION))
+                       return MTP_ERROR_INVALID_PARENT;
+
+               if (dst != _device_get_store_containing_obj(h_parent))
+                       return MTP_ERROR_INVALID_PARENT;
+
+               if (dst->store_id == src->store_id) {
+                       if (_entity_check_if_B_parent_of_A(dst, h_parent,
+                                               obj_handle))
+                               return MTP_ERROR_INVALID_PARENT;
+               }
+       } else
+               par_obj = NULL;
+
+       space_req = _entity_get_object_tree_size(src, obj);
+       if (dst->store_info.free_space < space_req) {
+               ERR("Insufficient free space");
+               return MTP_ERROR_STORE_FULL;
+       }
+
+       if((ret = _hutil_copy_object_entries(dst_store_id, src->store_id,
+                                       h_parent, obj_handle, new_handle, FALSE)) != MTP_ERROR_NONE) {
+               return ret;
+       }
+       /*
+        * After this command, Initiator will ask get object prop list (0x9805).
+        * update the media DB.
+        */
+       new_obj = _device_get_object_with_handle(*new_handle);
+       if (NULL == new_obj || NULL == new_obj->obj_info) {
+               ERR("new obj or info is NULL");
+               return MTP_ERROR_GENERAL;
+       }
+
+       if (new_obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION) {
+               _util_scan_folder_contents_in_db(new_obj->file_path);
+       } else {
+               _util_add_file_to_db(new_obj->file_path);
+       }
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_read_file_data_from_offset(mtp_uint32 obj_handle, off_t offset,
+               void *data, mtp_uint32 *data_sz)
+{
+       mtp_obj_t *obj = NULL;
+       mtp_uint32 h_file = INVALID_FILE;
+       mtp_int32 error = 0;
+       mtp_char fname[MTP_MAX_PATHNAME_SIZE + 1];
+       off_t result = 0;
+       mtp_uint32 num_bytes;
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (obj == NULL) {
+               ERR("_device_get_object_with_handle returned NULL object");
+               return MTP_ERROR_INVALID_OBJECTHANDLE;
+       }
+
+       if (obj->obj_info->protcn_status ==
+                       MTP_PROTECTIONSTATUS_NONTRANSFERABLE_DATA) {
+
+               ERR("protection data, NONTRANSFERABLE_OBJECT");
+               return MTP_ERROR_GENERAL;
+       }
+
+       g_strlcpy(fname, obj->file_path, MTP_MAX_PATHNAME_SIZE + 1);
+       h_file = _util_file_open(fname, MTP_FILE_READ, &error);
+       if (h_file == INVALID_FILE) {
+               ERR("file open Fail[%s]\n", fname);
+               return MTP_ERROR_GENERAL;
+       }
+
+       result = _util_file_seek(h_file, offset, SEEK_SET);
+       if (result < 0) {
+               ERR("file seek Fail [%d]\n", errno);
+               _util_file_close(h_file);
+               return MTP_ERROR_GENERAL;
+       }
+
+       num_bytes = *data_sz;
+       _util_file_read(h_file, data, *data_sz, data_sz);
+
+       if (num_bytes != *data_sz) {
+               ERR("requested[%d] and read[%d] number of bytes do not match\n",
+                               *data_sz, num_bytes);
+               _util_file_close(h_file);
+               return MTP_ERROR_GENERAL;
+       }
+
+       _util_file_close(h_file);
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_write_file_data(mtp_uint32 store_id, mtp_obj_t *obj,
+               mtp_char *fpath)
+{
+       mtp_store_t *store;
+       mtp_char fname[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+#ifdef MTP_SUPPORT_DELETE_MEDIA_ALBUM_FILE
+       mtp_char extn[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+#endif /*MTP_SUPPORT_DELETE_MEDIA_ALBUM_FILE*/
+       mtp_int32 error = 0;
+
+       retv_if(obj == NULL, MTP_ERROR_INVALID_PARAM);
+       retv_if(obj->obj_info == NULL, MTP_ERROR_INVALID_PARAM);
+
+       store = _device_get_store(store_id);
+       if (store == NULL) {
+               ERR("destination store is not valid");
+               return MTP_ERROR_INVALID_OBJECT_INFO;
+       }
+
+       g_strlcpy(fname, obj->file_path, MTP_MAX_PATHNAME_SIZE + 1);
+       if (access(fpath, F_OK) < 0) {
+               ERR("temp file does not exist");
+               return MTP_ERROR_GENERAL;
+       }
+
+#ifdef MTP_SUPPORT_DELETE_MEDIA_ALBUM_FILE
+       /* in case of alb extension, does not make real file just skip below */
+       if (obj_info->obj_fmt != PTP_FMT_ASSOCIATION ||
+                       (obj_info->obj_fmt == PTP_FMT_ASSOCIATION &&
+                        obj_info->association_type != PTP_ASSOCIATIONTYPE_UNDEFINED &&
+                        obj_info->association_type != PTP_ASSOCIATIONTYPE_FOLDER)) {
+
+               _util_get_file_extn(fname, extn);
+               if (strlen(extn) && !strcasecmp(extn, "alb")) {
+                       DBG("No need to create album file");
+                       remove(fpath, &error);
+                       return MTP_ERROR_NONE;
+               }
+       }
+#endif /*MTP_SUPPORT_DELETE_MEDIA_ALBUM_FILE*/
+
+       g_snprintf(g_last_moved, MTP_MAX_PATHNAME_SIZE + 1, "%s", fpath);
+       if (FALSE == _util_file_move(fpath, fname, &error)) {
+               memset(g_last_moved, 0, MTP_MAX_PATHNAME_SIZE + 1);
+               ERR("move to real file fail [%s]->[%s] \n", fpath, fname);
+               _entity_dealloc_mtp_obj(obj);
+
+               return MTP_ERROR_STORE_FULL;
+       }
+
+#ifdef MTP_SUPPORT_SET_PROTECTION
+       if ((obj_info->protcn_status == PTP_PROTECTIONSTATUS_READONLY) ||
+                       (obj_info->ProtectionStatus ==
+                        MTP_PROTECTIONSTATUS_READONLY_DATA)) {
+               file_attr_t attrs;
+               if (_util_get_file_attrs(fname, &attrs) == FALSE) {
+                       ERR("real file get attributes Fail");
+                       _entity_dealloc_mtp_obj(obj);
+                       return MTP_ERROR_GENERAL;
+               }
+               _util_set_file_attrs(fname, attrs.attribute |
+                               MTP_FILE_ATTR_MODE_READ_ONLY);
+       }
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+
+       _util_add_file_to_db(obj->file_path);
+
+#ifndef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+       if (updatePropertyValuesMtpObject(obj) == FALSE) {
+               ERR("update property values mtp obj Fail");
+               _entity_dealloc_mtp_obj(obj);
+               return MTP_ERROR_GENERAL;
+       }
+#endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+
+       _entity_add_object_to_store(store, obj);
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_get_object_entry_size(mtp_uint32 obj_handle,
+               mtp_uint64 *obj_sz)
+{
+       mtp_obj_t *obj = NULL;
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (obj == NULL) {
+               ERR("_device_get_object_with_handle returned Null object");
+               return MTP_ERROR_INVALID_OBJECTHANDLE;
+       }
+
+       *obj_sz = obj->obj_info->file_size;
+       return MTP_ERROR_NONE;
+}
+
+#ifdef MTP_SUPPORT_SET_PROTECTION
+mtp_err_t _hutil_set_protection(mtp_uint32 obj_handle, mtp_uint16 prot_status)
+{
+       mtp_obj_t *obj = NULL;
+       mtp_char fname[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       file_attr_t attrs = { 0 };
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (obj == NULL)
+               return MTP_ERROR_INVALID_OBJECTHANDLE;
+
+       if (MTP_EXTERNAL_STORE_ID == obj->obj_info->store_id) {
+               ERR("Storage is external");
+               return MTP_ERROR_OPERATION_NOT_SUPPORTED;
+       }
+
+       g_strlcpy(fname, obj->file_path, MTP_MAX_PATHNAME_SIZE + 1);
+       obj->obj_info->protcn_status = prot_status;
+
+       if (FALSE == _util_get_file_attrs(fname, &attrs)) {
+               ERR("Failed to get file[%s] attrs\n", fname);
+               return MTP_ERROR_GENERAL;
+       }
+
+       if (MTP_FILE_ATTR_MODE_NONE == attrs.attribute) {
+               return MTP_ERROR_GENERAL;
+       }
+
+       if (prot_status == PTP_PROTECTIONSTATUS_READONLY) {
+               attrs.attribute |= MTP_FILE_ATTR_MODE_READ_ONLY;
+       } else {
+               attrs.attribute &= ~MTP_FILE_ATTR_MODE_READ_ONLY;
+       }
+
+       if (FALSE == _util_set_file_attrs(fname, attrs.attribute)) {
+               ERR("Failed to set file[%s] attrs\n", fname);
+               return MTP_ERROR_GENERAL;
+       }
+
+       return MTP_ERROR_NONE;
+}
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+
+mtp_err_t _hutil_get_num_objects(mtp_uint32 store_id, mtp_uint32 h_parent,
+               mtp_uint32 format, mtp_uint32 *num_obj)
+{
+       mtp_store_t *store = NULL;
+       mtp_obj_t *obj = NULL;
+       mtp_int32 i = 0;
+       mtp_uint32 numobj = 0;
+
+       *num_obj = 0;
+       if (store_id != PTP_STORAGEID_ALL) {
+               store = _device_get_store(store_id);
+               if (store == NULL) {
+                       ERR("specific store is null");
+                       return MTP_ERROR_INVALID_STORE;
+               }
+       }
+
+       if (!h_parent) {
+               if (!format) {
+                       *num_obj = _device_get_num_objects(store_id);
+               } else {
+                       *num_obj = _device_get_num_objects_with_format(store_id,
+                                       format);
+               }
+               return MTP_ERROR_NONE;
+       }
+
+       /* return the number of direct children for a particular association
+        * (in a single store)
+        */
+       if (h_parent == PTP_OBJECTHANDLE_ALL) {
+
+               h_parent = PTP_OBJECTHANDLE_ROOT;
+               if (store_id == PTP_STORAGEID_ALL) {
+                       for (i = (_device_get_num_stores() - 1); i >= 0; i--) {
+                               store = _device_get_store_at_index(i);
+                               if (store == NULL) {
+                                       ERR("Store is null");
+                                       return MTP_ERROR_STORE_NOT_AVAILABLE;
+                               }
+                               numobj += _entity_get_num_children(store,
+                                               h_parent, format);
+                       }
+                       *num_obj = numobj;
+
+                       return MTP_ERROR_NONE;
+               }
+       } else {
+               /* Initiator wants number of children of a particular association */
+               obj = _device_get_object_with_handle(h_parent);
+               if (obj == NULL) {
+                       ERR("obj is null");
+                       return MTP_ERROR_INVALID_OBJECTHANDLE;
+               }
+
+               if (obj->obj_info->obj_fmt != PTP_FMT_ASSOCIATION) {
+                       ERR("format is not association");
+                       return MTP_ERROR_INVALID_PARENT;
+               }
+
+               store = _device_get_store_containing_obj(h_parent);
+       }
+
+       if (store == NULL) {
+               ERR("store is null");
+               return MTP_ERROR_STORE_NOT_AVAILABLE;
+       }
+
+       *num_obj = _entity_get_num_children(store, h_parent, format);
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_get_object_handles(mtp_uint32 store_id, mtp_uint32 format,
+               mtp_uint32 h_parent, ptp_array_t *handle_arr)
+{
+       mtp_store_t *store = NULL;
+       mtp_int32 i = 0;
+
+       if (h_parent == PTP_OBJECTHANDLE_ALL || h_parent == PTP_OBJECTHANDLE_ROOT) {
+               for (i = 0; i < _device_get_num_stores(); i++) {
+                       store = _device_get_store_at_index(i);
+                       if (store && store->obj_list.nnodes == 0)
+                               _entity_store_recursive_enum_folder_objects(store, NULL);
+               }
+               g_is_full_enum = TRUE;
+       }
+
+       if (store_id == PTP_STORAGEID_ALL && h_parent == PTP_OBJECTHANDLE_ROOT) {
+               for (i = 0; i < _device_get_num_stores(); i++) {
+                       store = _device_get_store_at_index(i);
+                       _entity_get_objects_from_store_by_format(store, format, handle_arr);
+               }
+               return MTP_ERROR_NONE;
+
+       } else if (store_id == PTP_STORAGEID_ALL && h_parent == PTP_OBJECTHANDLE_ALL) {
+               h_parent = PTP_OBJECTHANDLE_ROOT;
+               for (i = 0; i < _device_get_num_stores(); i++) {
+                       store = _device_get_store_at_index(i);
+                       _entity_get_child_handles_with_same_format(store, h_parent, format, handle_arr);
+               }
+               return MTP_ERROR_NONE;
+
+       } else if (store_id != PTP_STORAGEID_ALL && h_parent == PTP_OBJECTHANDLE_ROOT) {
+               store = _device_get_store(store_id);
+               if (store == NULL) {
+                       ERR("invalid store id [%d]\n", store_id);
+                       return MTP_ERROR_INVALID_STORE;
+               }
+
+               _entity_get_objects_from_store_by_format(store, format, handle_arr);
+               return MTP_ERROR_NONE;
+
+       } else if (store_id != PTP_STORAGEID_ALL && h_parent == PTP_OBJECTHANDLE_ALL) {
+               h_parent = PTP_OBJECTHANDLE_ROOT;
+               store = _device_get_store(store_id);
+               if (store == NULL) {
+                       ERR("invalid store id [%d]\n", store_id);
+                       return MTP_ERROR_INVALID_STORE;
+               }
+               _entity_get_child_handles_with_same_format(store, h_parent, format, handle_arr);
+               return MTP_ERROR_NONE;
+       }
+
+       store = _device_get_store(store_id);
+       if (store == NULL) {
+               ERR("invalid store id [%d]\n", store_id);
+               return MTP_ERROR_INVALID_STORE;
+       }
+
+       _entity_get_child_handles_with_same_format(store, h_parent, format, handle_arr);
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_construct_object_entry(mtp_uint32 store_id,
+               mtp_uint32 h_parent, obj_data_t *objdata, mtp_obj_t **obj, void *data,
+               mtp_uint32 data_sz)
+{
+       mtp_store_t *store = NULL;
+       mtp_obj_t *tobj = NULL;
+       obj_info_t *obj_info = NULL;
+       mtp_char file_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
+
+       if (store_id) {
+               if (!h_parent) {
+                       h_parent = _device_get_default_parent_handle();
+               } else if (h_parent == 0xFFFFFFFF) {
+                       h_parent = PTP_OBJECTHANDLE_ROOT;
+               }
+       } else {
+               store_id = _device_get_default_store_id();
+
+               if (!store_id) {
+                       ERR("_device_get_default_store_id Fail");
+                       return MTP_ERROR_STORE_NOT_AVAILABLE;
+               }
+
+               if (h_parent) {
+                       /* If the second parameter is used,
+                        * the first must also be used.
+                        */
+                       return MTP_ERROR_INVALID_PARAM;
+               } else {
+                       h_parent = _device_get_default_parent_handle();
+               }
+       }
+
+       if (objdata != NULL) {
+               store = _device_get_store(objdata->store_id);
+               if (store != NULL) {
+                       DBG("check free size instead of re-calculation");
+                       _entity_update_store_info_run_time(&(store->store_info),
+                                       (store->root_path));
+               }
+
+               /* Delete and invalidate the old obj_info for send object */
+               if (objdata->obj != NULL) {
+                       _entity_dealloc_mtp_obj(objdata->obj);
+               }
+       }
+
+       store = _device_get_store(store_id);
+       if (store == NULL) {
+               ERR("Store not found");
+               return MTP_ERROR_INVALID_STORE;
+       }
+
+       if (store->store_info.access == PTP_STORAGEACCESS_R) {
+               ERR("Read only storage");
+               return MTP_ERROR_STORE_READ_ONLY;
+       }
+
+       if ((store->store_info.free_space) == 0 ||
+                       (store->store_info.free_space >
+                        store->store_info.capacity)) {
+               ERR("free space is not enough [%ld:%ld]\n",
+                               store->store_info.free_space,
+                               store->store_info.capacity);
+               return MTP_ERROR_STORE_FULL;
+       }
+
+       obj_info = _entity_alloc_object_info();
+       if (obj_info == NULL) {
+               ERR("_entity_alloc_object_info Fail");
+               return MTP_ERROR_GENERAL;
+       }
+
+       if (_entity_parse_raw_obj_info(data, data_sz, obj_info, file_name,
+                               sizeof(file_name)) != data_sz) {
+               /* wrong object info sent from Host.*/
+               ERR("Invalid objet info");
+               _entity_dealloc_obj_info(obj_info);
+               return MTP_ERROR_INVALID_OBJECT_INFO;
+       }
+       obj_info->store_id = store_id;
+       obj_info->h_parent = h_parent;
+
+       switch (_hutil_add_object_entry(obj_info, file_name, &tobj)) {
+       case MTP_ERROR_NONE:
+               *obj = tobj;
+               break;
+
+       case MTP_ERROR_STORE_FULL:
+               return MTP_ERROR_STORE_FULL;
+
+       case MTP_ERROR_INVALID_OBJECTHANDLE:
+               return MTP_ERROR_INVALID_OBJECTHANDLE;
+
+       case MTP_ERROR_INVALID_PARENT:
+               return MTP_ERROR_INVALID_PARENT;
+
+       default:
+               return MTP_ERROR_GENERAL;
+       }
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_construct_object_entry_prop_list(mtp_uint32 store_id,
+               mtp_uint32 h_parent, mtp_uint16 format, mtp_uint64 obj_sz,
+               obj_data_t *obj_data, mtp_obj_t **obj_ptr, void *data,
+               mtp_int32 data_sz, mtp_uint32 *err_idx)
+{
+       mtp_uint32 index = 0;
+       mtp_store_t *store = NULL;
+       mtp_obj_t *obj = NULL;
+       obj_prop_desc_t *prop_desc = NULL;
+       obj_prop_val_t *prop_val = NULL;
+       mtp_uint32 num_elem = 0;
+       mtp_int32 quad_sz = 0;
+       mtp_uint32 obj_handle = 0;
+       mtp_uint16 prop_code = 0;
+       mtp_uint16 data_type = 0;
+       obj_info_t *obj_info = NULL;
+       mtp_uchar *temp = NULL;
+       mtp_int32 bytes_left = data_sz;
+       mtp_err_t resp = 0;
+
+#ifdef MTP_SUPPORT_ALBUM_ART
+       mtp_uint16 albumFormat = 0;
+       mtp_char alb_extn[MTP_MAX_EXTENSION_LENGTH + 1] = { 0 };
+       mtp_char *alb_buf = NULL;
+       mtp_uint32 alb_sz = 0;
+       mtp_uint32 h_temp = INVALID_FILE;
+       mtp_int32 error = 0;
+#endif /*MTP_SUPPORT_ALBUM_ART*/
+       mtp_char file_name[MTP_MAX_FILENAME_SIZE + 1] = { 0 };
+
+       if (obj_data != NULL && obj_data->obj != NULL) {
+               store = _device_get_store(obj_data->store_id);
+               if (store != NULL) {
+                       DBG("check free size instead of re-calculation");
+                       _entity_update_store_info_run_time(&(store->store_info),
+                                       (store->root_path));
+               }
+               _entity_dealloc_mtp_obj(obj_data->obj);
+       }
+
+       store = _device_get_store(store_id);
+       if (store == NULL) {
+               ERR("Could not get the store");
+               return MTP_ERROR_INVALID_STORE;
+       }
+
+       if (store->store_info.access == PTP_STORAGEACCESS_R) {
+               ERR("Only read access allowed on store");
+               return MTP_ERROR_STORE_READ_ONLY;
+       }
+
+       if ((store->store_info.free_space) == 0 ||
+                       (store->store_info.free_space > store->store_info.capacity)) {
+               ERR("free space is not enough [%ld bytes]\n",
+                               store->store_info.free_space);
+               return MTP_ERROR_STORE_FULL;
+       }
+
+       obj_info = _entity_alloc_object_info();
+       if (obj_info == NULL) {
+               ERR("_entity_alloc_object_info Fail");
+               return MTP_ERROR_GENERAL;
+       }
+
+       obj_info->obj_fmt = format;
+       if (obj_info->obj_fmt == PTP_FMT_ASSOCIATION) {
+               obj_info->association_type = PTP_ASSOCIATIONTYPE_FOLDER;
+       }
+
+       obj_info->file_size = obj_sz;
+
+       /* Prop value quadruple: Object Handle, PropertyCode, DataType
+        * and DTS Prop Value (assume a byte value)
+        */
+       temp = (mtp_uchar *) data;
+       bytes_left = data_sz;
+       quad_sz = sizeof(mtp_uint32) + sizeof(mtp_uint16) + sizeof(mtp_uint16) +
+               sizeof(mtp_char);
+       memcpy(&num_elem, temp, sizeof(mtp_uint32));
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(&num_elem, sizeof(mtp_uint32));
+#endif
+       temp += sizeof(mtp_uint32);
+       bytes_left -= sizeof(mtp_uint32);
+
+       /* frequent disconnect/connect make bluscreen since below process
+        * is not finished
+        */
+       for (index = 0; index < num_elem; index++) {
+               if (MTP_PHONE_USB_DISCONNECTED == _util_get_local_usb_status() ||
+                               TRUE == _transport_get_usb_discon_state()) {
+                       /* seems usb is disconnected, stop */
+                       _entity_dealloc_obj_info(obj_info);
+                       resp = MTP_ERROR_GENERAL;
+                       goto ERROR_EXIT;
+               }
+
+               *err_idx = index;
+               if (bytes_left < quad_sz) {
+                       /* seems invalid dataset received: Stops parsing */
+                       _entity_dealloc_obj_info(obj_info);
+                       resp = MTP_ERROR_INVALID_DATASET;
+                       goto ERROR_EXIT;
+               }
+
+               /* Get ObjectHandle & validate */
+               memcpy(&obj_handle, temp, sizeof(mtp_uint32));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(&obj_handle, sizeof(mtp_uint32));
+#endif /* __BIG_ENDIAN__ */
+               temp += sizeof(mtp_uint32);
+               bytes_left -= sizeof(mtp_uint32);
+               if (obj_handle != 0x00000000) {
+                       _entity_dealloc_obj_info(obj_info);
+                       resp = MTP_ERROR_INVALID_OBJECTHANDLE;
+                       goto ERROR_EXIT;
+               }
+
+               /* Get PropCode & Validate */
+               memcpy(&prop_code, temp, sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(&prop_code, sizeof(mtp_uint16));
+#endif /* __BIG_ENDIAN__ */
+               temp += sizeof(mtp_uint16);
+               bytes_left -= sizeof(mtp_uint16);
+               prop_desc = _prop_get_obj_prop_desc(obj_info->obj_fmt, prop_code);
+               if (prop_desc == NULL) {
+                       _entity_dealloc_obj_info(obj_info);
+                       ERR("property may be unsupported!!");
+                       resp = MTP_ERROR_INVALID_OBJ_PROP_CODE;
+                       goto ERROR_EXIT;
+               }
+
+               /* Verify that properties already present in parameters
+                * don't get repeated in the list
+                */
+               if ((prop_code == MTP_OBJ_PROPERTYCODE_STORAGEID) ||
+                               (prop_code == MTP_OBJ_PROPERTYCODE_PARENT) ||
+                               (prop_code == MTP_OBJ_PROPERTYCODE_OBJECTFORMAT) ||
+                               (prop_code == MTP_OBJ_PROPERTYCODE_OBJECTSIZE)) {
+                       _entity_dealloc_obj_info(obj_info);
+                       resp = MTP_ERROR_INVALID_DATASET;
+                       goto ERROR_EXIT;
+               }
+
+               /* Get DataType */
+               memcpy(&data_type, temp, sizeof(mtp_uint16));
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(&data_type, sizeof(mtp_uint16));
+#endif /* __BIG_ENDIAN__ */
+               temp += sizeof(mtp_uint16);
+               bytes_left -= sizeof(mtp_uint16);
+               if (data_type != prop_desc->propinfo.data_type) {
+                       _entity_dealloc_obj_info(obj_info);
+                       resp = MTP_ERROR_INVALID_OBJECT_PROP_FORMAT;
+                       goto ERROR_EXIT;
+               }
+
+               /* Acquire object information related data. */
+               prop_val = _prop_alloc_obj_propval(prop_desc);
+               if (prop_val == NULL) {
+                       continue;
+               }
+               _prop_set_current_array_val(prop_val, temp, bytes_left);
+               switch (prop_code) {
+               case MTP_OBJ_PROPERTYCODE_WIDTH:
+                       // TODO: find mechanism to save (integer)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_TRACK:
+                       // TODO: find mechanism to save (integer)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_GENRE:
+                       // TODO: find mechanism to save (string)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_HEIGHT:
+                       // TODO: find mechanism to save (integer)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_ARTIST:
+                       // TODO: find mechanism to save (string)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_DURATION:
+                       // TODO: find mechanism to save (integer)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_COMPOSER:
+                       // TODO: find mechanism to save (string)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_ALBUMNAME:
+                       // TODO: find mechanism to save (string)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_SAMPLERATE:
+                       // TODO: find mechanism to save (integer)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_DATECREATED:
+                       // TODO: find mechanism to save (string)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_DATEMODIFIED:
+                       // TODO: find mechanism to save (string)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_AUDIOBITRATE:
+                       // TODO: find mechanism to save (integer)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_VIDEOBITRATE:
+                       // TODO: find mechanism to save (integer)
+                       break;
+               case  MTP_OBJ_PROPERTYCODE_OBJECTFILENAME:
+                       /* empty metadata folder problem
+                        * emtpy file name
+                        */
+                       if (prop_val->current_val.str->num_chars == 0) {
+                               g_strlcpy(file_name, MTP_UNKNOWN_METADATA, sizeof(file_name));
+                       } else {
+                               _util_utf16_to_utf8(file_name, sizeof(file_name),
+                                               prop_val->current_val.str->str);
+                       }
+                       break;
+
+               case MTP_OBJ_PROPERTYCODE_PROTECTIONSTATUS:
+#ifdef MTP_SUPPORT_SET_PROTECTION
+                       memcpy(&obj_info->protcn_status, prop_val->current_val.integer,
+                                       sizeof(mtp_uint16));
+#else /* MTP_SUPPORT_SET_PROTECTION */
+                       obj_info->protcn_status = PTP_PROTECTIONSTATUS_NOPROTECTION;
+#endif /*MTP_SUPPORT_SET_PROTECTION*/
+                       break;
+
+               case MTP_OBJ_PROPERTYCODE_ASSOCIATIONTYPE:
+                       memcpy(&obj_info->association_type, prop_val->current_val.integer,
+                                       sizeof(mtp_uint16));
+                       break;
+
+               case MTP_OBJ_PROPERTYCODE_NUMBEROFCHANNELS:
+                       // TODO: find mechanism to save (integer)
+                       break;
+               case MTP_OBJ_PROPERTYCODE_FRAMESPER1KSECONDS:
+                       // TODO: find mechanism to save (integer)
+                       break;
+#ifdef MTP_SUPPORT_ALBUM_ART
+               case MTP_OBJ_PROPERTYCODE_SAMPLEDATA:
+                       /* save sample data(album cover data) with
+                        * sample format, otherwise no extension
+                        * update db with sample data path
+                        * there is no case that this position is called
+                        * again but prevent detect this
+                        */
+                       g_free(alb_buf);
+                       alb_buf = NULL;
+                       alb_buf = g_malloc(sizeof(mtp_uchar) *
+                                       (prop_val->current_val.array->num_ele) + 1);
+                       alb_sz = prop_val->current_val.array->num_ele;
+                       if (alb_buf != NULL) {
+                               memset(alb_buf, 0,
+                                               sizeof(mtp_uchar) * alb_sz + 1);
+                               if (alb_sz > 0)
+                                       memcpy(alb_buf,
+                                                       (prop_val->current_val.array->array_entry),
+                                                       sizeof(mtp_uchar) * alb_sz);
+                       } else {
+                               ERR("album art test mem allocation Fail");
+                               _prop_destroy_obj_propval(prop_val);
+                               _entity_dealloc_obj_info(obj_info);
+                               return MTP_ERROR_GENERAL;
+                       }
+                       break;
+
+               case MTP_OBJ_PROPERTYCODE_SAMPLEFORMAT:
+                       /* if is_albumart is turned on, Move file with
+                        * new extension. And update db with data path
+                        */
+                       memcpy(&albumFormat, prop_val->current_val.integer,
+                                       sizeof(mtp_uint16));
+                       switch (albumFormat) {
+                       case PTP_FMT_IMG_EXIF:
+                               g_snprintf(alb_extn, sizeof(alb_extn), "%s", "jpg");
+                               break;
+                       case PTP_FMT_IMG_GIF:
+                               g_snprintf(alb_extn, sizeof(alb_extn), "%s", "gif");
+                               break;
+                       case PTP_FMT_IMG_PNG:
+                               g_snprintf(alb_extn, sizeof(alb_extn), "%s", "png");
+                               break;
+                       case MTP_FMT_WMA:
+                               g_snprintf(alb_extn, sizeof(alb_extn), "%s", "wma");
+                               break;
+                       case PTP_FMT_MPEG:
+                               g_snprintf(alb_extn, sizeof(alb_extn), "%s", "mpg");
+                               break;
+                       default:
+                               g_snprintf(alb_extn, sizeof(alb_extn), "%s", "dat");
+                               break;
+                       }
+
+                       ERR("sampleformatl![0x%x], extension[%s]\n", prop_code, alb_extn);
+                       break;
+               case MTP_OBJ_PROPERTYCODE_SAMPLESIZE:
+               case MTP_OBJ_PROPERTYCODE_SAMPLEHEIGHT:
+               case MTP_OBJ_PROPERTYCODE_SAMPLEWIDTH:
+               case MTP_OBJ_PROPERTYCODE_SAMPLEDURATION:
+                       DBG("Sample data is not supported [0x%x]\n", prop_code);
+                       break;
+#endif /*MTP_SUPPORT_ALBUM_ART*/
+
+               default:
+                       DBG("Unsupported Property [0x%x]\n", prop_code);
+                       break;
+               }
+
+               temp += _prop_size_obj_propval(prop_val);
+               bytes_left -= _prop_size_obj_propval(prop_val);
+               _prop_destroy_obj_propval(prop_val);
+       }
+
+       obj_info->store_id = store_id;
+       obj_info->h_parent = h_parent;
+
+       if ((resp = _hutil_add_object_entry(obj_info, file_name, &obj)) !=
+                       MTP_ERROR_NONE) {
+               goto ERROR_EXIT;
+       }
+
+#ifdef MTP_SUPPORT_ALBUM_ART
+       mtp_char full_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char extn[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+       g_strlcpy(full_path, obj->file_path, MTP_MAX_PATHNAME_SIZE + 1);
+
+       /* in case of album, if there is album data, fill it in this file */
+       if (obj_info->obj_fmt != PTP_FMT_ASSOCIATION ||
+                       (obj_info->obj_fmt == PTP_FMT_ASSOCIATION &&
+                        obj_info->association_type != PTP_ASSOCIATIONTYPE_UNDEFINED &&
+                        obj_info->association_type != PTP_ASSOCIATIONTYPE_FOLDER)) {
+
+               _util_get_file_extn(full_path, extn);
+               if (!strcasecmp(extn, "alb")) {
+                       /* check db whether it contains sample form
+                        * save sample data(album cover data) with
+                        * sample format, otherwise no extension
+                        */
+                       if (alb_buf != NULL) {
+                               /* file write */
+                               h_temp = _util_file_open(full_path,
+                                               MTP_FILE_WRITE, &error);
+                               if (h_temp != INVALID_FILE) {
+                                       _util_file_write(h_temp, alb_buf,
+                                                       sizeof(mtp_uchar) *alb_sz);
+                                       _util_file_close(h_temp);
+                               } else {
+                                       ERR("open album file Fail!!");
+                               }
+                       } else {
+                               ERR("no album art data");
+                       }
+               }
+       }
+
+       g_free(alb_buf);
+#endif /* MTP_SUPPORT_ALBUM_ART */
+       *obj_ptr = obj;
+       return MTP_ERROR_NONE;
+
+ERROR_EXIT:
+#ifdef MTP_SUPPORT_ALBUM_ART
+       g_free(alb_buf);
+#endif /* MTP_SUPPORT_ALBUM_ART */
+       return resp;
+}
+
+mtp_err_t _hutil_get_object_prop_value(mtp_uint32 obj_handle,
+               mtp_uint32 prop_code, obj_prop_val_t *prop_val, mtp_obj_t **obj)
+{
+       obj_prop_val_t *tprop = NULL;
+       mtp_obj_t *tobj = NULL;
+
+       tobj = _device_get_object_with_handle(obj_handle);
+       if (NULL == tobj) {
+               ERR("requested handle does not exist[0x%x]\n",obj_handle);
+               return MTP_ERROR_INVALID_OBJECTHANDLE;
+       }
+
+       tprop = _prop_get_prop_val(tobj, prop_code);
+       if (tprop != NULL) {
+               memcpy(prop_val, tprop, sizeof(obj_prop_val_t));
+               *obj = tobj;
+               return MTP_ERROR_NONE;
+       }
+
+       ERR("can not get the prop value for propcode [0x%x]\n", prop_code);
+       return MTP_ERROR_GENERAL;
+}
+
+mtp_err_t _hutil_update_object_property(mtp_uint32 obj_handle,
+               mtp_uint32 prop_code, mtp_uint16 *data_type, void *buf,
+               mtp_uint32 buf_sz, mtp_uint32 *prop_sz)
+{
+       mtp_int32 error = 0;
+       mtp_uint32 p_size = 0;
+       mtp_obj_t *obj = NULL;
+       obj_info_t *obj_info = NULL;
+       obj_prop_desc_t *prp_dev = NULL;
+       mtp_char temp_buf[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char orig_pfpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_wchar mov_fpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char orig_fpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char dest_fpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+       retv_if(NULL == buf, MTP_ERROR_INVALID_PARAM);
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if ((NULL == obj) || (NULL == obj->obj_info)) {
+               ERR("Object not found");
+               return MTP_ERROR_INVALID_OBJECTHANDLE;
+       }
+
+       obj_info = obj->obj_info;
+       /* Avoid to rename file/folder during file operating by phone side. */
+       if (_util_is_file_opened(obj->file_path) == TRUE) {
+               ERR_SECURE("Object [%s] is already opened\n", obj->file_path);
+               return MTP_ERROR_GENERAL;
+       }
+
+       prp_dev = _prop_get_obj_prop_desc(obj_info->obj_fmt, prop_code);
+       if (prp_dev == NULL) {
+               ERR("_prop_get_obj_prop_desc Fail");
+               return MTP_ERROR_INVALID_OBJ_PROP_CODE;
+       }
+
+#ifdef MTP_SUPPORT_SET_PROTECTION
+       if (obj_info->protcn_status == PTP_PROTECTIONSTATUS_READONLY) {
+               ERR("protection is PTP_PROTECTIONSTATUS_READONLY");
+               return MTP_ERROR_ACCESS_DENIED;
+       }
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+
+       if (prp_dev->propinfo.get_set == PTP_PROPGETSET_GETONLY) {
+               ERR("property type is GETONLY");
+               return MTP_ERROR_ACCESS_DENIED;
+       }
+
+       if (data_type != NULL && *data_type != prp_dev->propinfo.data_type) {
+               ERR("Not matched data type [%d][%d]\n",
+                               *data_type, prp_dev->propinfo.data_type);
+               return MTP_ERROR_INVALID_OBJECT_PROP_FORMAT;
+       }
+
+       /* Set up needed object info fields */
+       if (prop_code == MTP_OBJ_PROPERTYCODE_OBJECTFILENAME) {
+               ptp_string_t fname = { 0 };
+
+               _prop_init_ptpstring(&fname);
+               _prop_parse_rawstring(&fname, buf, buf_sz);
+
+               _util_utf16_to_utf8(temp_buf, sizeof(temp_buf),
+                               fname.str);
+               g_strlcpy(orig_fpath, obj->file_path,
+                               MTP_MAX_PATHNAME_SIZE + 1);
+               _util_get_parent_path(orig_fpath, orig_pfpath);
+
+               if (_util_create_path(dest_fpath, sizeof(dest_fpath),
+                                       orig_pfpath, temp_buf) == FALSE) {
+                       ERR("Path is too long");
+                       return MTP_ERROR_ACCESS_DENIED;
+               }
+               _util_utf8_to_utf16(mov_fpath,
+                               sizeof(mov_fpath) / WCHAR_SIZ, dest_fpath);
+
+               /* when changed name is different */
+               if (strcasecmp(orig_fpath, dest_fpath)) {
+                       /* Extension change is not permitted */
+                       mtp_char orig_extn[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+                       mtp_char dest_extn[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+                       _util_get_file_extn(orig_fpath, orig_extn);
+                       _util_get_file_extn(dest_fpath, dest_extn);
+
+                       if (strcasecmp(orig_extn, dest_extn)) {
+                               ERR("file extension is different with original\
+                                               one [%s]:[%s]\n", orig_extn, dest_extn);
+                               return MTP_ERROR_INVALID_OBJECT_PROP_FORMAT;
+                       }
+
+                       /* FILE RENAME */
+                       if (_entity_check_child_obj_path(obj, orig_fpath,
+                                               dest_fpath) == FALSE) {
+                               ERR("_entity_check_child_obj_path FALSE. ");
+                               return MTP_ERROR_GENERAL;
+                       }
+                       g_snprintf(g_last_moved, MTP_MAX_PATHNAME_SIZE + 1,
+                                       "%s", orig_fpath);
+                       if (FALSE == _util_file_move(orig_fpath, dest_fpath,
+                                               &error)) {
+                               if (EACCES == error)
+                                       return MTP_ERROR_ACCESS_DENIED;
+                               return MTP_ERROR_GENERAL;
+                       }
+
+                       if (obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION) {
+                               _util_scan_folder_contents_in_db(orig_fpath);
+                               _util_scan_folder_contents_in_db(dest_fpath);
+                       } else {
+                               _util_delete_file_from_db(orig_fpath);
+                               _util_add_file_to_db(dest_fpath);
+
+                       }
+
+                       /* Finally assign new handle and update full path */
+                       _entity_set_object_file_path(obj, dest_fpath,
+                                       CHAR_TYPE);
+
+                       /* FILE RENAME */
+                       if (_entity_set_child_object_path(obj, orig_fpath,
+                                               dest_fpath) == FALSE) {
+                               ERR("failed to set the full path!!");
+                               return MTP_ERROR_INVALID_OBJECT_PROP_FORMAT;
+                       }
+
+                       DBG("File moved to [%s]\n", dest_fpath);
+               } else {
+                       ERR_SECURE("changed name is same with original one. [%s]\n",
+                                       dest_fpath);
+               }
+               p_size = _prop_size_ptpstring(&fname);
+       } else if (prop_code == MTP_OBJ_PROPERTYCODE_ASSOCIATIONTYPE) {
+               memcpy(&obj_info->association_type, buf, sizeof(mtp_uint16));
+               p_size = sizeof(mtp_uint16);
+       } else {
+               ERR("Propert [0x%x] is GETONLY\n", prop_code);
+       }
+
+       if (prop_sz != NULL) {
+               *prop_sz = p_size;
+       }
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_get_prop_desc(mtp_uint32 format, mtp_uint32 prop_code,
+               void *data)
+{
+       obj_prop_desc_t *prop = NULL;
+
+       prop = _prop_get_obj_prop_desc(format, prop_code);
+       if (prop == NULL) {
+               ERR("pProperty is NULL");
+               return MTP_ERROR_GENERAL;
+       }
+
+       memcpy(data, prop, sizeof(obj_prop_desc_t));
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_get_object_prop_supported(mtp_uint32 format,
+               ptp_array_t     *prop_arr)
+{
+       _prop_get_supp_obj_props(format, prop_arr);
+       return MTP_ERROR_NONE;
+}
+
+#ifndef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+mtp_err_t _hutil_get_object_prop_list(mtp_uint32 obj_handle, mtp_uint32 format,
+               mtp_uint32 prop_code, mtp_uint32 group_code, mtp_uint32 depth,
+               obj_proplist_t *prop_list)
+#else /* MTP_USE_RUNTIME_GETOBJECTPROPVALUE */
+mtp_err_t _hutil_get_object_prop_list(mtp_uint32 obj_handle, mtp_uint32 format,
+               mtp_uint32 prop_code, mtp_uint32 group_code, mtp_uint32 depth,
+               obj_proplist_t *prop_list, ptp_array_t *obj_arr)
+#endif /* MTP_USE_RUNTIME_GETOBJECTPROPVALUE */
+{
+#ifndef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+       ptp_array_t obj_arr = { 0 };
+#endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+       mtp_obj_t *obj = NULL;
+       mtp_uint32 i = 0;
+       mtp_uint32 ii = 0;
+       mtp_store_t *store = NULL;
+
+       if ((obj_handle != PTP_OBJECTHANDLE_UNDEFINED) &&
+                       (obj_handle != PTP_OBJECTHANDLE_ALL)) {
+               /* Is this object handle valid? */
+               store = _device_get_store_containing_obj(obj_handle);
+               if (store == NULL) {
+                       ERR("invalid object handle");
+                       return MTP_ERROR_INVALID_OBJECTHANDLE;
+               }
+       }
+
+       if (prop_code == PTP_PROPERTY_UNDEFINED) {
+               /* PropGroupCode should be used if Property code
+                * is not specified.
+                * */
+               if (group_code == 0x0) {
+                       ERR("PropGroupCode is zero");
+                       return MTP_ERROR_INVALID_PARAM;
+               }
+       }
+
+       if (!(obj_handle == PTP_OBJECTHANDLE_ALL ||
+                               obj_handle == PTP_OBJECTHANDLE_UNDEFINED) &&
+                       !(format == PTP_FORMATCODE_NOTUSED ||
+                               format == PTP_FORMATCODE_ALL)) {
+               ERR("both object handle and format code is specified!\
+                               return nospecification by format");
+               return MTP_ERROR_NO_SPEC_BY_FORMAT;
+       }
+
+       _util_init_list(&(prop_list->prop_quad_list));
+       _prop_init_ptparray(obj_arr, PTR_TYPE);
+
+       if (store != NULL) {
+               _entity_get_objects_from_store_till_depth(store, obj_handle,
+                               format, depth, obj_arr);
+       } else {
+               for (ii = 0; ii < _device_get_num_stores(); ii++) {
+                       store = _device_get_store_at_index(ii);
+                       _entity_get_objects_from_store_till_depth(store,
+                                       obj_handle, format, depth, obj_arr);
+               }
+       }
+
+       if (obj_arr->num_ele != 0) {
+               mtp_obj_t **ptr_obj;
+               ptr_obj = obj_arr->array_entry;
+
+               for (i = 0; i < obj_arr->num_ele; i++) {
+                       obj = ptr_obj[i];
+                       if (!obj)
+                               continue;
+
+                       if (_prop_get_obj_proplist(obj, prop_code, group_code,
+                                               prop_list) == FALSE) {
+                               ERR("Fail to create Proplist");
+#ifndef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+                               _prop_deinit_ptparray(&obj_arr);
+#endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+                               return MTP_ERROR_GENERAL;
+                       }
+               }
+       }
+
+#ifndef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
+       prop_deinit_ptparray(&obj_arr);
+#endif /*MTP_USE_RUNTIME_GETOBJECTPROPVALUE*/
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_remove_object_reference(mtp_uint32 obj_handle,
+               mtp_uint32 ref_handle)
+{
+       mtp_obj_t *obj = NULL;
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (obj == NULL) {
+               ERR("No object for handle[%d]\n", obj_handle);
+               return MTP_ERROR_NONE;
+       }
+
+       if (_entity_remove_reference_child_array(obj, ref_handle) == FALSE) {
+               ERR("_entity_remove_reference_child_array Fail");
+       }
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_add_object_references_enhanced(mtp_uint32 obj_handle,
+               mtp_uchar *buffer, mtp_uint32 buf_sz)
+{
+       mtp_obj_t *obj = NULL;
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (obj == NULL) {
+               DBG("No object for handle[0x%x]\n", obj_handle);
+               return MTP_ERROR_NONE;
+       }
+
+       if (_entity_set_reference_child_array(obj, buffer, buf_sz) == FALSE) {
+               ERR("_entity_set_reference_child_array Fail");
+               return MTP_ERROR_GENERAL;
+       }
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_get_object_references(mtp_uint32 obj_handle,
+               ptp_array_t *parray, mtp_uint32 *num_ele)
+{
+       mtp_obj_t *obj = NULL;
+       mtp_obj_t *ref_obj = NULL;
+       mtp_uint16 idx = 0;
+       mtp_uint32 *ref_ptr = NULL;
+       ptp_array_t ref_arr = { 0 };
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (NULL == obj || NULL == obj->obj_info) {
+               *num_ele = 0;
+               return MTP_ERROR_INVALID_OBJECTHANDLE;
+       }
+
+       if (parray == NULL) {
+               *num_ele = 0;
+               return MTP_ERROR_GENERAL;
+       }
+
+       if (obj->child_array.num_ele == 0) {
+               *num_ele = 0;
+               return MTP_ERROR_NONE;
+       }
+
+       _prop_init_ptparray(&ref_arr, obj->child_array.type);
+       _prop_copy_ptparray(&ref_arr, &(obj->child_array));
+       ref_ptr = (mtp_uint32 *)(ref_arr.array_entry);
+
+       for (idx = 0; idx < ref_arr.num_ele; idx++) {
+               ref_obj = _device_get_object_with_handle(ref_ptr[idx]);
+               if (ref_obj == NULL) {
+                       _entity_remove_reference_child_array(obj, ref_ptr[idx]);
+               }
+       }
+
+       *num_ele = obj->child_array.num_ele;
+       if (*num_ele) {
+               _prop_init_ptparray(parray, obj->child_array.type);
+               _prop_grow_ptparray(parray, *num_ele);
+               _prop_copy_ptparray(parray, &(obj->child_array));
+       }
+
+       _prop_deinit_ptparray(&ref_arr);
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_get_number_of_objects(mtp_uint32 store_id, mtp_uint32 *num_obj)
+{
+       *num_obj = _device_get_num_objects(store_id);
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_get_interdep_prop_config_list_size(mtp_uint32 *list_sz,
+               mtp_uint32 format)
+{
+       *list_sz = _prop_get_size_interdep_proplist(&interdep_proplist,
+                       format);
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _hutil_get_interdep_prop_config_list_data(void *data,
+               mtp_uint32 list_sz, mtp_uint32 format)
+{
+       if (list_sz == _prop_pack_interdep_proplist(&interdep_proplist,
+                               format, data, list_sz)) {
+               return MTP_ERROR_NONE;
+       }
+
+       ERR("packet and requested size do not match");
+       return MTP_ERROR_GENERAL;
+}
+
+mtp_err_t _hutil_get_playback_skip(mtp_int32 skip_param)
+{
+       mtp_int32 idx = 0;
+       mtp_obj_t *obj = NULL;
+       mtp_uint32 new_idx = 0;
+       mtp_uint32 new_hobj = 0;
+       mtp_uint32 obj_handle = 0;
+       mtp_obj_t *par_obj = NULL;
+       obj_info_t *obj_info = NULL;
+       ptp_array_t *ref_arr = NULL;
+       device_prop_desc_t *dev_prop = NULL;
+
+       retv_if(skip_param == 0, MTP_ERROR_INVALID_PARAM);
+
+       if (_device_get_playback_obj(&obj_handle) == FALSE) {
+               ERR("_device_get_playback_obj Fail");
+               return MTP_ERROR_GENERAL;
+       }
+
+       if (obj_handle == 0x0) {
+               return MTP_ERROR_NONE;
+       }
+
+       obj = _device_get_object_with_handle(obj_handle);
+       if (obj == NULL || obj->obj_info == NULL) {
+               ERR("obj or obj_info is NULL");
+               return MTP_ERROR_GENERAL;
+       }
+
+       obj_info = obj->obj_info;
+       if ((obj_info->obj_fmt == PTP_FMT_WAVE) ||
+                       (obj_info->obj_fmt == PTP_FMT_MP3) ||
+                       (obj_info->obj_fmt == MTP_FMT_WMA) ||
+                       (obj_info->obj_fmt == MTP_FMT_WMV) ||
+                       (obj_info->obj_fmt == MTP_FMT_UNDEFINED_AUDIO)) {
+               par_obj = _device_get_object_with_handle(obj_info->h_parent);
+               if (!par_obj) {
+                       ERR("parent not found in obj_list");
+                       return MTP_ERROR_GENERAL;
+               }
+               ref_arr = _entity_get_reference_child_array(par_obj);
+               idx = _prop_find_ele_ptparray(ref_arr, obj_handle);
+               if (idx != ELEMENT_NOT_FOUND) {
+                       if (((long long)idx + (long long)skip_param) > UINT_MAX) {
+                               new_idx = ref_arr->num_ele - 1;
+                       } else if ((idx + skip_param) >= ref_arr->num_ele) {
+                               new_idx = 0;
+                       } else {
+                               new_idx = idx + skip_param;
+                       }
+
+                       if (_prop_get_ele_ptparray(ref_arr, new_idx,
+                                               (void *)(&new_hobj)) == TRUE) {
+                               dev_prop = _device_get_device_property(
+                                               MTP_PROPERTYCODE_PLAYBACK_CONT_INDEX);
+                               if (dev_prop == NULL) {
+                                       ERR("dev_prop is null");
+                                       return MTP_ERROR_GENERAL;
+                               }
+                               _prop_set_current_integer(dev_prop, 0xFFFFFFFF);
+                               _device_set_playback_obj(new_hobj);
+                       }
+               }
+       } else if ((obj_info->obj_fmt == MTP_FMT_ABSTRACT_AUDIO_ALBUM) ||
+                       (obj_info->obj_fmt == MTP_FMT_ABSTRACT_VIDEO_ALBUM)) {
+               dev_prop = _device_get_device_property(
+                               MTP_PROPERTYCODE_PLAYBACK_CONT_INDEX);
+               if (dev_prop == NULL) {
+                       ERR("dev_prop is null");
+                       return MTP_ERROR_GENERAL;
+               }
+               memcpy(&idx, dev_prop->current_val.integer, sizeof(mtp_uint32));
+               ref_arr = _entity_get_reference_child_array(obj);
+               if (((long long)idx + (long long)skip_param) > UINT_MAX) {
+                       new_idx = ref_arr->num_ele - 1;
+               } else if ((idx + skip_param) >= ref_arr->num_ele) {
+                       new_idx = 0;
+               } else {
+                       new_idx = idx + skip_param;
+               }
+               _prop_set_current_integer(dev_prop, new_idx);
+               return MTP_ERROR_NONE;
+       }
+
+       return MTP_ERROR_GENERAL;
+}
+
+mtp_err_t _hutil_format_storage(mtp_uint32 store_id, mtp_uint32 fs_format)
+{
+       mtp_err_t error = MTP_ERROR_GENERAL;
+       mtp_store_t *store = NULL;
+
+       store = _device_get_store(store_id);
+       if (store == NULL) {
+               ERR("Store is NULL");
+               return error;
+       }
+
+       error = _entity_format_store(store, fs_format);
+       if (error == PTP_RESPONSE_OK) {
+               return MTP_ERROR_NONE;
+       }
+
+       ERR("Format store Fail");
+       return error;
+}
+
+mtp_uint32 _hutil_get_storage_info_size(store_info_t *store_info)
+{
+       mtp_uint32 size = 0;
+
+       size += sizeof(store_info->access);
+       size += sizeof(store_info->fs_type);
+       size += sizeof(store_info->free_space);
+       size += sizeof(store_info->free_space_in_objs);
+       size += sizeof(store_info->capacity);
+       size += sizeof(store_info->store_type);
+       size += _prop_size_ptpstring(&(store_info->store_desc));
+       size += _prop_size_ptpstring(&(store_info->vol_label));
+
+       return size;
+}
diff --git a/src/mtp_event_handler.c b/src/mtp_event_handler.c
new file mode 100755 (executable)
index 0000000..2be6496
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <glib.h>
+#include "mtp_event_handler.h"
+#include "mtp_cmd_handler.h"
+#include "mtp_util.h"
+#include "mtp_thread.h"
+#include "mtp_init.h"
+#include "mtp_usb_driver.h"
+#include "mtp_transport.h"
+#include "mtp_media_info.h"
+
+/*
+ * GLOBAL AND EXTERN VARIABLES
+ */
+extern mtp_mgr_t g_mtp_mgr;
+pthread_t g_eh_thrd;   /* event handler thread */
+mtp_int32 g_pipefd[2];
+
+/*
+ * STATIC VARIABLES
+ */
+static mtp_mgr_t *g_mgr = &g_mtp_mgr;
+
+/*
+ * STATIC FUNCTIONS
+ */
+static mtp_bool __process_event_request(mtp_event_t *evt);
+static void *__thread_event_handler(void *arg);
+static mtp_bool __send_events_from_device_to_pc(mtp_dword store_id,
+               mtp_uint16 ptp_event, mtp_uint32 param1, mtp_uint32 param2);
+static void __handle_usb_notification(keynode_t *key, void *data);
+static void __handle_usb_mode_notification(keynode_t *key, void *data);
+static mtp_bool __send_start_event_to_eh_thread(void);
+
+/*
+ * FUNCTIONS
+ */
+mtp_bool _eh_register_notification_callbacks(void)
+{
+       mtp_int32 ret;
+       phone_status_t val = 0;
+
+       _util_get_usb_status(&val);
+       _util_set_local_usb_status(val);
+       ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
+                       __handle_usb_notification, NULL);
+       if (ret < 0) {
+               ERR("vconf_notify_key_changed(%s) Fail", VCONFKEY_SYSMAN_USB_STATUS);
+               return FALSE;
+       }
+
+       _util_get_usbmode_status(&val);
+       _util_set_local_usbmode_status(val);
+       ret = vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
+                       __handle_usb_mode_notification, NULL);
+       if (ret < 0) {
+               ERR("vconf_notify_key_changed(%s) Fail", VCONFKEY_SETAPPL_USB_MODE_INT);
+               return FALSE;
+       }
+
+       _util_get_mmc_status(&val);
+       _util_set_local_mmc_status(val);
+
+       DBG("Phone status: USB = [%d] MMC = [%d] USB_MODE = [%d]\n",
+                       _util_get_local_usb_status(), _util_get_local_mmc_status(),
+                       _util_get_local_usbmode_status());
+
+       return TRUE;
+}
+
+mtp_bool _eh_handle_usb_events(mtp_uint32 type)
+{
+       mtp_state_t state = MTP_STATE_STOPPED;
+       mtp_int32 res = 0;
+       /* Prevent repeated USB insert/remove mal-function */
+       static mtp_int32 is_usb_inserted = 0;
+       static mtp_int32 is_usb_removed = 0;
+
+       state = _transport_get_mtp_operation_state();
+
+       switch (type) {
+       case USB_INSERTED:
+               if (is_usb_inserted == 1) {
+                       ERR("USB is already connected");
+                       return TRUE;
+               }
+
+               is_usb_inserted = 1;
+               /* check USB connection state */
+               if (MTP_PHONE_USB_DISCONNECTED == _util_get_local_usb_status()) {
+                       ERR("USB is disconnected. So just return.");
+                       return FALSE;
+               }
+
+               _transport_set_usb_discon_state(FALSE);
+               _transport_set_cancel_initialization(FALSE);
+
+               if (state == MTP_STATE_INITIALIZING) {
+                       ERR("MTP is already being initialized");
+                       break;
+               }
+
+               res = pipe(g_pipefd);
+               if (res < 0) {
+                       ERR("pipe() Fail");
+                       _util_print_error();
+                       return FALSE;
+               }
+
+               res = _util_thread_create(&g_eh_thrd,
+                               "Mtp Event Request Handler", PTHREAD_CREATE_JOINABLE,
+                               __thread_event_handler, NULL);
+               if (FALSE == res) {
+                       ERR("_util_thread_create() Fail");
+                       return FALSE;
+               }
+
+               __send_start_event_to_eh_thread();
+
+               break;
+
+       case USB_REMOVED:
+               if (is_usb_removed == 1) {
+                       ERR("USB is already removed");
+                       return TRUE;
+               }
+
+               is_usb_removed = 1;
+               DBG("USB is disconnected");
+
+               _transport_set_usb_discon_state(TRUE);
+               _transport_set_cancel_initialization(TRUE);
+
+               /* cancel all transaction */
+               _transport_set_control_event(PTP_EVENTCODE_CANCELTRANSACTION);
+
+               _transport_usb_finalize();
+               _transport_set_mtp_operation_state(MTP_STATE_STOPPED);
+
+               /*
+                * Temp file should be deleted after usb usb read/write threads
+                * are terminated. Because data receive thread tries to
+                * write the temp file until sink thread is terminated.
+                */
+               if (g_mgr->ftemp_st.filepath != NULL &&
+                               (access(g_mgr->ftemp_st.filepath, F_OK) == 0)) {
+                       DBG("USB disconnected but temp file is remaind.\
+                                       It will be deleted.");
+
+                       if (g_mgr->ftemp_st.fhandle != INVALID_FILE) {
+                               DBG("handle is found. At first close file");
+                               _util_file_close(g_mgr->ftemp_st.fhandle);
+                               g_mgr->ftemp_st.fhandle = INVALID_FILE;
+                       }
+                       if (remove(g_mgr->ftemp_st.filepath) < 0) {
+                               ERR_SECURE("remove(%s) Fail", g_mgr->ftemp_st.filepath);
+                               _util_print_error();
+                       }
+                       g_free(g_mgr->ftemp_st.filepath);
+                       g_mgr->ftemp_st.filepath = NULL;
+               }
+
+               _mtp_deinit();
+               _device_uninstall_storage(MTP_ADDREM_AUTO);
+               _eh_send_event_req_to_eh_thread(EVENT_CLOSE, 1, 0, NULL);
+               break;
+
+       default:
+               ERR("can be ignored notify [0x%x]\n", type);
+               break;
+       }
+       return TRUE;
+}
+
+static mtp_bool __process_event_request(mtp_event_t *evt)
+{
+       retv_if(evt == NULL, FALSE);
+
+       switch (evt->action) {
+       case EVENT_CANCEL_INITIALIZATION:
+               DBG("EVENT_CANCEL_INITIALIZATION entered.");
+               _device_uninstall_storage(MTP_ADDREM_AUTO);
+               break;
+
+       case EVENT_START_MAIN_OP:
+               DBG("EVENT_START_MAIN_OP entered.");
+
+               /* start MTP */
+               _transport_set_cancel_initialization(FALSE);
+               _transport_set_mtp_operation_state(MTP_STATE_INITIALIZING);
+
+               _mtp_init(evt->param1);
+               _transport_set_mtp_operation_state(MTP_STATE_READY_SERVICE);
+               if (FALSE == _transport_init_interfaces(_receive_mq_data_cb)) {
+                       ERR("USB init fail");
+                       kill(getpid(), SIGTERM);
+                       break;
+               }
+               _transport_set_mtp_operation_state(MTP_STATE_ONSERVICE);
+               break;
+
+       case EVENT_USB_REMOVED:
+               _util_flush_db();
+               _eh_handle_usb_events(USB_REMOVED);
+               break;
+
+       case EVENT_OBJECT_ADDED:
+               __send_events_from_device_to_pc(0, PTP_EVENTCODE_OBJECTADDED,
+                               evt->param1, 0);
+               break;
+
+       case EVENT_OBJECT_REMOVED:
+               __send_events_from_device_to_pc(0,
+                               PTP_EVENTCODE_OBJECTREMOVED, evt->param1, 0);
+               break;
+
+       case EVENT_OBJECT_PROP_CHANGED:
+               __send_events_from_device_to_pc(0,
+                               MTP_EVENTCODE_OBJECTPROPCHANGED, evt->param1,
+                               evt->param2);
+               break;
+
+       case EVENT_CLOSE:
+               break;
+
+       default:
+               ERR("Unknown action");
+               break;
+       }
+       return TRUE;
+}
+
+static void *__thread_event_handler(void *arg)
+{
+       DBG("__thread_event_handler is started ");
+
+       mtp_int32 flag = 1;
+       mtp_event_t evt;
+
+       while (flag) {
+               mtp_int32 status = 0;
+               status = read(g_pipefd[0], &evt, sizeof(mtp_event_t));
+               if(( status== -1) && errno == EINTR) {
+                       ERR("read() Fail");
+                       continue;
+               }
+
+               __process_event_request(&evt);
+
+               if (evt.action == EVENT_CLOSE) {
+                       /* USB removed, terminate the thread */
+                       flag = 0;
+               }
+       }
+
+       DBG("######### MTP TERMINATED #########");
+       close(g_pipefd[0]);
+       close(g_pipefd[1]);
+
+       _util_thread_exit("__thread_event_handler thread is over.");
+       return NULL;
+}
+
+static mtp_bool __send_events_from_device_to_pc(mtp_dword store_id,
+               mtp_uint16 ptp_event, mtp_uint32 param1, mtp_uint32 param2)
+{
+       cmd_container_t event = { 0, };
+
+       memset(&event, 0, sizeof(cmd_container_t));
+
+       switch (ptp_event) {
+       case PTP_EVENTCODE_STOREADDED:
+               DBG("case PTP_EVENTCODE_STOREADDED:");
+               DBG("store_id [0x%x]\n", store_id);
+               _hdlr_init_event_container(&event, PTP_EVENTCODE_STOREADDED, 0,
+                               store_id, 0);
+               break;
+
+       case PTP_EVENTCODE_STOREREMOVED:
+               DBG("case PTP_EVENTCODE_STOREREMOVED");
+               DBG("store_id [0x%x]\n", store_id);
+               _hdlr_init_event_container(&event,
+                               PTP_EVENTCODE_STOREREMOVED, 0, store_id, 0);
+               break;
+
+       case PTP_EVENTCODE_OBJECTADDED:
+               DBG("case PTP_EVENTCODE_OBJECTADDED");
+               DBG("param1 : [0x%x]\n", param1);
+               _hdlr_init_event_container(&event, PTP_EVENTCODE_OBJECTADDED,
+                               0, param1, 0);
+               break;
+
+       case PTP_EVENTCODE_OBJECTREMOVED:
+               DBG("case PTP_EVENTCODE_OBJECTREMOVED");
+               DBG("param1 [0x%x]\n", param1);
+               _hdlr_init_event_container(&event, PTP_EVENTCODE_OBJECTREMOVED,
+                               0, param1 , 0);
+               break;
+
+       case MTP_EVENTCODE_OBJECTPROPCHANGED:
+               DBG("case MTP_EVENTCODE_OBJECTPROPCHANGED");
+               DBG("param1 [0x%x]\n", param1);
+               DBG("param2 [0x%x]\n", param2);
+               _hdlr_init_event_container_with_param(&event,
+                               MTP_EVENTCODE_OBJECTPROPCHANGED, 0, param1 , param2);
+               break;
+
+       default:
+               DBG("Event not supported");
+               return FALSE;
+       }
+
+       return _hdlr_send_event_container(&event);
+}
+
+static void __handle_usb_notification(keynode_t *key, void *data)
+{
+       phone_status_t val = MTP_PHONE_USB_DISCONNECTED;
+       mtp_int32 intval = VCONFKEY_SYSMAN_USB_DISCONNECTED;
+
+       ret_if(key == NULL);
+
+       intval = vconf_keynode_get_int(key);
+       if (-1 == intval) {
+               ERR("vconf_keynode_get_int() Fail");
+               return;
+       }
+
+       if (VCONFKEY_SYSMAN_USB_DISCONNECTED == intval) {
+               DBG("USB Disconnected");
+               _util_set_local_usb_status(val);
+               mtp_end_event();
+               return;
+       }
+
+       val = MTP_PHONE_USB_CONNECTED;
+       _util_set_local_usb_status(val);
+       DBG("USB Connected. Just return.");
+       return;
+}
+
+static void __handle_usb_mode_notification(keynode_t *key, void *data)
+{
+       phone_status_t val = MTP_PHONE_USB_MODE_OTHER;
+
+       ret_if(key == NULL);
+
+       val = vconf_keynode_get_int(key);
+
+       _util_set_local_usbmode_status(val);
+       return;
+}
+
+void _handle_mmc_notification(keynode_t *key, void *data)
+{
+       phone_status_t val = MTP_PHONE_MMC_NONE;
+
+       _util_get_mmc_status(&val);
+       _util_set_local_mmc_status(val);
+
+       if (MTP_PHONE_MMC_INSERTED == val) {
+               _device_install_storage(MTP_ADDREM_EXTERNAL);
+               __send_events_from_device_to_pc(MTP_EXTERNAL_STORE_ID,
+                               PTP_EVENTCODE_STOREADDED, 0, 0);
+
+       } else if (MTP_PHONE_MMC_NONE == val) {
+               _device_uninstall_storage(MTP_ADDREM_EXTERNAL);
+
+               __send_events_from_device_to_pc(MTP_EXTERNAL_STORE_ID,
+                               PTP_EVENTCODE_STOREREMOVED, 0, 0);
+       }
+
+       return;
+}
+
+void _eh_deregister_notification_callbacks(void)
+{
+       vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
+                       __handle_usb_notification);
+       vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
+                       __handle_usb_mode_notification);
+
+       return;
+}
+
+void _eh_send_event_req_to_eh_thread(event_code_t action, mtp_ulong param1,
+               mtp_ulong param2, void *param3)
+{
+       mtp_event_t event = { 0 };
+       mtp_int32 status;
+
+       event.action = action;
+       event.param1 = param1;
+       event.param2 = param2;
+       event.param3 = (mtp_ulong)param3;
+
+       DBG("action[%d], param1[%ld], param2[%ld]\n", action, param1, param2);
+
+       status = write(g_pipefd[1], &event, sizeof(mtp_event_t));
+       if(status== -1 || errno == EINTR) {
+               ERR("Event write over pipe Fail, status = [%d], pipefd = [%d], errno [%d]\n",
+                               status, g_pipefd[1], errno);
+       }
+       return;
+}
+
+static mtp_bool __send_start_event_to_eh_thread(void)
+{
+       mtp_event_t event;
+       mtp_int32 status;
+
+       event.action = EVENT_START_MAIN_OP;
+       event.param1 = (mtp_ulong) MTP_ADDREM_AUTO;
+       event.param2 = 0;
+       event.param3 = 0;
+
+       DBG("Action : START MTP OPERATION");
+
+       status = write(g_pipefd[1], &event, sizeof(mtp_event_t));
+       if(status== -1 || errno == EINTR) {
+               ERR("Event write over pipe Fail, status= [%d],pipefd = [%d], errno [%d]\n",
+                               status, g_pipefd[1], errno);
+               return FALSE;
+       }
+
+       return TRUE;
+}
diff --git a/src/mtp_init.c b/src/mtp_init.c
new file mode 100755 (executable)
index 0000000..55b8fde
--- /dev/null
@@ -0,0 +1,495 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <unistd.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <privilege-control.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <malloc.h>
+#include <vconf.h>
+#include "mtp_init.h"
+#include "mtp_config.h"
+#include "mtp_thread.h"
+#include "mtp_support.h"
+#include "mtp_device.h"
+#include "mtp_event_handler.h"
+#include "mtp_cmd_handler.h"
+#include "mtp_inoti_handler.h"
+#include "mtp_transport.h"
+#include "mtp_util.h"
+#include "mtp_media_info.h"
+
+/*
+ * GLOBAL AND EXTERN VARIABLES
+ */
+extern pthread_t g_eh_thrd;
+extern pthread_mutex_t g_cmd_inoti_mutex;
+extern mtp_bool g_is_sync_estab;
+
+mtp_mgr_t g_mtp_mgr;
+mtp_config_t g_conf;
+
+/*
+ * STATIC VARIABLES AND FUNCTIONS
+ */
+static GMainLoop *g_mainloop = NULL;
+static mtp_mgr_t *g_mgr = &g_mtp_mgr;
+static void __read_mtp_conf(void);
+static void __init_mtp_info(void);
+static void __mtp_exit(void);
+/*
+ * FUNCTIONS
+ */
+
+/*
+ * static void __mtp_exit(void)
+ * This function send MTP stopped state to event handler thread and MTP UI
+ * @param[in]          None.
+ * @param[out]         None.
+ * @return             None.
+ */
+static void __mtp_exit(void)
+{
+       long cur_time;
+
+       DBG("## Terminate all threads");
+       if (g_eh_thrd) {
+               _eh_send_event_req_to_eh_thread(EVENT_USB_REMOVED, 0, 0, NULL);
+               if (_util_thread_join(g_eh_thrd, NULL) == FALSE) {
+                       ERR("_util_thread_join() Fail");
+               }
+               g_eh_thrd = 0;
+       }
+
+       if (g_is_sync_estab) {
+               time(&cur_time);
+               vconf_set_int(VCONFKEY_MTP_SYNC_TIME_INT, (int)cur_time);
+       }
+
+       DBG("## Terminate main loop");
+
+       g_main_loop_quit(g_mainloop);
+
+       return;
+}
+
+void _mtp_init(add_rem_store_t sel)
+{
+       mtp_char wmpinfopath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char *device_name = NULL;
+       mtp_char *sync_partner = NULL;
+       mtp_bool ret = 0;
+       int vconf_ret = 0;
+       mtp_int32 error = 0;
+
+       DBG("Initialization start!");
+
+       __read_mtp_conf();
+
+       if (g_conf.mmap_threshold) {
+               if (!mallopt(M_MMAP_THRESHOLD, g_conf.mmap_threshold))
+                       ERR("mallopt(M_MMAP_THRESHOLD) Fail");
+
+               if (!mallopt(M_TRIM_THRESHOLD, g_conf.mmap_threshold * 2))
+                       ERR("mallopt(M_TRIM_THRESHOLD) Fail");
+       }
+
+       __init_mtp_info();
+
+       _transport_init_status_info();
+       _transport_set_mtp_operation_state(MTP_STATE_INITIALIZING);
+
+       device_name = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
+       if (device_name != NULL) {
+               _device_set_device_name(device_name);
+               g_free(device_name);
+       } else {
+               _device_set_device_name(MTP_DEV_PROPERTY_FRIENDLYNAME);
+       }
+
+       sync_partner = vconf_get_str(VCONFKEY_MTP_SYNC_PARTNER_STR);
+       if (sync_partner != NULL && strlen(sync_partner) > 0) {
+               _device_set_sync_partner(sync_partner);
+               g_free(sync_partner);
+       } else {
+               _device_set_sync_partner(MTP_DEV_PROPERTY_SYNCPARTNER);
+       }
+
+
+       g_mgr->ftemp_st.filepath = g_strdup(MTP_TEMP_FILE_DEFAULT);
+       if (g_mgr->ftemp_st.filepath == NULL) {
+               ERR("g_strdup() Fail");
+               goto MTP_INIT_FAIL;
+       }
+
+       if (g_mgr->ftemp_st.temp_buff == NULL) {
+               /* Allocate memory for temporary */
+               g_mgr->ftemp_st.temp_buff = (mtp_char *)g_malloc(g_conf.write_file_size);
+               if (g_mgr->ftemp_st.temp_buff == NULL) {
+                       ERR("memory allocation fail");
+                       goto MTP_INIT_FAIL;
+               }
+       }
+
+       /* Internal Storage */
+       if (access(MTP_STORE_PATH_CHAR, F_OK) < 0) {
+               if (FALSE == _util_dir_create(MTP_STORE_PATH_CHAR, &error)) {
+                       ERR("Cannot make directory!! [%s]\n",
+                                       MTP_STORE_PATH_CHAR);
+                       goto MTP_INIT_FAIL;
+               }
+       }
+       /* External Storage */
+       if (MTP_PHONE_MMC_INSERTED == _util_get_local_mmc_status()) {
+               if (access(MTP_EXTERNAL_PATH_CHAR, F_OK) < 0) {
+                       if (FALSE == _util_dir_create(MTP_EXTERNAL_PATH_CHAR, &error)) {
+                               ERR("Cannot make directory!! [%s]\n",
+                                               MTP_EXTERNAL_PATH_CHAR);
+                               goto MTP_INIT_FAIL;
+                       }
+               }
+       }
+#ifndef MTP_SUPPORT_HIDE_WMPINFO_XML
+       /* Update WMPInfo.xml for preventing frequent saving */
+       ret = _util_create_path(wmpinfopath, sizeof(wmpinfopath),
+                       MTP_STORE_PATH_CHAR, MTP_FILE_NAME_WMPINFO_XML);
+       if (FALSE == ret) {
+               ERR("szWMPInfoPath is too long");
+               goto MTP_INIT_FAIL;
+       }
+#endif /*MTP_SUPPORT_HIDE_WMPINFO_XML*/
+
+       /* Set mtpdeviceinfo */
+       _init_mtp_device();
+
+       _features_supported_info();
+
+       /* Install storage */
+       _device_install_storage(sel);
+
+#ifdef MTP_SUPPORT_OBJECTADDDELETE_EVENT
+       _inoti_init_filesystem_evnts();
+#endif /*MTP_SUPPORT_OBJECTADDDELETE_EVENT*/
+
+       vconf_ret = vconf_notify_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
+                       _handle_mmc_notification, NULL);
+       if (vconf_ret < 0) {
+               ERR("vconf_notify_key_changed(%s) Fail", VCONFKEY_SYSMAN_MMC_STATUS);
+               goto MTP_INIT_FAIL;
+       }
+
+       return;
+
+MTP_INIT_FAIL:
+       /* Set MTP state to stopped */
+       _transport_set_mtp_operation_state(MTP_STATE_STOPPED);
+       mtp_end_event();
+
+       return;
+}
+
+void _mtp_deinit(void)
+{
+       _cmd_hdlr_reset_cmd(&g_mgr->hdlr);
+
+       /* initialize MTP_USE_FILE_BUFFER*/
+       if (g_mgr->ftemp_st.temp_buff != NULL) {
+               g_free(g_mgr->ftemp_st.temp_buff);
+               g_mgr->ftemp_st.temp_buff = NULL;
+       }
+
+#ifdef MTP_SUPPORT_OBJECTADDDELETE_EVENT
+       _inoti_deinit_filesystem_events();
+#endif /*MTP_SUPPORT_OBJECTADDDELETE_EVENT*/
+
+       vconf_ignore_key_changed(VCONFKEY_SYSMAN_MMC_STATUS,
+                       _handle_mmc_notification);
+
+       return;
+}
+
+static void __print_mtp_conf(void)
+{
+       if (g_conf.is_init == false) {
+               ERR("g_conf is not initialized");
+               return;
+       }
+
+       DBG("MMAP_THRESHOLD : %d\n", g_conf.mmap_threshold);
+       DBG("INIT_RX_IPC_SIZE : %d\n", g_conf.init_rx_ipc_size);
+       DBG("INIT_TX_IPC_SIZE : %d\n", g_conf.init_tx_ipc_size);
+       DBG("MAX_RX_IPC_SIZE : %d\n", g_conf.max_rx_ipc_size);
+       DBG("MAX_TX_IPC_SIZE : %d\n", g_conf.max_tx_ipc_size);
+       DBG("READ_USB_SIZE : %d\n", g_conf.read_usb_size);
+       DBG("WRITE_USB_SIZE : %d\n", g_conf.write_usb_size);
+       DBG("READ_FILE_SIZE : %d\n", g_conf.read_file_size);
+       DBG("WRITE_FILE_SIZE : %d\n", g_conf.write_file_size);
+       DBG("MAX_IO_BUF_SIZE : %d\n\n", g_conf.max_io_buf_size);
+
+       DBG("SUPPORT_PTHEAD_SHCED : %s\n", g_conf.support_pthread_sched ? "Support" : "Not support");
+       DBG("INHERITSCHED : %c\n", g_conf.inheritsched);
+       DBG("SCHEDPOLICY : %c\n", g_conf.schedpolicy);
+       DBG("FILE_SCHEDPARAM: %d\n", g_conf.file_schedparam);
+       DBG("USB_SCHEDPARAM: %d\n\n", g_conf.usb_schedparam);
+}
+
+static void __read_mtp_conf(void)
+{
+       FILE *fp;
+       char buf[256];
+       char *token;
+
+       g_conf.mmap_threshold = MTP_MMAP_THRESHOLD;
+
+       g_conf.read_usb_size = MTP_READ_USB_SIZE;
+       g_conf.write_usb_size = MTP_WRITE_USB_SIZE;
+
+       g_conf.read_file_size = MTP_READ_FILE_SIZE;
+       g_conf.write_file_size = MTP_WRITE_FILE_SIZE;
+
+       g_conf.init_rx_ipc_size = MTP_INIT_RX_IPC_SIZE;
+       g_conf.init_tx_ipc_size = MTP_INIT_TX_IPC_SIZE;
+
+       g_conf.max_rx_ipc_size = MTP_MAX_RX_IPC_SIZE;
+       g_conf.max_tx_ipc_size = MTP_MAX_TX_IPC_SIZE;
+
+       g_conf.max_io_buf_size = MTP_MAX_IO_BUF_SIZE;
+       g_conf.read_file_delay = MTP_READ_FILE_DELAY;
+
+       if (MTP_SUPPORT_PTHREAD_SCHED) {
+               g_conf.support_pthread_sched = MTP_SUPPORT_PTHREAD_SCHED;
+               g_conf.inheritsched = MTP_INHERITSCHED;
+               g_conf.schedpolicy = MTP_SCHEDPOLICY;
+               g_conf.file_schedparam = MTP_FILE_SCHEDPARAM;
+               g_conf.usb_schedparam = MTP_USB_SCHEDPARAM;
+       }
+
+       fp = fopen(MTP_CONFIG_FILE_PATH, "r");
+       if (fp == NULL) {
+               DBG("Default configuration is used");
+               g_conf.is_init = true;
+
+               __print_mtp_conf();
+               return;
+       }
+
+       while (fgets(buf, sizeof(buf), fp)) {
+               if (buf[0] == '#' || buf[0] == '\n')
+                       continue;
+
+               token = strrchr(buf, '\n');
+               if (token == NULL) {
+                       ERR("g_conf is too long");
+                       break;
+               }
+               *token = '\0';
+
+               token = strtok(buf, "=");
+               if (token == NULL) {
+                       continue;
+               }
+
+               if (strcasecmp(token, "mmap_threshold") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.mmap_threshold = atoi(token);
+
+               } else if (strcasecmp(token, "init_rx_ipc_size") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.init_rx_ipc_size = atoi(token);
+
+               } else if (strcasecmp(token, "init_tx_ipc_size") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.init_tx_ipc_size = atoi(token);
+
+               } else if (strcasecmp(token, "max_rx_ipc_size") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.max_rx_ipc_size = atoi(token);
+
+               } else if (strcasecmp(token, "max_tx_ipc_size") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.max_tx_ipc_size = atoi(token);
+
+               } else if (strcasecmp(token, "read_usb_size") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.read_usb_size = atoi(token);
+
+               } else if (strcasecmp(token, "write_usb_size") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.write_usb_size = atoi(token);
+
+               } else if (strcasecmp(token, "read_file_size") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.read_file_size = atoi(token);
+
+               } else if (strcasecmp(token, "write_file_size") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.write_file_size = atoi(token);
+
+               } else if (strcasecmp(token, "max_io_buf_size") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.max_io_buf_size = atoi(token);
+
+               } else if (strcasecmp(token, "read_file_delay") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.read_file_delay = atoi(token);
+
+               } else if (strcasecmp(token, "support_pthread_sched") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.support_pthread_sched = atoi(token) ? true : false;
+
+               } else if (strcasecmp(token, "inheritsched") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.inheritsched = *token;
+
+               } else if (strcasecmp(token, "schedpolicy") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.schedpolicy = *token;
+
+               } else if (strcasecmp(token, "file_schedparam") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.file_schedparam = atoi(token);
+
+               } else if (strcasecmp(token, "usb_schedparam") == 0) {
+                       token = strtok(NULL, "=");
+                       g_conf.usb_schedparam = atoi(token);
+
+               } else {
+                       ERR("Unknown option : %s\n", buf);
+               }
+       }
+       fclose(fp);
+       g_conf.is_init = true;
+
+       __print_mtp_conf();
+       return;
+}
+
+void __init_mtp_info(void)
+{
+       /* initialize struct one time*/
+       memset(&g_mgr->ftemp_st, 0, sizeof(g_mgr->ftemp_st));
+       memset(&g_mgr->hdlr, 0, sizeof(g_mgr->hdlr));
+       memset(&g_mgr->meta_info, 0, sizeof(g_mgr->meta_info));
+
+       return ;
+}
+
+void _features_supported_info(void)
+{
+       DBG("***********************************************************");
+       DBG("### MTP Information ###");
+       DBG("### 1. Solution            : SLP");
+       DBG("### 2. MTP Version         : 1.0");
+       DBG("### 3. DB Limitation       : Reference(%d)\n", MTP_MAX_REFDB_ROWCNT);
+
+       DBG("***********************************************************");
+       DBG("### Extension ###");
+       if (_get_oma_drm_status() == TRUE) {
+               DBG("### 2. OMADRM              : [ON]");
+       } else {
+               DBG("### 2. OMADRM              : [OFF]");
+       }
+
+       DBG("***********************************************************");
+       DBG("### Feature ###");
+
+#ifdef MTP_SUPPORT_ALBUM_ART
+       DBG("### 2. MTP_SUPPORT_ALBUM_ART       : [ON]");
+#else /* MTP_SUPPORT_ALBUM_ART */
+       DBG("### 2. MTP_SUPPORT_ALBUM_ART       : [OFF]");
+#endif /* MTP_SUPPORT_ALBUM_ART */
+
+#ifdef MTP_SUPPORT_SET_PROTECTION
+       DBG("### 3. MTP_SUPPORT_SET_PROTECTION  : [ON]");
+#else /* MTP_SUPPORT_SET_PROTECTION */
+       DBG("### 3. MTP_SUPPORT_SET_PROTECTION  : [OFF]");
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+       DBG("***********************************************************");
+       return;
+}
+
+/*
+ * void mtp_end_event(void)
+ * This function terminates mtp.
+ * It must not be called in gthr_mtp_event thread.
+ * It makes dead lock state if it is called in gthr_mtp_event thread.
+ */
+void mtp_end_event(void)
+{
+       __mtp_exit();
+}
+
+static inline int _main_init()
+{
+       pthread_mutexattr_t mutex_attr;
+
+       pthread_mutexattr_init(&mutex_attr);
+       pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
+       if (0 != pthread_mutex_init(&g_cmd_inoti_mutex, &mutex_attr)) {
+               ERR("pthread_mutex_init() Fail");
+               _util_print_error();
+               pthread_mutexattr_destroy(&mutex_attr);
+               return MTP_ERROR_GENERAL;
+       }
+       pthread_mutexattr_destroy(&mutex_attr);
+
+       if (_eh_handle_usb_events(USB_INSERTED) == FALSE) {
+               ERR("_eh_handle_usb_events() Fail");
+               return MTP_ERROR_GENERAL;
+       }
+
+       g_mainloop = g_main_loop_new(NULL, FALSE);
+       if (g_mainloop == NULL) {
+               ERR("g_mainloop is NULL");
+               return MTP_ERROR_GENERAL;
+       }
+
+       return MTP_ERROR_NONE;
+}
+
+int main(int argc, char *argv[])
+{
+       mtp_int32 ret;
+
+       ret = media_content_connect();
+       if (MEDIA_CONTENT_ERROR_NONE != ret) {
+               ERR("media_content_connect() Fail(%d)", ret);
+               return MTP_ERROR_GENERAL;
+       }
+
+       if (_eh_register_notification_callbacks() == FALSE) {
+               ERR("_eh_register_notification_callbacks() Fail");
+               return MTP_ERROR_GENERAL;
+       }
+
+       ret = _main_init();
+       if (MTP_ERROR_NONE != ret) {
+               ERR("_main_init() Fail(%d)", ret);
+               _eh_deregister_notification_callbacks();
+               media_content_disconnect();
+               return MTP_ERROR_GENERAL;
+       }
+       DBG("MTP UID = [%u] and GID = [%u]\n", getuid(), getgid());
+
+       g_main_loop_run(g_mainloop);
+
+       _eh_deregister_notification_callbacks();
+       media_content_disconnect();
+
+       return MTP_ERROR_NONE;
+}
diff --git a/src/mtp_inoti_handler.c b/src/mtp_inoti_handler.c
new file mode 100755 (executable)
index 0000000..64aeafc
--- /dev/null
@@ -0,0 +1,709 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <unistd.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include "mtp_thread.h"
+#include "mtp_inoti_handler.h"
+#include "mtp_event_handler.h"
+#include "mtp_support.h"
+#include "mtp_device.h"
+#include "mtp_util.h"
+
+/*
+ * GLOBAL AND STATIC VARIABLES
+ */
+pthread_mutex_t g_cmd_inoti_mutex;
+
+#ifdef MTP_SUPPORT_OBJECTADDDELETE_EVENT
+mtp_char g_last_created_dir[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+mtp_char g_last_deleted[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+mtp_char g_last_moved[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+mtp_char g_last_copied[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+static pthread_t g_inoti_thrd;
+static mtp_int32 g_cnt_watch_folder = 0;
+static mtp_int32 g_inoti_fd;
+static open_files_info_t *g_open_files_list;
+static inoti_watches_t g_inoti_watches[INOTI_FOLDER_COUNT_MAX];
+#endif /*MTP_SUPPORT_OBJECTADDDELETE_EVENT*/
+
+/*
+ * STATIC FUNCTIONS
+ */
+#ifdef MTP_SUPPORT_OBJECTADDDELETE_EVENT
+static mtp_bool __process_inoti_event(struct inotify_event *event);
+static void __remove_inoti_watch(mtp_char *path);
+static mtp_bool __add_file_to_inoti_open_files_list(mtp_int32 wd,
+               mtp_char *event_name);
+static open_files_info_t *__find_file_in_inoti_open_files_list(mtp_int32 wd,
+               mtp_char *event_name);
+static void __remove_file_from_inoti_open_files_list(open_files_info_t *node);
+static mtp_int32 __get_inoti_watch_id(mtp_int32 iwd);
+static mtp_bool __get_inoti_event_full_path(mtp_int32 wd, mtp_char *event_name,
+               mtp_char *path, mtp_int32 path_len, mtp_char *parent_path);
+static void __remove_recursive_inoti_watch(mtp_char *path);
+static void __clean_up_inoti(void *data);
+static void __delete_children_from_store_inoti(mtp_store_t *store,
+               mtp_obj_t *obj);
+static void __process_object_added_event(mtp_char *fullpath,
+               mtp_char *file_name, mtp_char *parent_path);
+static void __process_object_deleted_event(mtp_char *fullpath,
+               mtp_char *file_name, mtp_bool isdir);
+static void __destroy_inoti_open_files_list();
+#endif /* MTP_SUPPORT_OBJECTADDDELETE_EVENT */
+
+/*
+ * FUNCTIONS
+ */
+#ifdef MTP_SUPPORT_OBJECTADDDELETE_EVENT
+void *_thread_inoti(void *arg)
+{
+       mtp_int32 i = 0;
+       mtp_int32 length = 0;
+       mtp_int64 temp_idx;
+       mtp_char buffer[INOTI_BUF_LEN] = { 0 };
+       struct inotify_event *event = NULL;
+
+       pthread_cleanup_push(__clean_up_inoti, NULL);
+
+       DBG("START INOTIFY SYSTEM");
+
+       while (1) {
+               pthread_testcancel();
+               errno = 0;
+               i = 0;
+               length = read(g_inoti_fd, buffer, sizeof(buffer));
+               if (length < 0) {
+                       ERR("read() Fail");
+                       _util_print_error();
+                       break;
+               }
+
+               while (i < length) {
+                       event = (struct inotify_event *)(&buffer[i]);
+                       __process_inoti_event(event);
+                       temp_idx = i + event->len + INOTI_EVENT_SIZE;
+                       if (temp_idx > length) {
+                               break;
+                       } else {
+                               i = temp_idx;
+                       }
+               }
+       }
+
+       DBG("Inoti thread exited");
+       pthread_cleanup_pop(1);
+
+       return NULL;
+}
+
+void _inoti_add_watch_for_fs_events(mtp_char *path)
+{
+       mtp_int32 i = 0;
+
+       ret_if(path == NULL);
+
+       if (g_cnt_watch_folder == INOTI_FOLDER_COUNT_MAX) {
+               /* find empty cell */
+               for (i = 0; i < INOTI_FOLDER_COUNT_MAX; i++) {
+                       /* If not empty */
+                       if (g_inoti_watches[i].wd != 0) {
+                               continue;
+                       } else {
+                               break;
+                       }
+               }
+
+               if (i == INOTI_FOLDER_COUNT_MAX) {
+                       ERR("no empty space for a new inotify watch.");
+                       return;
+               }
+               DBG("g_watch_folders[%d] add watch : %s\n", i, path);
+               g_inoti_watches[i].forlder_name = g_strdup(path);
+               g_inoti_watches[i].wd = inotify_add_watch(g_inoti_fd,
+                               g_inoti_watches[i].forlder_name,
+                               IN_CLOSE_WRITE | IN_CREATE |
+                               IN_DELETE | IN_MOVED_FROM |
+                               IN_MOVED_TO);
+               return;
+       }
+
+       DBG("g_watch_folders[%d] add watch : %s\n", g_cnt_watch_folder, path);
+       g_inoti_watches[g_cnt_watch_folder].forlder_name = g_strdup(path);
+       g_inoti_watches[g_cnt_watch_folder].wd = inotify_add_watch(g_inoti_fd,
+                       g_inoti_watches[g_cnt_watch_folder].forlder_name,
+                       IN_CLOSE_WRITE |
+                       IN_CREATE | IN_DELETE |
+                       IN_MOVED_FROM |
+                       IN_MOVED_TO);
+       g_cnt_watch_folder++;
+
+       return;
+}
+
+mtp_bool _inoti_init_filesystem_evnts()
+{
+       mtp_bool ret = FALSE;
+
+       g_inoti_fd = inotify_init();
+       if (g_inoti_fd < 0) {
+               ERR("inotify_init() Fail : g_inoti_fd = %d", g_inoti_fd);
+               return FALSE;
+       }
+
+       ret = _util_thread_create(&g_inoti_thrd, "File system inotify thread\n",
+                       PTHREAD_CREATE_JOINABLE, _thread_inoti, NULL);
+       if (FALSE == ret) {
+               ERR("_util_thread_create() Fail");
+               _util_print_error();
+               close(g_inoti_fd);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+static mtp_bool __process_inoti_event(struct inotify_event *event)
+{
+       static mtp_int32 last_moved_cookie = -1;
+
+       mtp_bool res = FALSE;
+       mtp_char full_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char parentpath[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+       if (event->len == 0 || event->len > MTP_MAX_FILENAME_SIZE) {
+               ERR_SECURE("Event len is invalid[%d], event->name[%s]\n", event->len,
+                               event->name);
+               return FALSE;
+       } else if (event->wd < 1) {
+               ERR("invalid wd : %d\n", event->wd);
+               return FALSE;
+       }
+
+       /* start of one event */
+       res = __get_inoti_event_full_path(event->wd, event->name, full_path,
+                       sizeof(full_path), parentpath);
+       if (res == FALSE) {
+               ERR("__get_inoti_event_full_path() Fail");
+               return FALSE;
+       }
+
+       if (_util_is_path_len_valid(full_path) == FALSE) {
+               ERR("path len is invalid");
+               return FALSE;
+       }
+       DBG_SECURE("Event full path = %s\n", full_path);
+       if (event->mask & IN_MOVED_FROM) {
+               if (!g_strcmp0(g_last_moved, full_path)) {
+                       /* Ignore this case as this is generated due to MTP*/
+                       DBG("[%s] is moved_from by MTP\n", full_path);
+                       memset(g_last_moved, 0,
+                                       MTP_MAX_PATHNAME_SIZE + 1);
+                       last_moved_cookie = event->cookie;
+               } else if (event->mask & IN_ISDIR) {
+                       DBG("IN_MOVED_FROM --> IN_ISDIR");
+                       UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
+                       __process_object_deleted_event(full_path,
+                                       event->name, TRUE);
+                       UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
+               } else {
+                       DBG("IN_MOVED_FROM --> NOT IN_ISDIR");
+                       UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
+                       __process_object_deleted_event(full_path,
+                                       event->name, FALSE);
+                       UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
+               }
+       } else if (event->mask & IN_MOVED_TO) {
+               DBG("Moved To event, path = [%s]\n", full_path);
+               if (last_moved_cookie == event->cookie) {
+                       /* Ignore this case as this is generated due to MTP*/
+                       DBG("%s  is moved_to by MTP\n", full_path);
+                       last_moved_cookie = -1;
+               } else {
+                       UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
+                       __process_object_added_event(full_path,
+                                       event->name, parentpath);
+                       UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
+               }
+       } else if (event->mask & IN_CREATE) {
+               if (event->mask & IN_ISDIR) {
+                       DBG("IN_CREATE --> IN_ISDIR");
+                       if (!g_strcmp0(g_last_created_dir, full_path)) {
+                               /* Ignore this case as this is generated due to MTP*/
+                               DBG("%s folder is generated by MTP\n",
+                                               full_path);
+                               memset(g_last_created_dir, 0,
+                                               MTP_MAX_PATHNAME_SIZE + 1);
+                       } else {
+                               UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
+                               __process_object_added_event(full_path,
+                                               event->name, parentpath);
+                               UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
+                       }
+               } else {
+                       if (FALSE == __add_file_to_inoti_open_files_list(event->wd,
+                                               event->name)) {
+                               DBG_SECURE("__add_file_to_inoti_open_files_list fail\
+                                               %s\n", event->name);
+                       }
+                       DBG("IN_CREATE --> NOT IN_ISDIR");
+               }
+       } else if (event->mask &  IN_DELETE) {
+               if (!g_strcmp0(g_last_deleted, full_path)) {
+                       /* Ignore this case as this is generated due to MTP*/
+                       DBG("%s  is deleted by MTP\n", full_path);
+                       memset(g_last_deleted, 0,
+                                       MTP_MAX_PATHNAME_SIZE + 1);
+               } else if (event->mask & IN_ISDIR) {
+                       DBG("IN_DELETE --> IN_ISDIR");
+                       UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
+                       __process_object_deleted_event(full_path,
+                                       event->name, TRUE);
+                       UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
+               } else {
+                       DBG("IN_DELETE --> NOT IN_ISDIR");
+                       UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
+                       __process_object_deleted_event(full_path,
+                                       event->name, FALSE);
+                       UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
+               }
+       } else if (event->mask & IN_CLOSE_WRITE) {
+               DBG_SECURE("IN_CLOSE_WRITE %d, %s\n", event->wd, event->name);
+               if (!g_strcmp0(g_last_copied, full_path)) {
+                       /* Ignore this case as this is generated due to MTP*/
+                       DBG("[%s] is copied by MTP\n", full_path);
+                       memset(g_last_copied, 0,
+                                       MTP_MAX_PATHNAME_SIZE + 1);
+               } else {
+                       open_files_info_t *node = NULL;
+                       node = __find_file_in_inoti_open_files_list(event->wd,
+                                       event->name);
+
+                       if (node != NULL) {
+                               UTIL_LOCK_MUTEX(&g_cmd_inoti_mutex);
+                               __process_object_added_event(full_path,
+                                               event->name, parentpath);
+                               UTIL_UNLOCK_MUTEX(&g_cmd_inoti_mutex);
+                               __remove_file_from_inoti_open_files_list(node);
+                       }
+               }
+       } else {
+               DBG("This case is ignored");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+void _inoti_deinit_filesystem_events()
+{
+       if (TRUE != _util_thread_cancel(g_inoti_thrd)) {
+               ERR("thread cancel fail.");
+               return;
+       }
+
+       if (_util_thread_join(g_inoti_thrd, 0) == FALSE) {
+               ERR("_util_thread_join() Fail");
+       }
+
+       return;
+}
+
+static void __remove_inoti_watch(mtp_char *path)
+{
+       mtp_int32 i = 0;
+
+       for (i = 0; i < g_cnt_watch_folder; i++) {
+               if (g_inoti_watches[i].forlder_name == NULL) {
+                       continue;
+               }
+
+               if (g_strcmp0(g_inoti_watches[i].forlder_name, path) != 0) {
+                       continue;
+               }
+
+               g_free(g_inoti_watches[i].forlder_name);
+               g_inoti_watches[i].forlder_name = NULL;
+               inotify_rm_watch(g_inoti_fd, g_inoti_watches[i].wd);
+               g_inoti_watches[i].wd = 0;
+
+               break;
+       }
+
+       if (i == g_cnt_watch_folder)
+               ERR("Path not found in g_noti_watches");
+       return;
+}
+
+static mtp_bool __add_file_to_inoti_open_files_list(mtp_int32 wd,
+               mtp_char *event_name)
+{
+       open_files_info_t *new_node = NULL;
+
+       new_node = (open_files_info_t *)g_malloc(sizeof(open_files_info_t));
+       if (NULL == new_node) {
+               ERR("new_node is null malloc fail");
+               return FALSE;
+       }
+
+       new_node->name = g_strdup(event_name);
+       new_node->wd = wd;
+
+       /* First created file */
+       if (NULL == g_open_files_list) {
+               new_node->previous = NULL;
+       } else {
+               g_open_files_list->next = new_node;
+               new_node->previous = g_open_files_list;
+       }
+       new_node->next = NULL;
+       g_open_files_list = new_node;
+
+       return TRUE;
+}
+
+static open_files_info_t *__find_file_in_inoti_open_files_list(mtp_int32 wd,
+               mtp_char *event_name)
+{
+       open_files_info_t *current_node = g_open_files_list;
+
+       while (NULL != current_node) {
+               if ((current_node->wd == wd) &&
+                               (g_strcmp0(current_node->name, event_name) == 0)) {
+                       return current_node;
+               }
+
+               current_node = current_node->previous;
+       }
+
+       ERR("Cannot find file in open file's list");
+       return NULL;
+}
+
+static void __remove_file_from_inoti_open_files_list(open_files_info_t *node)
+{
+       if (NULL != node->previous) {
+               node->previous->next = node->next;
+       }
+
+       if (NULL != node->next) {
+               node->next->previous = node->previous;
+       }
+
+       if (node == g_open_files_list) {
+               g_open_files_list = node->previous;
+       }
+       g_free(node->name);
+       g_free(node);
+
+       return;
+}
+
+static mtp_int32 __get_inoti_watch_id(mtp_int32 iwd)
+{
+       mtp_int32 i = 0;
+
+       for (i = 0; i < INOTI_FOLDER_COUNT_MAX; i++) {
+               if (iwd == g_inoti_watches[i].wd)
+                       break;
+       }
+
+       if (i >= INOTI_FOLDER_COUNT_MAX) {
+               ERR("inoti_folder is not found");
+               return -1;
+       }
+
+       return i;
+}
+
+static mtp_bool __get_inoti_event_full_path(mtp_int32 wd, mtp_char *event_name,
+               mtp_char *path, mtp_int32 path_len, mtp_char *parent_path)
+{
+       mtp_int32 inoti_id = 0;
+
+       retv_if(wd == 0, FALSE);
+       retv_if(path == NULL, FALSE);
+       retv_if(event_name == NULL, FALSE);
+
+       inoti_id = __get_inoti_watch_id(wd);
+       if (inoti_id < 0) {
+               ERR("FAIL to find last_inoti_id : %d\n", inoti_id);
+               return FALSE;
+       }
+
+       /* 2 is for / and null character */
+       if (path_len < (strlen(g_inoti_watches[inoti_id].forlder_name) +
+                               strlen(event_name) + 2))
+               return FALSE;
+
+       g_snprintf(path, path_len, "%s/%s",
+                       g_inoti_watches[inoti_id].forlder_name, event_name);
+       g_snprintf(parent_path, path_len, "%s",
+                       g_inoti_watches[inoti_id].forlder_name);
+
+       return TRUE;
+}
+
+static void __remove_recursive_inoti_watch(mtp_char *path)
+{
+       mtp_int32 i = 0;
+       mtp_char *res = NULL;
+
+       for (i = 0; i < g_cnt_watch_folder; i++) {
+               if (g_inoti_watches[i].forlder_name == NULL)
+                       continue;
+
+               res = strstr(g_inoti_watches[i].forlder_name, path);
+               if (res == NULL)
+                       continue;
+
+               g_free(g_inoti_watches[i].forlder_name);
+               g_inoti_watches[i].forlder_name = NULL;
+               inotify_rm_watch(g_inoti_fd, g_inoti_watches[i].wd);
+               g_inoti_watches[i].wd = 0;
+       }
+
+       return;
+}
+
+static void __clean_up_inoti(void *data)
+{
+       __remove_recursive_inoti_watch(MTP_STORE_PATH_CHAR);
+       __remove_recursive_inoti_watch(MTP_EXTERNAL_PATH_CHAR);
+       __destroy_inoti_open_files_list();
+
+       close(g_inoti_fd);
+       g_inoti_fd = 0;
+       return;
+}
+
+static void __delete_children_from_store_inoti(mtp_store_t *store,
+               mtp_obj_t *obj)
+{
+       mtp_uint32 i = 0;
+       ptp_array_t child_arr = { 0 };
+       mtp_obj_t *child_obj = NULL;
+       slist_node_t *node = NULL;
+
+       __remove_inoti_watch(obj->file_path);
+
+       _prop_init_ptparray(&child_arr, UINT32_TYPE);
+       _entity_get_child_handles(store, obj->obj_handle, &child_arr);
+
+       for (i = 0; i < child_arr.num_ele; i++) {
+
+               mtp_uint32 *ptr32 = child_arr.array_entry;
+               child_obj = _entity_get_object_from_store(store, ptr32[i]);
+
+               if (child_obj != NULL && child_obj->obj_info != NULL &&
+                               child_obj->obj_info->obj_fmt ==
+                               PTP_FMT_ASSOCIATION) {
+                       __delete_children_from_store_inoti(store, child_obj);
+               }
+
+               node = _util_delete_node(&(store->obj_list), child_obj);
+               g_free(node);
+               _entity_dealloc_mtp_obj(child_obj);
+       }
+
+       _prop_deinit_ptparray(&child_arr);
+       return;
+}
+
+static void __process_object_added_event(mtp_char *fullpath,
+               mtp_char *file_name, mtp_char *parent_path)
+{
+       mtp_uint32 store_id = 0;
+       mtp_store_t *store = NULL;
+       mtp_obj_t *parent_obj = NULL;
+       mtp_uint32 h_parent = 0;
+       mtp_obj_t *obj = NULL;
+       struct stat stat_buf = { 0 };
+       mtp_int32 ret = 0;
+       dir_entry_t dir_info = { { 0 }, 0 };
+
+       if (NULL != g_strrstr(file_name, MTP_TEMP_FILE)) {
+               ERR("File is a temp file");
+               return;
+       }
+
+       if (file_name[0] == '.') {
+               DBG_SECURE("Hidden file filename=[%s]\n", file_name);
+               return;
+       }
+
+       store_id = _entity_get_store_id_by_path(fullpath);
+       store = _device_get_store(store_id);
+       if (NULL == store) {
+               ERR("store is NULL so return");
+               return;
+       }
+       parent_obj = _entity_get_object_from_store_by_path(store, parent_path);
+       if (NULL == parent_obj) {
+               if (!g_strcmp0(parent_path, MTP_STORE_PATH_CHAR) ||
+                               !g_strcmp0(parent_path, MTP_EXTERNAL_PATH_CHAR))
+               {
+                       DBG("parent is the root folder");
+                       h_parent = 0;
+               } else {
+                       DBG("Cannot find the parent, return");
+                       return;
+               }
+       } else {
+               h_parent = parent_obj->obj_handle;
+       }
+
+       ret = stat(fullpath, &stat_buf);
+       if (ret < 0) {
+               ERR("stat() Fail");
+               _util_print_error();
+               return;
+       }
+
+       g_strlcpy(dir_info.filename, fullpath, MTP_MAX_PATHNAME_SIZE + 1);
+       dir_info.attrs.mtime = stat_buf.st_mtime;
+       dir_info.attrs.fsize = stat_buf.st_size;
+
+       /* Reset the attributes */
+       dir_info.attrs.attribute = MTP_FILE_ATTR_MODE_NONE;
+       if (S_ISBLK(stat_buf.st_mode) || S_ISCHR(stat_buf.st_mode) ||
+                       S_ISLNK(stat_buf.st_mode) || S_ISSOCK(stat_buf.st_mode)) {
+               dir_info.attrs.attribute |= MTP_FILE_ATTR_MODE_SYSTEM;
+       }
+
+       if (S_ISREG(stat_buf.st_mode)) {
+               dir_info.type = MTP_FILE_TYPE;
+               dir_info.attrs.attribute |= MTP_FILE_ATTR_MODE_NONE;
+
+               if (!((S_IWUSR & stat_buf.st_mode) ||
+                                       (S_IWGRP & stat_buf.st_mode) ||
+                                       (S_IWOTH & stat_buf.st_mode))) {
+                       dir_info.attrs.attribute |= MTP_FILE_ATTR_MODE_READ_ONLY;
+               }
+
+               obj = _entity_add_file_to_store(store, h_parent, fullpath,
+                               file_name, &dir_info);
+               if (NULL == obj) {
+                       ERR("_entity_add_file_to_store fail.");
+                       return;
+               }
+       } else if (S_ISDIR(stat_buf.st_mode)) {
+               dir_info.type = MTP_DIR_TYPE;
+               dir_info.attrs.attribute  |= MTP_FILE_ATTR_MODE_DIR;
+               obj = _entity_add_folder_to_store(store, h_parent, fullpath,
+                               file_name, &dir_info);
+               if (NULL == obj) {
+                       ERR("_entity_add_folder_to_store fail.");
+                       return;
+               }
+       } else {
+               ERR("%s type is neither DIR nor FILE.\n", fullpath);
+               return;
+       }
+
+       _eh_send_event_req_to_eh_thread(EVENT_OBJECT_ADDED,
+                       obj->obj_handle, 0, NULL);
+
+       return;
+}
+
+static void __process_object_deleted_event(mtp_char *fullpath,
+               mtp_char *file_name, mtp_bool isdir)
+{
+       mtp_obj_t *obj = NULL;
+       mtp_obj_t *parent_obj = NULL;
+       mtp_store_t *store = NULL;
+       mtp_uint32 storageid = 0;
+       mtp_uint32 h_parent = 0;
+       mtp_uint32 obj_handle = 0;
+       slist_node_t *node = NULL;
+
+       if (NULL != strstr(fullpath, MTP_TEMP_FILE)) {
+               ERR("File is a temp file, need to ignore");
+               return;
+       }
+
+       if (file_name[0] == '.') {
+               DBG_SECURE("Hidden file filename=[%s], Ignore\n", file_name);
+               return;
+       }
+
+       storageid = _entity_get_store_id_by_path(fullpath);
+       store = _device_get_store(storageid);
+       if (NULL == store) {
+               ERR("store is NULL so return");
+               return;
+       }
+
+       obj = _entity_get_object_from_store_by_path(store, fullpath);
+       if (NULL == obj) {
+               ERR("object is NULL so return");
+               return;
+       }
+
+       obj_handle = obj->obj_handle;
+       h_parent = obj->obj_info->h_parent;
+       if (h_parent != PTP_OBJECTHANDLE_ROOT) {
+               parent_obj = _entity_get_object_from_store(store, h_parent);
+               if (NULL != parent_obj) {
+                       _entity_remove_reference_child_array(parent_obj,
+                                       obj->obj_handle);
+               }
+       }
+
+       if (TRUE == isdir) {
+               __delete_children_from_store_inoti(store, obj);
+       }
+
+       node = _util_delete_node(&(store->obj_list), obj);
+       g_free(node);
+       _entity_dealloc_mtp_obj(obj);
+
+       _eh_send_event_req_to_eh_thread(EVENT_OBJECT_REMOVED, obj_handle,
+                       0, NULL);
+
+       return;
+}
+
+static void __destroy_inoti_open_files_list()
+{
+       open_files_info_t *current = NULL;
+
+       ret_if(g_open_files_list == NULL);
+
+       while(g_open_files_list) {
+               current = g_open_files_list;
+               g_open_files_list = g_open_files_list->previous;
+
+               if (g_open_files_list) {
+                       g_open_files_list->next = NULL;
+               }
+
+               g_free(current->name);
+               current->wd = 0;
+               current->previous = NULL;
+               current->next = NULL;
+               g_free(current);
+       }
+
+       g_open_files_list = NULL;
+       return;
+}
+#endif /*MTP_SUPPORT_OBJECTADDDELETE_EVENT*/
diff --git a/src/ptp_container.c b/src/ptp_container.c
new file mode 100755 (executable)
index 0000000..d9a8aa8
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <glib.h>
+#include "ptp_container.h"
+#include "ptp_datacodes.h"
+#include "mtp_transport.h"
+#include "mtp_support.h"
+#include "mtp_util.h"
+
+/*
+ * FUNCTIONS
+ */
+void _hdlr_init_cmd_container(cmd_container_t *cntr)
+{
+       cntr->tid = 0;
+       cntr->type = CONTAINER_UNDEFINED;
+       cntr->code = PTP_OPCODE_UNDEFINED;
+       cntr->len = sizeof(header_container_t);
+       cntr->no_param = 0;
+       return;
+}
+
+mtp_uint32 _hdlr_get_param_cmd_container(cmd_container_t *cntr,
+               mtp_uint32 index)
+{
+       if (index < cntr->no_param) {
+               return cntr->params[index];
+       }
+       return 0;
+}
+
+void _hdlr_copy_cmd_container_unknown_params(cmd_container_t *src,
+               cmd_container_t *dst)
+{
+       mtp_uint16 ii;
+
+       dst->tid = src->tid;
+       dst->type = src->type;
+       dst->code = src->code;
+       dst->len = src->len;
+       dst->no_param =
+               (src->len - sizeof(header_container_t)) / sizeof(mtp_uint32);
+
+       for (ii = 0; ii < dst->no_param; ii++) {
+               dst->params[ii] = src->params[ii];
+       }
+       return;
+}
+
+void _hdlr_copy_cmd_container(cmd_container_t *src, cmd_container_t *dst)
+{
+       mtp_uint16 ii;
+
+       dst->tid = src->tid;
+       dst->type = src->type;
+       dst->code = src->code;
+       dst->len = src->len;
+       dst->no_param = src->no_param;
+
+       for (ii = 0; ii < dst->no_param; ii++) {
+               dst->params[ii] = src->params[ii];
+       }
+
+       return;
+}
+
+mtp_bool _hdlr_add_param_resp_container(resp_blk_t *dst, mtp_uint32 num,
+               mtp_uint32 *params)
+{
+       mtp_uint16 ii;
+
+       retvm_if(num > MAX_MTP_PARAMS, FALSE, "num(%d) exceed", num);
+       retvm_if(num != 0 && params == NULL, FALSE, "num = %d, params = %p", num, params);
+
+       dst->no_param = num;
+       dst->len = sizeof(header_container_t) + sizeof(mtp_uint32) * (dst->no_param);
+
+       for (ii = 0; ii < dst->no_param; ii++) {
+               dst->params[ii] = params[ii];
+#ifdef __BIG_ENDIAN__
+               _util_conv_byte_order(&(dst->params[ii]),
+                               sizeof(dst->params[ii]));
+#endif /* __BIG_ENDIAN__ */
+       }
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(&(dst->no_param), sizeof(dst->no_param));
+       _util_conv_byte_order(&(dst->len), sizeof(dst->len));
+#endif /* __BIG_ENDIAN__ */
+
+       return TRUE;
+}
+
+mtp_bool _hdlr_validate_cmd_container(mtp_uchar *blk, mtp_uint32 size)
+{
+       if (size < sizeof(header_container_t) || size > sizeof(cmd_container_t))
+               return FALSE;
+
+       cmd_container_t *ptr = NULL;
+
+       ptr = (cmd_container_t *)blk;
+
+       if (ptr->len != size || ptr->type != CONTAINER_CMD_BLK) {
+               ERR("size = [%d] length[%d] type[%d]\n", size, ptr->len,
+                               ptr->type);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+void _hdlr_init_data_container(data_container_t *dst, mtp_uint16 code,
+               mtp_uint32 trans_id)
+{
+       _hdlr_init_cmd_container((cmd_container_t *)dst);
+       dst->type = CONTAINER_DATA_BLK;
+       dst->code = code;
+       dst->tid = trans_id;
+       dst->data = NULL;
+#ifdef __BIG_ENDIAN__
+       _hdlr_conv_data_container_byte_order(dst);
+#endif /* __BIG_ENDIAN__ */
+       return;
+}
+
+mtp_uchar *_hdlr_alloc_buf_data_container(data_container_t *dst,
+               mtp_uint32 bufsz, mtp_uint64 pkt_size)
+{
+       mtp_uint32 blk_len;
+       header_container_t *header = NULL;
+
+       pkt_size = (pkt_size + sizeof(header_container_t) > 0xFFFFFFFF) ?
+               0xFFFFFFFF : pkt_size + sizeof(header_container_t);
+
+
+       blk_len = bufsz + sizeof(header_container_t);
+       dst->data = (mtp_uchar *)g_malloc(blk_len);
+       if (dst->data == NULL) {
+               ERR("g_malloc() Fail");
+               return NULL;
+       }
+
+       memset(dst->data, 0, blk_len);
+       dst->len = bufsz + sizeof(header_container_t);
+       header = (header_container_t *)dst->data;
+       header->len = pkt_size;
+#ifdef __BIG_ENDIAN__
+       _util_conv_byte_order(&(header->len), sizeof(header->len));
+#endif /* __BIG_ENDIAN__ */
+       header->type = dst->type;
+       header->code = dst->code;
+       header->tid = dst->tid;
+       return (dst->data + sizeof(header_container_t));
+}
+
+mtp_bool _hdlr_send_data_container(data_container_t *dst)
+{
+       mtp_uint32 sent;
+
+       sent = _transport_send_pkt_to_tx_mq(dst->data, dst->len);
+
+       if (sent != dst->len)
+               return FALSE;
+
+       return TRUE;
+}
+
+mtp_bool _hdlr_send_bulk_data(mtp_uchar *dst, mtp_uint32 len)
+{
+       mtp_uint32 sent = 0;
+
+       sent = _transport_send_bulk_pkt_to_tx_mq(dst, len);
+       if (sent != len)
+               return FALSE;
+
+       return TRUE;
+}
+
+mtp_bool _hdlr_rcv_data_container(data_container_t *dst, mtp_uint32 size)
+{
+       mtp_uint32 blk_size;
+       mtp_uint32 bytes_rcvd;
+       mtp_uint16 exp_code;
+       mtp_uint32 exp_tid;
+       header_container_t *header = NULL;
+
+       g_free(dst->data);
+       dst->data = NULL;
+
+       /* Allocated space for data + header */
+       /* Also allocate extra space in case chip writes DWORDS */
+
+       blk_size = size + sizeof(header_container_t) + sizeof(mtp_uint32);
+       dst->data = (mtp_uchar *)g_malloc(blk_size);
+       if (dst->data == NULL) {
+               ERR("g_malloc() Fail");
+               return FALSE;
+       }
+       bytes_rcvd = 0;
+
+       _transport_rcv_temp_file_data(dst->data, blk_size, &bytes_rcvd);
+       exp_code = dst->code;
+       exp_tid = dst->tid;
+       header = (header_container_t *)dst->data;
+
+#ifdef __BIG_ENDIAN__
+       _hdlr_conv_data_container_byte_order((data_container_t *)dst->data);
+#endif /* __BIG_ENDIAN__ */
+
+       /* Copy the header from the data block to the structure */
+       dst->len = header->len;
+       dst->type = header->type;
+       dst->code = header->code;
+       dst->tid = header->tid;
+       if (dst->len != bytes_rcvd || dst->type != CONTAINER_DATA_BLK ||
+                       dst->code != exp_code || dst->tid != exp_tid) {
+               ERR("HEADER FAILURE");
+               ERR("HEADER length[%d], Type[%d], Code[%d], tid[%d]\n",
+                               dst->len, dst->type, dst->code, dst->tid);
+               ERR("EXPECTED length[%d], Type[%d], Code[%d], tid[%d]\n",
+                               bytes_rcvd, CONTAINER_DATA_BLK, exp_code, exp_tid);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+mtp_bool _hdlr_rcv_file_in_data_container(data_container_t *dst,
+               mtp_char *filepath, mtp_uint32 path_len)
+{
+       mtp_uint32 blk_size;
+       mtp_uint64 bytes_rcvd;
+       mtp_uint16 exp_code;
+       mtp_uint32 exp_tid;
+       header_container_t *header = NULL;
+
+       g_free(dst->data);
+       dst->data = NULL;
+
+       /* Allocated space for data + header */
+       /* Also allocate extra space in case chip writes DWORDS */
+
+       blk_size = sizeof(header_container_t) + sizeof(mtp_uint32);
+       dst->data = (mtp_uchar *)g_malloc((mtp_uint32) blk_size);
+       if (dst->data == NULL) {
+               ERR("g_malloc() Fail");
+               return FALSE;
+       }
+
+       bytes_rcvd = 0;
+       _transport_rcv_temp_file_info(dst->data, filepath, &bytes_rcvd,
+                       path_len);
+       exp_code = dst->code;
+       exp_tid = dst->tid;
+       header = (header_container_t *)dst->data;
+
+#ifdef __BIG_ENDIAN__
+       _hdlr_conv_data_container_byte_order((data_container_t *)dst->data);
+#endif /* __BIG_ENDIAN__ */
+
+       /* Copy the header from the data block to the structure */
+       dst->len = header->len;
+       dst->type = header->type;
+       dst->code = header->code;
+       dst->tid = header->tid;
+
+       if ((dst->len != bytes_rcvd && bytes_rcvd < MTP_FILESIZE_4GB) ||
+                       dst->type != CONTAINER_DATA_BLK ||
+                       dst->code != exp_code || dst->tid != exp_tid) {
+               ERR("HEADER FAILURE");
+               ERR("HEADER length[%d], Type[%d], Code[%d], tid[%d]\n",
+                               dst->len, dst->type, dst->code, dst->tid);
+               ERR("EXPECTED length[%d], Type[%d], Code[%d], tid[%d]\n",
+                               bytes_rcvd, CONTAINER_DATA_BLK, exp_code, exp_tid);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+mtp_uint32 _hdlr_get_payload_size(data_container_t *dst)
+{
+       if (dst->data == NULL) {
+               ERR("Payload data is NULL");
+               return 0;
+       }
+
+       return (dst->len - sizeof(header_container_t));
+}
+
+mtp_uchar *_hdlr_get_payload_data(data_container_t *dst)
+{
+       if (dst->data == NULL) {
+               ERR("Payload data is NULL");
+               return NULL;
+       }
+
+       return (dst->data + sizeof(header_container_t));
+}
+
+void _hdlr_resp_container_init(cmd_container_t *dst, mtp_uint16 resp_code,
+               mtp_uint32 tid)
+{
+       _hdlr_init_cmd_container(dst);
+       dst->type = CONTAINER_RESP_BLK;
+       dst->code = resp_code;
+       dst->tid = tid;
+#ifdef __BIG_ENDIAN__
+       _hdlr_conv_cmd_container_byte_order(dst);
+#endif /* __BIG_ENDIAN__ */
+       return;
+}
+
+mtp_bool _hdlr_send_resp_container(cmd_container_t *dst)
+{
+       mtp_uint32 sent = 0;
+
+#ifdef __BIG_ENDIAN__
+       resp_blk_t resp_blk;
+
+       _hdlr_copy_cmd_container(dst, &resp_blk);
+       _hdlr_conv_cmd_container_byte_order(&resp_blk);
+       sent = _transport_send_pkt_to_tx_mq((mtp_uchar *)&resp_blk, dst->len);
+#else /* __BIG_ENDIAN__ */
+
+       sent = _transport_send_pkt_to_tx_mq((mtp_uchar *)dst, dst->len);
+#endif
+       if (sent != dst->len) {
+               ERR("_transport_send_pkt_to_tx_mq() Fail: dst->len(%u), sent(%u)",
+                       dst->len, sent);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+void _hdlr_init_event_container(cmd_container_t *dst, mtp_uint16 code,
+               mtp_uint32 tid, mtp_uint32 param1, mtp_uint32 param2)
+{
+       dst->type = CONTAINER_EVENT_BLK;
+       dst->code = code;
+       dst->tid = tid;
+       dst->no_param = 1;
+       dst->params[0] = param1;
+       dst->len = sizeof(header_container_t) + sizeof(mtp_uint32) * 1;
+#ifdef __BIG_ENDIAN__
+       _hdlr_conv_cmd_container_byte_order(dst);
+#endif /* __BIG_ENDIAN__ */
+       return;
+}
+
+void _hdlr_init_event_container_with_param(cmd_container_t *dst,
+               mtp_uint16 code, mtp_uint32 tid, mtp_uint32 param1, mtp_uint32 param2)
+{
+       dst->type = CONTAINER_EVENT_BLK;
+       dst->code = code;
+       dst->tid = tid;
+       dst->no_param = 2;
+       dst->params[0] = param1;
+       dst->params[1] = param2;
+       dst->len = sizeof(header_container_t) + sizeof(mtp_uint32) * 3;
+#ifdef __BIG_ENDIAN__
+       _hdlr_conv_cmd_container_byte_order(dst);
+#endif /* __BIG_ENDIAN__ */
+       return;
+}
+mtp_bool _hdlr_send_event_container(cmd_container_t *dst)
+{
+       mtp_uint32 sent = 0;
+       mtp_err_t retval;
+
+       retval = _transport_send_event((mtp_uchar *)dst, dst->len, &sent);
+       return (retval == MTP_ERROR_NONE && sent == dst->len) ?
+               TRUE : FALSE;
+}
+
+void _hdlr_conv_cmd_container_byte_order(cmd_container_t *dst)
+{
+#ifdef __BIG_ENDIAN__
+       mtp_uchar idx;
+
+       _util_conv_byte_order(&(dst->code), sizeof(dst->code));
+       _util_conv_byte_order(&(dst->len), sizeof(dst->len));
+       _util_conv_byte_order(&(dst->no_param), sizeof(dst->NumParams));
+       _util_conv_byte_order(&(dst->tid), sizeof(dst->tid));
+       _util_conv_byte_order(&(dst->type), sizeof(dst->Type));
+
+       for (idx = 0; idx < dst->no_param; idx++) {
+               _util_conv_byte_order(&(dst->params[idx]),
+                               sizeof(dst->params[idx]));
+       }
+#endif /* __BIG_ENDIAN__ */
+       return;
+}
+
+void _hdlr_conv_data_container_byte_order(data_container_t *dst)
+{
+#ifdef __BIG_ENDIAN__
+       mtp_uchar idx;
+
+       _util_conv_byte_order(&(dst->code), sizeof(dst->code));
+       _util_conv_byte_order(&(dst->len), sizeof(dst->len));
+       _util_conv_byte_order(&(dst->no_param), sizeof(dst->NumParams));
+       _util_conv_byte_order(&(dst->tid), sizeof(dst->tid));
+       _util_conv_byte_order(&(dst->type), sizeof(dst->Type));
+       for (idx = 0; idx < dst->no_param; idx++) {
+               _util_conv_byte_order(&(dst->params[idx]),
+                               sizeof(dst->params[idx]));
+       }
+#endif /* __BIG_ENDIAN__ */
+       return;
+}
diff --git a/src/transport/mtp_transport.c b/src/transport/mtp_transport.c
new file mode 100755 (executable)
index 0000000..2e382c3
--- /dev/null
@@ -0,0 +1,534 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <unistd.h>
+#include <glib.h>
+#include "mtp_config.h"
+#include "mtp_transport.h"
+#include "mtp_support.h"
+#include "mtp_util.h"
+#include "ptp_datacodes.h"
+#include "mtp_device.h"
+#include "mtp_msgq.h"
+#include "mtp_cmd_handler.h"
+#include "mtp_thread.h"
+#include "mtp_usb_driver.h"
+
+/*
+ * GLOBAL AND EXTERN VARIABLES
+ */
+extern mtp_config_t g_conf;
+extern mtp_mgr_t g_mtp_mgr;
+
+/*
+ * STATIC VARIABLES
+ */
+static mtp_mgr_t *g_mgr = &g_mtp_mgr;
+static mtp_bool g_usb_threads_created = FALSE;
+static pthread_t g_tx_thrd = 0;
+static pthread_t g_rx_thrd = 0;
+static pthread_t g_data_rcv = 0;
+static msgq_id_t mtp_to_usb_mqid;
+static msgq_id_t g_usb_to_mtp_mqid;
+static status_info_t g_status;
+
+/*
+ * STATIC FUNCTIONS
+ */
+static void *__transport_thread_data_rcv(void *func);
+static mtp_err_t __transport_init_io();
+static void __transport_deinit_io();
+
+/*
+ * FUNCTIONS
+ */
+void _transport_save_cmd_buffer(mtp_char *buffer, mtp_uint32 size)
+{
+       memcpy(g_mgr->ftemp_st.cmd_buf, buffer, size);
+       g_mgr->ftemp_st.cmd_size = size;
+       g_mgr->ftemp_st.data_count = 0;
+       return;
+}
+
+mtp_err_t _transport_rcv_temp_file_data(mtp_byte *buffer, mtp_uint32 size,
+               mtp_uint32 *count)
+{
+       mtp_uint32 h_file = INVALID_FILE;
+       mtp_int32 error = 0;
+       mtp_uint32 data_sz;
+
+
+       h_file = _util_file_open(g_mgr->ftemp_st.filepath,
+                       MTP_FILE_READ, &error);
+       if (h_file == INVALID_FILE) {
+               DBG_SECURE("_util_file_open(%s) Fail", g_mgr->ftemp_st.filepath);
+               return MTP_ERROR_NONE;
+       }
+
+       /*copy header */
+       memcpy(buffer, g_mgr->ftemp_st.header_buf,
+                       sizeof(header_container_t));
+
+       /*copy body packet */
+       data_sz = size - sizeof(header_container_t);
+       _util_file_read(h_file, &buffer[sizeof(header_container_t)],
+                       data_sz, count);
+       if (*count <= 0) {
+               ERR("file read error expected [%u] actual [%u]\n",
+                               data_sz, *count);
+       }
+
+       *count += sizeof(header_container_t);
+
+       if (_util_file_close(h_file) != 0) {
+               ERR("_util_file_close Fail");
+               _util_print_error();
+       }
+
+       /* delete temp file, it have to be called in receive_data fn */
+       if (remove(g_mgr->ftemp_st.filepath) < 0) {
+               ERR_SECURE("remove(%s) Fail", g_mgr->ftemp_st.filepath);
+               _util_print_error();
+       }
+
+       g_mgr->ftemp_st.data_size = 0;
+       g_mgr->ftemp_st.data_count = 0;
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _transport_rcv_temp_file_info(mtp_byte *buf, char *filepath,
+               mtp_uint64 *t_size, mtp_uint32 filepath_len)
+{
+       file_attr_t atttrs = { 0 };
+       mtp_bool ret = FALSE;
+
+       memcpy(buf, g_mgr->ftemp_st.header_buf,
+                       sizeof(header_container_t));
+
+       ret = _util_get_file_attrs(g_mgr->ftemp_st.filepath, &atttrs);
+       if (FALSE == ret) {
+               ERR_SECURE("_util_get_file_attrs(%s) Fail", g_mgr->ftemp_st.filepath);
+               return MTP_ERROR_GENERAL;
+       }
+
+       *t_size = sizeof(header_container_t) + atttrs.fsize;
+       g_strlcpy(filepath, g_mgr->ftemp_st.filepath, filepath_len);
+
+       g_mgr->ftemp_st.data_size = 0;
+       g_mgr->ftemp_st.data_count = 0;
+
+       g_strlcpy(g_mgr->ftemp_st.filepath, MTP_TEMP_FILE_DEFAULT,
+                       MTP_MAX_PATHNAME_SIZE + 1);
+       g_mgr->ftemp_st.fhandle = INVALID_FILE;
+       g_mgr->ftemp_st.file_size = 0;
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_err_t _transport_send_event(mtp_byte *buf, mtp_uint32 size,
+               mtp_uint32 *count)
+{
+       mtp_bool resp = FALSE;
+       msgq_ptr_t pkt = { 0 };
+
+       retv_if(buf == NULL, MTP_ERROR_INVALID_PARAM);
+       retvm_if(size > _get_tx_pkt_size(), MTP_ERROR_INVALID_PARAM,
+                       "size = %d, _get_tx_pkt_size() = (%d)", size, _get_tx_pkt_size());
+
+       pkt.mtype = MTP_EVENT_PACKET;
+       pkt.signal = 0x0000;
+       pkt.length = size;
+
+       pkt.buffer = (mtp_uchar *)g_malloc(size);
+       if (NULL == pkt.buffer) {
+               ERR("g_malloc() Fail");
+               return MTP_ERROR_GENERAL;
+       }
+       memcpy(pkt.buffer, buf, size);
+       resp = _util_msgq_send(mtp_to_usb_mqid, (void *)&pkt,
+                       sizeof(msgq_ptr_t) - sizeof(long), 0);
+       if (resp == FALSE) {
+               ERR("_util_msgq_send() Fail");
+               return MTP_ERROR_GENERAL;
+       }
+
+       *count = size;
+       return MTP_ERROR_NONE;
+}
+
+/*
+ * This function writes data to Message Queue, which will be read by a thread.
+ * the thread will write message, read from MQ, on USB.
+ * @param      buf             [in] A pointer to data written.
+ * @param      pkt_len         [in] Specifies the number of bytes to write.
+ * @return     This function returns length of written data in bytes
+ */
+mtp_uint32 _transport_send_pkt_to_tx_mq(const mtp_byte *buf,
+               mtp_uint32 pkt_len)
+{
+       mtp_bool ret = 0;
+       mtp_uint32 len = pkt_len;
+       mtp_uint32 sent_len = 0;
+       msgq_ptr_t pkt = { 0 };
+       mtp_uint32 tx_size = _get_tx_pkt_size();
+       const mtp_uchar *temp = (const mtp_uchar *)buf;
+
+       retv_if(buf == NULL, 0);
+       retv_if(pkt_len == 0, 0);
+
+       pkt.mtype = MTP_DATA_PACKET;
+       pkt.signal = 0x0000;
+
+       while (len) {
+               sent_len = len < tx_size ? len : tx_size;
+
+               pkt.length = sent_len;
+               pkt.buffer = (mtp_uchar *)g_malloc(sent_len);
+               if (NULL == pkt.buffer) {
+                       ERR("g_malloc() Fail");
+                       return 0;
+               }
+
+               memcpy(pkt.buffer, temp, sent_len);
+               ret = _util_msgq_send(mtp_to_usb_mqid, (void *)&pkt,
+                               sizeof(msgq_ptr_t) - sizeof(long), 0);
+               if (ret == FALSE) {
+                       ERR("_util_msgq_send() Fail");
+                       g_free(pkt.buffer);
+                       return 0;
+               }
+
+               len -= sent_len;
+               temp += sent_len;
+       }
+
+       return pkt_len;
+}
+
+mtp_uint32 _transport_send_bulk_pkt_to_tx_mq(const mtp_byte *buf,
+               mtp_uint32 pkt_len)
+{
+       mtp_uint32 sent_len = 0;
+       mtp_uint32 tx_size = _get_tx_pkt_size();
+       msgq_ptr_t pkt = {MTP_BULK_PACKET, 0, 0, NULL};
+
+       retv_if(buf == NULL, 0);
+       retv_if(pkt_len == 0, 0);
+
+       pkt.length = tx_size;
+       while (pkt_len > tx_size) {
+               pkt.buffer = (mtp_uchar *)g_malloc(pkt.length);
+               if (NULL == pkt.buffer) {
+                       ERR("g_malloc() Fail");
+                       return 0;
+               }
+               memcpy(pkt.buffer, &buf[sent_len], pkt.length);
+
+               if (!_util_msgq_send(mtp_to_usb_mqid, (void *)&pkt,
+                                       sizeof(msgq_ptr_t) - sizeof(long), 0)) {
+                       ERR("_util_msgq_send() Fail");
+                       g_free(pkt.buffer);
+                       return 0;
+               }
+
+               pkt_len -= pkt.length;
+               sent_len += pkt.length;
+       }
+
+       pkt.length = pkt_len;
+       pkt.buffer = (mtp_uchar *)g_malloc(pkt.length);
+       if (NULL == pkt.buffer) {
+               ERR("g_malloc() Fail");
+               return 0;
+       }
+       memcpy(pkt.buffer, &buf[sent_len], pkt.length);
+
+       if (!_util_msgq_send(mtp_to_usb_mqid, (void *)&pkt,
+                               sizeof(msgq_ptr_t) - sizeof(long), 0)) {
+               ERR("_util_msgq_send() Fail");
+               g_free(pkt.buffer);
+               return 0;
+       }
+       sent_len += pkt.length;
+
+       return sent_len;
+}
+
+void _transport_send_zlp(void)
+{
+       msgq_ptr_t pkt = { 0 };
+       mtp_bool resp = FALSE;
+
+       pkt.mtype = MTP_ZLP_PACKET;
+       pkt.signal = 0x0000;
+       pkt.length = 0;
+       pkt.buffer = NULL;
+
+       resp = _util_msgq_send(mtp_to_usb_mqid, (void *)&pkt,
+                       sizeof(msgq_ptr_t) - sizeof(long), 0);
+       if (resp == FALSE)
+               ERR("_util_msgq_send() Fail");
+       return;
+}
+
+static mtp_err_t __transport_init_io()
+{
+       mtp_int32 res = 0;
+       thread_func_t usb_write_thread = _transport_thread_usb_write;
+       thread_func_t usb_read_thread = _transport_thread_usb_read;
+
+       res = _util_thread_create(&g_tx_thrd, "usb write thread",
+                       PTHREAD_CREATE_JOINABLE, usb_write_thread,
+                       (void *)&mtp_to_usb_mqid);
+       if (FALSE == res) {
+               ERR("_util_thread_create(TX) Fail");
+               goto cleanup;
+       }
+
+       res = _util_thread_create(&g_rx_thrd, "usb read thread",
+                       PTHREAD_CREATE_JOINABLE, usb_read_thread,
+                       (void *)&g_usb_to_mtp_mqid);
+       if (FALSE == res) {
+               ERR("_util_thread_create(RX) Fail");
+               goto cleanup;
+       }
+
+       g_usb_threads_created = TRUE;
+
+       return MTP_ERROR_NONE;
+
+cleanup:
+       _util_print_error();
+
+       if (g_rx_thrd) {
+               res = _util_thread_cancel(g_rx_thrd);
+               DBG("pthread_cancel [%d]\n", res);
+               g_rx_thrd = 0;
+       }
+       if (g_tx_thrd) {
+               res = _util_thread_cancel(g_tx_thrd);
+               DBG("pthread_cancel [%d]\n", res);
+               g_tx_thrd = 0;
+       }
+       g_usb_threads_created = FALSE;
+
+       return MTP_ERROR_GENERAL;
+}
+
+static void __transport_deinit_io()
+{
+       if (g_usb_threads_created == FALSE) {
+               ERR("io threads are not created.");
+               return;
+       }
+       errno = 0;
+
+       if (FALSE == _util_thread_cancel(g_rx_thrd))
+               ERR("_util_thread_cancel(rx) Fail");
+
+       if (_util_thread_join(g_rx_thrd, 0) == FALSE)
+               ERR("_util_thread_join(rx) Fail");
+
+       g_rx_thrd = 0;
+
+       if (FALSE == _util_thread_cancel(g_tx_thrd))
+               ERR("_util_thread_cancel(tx) Fail");
+
+       if (_util_thread_join(g_tx_thrd, 0) == FALSE)
+               ERR("_util_thread_join(tx) Fail");
+
+       g_tx_thrd = 0;
+
+       g_usb_threads_created = FALSE;
+       return;
+}
+
+mtp_bool _transport_init_interfaces(_cmd_handler_cb func)
+{
+       mtp_int32 res = 0;
+       mtp_bool ret = FALSE;
+
+       ret = _transport_init_usb_device();
+       if (ret == FALSE) {
+               /* mtp driver open failed */
+               ERR("_transport_init_usb_device() Fail");
+               return FALSE;
+       }
+
+       if (_transport_mq_init(&g_usb_to_mtp_mqid, &mtp_to_usb_mqid) == FALSE) {
+               ERR("_transport_mq_init() Fail");
+               _transport_deinit_usb_device();
+               return FALSE;
+       }
+
+       if (__transport_init_io() != MTP_ERROR_NONE) {
+               ERR("__transport_init_io() Fail");
+               _transport_mq_deinit(&g_usb_to_mtp_mqid, &mtp_to_usb_mqid);
+               _transport_deinit_usb_device();
+               return FALSE;
+       }
+
+       res = _util_thread_create(&g_data_rcv, "Data Receive thread",
+                       PTHREAD_CREATE_JOINABLE, __transport_thread_data_rcv,
+                       (void *)func);
+       if (res == FALSE) {
+               ERR("_util_thread_create(data_rcv) Fail");
+               __transport_deinit_io();
+               _transport_mq_deinit(&g_usb_to_mtp_mqid, &mtp_to_usb_mqid);
+               _transport_deinit_usb_device();
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+void _transport_usb_finalize(void)
+{
+       mtp_int32 res = 0;
+       void *th_result = NULL;
+       msgq_ptr_t pkt;
+       mtp_uint32 rx_size = _get_rx_pkt_size();
+
+       __transport_deinit_io();
+
+       if (g_data_rcv != 0) {
+               pkt.buffer = (mtp_uchar *)g_malloc(rx_size);
+               if (pkt.buffer == NULL) {
+                       ERR("g_malloc() Fail");
+                       return;
+               }
+               pkt.mtype = MTP_DATA_PACKET;
+               pkt.signal = 0xABCD;
+               pkt.length = 6;
+               memset(pkt.buffer, 0, rx_size);
+               if (FALSE == _util_msgq_send(g_usb_to_mtp_mqid, (void *)&pkt,
+                                       sizeof(msgq_ptr_t) - sizeof(long), 0)) {
+                       ERR("_util_msgq_send() Fail");
+               }
+
+               res = _util_thread_join(g_data_rcv, &th_result);
+               if (res == FALSE) {
+                       ERR("_util_thread_join(data_rcv) Fail");
+               }
+       }
+
+       if (_transport_mq_deinit(&g_usb_to_mtp_mqid, &mtp_to_usb_mqid) == FALSE) {
+               ERR("_transport_mq_deinit() Fail");
+       }
+
+       _transport_deinit_usb_device();
+
+       return;
+}
+
+static void *__transport_thread_data_rcv(void *func)
+{
+       msgq_ptr_t pkt = { 0 };
+       mtp_uchar *pkt_data = NULL;
+       mtp_uint32 pkt_len = 0;
+       mtp_int32 flag = 1;
+       mtp_int32 len = 0;
+       _cmd_handler_cb _cmd_handler_func = (_cmd_handler_cb )func;
+
+       while (flag) {
+               if (_util_msgq_receive(g_usb_to_mtp_mqid, (void *)&pkt,
+                                       sizeof(pkt) - sizeof(long), 0, &len) == FALSE) {
+                       ERR("_util_msgq_receive() Fail");
+                       flag = 0;
+                       break;
+               }
+               if (len == sizeof(msgq_ptr_t) - sizeof(long)) {
+                       len = pkt.length;
+                       if (pkt.length == 6 && pkt.signal == 0xABCD) {
+                               ERR("Got NULL character in MQ");
+                               flag = 0;
+                               break;
+                       }
+                       pkt_data = pkt.buffer;
+                       pkt_len = pkt.length;
+                       _cmd_handler_func((mtp_char *)pkt_data, pkt_len);
+                       g_free(pkt_data);
+                       pkt_data = NULL;
+                       pkt_len = 0;
+                       memset(&pkt, 0, sizeof(pkt));
+               } else {
+                       g_free(pkt.buffer);
+                       pkt.buffer = NULL;
+                       ERR("Received packet is less than real size");
+               }
+       }
+
+       ERR("thread_data_rcv[%u] exiting\n", g_data_rcv);
+       _util_thread_exit("__transport_thread_data_rcv is over");
+       return NULL;
+}
+
+void _transport_init_status_info(void)
+{
+       memset((void *)&g_status, 0, sizeof(status_info_t));
+       return;
+}
+
+mtp_int32 _transport_get_control_event(void)
+{
+       mtp_uint32 event_code;
+
+       event_code = g_status.ctrl_event_code;
+
+       /* initialize for next usage */
+       if (event_code != 0)
+               g_status.ctrl_event_code = 0;
+
+       return event_code;
+}
+
+void _transport_set_control_event(mtp_int32 event_code)
+{
+       g_status.ctrl_event_code = event_code;
+}
+
+mtp_state_t _transport_get_mtp_operation_state(void)
+{
+       return g_status.mtp_op_state;
+}
+
+void _transport_set_mtp_operation_state(mtp_state_t state)
+{
+       g_status.mtp_op_state = state;
+       return;
+}
+
+void _transport_set_usb_discon_state(mtp_bool is_usb_discon)
+{
+       g_status.is_usb_discon = is_usb_discon;
+       return;
+}
+
+mtp_bool _transport_get_usb_discon_state(void)
+{
+       return g_status.is_usb_discon;
+}
+
+void _transport_set_cancel_initialization(mtp_bool value)
+{
+       g_status.cancel_intialization = value;
+}
+
+mtp_bool _transport_get_cancel_initialization(void)
+{
+       return g_status.cancel_intialization;
+}
diff --git a/src/transport/mtp_usb_driver.c b/src/transport/mtp_usb_driver.c
new file mode 100755 (executable)
index 0000000..91a9b73
--- /dev/null
@@ -0,0 +1,472 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <glib.h>
+#include "mtp_usb_driver.h"
+#include "mtp_device.h"
+#include "ptp_datacodes.h"
+#include "mtp_support.h"
+#include "ptp_container.h"
+#include "mtp_msgq.h"
+#include "mtp_util.h"
+#include "mtp_thread.h"
+#include "mtp_transport.h"
+#include "mtp_event_handler.h"
+
+/*
+ * GLOBAL AND EXTERN VARIABLES
+ */
+extern mtp_config_t g_conf;
+
+/*
+ * STATIC VARIABLES AND FUNCTIONS
+ */
+static mtp_int32 g_usb_fd = -1;
+static mtp_max_pkt_size_t pkt_size;
+static mtp_uint32 rx_mq_sz;
+static mtp_uint32 tx_mq_sz;
+
+static mtp_int32 __handle_usb_read_err(mtp_int32 err,
+               mtp_uchar *buf, mtp_int32 buf_len);
+static void __clean_up_msg_queue(void *pmsqid);
+static void __handle_control_request(mtp_int32 request);
+static void __receive_signal(mtp_int32 n, siginfo_t *info, void *unused);
+
+/*
+ * FUNCTIONS
+ */
+mtp_bool _transport_init_usb_device(void)
+{
+       mtp_int32 status = 0;
+       struct sigaction sig;
+       pid_t mtp_pid = 0;
+       int msg_size;
+
+       /* Kernel will inform to User Space using signal. */
+       memset(&sig, 0, sizeof(sig));
+       sig.sa_sigaction = __receive_signal;
+       sig.sa_flags = SA_SIGINFO;
+       sigaction(SIG_SETUP, &sig, NULL);
+
+       if (g_usb_fd > 0) {
+               DBG("Device Already open");
+               return TRUE;
+       }
+
+       g_usb_fd = open(MTP_DRIVER_PATH, O_RDWR);
+       if (g_usb_fd < 0) {
+               ERR("Device node [%s] open Fail,errno [%d]\n", MTP_DRIVER_PATH, errno);
+               return FALSE;
+       }
+
+       mtp_pid = getpid();
+       status = ioctl(g_usb_fd, MTP_SET_USER_PID, &mtp_pid);
+       if (status < 0) {
+               ERR("IOCTL MTP_SET_USER_PID Fail = [%d]\n", status);
+               _transport_deinit_usb_device();
+               return FALSE;
+       }
+
+       pkt_size.rx = g_conf.read_usb_size;
+       pkt_size.tx = g_conf.write_usb_size;
+
+       DBG("Final : Tx pkt size:[%u], Rx pkt size:[%u]\n", pkt_size.tx, pkt_size.rx);
+
+       msg_size = sizeof(msgq_ptr_t) - sizeof(long);
+       rx_mq_sz = (g_conf.max_io_buf_size / g_conf.max_rx_ipc_size) * msg_size;
+       tx_mq_sz = (g_conf.max_io_buf_size / g_conf.max_tx_ipc_size) * msg_size;
+
+       DBG("RX MQ size :[%u], TX MQ size:[%u]\n", rx_mq_sz, tx_mq_sz);
+
+       return TRUE;
+}
+
+void _transport_deinit_usb_device(void)
+{
+       if (g_usb_fd >= 0)
+               close(g_usb_fd);
+       g_usb_fd = -1;
+
+       return;
+}
+
+mtp_uint32 _get_tx_pkt_size(void)
+{
+       return pkt_size.tx;
+}
+
+mtp_uint32 _get_rx_pkt_size(void)
+{
+       return pkt_size.rx;
+}
+
+/*
+ * static mtp_int32 _transport_mq_init()
+ * This function create a message queue for MTP,
+ * A created message queue will be used to help data transfer between
+ * MTP module and usb buffer.
+ * @return     This function returns TRUE on success or
+ *             returns FALSE on failure.
+ */
+mtp_int32 _transport_mq_init(msgq_id_t *rx_mqid, msgq_id_t *tx_mqid)
+{
+       if (_util_msgq_init(rx_mqid, 0) == FALSE) {
+               ERR("RX MQ init Fail [%d]\n", errno);
+               return FALSE;
+       }
+
+       if (_util_msgq_set_size(*rx_mqid, rx_mq_sz) == FALSE)
+               ERR("RX MQ setting size Fail [%d]\n", errno);
+
+       if (_util_msgq_init(tx_mqid, 0) == FALSE) {
+               ERR("TX MQ init Fail [%d]\n", errno);
+               _util_msgq_deinit(rx_mqid);
+               *rx_mqid = -1;
+               return FALSE;
+       }
+
+       if (_util_msgq_set_size(*tx_mqid, tx_mq_sz) == FALSE)
+               ERR("TX MQ setting size Fail [%d]\n", errno);
+
+       return TRUE;
+}
+
+void *_transport_thread_usb_write(void *arg)
+{
+       mtp_int32 status = 0;
+       mtp_uint32 len = 0;
+       unsigned char *mtp_buf = NULL;
+       msg_type_t mtype = MTP_UNDEFINED_PACKET;
+       msgq_id_t *mqid = (msgq_id_t *)arg;
+
+       pthread_cleanup_push(__clean_up_msg_queue, mqid);
+
+       do {
+               /* original LinuxThreads cancelation didn't work right
+                * so test for it explicitly.
+                */
+               pthread_testcancel();
+
+               _util_rcv_msg_from_mq(*mqid, &mtp_buf, &len, &mtype);
+
+               if (mtype == MTP_BULK_PACKET || mtype == MTP_DATA_PACKET) {
+                       status = write(g_usb_fd, mtp_buf, len);
+                       if (status < 0) {
+                               ERR("USB write fail : %d\n", errno);
+                               if (errno == ENOMEM || errno == ECANCELED) {
+                                       status = 0;
+                                       __clean_up_msg_queue(mqid);
+                               }
+                       }
+                       g_free(mtp_buf);
+                       mtp_buf = NULL;
+               } else if (MTP_EVENT_PACKET == mtype) {
+                       /* Handling the MTP Asynchronous Events */
+                       DBG("Send Interrupt data to kernel by IOCTL ");
+                       status = ioctl(g_usb_fd, MTP_WRITE_INT_DATA, mtp_buf);
+                       g_free(mtp_buf);
+                       mtp_buf = NULL;
+               } else if (MTP_ZLP_PACKET == mtype) {
+                       DBG("Send ZLP data to kernel by IOCTL ");
+                       status = ioctl(g_usb_fd, MTP_SET_ZLP_DATA, NULL);
+               } else {
+                       DBG("mtype = %d is not valid\n", mtype);
+                       status = -1;
+               }
+
+               if (status < 0) {
+                       ERR("write data to the device node Fail:\
+                                       status = %d\n", status);
+                       break;
+               }
+       } while (status >= 0);
+
+       DBG("exited Source thread with status %d\n", status);
+       pthread_cleanup_pop(1);
+       g_free(mtp_buf);
+
+       return NULL;
+}
+
+void *_transport_thread_usb_read(void *arg)
+{
+       mtp_int32 status = 0;
+       msgq_ptr_t pkt = {MTP_DATA_PACKET, 0, 0, NULL};
+       msgq_id_t *mqid = (msgq_id_t *)arg;
+       mtp_uint32 rx_size = _get_rx_pkt_size();
+
+       pthread_cleanup_push(__clean_up_msg_queue, mqid);
+
+       do {
+               pthread_testcancel();
+
+               pkt.buffer = (mtp_uchar *)g_malloc(rx_size);
+               if (NULL == pkt.buffer) {
+                       ERR("Sink thread: memalloc Fail.");
+                       break;
+               }
+
+               status = read(g_usb_fd, pkt.buffer, rx_size);
+               if (status <= 0) {
+                       status = __handle_usb_read_err(status, pkt.buffer, rx_size);
+                       if (status <= 0) {
+                               ERR("__handle_usb_read_err Fail");
+                               g_free(pkt.buffer);
+                               break;
+                       }
+               }
+
+               pkt.length = status;
+               if (FALSE == _util_msgq_send(*mqid, (void *)&pkt,
+                                       sizeof(msgq_ptr_t) - sizeof(long), 0)) {
+                       ERR("msgsnd Fail");
+                       g_free(pkt.buffer);
+               }
+       } while (status > 0);
+
+       DBG("status[%d] errno[%d]\n", status, errno);
+       pthread_cleanup_pop(1);
+
+       return NULL;
+}
+
+static mtp_int32 __handle_usb_read_err(mtp_int32 err,
+               mtp_uchar *buf, mtp_int32 buf_len)
+{
+       mtp_int32 retry = 0;
+       mtp_bool ret;
+
+       while (retry++ < MTP_USB_ERROR_MAX_RETRY) {
+               if (err == 0) {
+                       DBG("ZLP(Zero Length Packet). Skip");
+               } else if (err < 0 && errno == EINTR) {
+                       DBG("read () is interrupted. Skip");
+               } else if (err < 0 && errno == EIO) {
+                       DBG("EIO");
+
+                       if (MTP_PHONE_USB_CONNECTED !=
+                                       _util_get_local_usb_status()) {
+                               ERR("USB is disconnected");
+                               break;
+                       }
+
+                       _transport_deinit_usb_device();
+                       ret = _transport_init_usb_device();
+                       if (ret == FALSE) {
+                               ERR("_transport_init_usb_device Fail");
+                               continue;
+                       }
+               } else {
+                       ERR("Unknown error : %d, errno [%d] \n", err, errno);
+                       break;
+               }
+
+               err = read(g_usb_fd, buf, buf_len);
+               if (err > 0)
+                       break;
+       }
+
+       if (err <= 0)
+               ERR("USB error handling Fail");
+
+       return err;
+}
+
+static void __clean_up_msg_queue(void *mq_id)
+{
+       mtp_int32 len = 0;
+       msgq_ptr_t pkt = { 0 };
+       msgq_id_t l_mqid = *(msgq_id_t *)mq_id;
+
+       ret_if(mq_id == NULL);
+
+       _transport_set_control_event(PTP_EVENTCODE_CANCELTRANSACTION);
+       while (TRUE == _util_msgq_receive(l_mqid, (void *)&pkt,
+                               sizeof(msgq_ptr_t) - sizeof(long), 1, &len)) {
+               g_free(pkt.buffer);
+               memset(&pkt, 0, sizeof(msgq_ptr_t));
+       }
+
+       return;
+}
+
+static void __handle_control_request(mtp_int32 request)
+{
+       static mtp_bool kernel_reset = FALSE;
+       static mtp_bool host_cancel = FALSE;
+       mtp_int32 status = 0;
+
+       switch (request) {
+       case USB_PTPREQUEST_CANCELIO:
+               DBG("USB_PTPREQUEST_CANCELIO");
+               cancel_req_t cancelreq_data;
+               mtp_byte buffer[USB_PTPREQUEST_CANCELIO_SIZE + 1] = { 0 };
+
+               host_cancel = TRUE;
+               _transport_set_control_event(PTP_EVENTCODE_CANCELTRANSACTION);
+               status = ioctl(g_usb_fd, MTP_GET_SETUP_DATA, buffer);
+               if (status < 0) {
+                       ERR("IOCTL GET_SETUP_DATA Fail [%d]\n", status);
+                       return;
+               }
+
+               memcpy(&(cancelreq_data.io_code), buffer, sizeof(mtp_word));
+               memcpy(&(cancelreq_data.tid), &buffer[2], sizeof(mtp_dword));
+               DBG("cancel io code [%d], transaction id [%ld]\n",
+                               cancelreq_data.io_code, cancelreq_data.tid);
+               break;
+
+       case USB_PTPREQUEST_RESET:
+
+               DBG("USB_PTPREQUEST_RESET");
+               _reset_mtp_device();
+               if (kernel_reset == FALSE) {
+                       kernel_reset = TRUE;
+               }
+
+               status = ioctl(g_usb_fd, MTP_SEND_RESET_ACK, NULL);
+               if (status < 0) {
+                       ERR("IOCTL MTP_SEND_RESET_ACK Fail [%d]\n",
+                                       status);
+               }
+               break;
+
+       case USB_PTPREQUEST_GETSTATUS:
+
+               DBG("USB_PTPREQUEST_GETSTATUS");
+
+               /* Send busy status response just once. This flag is also for
+                * the case that mtp misses the cancel request packet.
+                */
+               static mtp_bool sent_busy = FALSE;
+               usb_status_req_t statusreq_data = { 0 };
+               mtp_dword num_param = 0;
+
+               memset(&statusreq_data, 0x00, sizeof(usb_status_req_t));
+               if (host_cancel == TRUE || (sent_busy == FALSE &&
+                                       kernel_reset == FALSE)) {
+                       DBG("Send busy response, set host_cancel to FALSE");
+                       statusreq_data.len = 0x08;
+                       statusreq_data.code = PTP_RESPONSE_DEVICEBUSY;
+                       host_cancel = FALSE;
+               } else if (_device_get_phase() == DEVICE_PHASE_NOTREADY) {
+                       statusreq_data.code =
+                               PTP_RESPONSE_TRANSACTIONCANCELLED;
+                       DBG("PTP_RESPONSE_TRANSACTIONCANCELLED");
+                       statusreq_data.len = (mtp_word)(sizeof(usb_status_req_t) +
+                                       (num_param - 2) * sizeof(mtp_dword));
+               } else if (_device_get_status() == DEVICE_STATUSOK) {
+                       DBG("PTP_RESPONSE_OK");
+                       statusreq_data.len = 0x08;
+                       statusreq_data.code = PTP_RESPONSE_OK;
+
+                       if (kernel_reset == TRUE)
+                               kernel_reset = FALSE;
+               } else {
+                       DBG("PTP_RESPONSE_GEN_ERROR");
+                       statusreq_data.len = 0x08;
+                       statusreq_data.code = PTP_RESPONSE_GEN_ERROR;
+               }
+
+               if (statusreq_data.code == PTP_RESPONSE_DEVICEBUSY) {
+                       sent_busy = TRUE;
+               } else {
+                       sent_busy = FALSE;
+               }
+
+               status = ioctl(g_usb_fd, MTP_SET_SETUP_DATA, &statusreq_data);
+               if (status < 0) {
+                       DBG("IOCTL MTP_SET_SETUP_DATA Fail [%d]\n",
+                                       status);
+                       return;
+               }
+               break;
+
+       case USB_PTPREQUEST_GETEVENT:
+               DBG("USB_PTPREQUEST_GETEVENT");
+               break;
+
+       default:
+               DBG("Invalid class specific setup request");
+               break;
+       }
+       return;
+}
+
+static void __receive_signal(mtp_int32 n, siginfo_t *info, void *arg)
+{
+       mtp_int32 request = info->si_int;
+
+       DBG("Received SIgnal From Kernel");
+       __handle_control_request(request);
+       return;
+}
+
+/*
+ * mtp_bool __transport_mq_deinit()
+ * This function destroy a message queue for MTP,
+ * @return     This function returns TRUE on success or
+ *             returns FALSE on failure.
+ */
+mtp_bool _transport_mq_deinit(msgq_id_t *rx_mqid, msgq_id_t *tx_mqid)
+{
+       mtp_int32 res = TRUE;
+
+       if (*rx_mqid) {
+               res = _util_msgq_deinit(rx_mqid);
+               if (res == FALSE) {
+                       ERR("rx_mqid deinit Fail [%d]\n", errno);
+               } else {
+                       *rx_mqid = 0;
+               }
+       }
+
+       if (*tx_mqid) {
+               res = _util_msgq_deinit(tx_mqid);
+               if (res == FALSE) {
+                       ERR("tx_mqid deinit fail [%d]\n", errno);
+               } else {
+                       *tx_mqid = 0;
+               }
+       }
+
+       return res;
+}
+
+mtp_uint32 _transport_get_usb_packet_len(void)
+{
+       mtp_int32 status = 0;
+       static mtp_int32 usb_speed = 0;
+
+       if (usb_speed == 0) {
+
+               status = ioctl(g_usb_fd, MTP_GET_HIGH_FULL_SPEED, &usb_speed);
+               if (status < 0) {
+                       ERR("MTP_GET_HIGH_FULL_SPEED Fail [%d]\n", status);
+                       return MTP_MAX_PACKET_SIZE_SEND_FS;
+               }
+       }
+
+       if (usb_speed % MTP_MAX_PACKET_SIZE_SEND_HS) {
+               return MTP_MAX_PACKET_SIZE_SEND_FS;
+       }
+
+       return MTP_MAX_PACKET_SIZE_SEND_HS;
+}
diff --git a/src/util/mtp_fs.c b/src/util/mtp_fs.c
new file mode 100755 (executable)
index 0000000..4257446
--- /dev/null
@@ -0,0 +1,949 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#define __USE_STDIO__
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/vfs.h>
+#include <sys/sendfile.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include "mtp_fs.h"
+#include "mtp_util.h"
+#include "mtp_support.h"
+#include "ptp_datacodes.h"
+
+/*
+ * FUNCTIONS
+ */
+
+/*
+ * mtp_uint32 _util_file_open(const mtp_char *filename,
+ *     file_mode_t mode, mtp_int32 *error)
+ * This function opens the file in specific mode.
+ *
+ * @param[in]  filename        Specifies the name of file to open.
+ * @param[in]  mode            Specifies the mode of file to open.
+ * @param[out] error           Specifies the type of error
+ * @return     This function returns the file handle  on success,
+ or INVALID_FILE on failure
+ */
+mtp_uint32 _util_file_open(const mtp_char *filename, file_mode_t mode,
+               mtp_int32 *error)
+{
+#ifdef __USE_STDIO__
+       FILE *fhandle = NULL;
+       char *fmode = NULL;
+
+       switch ((int)mode) {
+       case MTP_FILE_READ:
+               fmode = "rm";
+               break;
+
+       case MTP_FILE_WRITE:
+               fmode = "w";
+               break;
+
+       case MTP_FILE_APPEND:
+               fmode = "a";
+               break;
+
+       case MTP_FILE_READ | MTP_FILE_WRITE:
+               fmode = "r+";
+               break;
+
+       case MTP_FILE_READ | MTP_FILE_WRITE | MTP_FILE_APPEND:
+               fmode = "a+";
+               break;
+
+       default:
+               ERR("Invalid mode : %d\n", mode);
+               *error = EINVAL;
+               return INVALID_FILE;
+       }
+
+       fhandle = fopen(filename, fmode);
+       if (fhandle == NULL) {
+               ERR("File open Fail:mode[0x%x], errno [%d]\n", mode, errno);
+               ERR_SECURE("filename[%s]\n", filename);
+               *error = errno;
+               return INVALID_FILE;
+       }
+
+       fcntl(fileno(fhandle), F_SETFL, O_NOATIME);
+
+       return (mtp_uint32)fhandle;
+
+#else /* __USE_STDIO__ */
+
+       mtp_int32 fhandle = 0;
+       mtp_int32 flags = 0;
+       mode_t perm = 0;
+
+       switch ((int)mode) {
+       case MTP_FILE_READ:
+               flags = O_RDONLY;
+               break;
+
+       case MTP_FILE_WRITE:
+               flags = O_WRONLY | O_CREAT | O_TRUNC;
+               perm = 0644;
+               break;
+
+       case MTP_FILE_APPEND:
+               flags = O_WRONLY | O_APPEND | O_CREAT;
+               perm = 0644;
+               break;
+
+       case MTP_FILE_READ | MTP_FILE_WRITE:
+               flags = O_RDWR;
+               break;
+
+       case MTP_FILE_READ | MTP_FILE_WRITE | MTP_FILE_APPEND:
+               flags = O_RDWR | O_APPEND | O_CREAT;
+               perm = 0644;
+               break;
+
+       default:
+               ERR("Invalid mode : %d\n", mode);
+               *error = EINVAL;
+               return INVALID_FILE;
+       }
+
+       if (perm)
+               fhandle = open(filename, flags, perm);
+       else
+               fhandle = open(filename, flags);
+
+       if (fhandle < 0) {
+               ERR("File open Fail:mode[0x%x], errno [%d]\n", mode, errno);
+               ERR_SECURE("filename[%s]\n", filename);
+               *error = errno;
+               return INVALID_FILE;
+       }
+
+       return (mtp_uint32)fhandle;
+#endif /* __USE_STDIO__ */
+}
+
+/*
+ * void _util_file_read(mtp_uint32 handle, void *bufptr, mtp_uint32 size,
+ *     mtp_uint32 *preadcount)
+ *
+ * This function reads data from the file handle into the data buffer.
+ *
+ * @param[in]  handle          Specifies the handle of file to read.
+ * @param[out] bufptr          Points to buff where data is to be read.
+ * @param[in]  size            Specifies the num bytes to be read.
+ * @param[out] preadcount      Will store the actual num bytes read.
+ * @return     None
+ */
+void _util_file_read(mtp_uint32 fhandle, void *bufptr, mtp_uint32 size,
+               mtp_uint32 *read_count)
+{
+       mtp_uint32 bytes_read = 0;
+
+#ifdef __USE_STDIO__
+       bytes_read = fread_unlocked(bufptr, sizeof(mtp_char), size, (FILE *)fhandle);
+#else /* __USE_STDIO__ */
+       bytes_read = read(fhandle, bufptr, size);
+#endif /* __USE_STDIO__ */
+
+       *read_count = bytes_read;
+}
+/**
+ * mtp_uint32 _util_file_write(mtp_uint32 fhandle, void *bufptr, mtp_uint32 size)
+ *
+ * This function writes data to the file using the data buffer passed.
+ *
+ * @param[in]  handle  Specifies the handle of file to write.
+ * @param[in]  bufptr  Points the buffer which holds the data.
+ * @param[in]  size    Specifies num bytes to be written.
+ * @return     This function returns num bytes written.
+ */
+
+mtp_uint32 _util_file_write(mtp_uint32 fhandle, void *bufptr, mtp_uint32 size)
+{
+       mtp_uint32 bytes_written = 0;
+
+#ifdef __USE_STDIO__
+       bytes_written = fwrite_unlocked(bufptr, sizeof(mtp_char), size, (FILE *)fhandle);
+#else /* __USE_STDIO__ */
+       mtp_int32 ret = 0;
+
+       ret = write(fhandle, bufptr, size);
+       if (ret < 0)
+               ret = 0;
+
+       bytes_written = ret;
+#endif /* __USE_STDIO__ */
+
+       return bytes_written;
+}
+
+/**
+ * mtp_int32 _util_file_close(mtp_uint32 fhandle)
+ * This function closes the file.
+ *
+ * @param[in]  handle  Specifies the handle of file to close.
+ * @return     0 in case of success or EOF on failure.
+ */
+mtp_int32 _util_file_close(mtp_uint32 fhandle)
+{
+#ifdef __USE_STDIO__
+       return fclose((FILE *)fhandle);
+#else /* __USE_STDIO__ */
+       return close(fhandle);
+#endif /* __USE_STDIO__ */
+}
+
+/*
+ * This function seeks to a particular location in a file.
+ *
+ * @param[in]  handle          Specifies the handle of file to seek.
+ * @param[in]  offset          Specifies the starting point.
+ * @param[in]  whence          Specifies the setting value
+ * @return     Returns TRUE in case of success or FALSE on Failure.
+ */
+mtp_bool _util_file_seek(mtp_uint32 handle, off_t offset, mtp_int32 whence)
+{
+       mtp_int64 ret_val = 0;
+
+#ifdef __USE_STDIO__
+       ret_val = fseek((FILE *)handle, offset, whence);
+#else /* __USE_STDIO__ */
+       ret_val = lseek(handle, offset, whence);
+       if (ret_val > 0)
+               ret_val = 0;
+#endif /* __USE_STDIO__ */
+       if (ret_val < 0) {
+               ERR(" _util_file_seek error errno [%d]\n", errno);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+mtp_bool _util_file_copy(const mtp_char *origpath, const mtp_char *newpath,
+               mtp_int32 *error)
+{
+#ifdef __USE_STDIO__
+       FILE *fold = NULL;
+       FILE *fnew = NULL;
+       size_t nmemb = 0;
+       mtp_int32 ret = 0;
+       mtp_char buf[BUFSIZ] = { 0 };
+
+       if ((fold = fopen(origpath, "rb")) == NULL) {
+               ERR("In-file open Fail errno [%d]\n", errno);
+               *error = errno;
+               return FALSE;
+       }
+
+       if ((fnew = fopen(newpath, "wb")) == NULL) {
+               ERR("Out-file open Fail errno [%d]\n", errno);
+               *error = errno;
+               fclose(fold);
+               return FALSE;
+       }
+
+       do {
+               nmemb = fread(buf, sizeof(mtp_char), BUFSIZ, fold);
+               if (nmemb < BUFSIZ && ferror(fold)) {
+                       ERR("fread Fail errno [%d] \n", errno);
+                       *error = errno;
+                       fclose(fnew);
+                       fclose(fold);
+                       if (remove(newpath) < 0)
+                               ERR("Remove Fail");
+                       return FALSE;
+               }
+
+               ret = fwrite(buf, sizeof(mtp_char), nmemb, fnew);
+               if (ret < nmemb && ferror(fnew)) {
+                       ERR("fwrite Fail errno [%d]\n", errno);
+                       *error = errno;
+                       fclose(fnew);
+                       fclose(fold);
+                       if (remove(newpath) < 0)
+                               ERR("Remove Fail");
+                       return FALSE;
+               }
+       } while (!feof(fold));
+
+       fclose(fnew);
+       fclose(fold);
+#else /* __USE_STDIO__ */
+       mtp_int32 in_fd = 0;
+       mtp_int32 out_fd = 0;
+       mtp_int32 ret = 0;
+       off_t offset = 0;
+
+       if ((in_fd = open(origpath, O_RDONLY)) < 0) {
+               ERR("In-file open Fail, errno [%d]\n", errno);
+               *error = errno;
+               return FALSE;
+       }
+
+       if ((out_fd = open(newpath, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
+               ERR("Out-file open Fail errno [%d] \n", errno);
+               *error = errno;
+               close(in_fd);
+               return FALSE;
+       }
+
+       do {
+               ret = sendfile(out_fd, in_fd, &offset, BUFSIZ);
+               if (ret < 0) {
+                       ERR("sendfile Fail errno [%d]\n", errno);
+                       *error = errno;
+                       close(out_fd);
+                       close(in_fd);
+                       if (remove(newpath) < 0)
+                               ERR("Remove Fail");
+                       return FALSE;
+               }
+       } while (ret == BUFSIZ);
+
+       close(out_fd);
+       close(in_fd);
+#endif /* __USE_STDIO__ */
+
+       return TRUE;
+}
+
+mtp_bool _util_copy_dir_children_recursive(const mtp_char *origpath,
+               const mtp_char *newpath, mtp_int32 *error)
+{
+       DIR *dir = NULL;
+       struct dirent entry = { 0 };
+       struct dirent *entryptr = NULL;
+       mtp_int32 retval = 0;
+       mtp_char old_pathname[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       mtp_char new_pathname[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       struct stat entryinfo;
+
+       retv_if(origpath == NULL, FALSE);
+       retv_if(newpath == NULL, FALSE);
+
+       /* Open the given directory */
+       dir = opendir(origpath);
+       if (dir == NULL) {
+               ERR("opendir(%s) Fail", origpath);
+               _util_print_error();
+               return FALSE;
+       }
+
+       retval = readdir_r(dir, &entry, &entryptr);
+
+       while (retval == 0 && entryptr != NULL) {
+               /* Skip the names "." and ".." as we don't want to recurse on them. */
+               if (!g_strcmp0(entry.d_name, ".") ||
+                               !g_strcmp0(entry.d_name, "..")) {
+                       retval = readdir_r(dir, &entry, &entryptr);
+                       continue;
+               }
+               g_snprintf(old_pathname, MTP_MAX_PATHNAME_SIZE + 1,
+                               "%s/%s", origpath, entry.d_name);
+               g_snprintf(new_pathname, MTP_MAX_PATHNAME_SIZE + 1,
+                               "%s/%s", newpath, entry.d_name);
+
+               if (stat(old_pathname, &entryinfo) != 0) {
+                       ERR("Error statting [%s] errno [%d]\n", old_pathname, errno);
+                       closedir(dir);
+                       return FALSE;
+               }
+
+               if (S_ISDIR(entryinfo.st_mode)) {
+                       if (FALSE == _util_dir_create(new_pathname, error)) {
+                               /* dir already exists
+                                  merge the contents */
+                               if (EEXIST != *error) {
+                                       ERR("directory[%s] create Fail errno [%d]\n", new_pathname, errno);
+                                       closedir(dir);
+                                       return FALSE;
+                               }
+                       }
+                       if (FALSE == _util_copy_dir_children_recursive(old_pathname,
+                                               new_pathname, error)) {
+                               ERR("Recursive Copy of Children Fail\
+                                               [%s]->[%s], errno [%d]\n", old_pathname, new_pathname, errno);
+                               closedir(dir);
+                               return FALSE;
+                       }
+               } else {
+                       if (FALSE == _util_file_copy(old_pathname, new_pathname, error)) {
+                               ERR("file copy fail [%s]->[%s]\n",
+                                               old_pathname, new_pathname);
+                               /* Cannot overwrite a read-only file,
+                                  Skip copy and retain the read-only file
+                                  on destination */
+                               if (EACCES == *error)
+                                       goto DONE;
+                               closedir(dir);
+                               return FALSE;
+                       }
+#ifdef MTP_SUPPORT_SET_PROTECTION
+                       mtp_bool ret = FALSE;
+
+                       if (!((S_IWUSR & entryInfo.st_mode) ||
+                                               (S_IWGRP & entryInfo.st_mode) ||
+                                               (S_IWOTH & entryInfo.st_mode))) {
+                               ret = _util_set_file_attrs(newPathName,
+                                               MTP_FILE_ATTR_MODE_REG |
+                                               MTP_FILE_ATTR_MODE_READ_ONLY);
+                               if (!ret) {
+                                       ERR("Failed to set directory attributes errno [%d]\n", errno);
+                                       closedir(dir);
+                                       return FALSE;
+                               }
+                       }
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+               }
+DONE:
+               retval = readdir_r(dir, &entry, &entryptr);
+       }
+
+       closedir(dir);
+       return (retval == 0) ? TRUE : FALSE;
+}
+
+mtp_bool _util_file_move(const mtp_char *origpath, const mtp_char *newpath,
+               mtp_int32 *error)
+{
+       mtp_int32 ret = 0;
+
+       ret = rename(origpath, newpath);
+       if (ret < 0) {
+               if (errno == EXDEV) {
+                       DBG("oldpath  and  newpath  are not on the same\
+                                       mounted file system.");
+                       if (_util_file_copy(origpath, newpath, error) == FALSE) {
+                               ERR("_util_file_copy Fail errno [%d]\n", errno);
+                               return FALSE;
+                       }
+                       if (remove(origpath) < 0) {
+                               ERR("remove Fail : %d\n", errno);
+                               return FALSE;
+                       }
+               } else {
+                       ERR("rename Fail : %d\n", errno);
+                       *error = errno;
+                       return FALSE;
+               }
+       }
+
+       return TRUE;
+}
+
+mtp_bool _util_is_file_opened(const mtp_char *fullpath)
+{
+       mtp_int32 ret = 0;
+
+       ret = rename(fullpath, fullpath);
+       return (ret != 0);
+}
+
+mtp_bool _util_dir_create(const mtp_char *dirname, mtp_int32 *error)
+{
+
+       if (mkdir(dirname, S_IRWXU | S_IRGRP |
+                               S_IXGRP | S_IROTH | S_IXOTH) < 0) {
+               *error = errno;
+               return FALSE;
+       }
+       return TRUE;
+}
+
+mtp_int32 _util_remove_dir_children_recursive(const mtp_char *dirname,
+               mtp_uint32 *num_of_deleted_file, mtp_uint32 *num_of_file, mtp_bool breadonly)
+{
+       retv_if(dirname == NULL, FALSE);
+
+       DIR *dir = NULL;
+       struct dirent entry = { 0 };
+       struct dirent *entryptr = NULL;
+       mtp_int32 retval = 0;
+       mtp_char pathname[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+       struct stat entryinfo;
+       mtp_int32 ret = MTP_ERROR_NONE;
+
+       /* Open the given directory */
+       dir = opendir(dirname);
+       if (dir == NULL) {
+               ERR("Open directory Fail[%s], errno [%d]", dirname, errno);
+               return MTP_ERROR_GENERAL;
+       }
+
+       retval = readdir_r(dir, &entry, &entryptr);
+
+       while (retval == 0 && entryptr != NULL) {
+               /* Skip the names "." and ".."
+                  as we don't want to recurse on them. */
+               if (!g_strcmp0(entry.d_name, ".") ||
+                               !g_strcmp0(entry.d_name, "..")) {
+                       retval = readdir_r(dir, &entry, &entryptr);
+                       continue;
+               }
+               g_snprintf(pathname, MTP_MAX_PATHNAME_SIZE + 1,
+                               "%s/%s", dirname, entry.d_name);
+               if (stat(pathname, &entryinfo) != 0) {
+                       ERR("Error statting %s errno [%d]\n", pathname, errno);
+                       closedir(dir);
+                       return MTP_ERROR_GENERAL;
+               }
+               *num_of_file += 1;
+               if (S_ISDIR(entryinfo.st_mode)) {
+                       ret = _util_remove_dir_children_recursive(pathname,
+                                       num_of_deleted_file, num_of_file, breadonly);
+                       if (MTP_ERROR_GENERAL == ret || MTP_ERROR_ACCESS_DENIED == ret) {
+                               ERR("deletion fail [%s]\n", pathname);
+                               closedir(dir);
+                               return ret;
+                       }
+                       if (MTP_ERROR_OBJECT_WRITE_PROTECTED == ret) {
+                               DBG("Folder[%s] contains read-only files,hence\
+                                               folder is not deleted\n",pathname);
+                               /* Read the next entry */
+                               goto DONE;
+                       }
+                       if (rmdir(pathname) < 0) {
+                               ERR("deletion fail [%s], errno [%d]\n", pathname, errno);
+                               closedir(dir);
+                               if (EACCES == errno)
+                                       return MTP_ERROR_ACCESS_DENIED;
+                               return MTP_ERROR_GENERAL;
+                       }
+                       *num_of_deleted_file += 1;
+               } else {
+                       /* Only during Deleteobject, bReadOnly(TRUE)
+                          do not delete read-only files */
+#ifdef MTP_SUPPORT_SET_PROTECTION
+                       if (breadonly) {
+                               /* check for file attributes */
+                               if (!((S_IWUSR & entryinfo.st_mode) ||
+                                                       (S_IWGRP & entryinfo.st_mode) ||
+                                                       (S_IWOTH & entryinfo.st_mode))) {
+                                       ret = MTP_ERROR_OBJECT_WRITE_PROTECTED;
+                                       DBG("File [%s] is readOnly:Deletion Fail\n",pathname);
+                                       goto DONE;
+                               }
+                       }
+#endif /* MTP_SUPPORT_SET_PROTECTION */
+                       if (unlink(pathname) < 0) {
+                               ERR("deletion fail [%s], errno [%d]\n", pathname, errno);
+                               closedir(dir);
+                               if (EACCES == errno)
+                                       return MTP_ERROR_ACCESS_DENIED;
+                               return MTP_ERROR_GENERAL;
+                       }
+                       *num_of_deleted_file += 1;
+               }
+DONE:
+               retval = readdir_r(dir, &entry, &entryptr);
+               if (retval != 0) {
+                       closedir(dir);
+                       return MTP_ERROR_GENERAL;
+               }
+       }
+
+       closedir(dir);
+       return ret;
+}
+
+/*
+ * mtp_bool _util_get_file_attrs(const mtp_char *filename, file_attr_t *attrs)
+ * This function gets the file attributes.
+ *
+ * @param[in]          filename        Specifies the name of file to find.
+ * @param[out]         attrs           Points the file Attributes.
+ * @return             This function returns TRUE if gets the attributes
+ *                     successfully, otherwise FALSE.
+ */
+mtp_bool _util_get_file_attrs(const mtp_char *filename, file_attr_t *attrs)
+{
+       struct stat fileinfo = { 0 };
+
+       if (stat(filename, &fileinfo) < 0) {
+               ERR_SECURE("%s : stat Fail errno [%d]\n", filename, errno);
+               return FALSE;
+       }
+
+       memset(attrs, 0, sizeof(file_attr_t));
+       attrs->fsize = fileinfo.st_size;
+       attrs->ctime = fileinfo.st_ctime;
+       attrs->mtime = fileinfo.st_mtime;
+
+       /*Reset attribute mode */
+       attrs->attribute = MTP_FILE_ATTR_MODE_NONE;
+       if (S_ISREG(fileinfo.st_mode)) {
+               attrs->attribute |= MTP_FILE_ATTR_MODE_REG;
+               if (!((S_IWUSR & fileinfo.st_mode) ||
+                                       (S_IWGRP & fileinfo.st_mode) ||
+                                       (S_IWOTH & fileinfo.st_mode))) {
+                       attrs->attribute |= MTP_FILE_ATTR_MODE_READ_ONLY;
+               }
+       } else if (S_ISDIR(fileinfo.st_mode)) {
+               attrs->attribute |= MTP_FILE_ATTR_MODE_DIR;
+       } else if (S_ISBLK(fileinfo.st_mode) || S_ISCHR(fileinfo.st_mode) ||
+                       S_ISLNK(fileinfo.st_mode) || S_ISSOCK(fileinfo.st_mode)) {
+               attrs->attribute |= MTP_FILE_ATTR_MODE_SYSTEM;
+       }
+       return TRUE;
+}
+
+mtp_bool _util_set_file_attrs(const mtp_char *filename, mtp_dword attrib)
+{
+       mtp_dword attrs = 0;
+
+       if (MTP_FILE_ATTR_MODE_REG & attrib) {
+               /*Reqular file */
+               if (MTP_FILE_ATTR_MODE_READ_ONLY & attrib)
+                       attrs |= (S_IRUSR | S_IRGRP | S_IROTH);
+               else
+                       attrs |= (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+       } else {
+               /* do nothing for files other than File/Folder */
+               DBG("entered here nothing");
+               return FALSE;
+       }
+
+       if (0 != chmod(filename, attrs)) {
+               if (EPERM == errno)
+                       return TRUE;
+               ERR_SECURE("Change mode of [File : %s] Fail\n", filename);
+               _util_print_error();
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/*
+ * mtp_bool _util_ifind_first(mtp_char *dirname, DIR **dirp,
+ *     dir_entry_t *dir_info)
+ * This function finds the first file in the directory stream.
+ *
+ * @param[in]          dirname         specifies the name of directory.
+ * @param[out]         dirp            pointer to the directory stream.
+ * @param[in]          dir_info        pointer to the file information.
+ * @return             This function returns TRUE on success, otherwise FALSE.
+ */
+mtp_bool _util_ifind_first(mtp_char *dirname, DIR **dirp, dir_entry_t *dir_info)
+{
+       DIR *dir;
+
+       retv_if(dirp == NULL, FALSE);
+       retv_if(dirname == NULL, FALSE);
+       retv_if(dir_info == NULL, FALSE);
+
+       dir = opendir(dirname);
+       if (NULL == dir) {
+               ERR("opendir(%s) Fail", dirname);
+               _util_print_error();
+
+               return FALSE;
+       }
+
+       if (_util_ifind_next(dirname, dir, dir_info) == FALSE) {
+               DBG("Stop enumeration");
+               _util_print_error();
+               closedir(dir);
+               return FALSE;
+       }
+
+       *dirp = dir;
+
+       return TRUE;
+}
+
+/*
+ * mtp_bool _util_ifind_next(mtp_char *dirname, DIR *dirp, dir_entry_t *dir_info)
+ * This function finds the next successive file in the directory stream.
+ *
+ * @param[in]          dirname         name of the directory.
+ * @param[in]          dirp            pointer to the directory stream.
+ * @param[out]         dir_info        Points the file information.
+ * @return             This function returns TRUE on success, otherwise FALSE.
+ */
+mtp_bool _util_ifind_next(mtp_char *dir_name, DIR *dirp, dir_entry_t *dir_info)
+{
+       mtp_int32 ret = 0;
+       struct dirent entry = {0};
+       struct stat stat_buf = {0};
+       struct dirent *result = NULL;
+       mtp_char path_name[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
+
+       retv_if(dir_name == NULL, FALSE);
+       retv_if(dir_info == NULL, FALSE);
+
+       do {
+               ret = readdir_r(dirp, &entry, &result);
+               if (ret != 0) {
+                       ERR("readdir_r Fail : %d\n", ret);
+                       return FALSE;
+               } else if (result == NULL) {
+                       DBG("There is no more entry");
+                       return FALSE;
+               }
+
+               if (_util_create_path(path_name, sizeof(path_name),
+                                       dir_name, entry.d_name) == FALSE) {
+                       continue;
+               }
+
+               if (stat(path_name, &stat_buf) < 0) {
+                       ERR_SECURE("stat Fail, skip [%s]\n", path_name);
+                       continue;
+               }
+               break;
+       } while (1);
+
+       g_strlcpy(dir_info->filename, path_name, sizeof(dir_info->filename));
+       dir_info->attrs.attribute = MTP_FILE_ATTR_MODE_NONE;
+
+       switch (stat_buf.st_mode & S_IFMT) {
+       case S_IFREG:
+               dir_info->type = MTP_FILE_TYPE;
+               if (!(stat_buf.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) {
+                       dir_info->attrs.attribute |= MTP_FILE_ATTR_MODE_READ_ONLY;
+               }
+               break;
+
+       case S_IFDIR:
+               dir_info->type = MTP_DIR_TYPE;
+               dir_info->attrs.attribute = MTP_FILE_ATTR_MODE_DIR;
+               break;
+
+       case S_IFBLK:
+       case S_IFCHR:
+       case S_IFIFO:
+       case S_IFLNK:
+       case S_IFSOCK:
+               dir_info->attrs.attribute |= MTP_FILE_ATTR_MODE_SYSTEM;
+               break;
+
+       default:
+               dir_info->attrs.attribute |= MTP_FILE_ATTR_MODE_SYSTEM;
+               ERR_SECURE("%s has unknown type. mode[0x%x]\n",
+                               dir_info->filename, stat_buf.st_mode);
+               break;
+       }
+
+       /* Directory Information */
+       dir_info->attrs.mtime = stat_buf.st_mtime;
+       dir_info->attrs.fsize = stat_buf.st_size;
+
+       return TRUE;
+}
+
+mtp_bool _util_get_filesystem_info(mtp_char *storepath, fs_info_t *fs_info)
+{
+       struct statfs buf = { 0 };
+       mtp_uint64 avail_size = 0;
+       mtp_uint64 capacity = 0;
+       mtp_uint64 used_size = 0;
+
+       if (statfs(storepath, &buf) != 0) {
+               ERR("statfs Fail");
+               return FALSE;
+       }
+
+       capacity = used_size = avail_size = buf.f_bsize;
+       DBG("Block size : %d\n", buf.f_bsize);
+       capacity *= buf.f_blocks;
+       used_size *= (buf.f_blocks - buf.f_bavail);
+       avail_size *= buf.f_bavail;
+
+       fs_info->disk_size = capacity;
+       fs_info->reserved_size = used_size;
+       fs_info->avail_size = avail_size;
+
+       return TRUE;
+}
+
+void _util_count_num_lines(mtp_uint32 fhandle, mtp_uint32 *num_lines)
+{
+       if (fhandle == INVALID_FILE)
+               return;
+
+       mtp_uint32 line_count = 0;
+       mtp_char *buffer = NULL;
+       mtp_int32 read_bytes;
+       mtp_uint32 line_max_length;
+
+       line_max_length = LINUX_MAX_PATHNAME_LENGTH + 2;
+       buffer = (mtp_char *)g_malloc(line_max_length);
+       if (buffer == NULL) {
+               ERR("Malloc Fail");
+               return;
+       }
+
+#ifdef __USE_STDIO__
+       while((read_bytes = getline(&buffer,
+                                       &line_max_length, (FILE *)fhandle)) != -1) {
+               if (read_bytes > MTP_MAX_PATHNAME_SIZE + 1)
+                       continue;
+               line_count++;
+       }
+#else /* __USE_STDIO__ */
+
+       mtp_uint16 ii = 0;
+       mtp_uint32 prev_pos = -1;
+       mtp_uint32 new_pos;
+       mtp_uint32 filename_len = 0;
+       while((read_bytes = read(fhandle, buffer, LINUX_MAX_PATHNAME_LENGTH)) > 0) {
+               for (ii = 0; ii < read_bytes; ii++) {
+                       if (buffer[ii] != '\n')
+                               continue;
+                       new_pos = ii;
+                       filename_len = new_pos - prev_pos -1;
+                       prev_pos = new_pos;
+                       if (filename_len > MTP_MAX_PATHNAME_SIZE)
+                               continue;
+                       line_count++;
+               }
+               if (buffer[read_bytes - 1] != '\n') {
+                       _util_file_seek(fhandle, prev_pos + 1 - read_bytes, SEEK_CUR);
+               }
+               prev_pos = -1;
+       }
+#endif /* __USE_STDIO__ */
+
+       *num_lines = line_count;
+       g_free(buffer);
+       return;
+}
+
+void _util_fill_guid_array(void *guidarray, mtp_uint32 start_index,
+               mtp_uint32 fhandle, mtp_uint32 size)
+{
+       ptp_array_t *pguidarray = NULL;
+       mtp_uint32 *guidptr = NULL;
+       mtp_uint32 num_lines = 0;
+       mtp_wchar objfullpath[MTP_MAX_PATHNAME_SIZE * 2 + 1] = { 0 };
+       mtp_char guid[16] = { 0 };
+       mtp_char *buffer = NULL;
+       mtp_uint32 line_max_length;
+       mtp_uint32 len = 0;
+
+       line_max_length = LINUX_MAX_PATHNAME_LENGTH + 2;
+       pguidarray = (ptp_array_t *)guidarray;
+       guidptr = (mtp_uint32 *)(pguidarray->array_entry);
+
+       buffer = (mtp_char *)g_malloc(line_max_length);
+       if (buffer == NULL) {
+               ERR("Malloc Fail");
+               return;
+       }
+
+#ifdef __USE_STDIO__
+       while ((len = getline(&buffer, &line_max_length, (FILE *)fhandle)) != -1 &&
+                       (num_lines - start_index) <= size) {
+               if (len > MTP_MAX_PATHNAME_SIZE + 1)
+                       continue;
+               num_lines++;
+               if (num_lines < start_index)
+                       continue;
+               buffer[len - 1] = '\0';
+               _util_utf8_to_utf16(objfullpath,
+                               sizeof(objfullpath) / WCHAR_SIZ, buffer);
+               _util_conv_wstr_to_guid(objfullpath, (mtp_uint64 *)guid);
+               memcpy(&(guidptr[pguidarray->num_ele]),
+                               guid, sizeof(guid));
+               pguidarray->num_ele += sizeof(mtp_uint32);
+       }
+#else /* __USE_STDIO__ */
+       mtp_uint16 ii = 0;
+       mtp_uint32 prev_pos = -1;
+       mtp_uint32 new_pos;
+       mtp_char file_name[MTP_MAX_PATHNAME_SIZE + 1];
+       mtp_int32 read_bytes;
+
+       while ((read_bytes = read(fHandle, buffer,
+                                       LINUX_MAX_PATHNAME_LENGTH)) > 0 &&
+                       (num_lines - start_index) <= size) {
+
+               for (ii = 0; ii < read_bytes; ii++) {
+                       if (buffer[ii] != '\n')
+                               continue;
+                       new_pos = ii;
+                       len = new_pos - prev_pos - 1;
+                       prev_pos = new_pos;
+                       if (len > MTP_MAX_PATHNAME_SIZE)
+                               continue;
+                       num_lines++;
+                       if (num_lines < start_index)
+                               continue;
+                       strncpy(file_name, &buffer[new_pos - len], len);
+                       file_name[len] = '\0';
+                       _util_utf8_to_utf16(objfullpath,
+                                       sizeof(objfullpath) / WCHAR_SIZ, file_name);
+                       _util_conv_wstr_to_guid(objfullpath, (mtp_uint64 *)guid);
+                       memcpy(&(guidptr[pguidarray->num_elements]),
+                                       guid, sizeof(guid));
+                       pguidarray->num_elements += sizeof(mtp_uint32);
+               }
+
+               if (buffer[read_bytes - 1] != '\n') {
+                       _util_file_seek(fhandle, prev_pos + 1 - read_bytes, SEEK_CUR);
+               }
+               prev_pos = -1;
+       }
+#endif /* __USE_STDIO__ */
+
+       g_free(buffer);
+
+       return;
+}
+
+/*
+ * void FLOGD(const char *fmt, ...)
+ * This function writes MTP debug message to MTP log file
+ *
+ * @param[in]          fmt Formatted debug message.
+ * @param[out]         None.
+ * @return             None.
+ */
+void FLOGD(const char *fmt, ...)
+{
+       static int written_bytes = 0;
+       FILE *fp = NULL;
+       va_list ap;
+
+       if (written_bytes == 0 || written_bytes > MTP_LOG_MAX_SIZE) {
+               fp = fopen(MTP_LOG_FILE, "w");
+               written_bytes = 0;
+       } else {
+               fp = fopen(MTP_LOG_FILE, "a+");
+       }
+
+       if (fp == NULL) {
+               return;
+       }
+
+       written_bytes += fprintf(fp, "%s ", __FILE__);
+       va_start(ap, fmt);
+       written_bytes += vfprintf(fp, fmt, ap);
+       va_end(ap);
+
+       fclose(fp);
+       return;
+}
diff --git a/src/util/mtp_list.c b/src/util/mtp_list.c
new file mode 100755 (executable)
index 0000000..1ba7050
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <glib.h>
+#include "mtp_list.h"
+
+/*
+ * FUNCTIONS
+ */
+static slist_node_t *__util_del_first_node(slist_t *l_ptr);
+
+void _util_init_list(slist_t *l_ptr)
+{
+       ret_if(l_ptr == NULL);
+
+       l_ptr->start = NULL;
+       l_ptr->end = NULL;
+       l_ptr->nnodes = 0;
+
+       return;
+}
+
+mtp_bool _util_add_node(slist_t *l_ptr, void *data)
+{
+       retv_if(l_ptr == NULL, FALSE);
+
+       slist_node_t *node = NULL;
+
+       node = (slist_node_t *)g_malloc(sizeof(slist_node_t));
+       if (node == NULL) {
+               ERR("g_malloc() Fail");
+               return FALSE;
+       }
+
+       node->value = data;
+       node->link = NULL;
+
+       if (l_ptr->start == NULL)
+               l_ptr->start = node;
+       else
+               l_ptr->end->link = node;
+
+       l_ptr->end = node;
+       l_ptr->nnodes += 1;
+       return TRUE;
+}
+
+slist_node_t* _util_delete_node(slist_t *l_ptr, void *data)
+{
+       retv_if(data == NULL, NULL);
+       retv_if(l_ptr == NULL, NULL);
+       retv_if(l_ptr->start == NULL, NULL);
+
+       slist_node_t *nptr = l_ptr->start;
+       slist_node_t *temp = NULL;
+
+       if (nptr->value == data) {
+               return __util_del_first_node(l_ptr);
+       }
+
+       while (nptr->link) {
+               if (nptr->link->value == data)
+                       break;
+               nptr = nptr->link;
+       }
+
+       if (nptr->link == NULL) {
+               ERR("Node not found in the list");
+               return NULL;
+       }
+
+       temp = nptr->link;
+       nptr->link = nptr->link->link;
+       l_ptr->nnodes -= 1;
+
+       if (temp == l_ptr->end)
+               l_ptr->end = nptr;
+
+       return temp;
+}
+
+static slist_node_t *__util_del_first_node(slist_t *l_ptr)
+{
+       slist_node_t *temp = NULL;
+
+       temp = l_ptr->start;
+       l_ptr->nnodes -= 1;
+       l_ptr->start = temp->link;
+       if (temp == l_ptr->end) {
+               l_ptr->end = NULL;
+       }
+
+       return temp;
+}
+
+/* This API will send NULL if list does not have elements */
+slist_iterator* _util_init_list_iterator(slist_t *l_ptr)
+{
+       slist_iterator *temp = NULL;
+
+       retv_if(l_ptr == NULL, NULL);
+       retv_if(l_ptr->start == NULL, NULL);
+
+       temp = (slist_iterator *)g_malloc(sizeof(slist_iterator));
+       if (temp == NULL) {
+               ERR("g_malloc() Fail");
+               return NULL;
+       }
+
+       temp->node_ptr = l_ptr->start;
+       return temp;
+}
+
+/* Befor calling this please make sure
+   next element exists using _util_check_list_next */
+void* _util_get_list_next(slist_iterator *iter)
+{
+       slist_node_t *temp = NULL;
+
+       retv_if(iter == NULL, NULL);
+
+       temp = iter->node_ptr;
+       iter->node_ptr = iter->node_ptr->link;
+
+       return temp->value;
+}
+
+slist_node_t* _util_get_first_node(slist_t *l_ptr)
+{
+       retv_if(l_ptr == NULL, NULL);
+
+       return l_ptr->start;
+}
+
+void _util_deinit_list_iterator(slist_iterator *iter)
+{
+       ret_if(iter == NULL);
+
+       g_free(iter);
+}
diff --git a/src/util/mtp_media_info.c b/src/util/mtp_media_info.c
new file mode 100755 (executable)
index 0000000..eb0421e
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include <metadata_extractor.h>
+#include "mtp_media_info.h"
+#include "mtp_util.h"
+#include "mtp_support.h"
+#include "mtp_fs.h"
+
+static bool __fill_media_id_cb(media_info_h media, void *user_data)
+{
+       media_info_h *media_id = (media_info_h *)user_data;
+       DBG("INTO MEdia id retrieval callback");
+       media_info_clone(media_id, media);
+
+       return FALSE;
+}
+
+static void __scan_folder_cb(media_content_error_e err, void *user_data)
+{
+       if (err != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("Scan folder callback returns error = [%d]\n", err);
+       }
+
+       return;
+}
+
+mtp_bool _util_get_audio_metadata(const mtp_char *filepath,
+               comp_audio_meta_t *audio_data)
+{
+       char *temp = NULL;
+       audio_meta_h audio;
+       filter_h filter = NULL;
+       media_info_h media_item = NULL;
+       mtp_int32 ret = MEDIA_CONTENT_ERROR_NONE;
+       mtp_char condition[MEDIA_PATH_COND_MAX_LEN + 1];
+
+       retv_if(filepath == NULL, FALSE);
+       retv_if(audio_data == NULL, FALSE);
+
+       g_snprintf(condition, MEDIA_PATH_COND_MAX_LEN + 1, "%s\"%s\"",
+                       MEDIA_PATH_COND, filepath);
+
+       ret = media_filter_create(&filter);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("Fail to create filter ");
+               return FALSE;
+       }
+
+       ret = media_filter_set_condition(filter, condition,
+                       MEDIA_CONTENT_COLLATE_DEFAULT);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("Failed to set condition ");
+               media_filter_destroy(filter);
+               return FALSE;
+       }
+
+       ret = media_info_foreach_media_from_db(filter, __fill_media_id_cb,
+                       &media_item);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("media_info_foreach_media_from_db Fail");
+               media_filter_destroy(filter);
+               return FALSE;
+       }
+
+       media_filter_destroy(filter);
+
+       if (media_item == NULL) {
+               ERR("File entry not found in db");
+               return FALSE;
+       }
+
+       ret = media_info_get_audio(media_item, &audio);
+       if (ret != MEDIA_CONTENT_ERROR_NONE || audio == NULL) {
+               ERR("media_info_get_audio Fail or Audio is NULL");
+               media_info_destroy(media_item);
+               return FALSE;
+       }
+
+       ret = audio_meta_get_album(audio, &(audio_data->commonmeta.album));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_ALBUM Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = audio_meta_get_artist(audio, &(audio_data->commonmeta.artist));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_ARTIST Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = audio_meta_get_bit_rate(audio,
+                       &(audio_data->commonmeta.audio_bitrate));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_AUDIO_BITRATE Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret =audio_meta_get_composer(audio, &(audio_data->commonmeta.author));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_AUTHOR Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = audio_meta_get_copyright(audio,
+                       &(audio_data->commonmeta.copyright));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_COPYRIGHT Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = audio_meta_get_duration(audio,
+                       &(audio_data->commonmeta.duration));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_DURATION Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = audio_meta_get_genre(audio, &(audio_data->commonmeta.genre));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_GENRE Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = audio_meta_get_recorded_date(audio,
+                       &(audio_data->commonmeta.year));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_RECDATE Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = audio_meta_get_track_num(audio, &temp);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_TRACK_NUM Fail");
+               goto ERROR_EXIT;
+       }
+
+       if (NULL != temp) {
+               audio_data->audiometa.track = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = audio_meta_get_channel(audio,
+                       &(audio_data->commonmeta.num_channel));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_NUM_CHANNEL Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = audio_meta_get_sample_rate(audio,
+                       &(audio_data->commonmeta.sample_rate));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_SAMPLE_RATE Fail");
+               goto ERROR_EXIT;
+       }
+
+       audio_data->commonmeta.description = g_strdup("Unknown");
+       audio_data->commonmeta.audio_codec = 0;
+
+       audio_meta_destroy(audio);
+       media_info_destroy(media_item);
+       return TRUE;
+
+ERROR_EXIT:
+
+       audio_meta_destroy(audio);
+       media_info_destroy(media_item);
+       return FALSE;
+}
+
+mtp_bool _util_get_video_metadata(mtp_char *filepath,
+               comp_video_meta_t *video_data)
+{
+       filter_h filter = NULL;
+       video_meta_h video;
+       media_info_h media_item = NULL;
+       mtp_int32 ret = MEDIA_CONTENT_ERROR_NONE;
+       mtp_char condition[MEDIA_PATH_COND_MAX_LEN + 1];
+
+       retv_if(filepath == NULL, FALSE);
+       retv_if(video_data == NULL, FALSE);
+
+       g_snprintf(condition, sizeof(condition), "%s\"%s\"", MEDIA_PATH_COND, filepath);
+
+       ret = media_filter_create(&filter);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("Fail to create filter ");
+               return FALSE;
+       }
+
+       ret = media_filter_set_condition(filter, condition,
+                       MEDIA_CONTENT_COLLATE_DEFAULT);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("Failed to set condition ");
+               media_filter_destroy(filter);
+               return FALSE;
+       }
+
+       ret = media_info_foreach_media_from_db(filter, __fill_media_id_cb,
+                       &media_item);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("media_info_foreach_media_from_db Fail");
+               media_filter_destroy(filter);
+               return FALSE;
+       }
+
+       media_filter_destroy(filter);
+
+       if (media_item == NULL) {
+               ERR("File entry not found in db");
+               return FALSE;
+       }
+
+       ret = media_info_get_video(media_item, &video);
+       if (ret != MEDIA_CONTENT_ERROR_NONE || video == NULL) {
+               ERR("media_info_get_audio Fail or video is NULL");
+               media_info_destroy(media_item);
+               return FALSE;
+       }
+
+       ret = video_meta_get_album(video, &(video_data->commonmeta.album));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_ALBUM Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = video_meta_get_artist(video, &(video_data->commonmeta.artist));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_ARTIST Fail");
+               goto ERROR_EXIT;
+       }
+
+       /* AUDIO BITRATE */
+       video_data->commonmeta.audio_bitrate = 0;
+
+       ret = video_meta_get_composer(video, &(video_data->commonmeta.author));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_AUTHOR Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = video_meta_get_copyright(video,
+                       &(video_data->commonmeta.copyright));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_COPYRIGHT Fail");
+               goto ERROR_EXIT;
+       }
+
+       /* Description */
+       video_data->commonmeta.description = g_strdup("Unknown");
+
+       ret = video_meta_get_duration(video,
+                       &(video_data->commonmeta.duration));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_DURATION Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = video_meta_get_genre(video, &(video_data->commonmeta.genre));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_GENRE Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = video_meta_get_recorded_date(video,
+                       &(video_data->commonmeta.year));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_REC_DATE Fail");
+               goto ERROR_EXIT;
+       }
+
+       /* METADATA_AUDIO_CHANNELS */
+       video_data->commonmeta.num_channel = 0;
+
+       /* METADAT_RATING */
+       video_data->commonmeta.rating = 0;
+
+       /* METADATA_SAMPLE_RATE */
+       video_data->commonmeta.sample_rate = 0;
+
+       ret = video_meta_get_track_num(video, &(video_data->videometa.track));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_TRACK_NUM Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = video_meta_get_bit_rate(video, &(video_data->videometa.video_br));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_VIDEO_BITRATE Fail");
+               goto ERROR_EXIT;
+       }
+
+       /* VIDEO_FPS */
+       video_data->videometa.video_fps = 0;
+       video_data->commonmeta.audio_codec = 0;
+       video_data->videometa.video_br = 0;
+
+       ret = video_meta_get_height(video, &(video_data->videometa.video_h));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_HEIGHT Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = video_meta_get_width(video, &(video_data->videometa.video_w));
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("METADATA_WIDTH Fail");
+               goto ERROR_EXIT;
+       }
+
+       video_meta_destroy(video);
+       media_info_destroy(media_item);
+       return TRUE;
+ERROR_EXIT:
+       video_meta_destroy(video);
+       media_info_destroy(media_item);
+
+       return FALSE;
+}
+
+static media_info_h __util_find_media_info(mtp_char *condition)
+{
+       int ret;
+       filter_h filter = NULL;
+       media_info_h media_item = NULL;
+
+       ret = media_filter_create(&filter);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("Fail to create filter ");
+               return NULL;
+       }
+
+       do {
+               ret = media_filter_set_condition(filter, condition, MEDIA_CONTENT_COLLATE_DEFAULT);
+               if (ret != MEDIA_CONTENT_ERROR_NONE) {
+                       ERR("media_filter_set_condition() Fail");
+                       break;
+               }
+
+               ret = media_filter_set_offset(filter, 0, 1);
+               if (ret != MEDIA_CONTENT_ERROR_NONE) {
+                       ERR("media_filter_set_offset() Fail");
+                       break;
+               }
+
+               ret = media_info_foreach_media_from_db(filter, __fill_media_id_cb, &media_item);
+               if (ret != MEDIA_CONTENT_ERROR_NONE) {
+                       ERR("media_info_foreach_media_from_db() Fail");
+                       break;
+               }
+       }while (0);
+
+       media_filter_destroy(filter);
+
+       return media_item;
+}
+
+
+static mtp_bool __util_get_height_width(image_meta_h image, int *h, int *w)
+{
+       int ret;
+
+       ret = image_meta_get_height(image, h);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("image_meta_get_height() Fail(%d)", ret);
+               return FALSE;
+       }
+
+       ret = image_meta_get_width(image, w);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("image_meta_get_width() Fail(%d)", ret);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+mtp_bool _util_get_image_ht_wt(const mtp_char *filepath,
+               image_meta_t *image_data)
+{
+       mtp_int32 ret;
+       image_meta_h image;
+       media_info_h media_item;
+       mtp_char condition[MEDIA_PATH_COND_MAX_LEN + 1];
+
+       retv_if(filepath == NULL, FALSE);
+       retv_if(image_data == NULL, FALSE);
+
+       g_snprintf(condition, sizeof(condition), "%s\"%s\"", MEDIA_PATH_COND, filepath);
+
+       media_item = __util_find_media_info(condition);
+       if (media_item == NULL) {
+               ERR("File entry not found in db");
+               return FALSE;
+       }
+
+       ret = media_info_get_image(media_item, &image);
+       if (ret != MEDIA_CONTENT_ERROR_NONE || image == NULL) {
+               ERR("media_info_get_image() Fail(%d) or image(%p) is NULL", ret, image);
+               media_info_destroy(media_item);
+               return FALSE;
+       }
+
+       ret = __util_get_height_width(image, &image_data->ht, &image_data->wt);
+       if (FALSE == ret)
+               ERR("__util_get_height_width() Fail");
+
+       media_info_destroy(media_item);
+       image_meta_destroy(image);
+
+       return ret;
+}
+
+mtp_bool _util_get_audio_meta_from_extractor(const mtp_char *filepath,
+               comp_audio_meta_t *audio_data)
+{
+       mtp_int32 ret = 0;
+       mtp_char *temp = NULL;
+       metadata_extractor_h metadata = NULL;
+
+       retv_if(filepath == NULL, FALSE);
+       retv_if(audio_data == NULL, FALSE);
+
+       ret = metadata_extractor_create(&metadata);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("metadata extractor create Fail");
+               return FALSE;
+       }
+
+       ret = metadata_extractor_set_path(metadata, filepath);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("metadata extractor set path Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_ALBUM,
+                       &(audio_data->commonmeta.album));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_ALBUM Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_ARTIST,
+                       &(audio_data->commonmeta.artist));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_ARTIST Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_AUDIO_BITRATE,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_AUDIO_BITRATE Fail");
+               goto ERROR_EXIT;
+       }
+
+       if (NULL != temp) {
+               audio_data->commonmeta.audio_bitrate = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_AUTHOR,
+                       &(audio_data->commonmeta.author));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_AUTHOR Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_COPYRIGHT,
+                       &(audio_data->commonmeta.copyright));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_COPYRIGHT Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_DESCRIPTION,
+                       &(audio_data->commonmeta.description));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_DESCRIPTION Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_DURATION,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_DURATION Fail");
+               goto ERROR_EXIT;
+       }
+
+       if (NULL != temp) {
+               audio_data->commonmeta.duration = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_GENRE,
+                       &(audio_data->commonmeta.genre));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_GENRE Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_RECDATE,
+                       &(audio_data->commonmeta.year));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_RECDATE Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_TRACK_NUM,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_TRACK_NUM Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               audio_data->audiometa.track = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_RATING,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_RATING Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               audio_data->commonmeta.rating = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata,
+                       METADATA_AUDIO_SAMPLERATE, &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_SAMPLERATE Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               audio_data->commonmeta.sample_rate = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_AUDIO_CHANNELS,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_CHANNELS Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               audio_data->commonmeta.num_channel = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       audio_data->commonmeta.audio_codec = 0;
+
+       metadata_extractor_destroy(metadata);
+       return TRUE;
+
+ERROR_EXIT:
+       metadata_extractor_destroy(metadata);
+       return FALSE;
+}
+
+mtp_bool _util_get_video_meta_from_extractor(const mtp_char *filepath,
+               comp_video_meta_t *video_data)
+{
+       mtp_int32 ret = 0;
+       mtp_char *temp = NULL;
+       metadata_extractor_h metadata = NULL;
+
+       retv_if(filepath == NULL, FALSE);
+       retv_if(video_data == NULL, FALSE);
+
+       ret = metadata_extractor_create(&metadata);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("metadata extractor create Fail");
+               return FALSE;
+       }
+
+       ret = metadata_extractor_set_path(metadata, filepath);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("metadata extractor set path Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_ALBUM,
+                       &(video_data->commonmeta.album));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_ALBUM Fail");
+               goto ERROR_EXIT;
+
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_ARTIST,
+                       &(video_data->commonmeta.artist));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_ARTIST Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_AUDIO_BITRATE,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_AUDIO_BITRATE Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               video_data->commonmeta.audio_bitrate = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_AUTHOR,
+                       &(video_data->commonmeta.author));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_AUTHOR Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_COPYRIGHT,
+                       &(video_data->commonmeta.copyright));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_COPYRIGHT Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_DESCRIPTION,
+                       &(video_data->commonmeta.description));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_DESCRIPTION Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_DURATION,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_DURATION Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               video_data->commonmeta.duration = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_GENRE,
+                       &(video_data->commonmeta.genre));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_GENRE Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_RECDATE,
+                       &(video_data->commonmeta.year));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_RECDATE Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_AUDIO_CHANNELS,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_AUDIO_CHANNELS Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               video_data->commonmeta.num_channel = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_RATING,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_RATING Fail");
+               goto ERROR_EXIT;
+       }
+
+       if (NULL != temp) {
+               video_data->commonmeta.rating = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata,
+                       METADATA_AUDIO_SAMPLERATE, &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_AUDIO_SAMPLERATE Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               video_data->commonmeta.sample_rate = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_TRACK_NUM,
+                       &(video_data->videometa.track));
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_TRACK_NUM Fail");
+               goto ERROR_EXIT;
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_VIDEO_BITRATE,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_VIDEO_BITRATE Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               video_data->videometa.video_br = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_VIDEO_FPS,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_VIDEO_FPS Fail");
+               goto ERROR_EXIT;
+       }
+       video_data->videometa.video_fps = atoi(temp);
+       MTP_PAL_SAFE_FREE(temp);
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_VIDEO_HEIGHT,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_VIDEO_HEIGHT Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               video_data->videometa.video_h = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       ret = metadata_extractor_get_metadata(metadata, METADATA_VIDEO_WIDTH,
+                       &temp);
+       if (ret != METADATA_EXTRACTOR_ERROR_NONE) {
+               ERR("METADATA_VIDEO_WIDTH Fail");
+               goto ERROR_EXIT;
+       }
+       if (NULL != temp) {
+               video_data->videometa.video_w = atoi(temp);
+               MTP_PAL_SAFE_FREE(temp);
+       }
+
+       metadata_extractor_destroy(metadata);
+       return TRUE;
+
+ERROR_EXIT:
+       metadata_extractor_destroy(metadata);
+       return FALSE;
+
+}
+
+void _util_flush_db(void)
+{
+       _util_add_file_to_db(NULL);
+       _util_delete_file_from_db(NULL);
+}
+
+void _util_delete_file_from_db(const mtp_char *filepath)
+{
+       int ret;
+
+       ret_if(NULL == filepath);
+
+       ret = media_info_delete_from_db(filepath);
+       if (MEDIA_CONTENT_ERROR_NONE != ret)
+               ERR("media_info_delete_from_db() Fail(%d)", ret);
+
+       return;
+}
+
+void _util_add_file_to_db(const mtp_char *filepath)
+{
+       mtp_int32 ret;
+       media_info_h info = NULL;
+
+       ret_if(NULL == filepath);
+
+       ret = media_info_insert_to_db(filepath, &info);
+       if (MEDIA_CONTENT_ERROR_NONE != ret)
+               ERR("media_info_insert_to_db() Fail(%d)", ret);
+
+       if (info)
+               media_info_destroy(info);
+
+       return;
+}
+
+void _util_scan_folder_contents_in_db(const mtp_char *filepath)
+{
+       mtp_int32 ret;
+
+       ret_if(filepath == NULL);
+
+       ret = media_content_scan_folder(filepath, true, __scan_folder_cb, NULL);
+       if (ret != MEDIA_CONTENT_ERROR_NONE) {
+               ERR("media_content_scan_folder Fail : %d\n", ret);
+       }
+
+       return;
+}
+
+void _util_free_common_meta(common_meta_t *metadata)
+{
+       MTP_PAL_SAFE_FREE(metadata->album);
+       MTP_PAL_SAFE_FREE(metadata->artist);
+       MTP_PAL_SAFE_FREE(metadata->author);
+       MTP_PAL_SAFE_FREE(metadata->copyright);
+       MTP_PAL_SAFE_FREE(metadata->description);
+       MTP_PAL_SAFE_FREE(metadata->genre);
+       MTP_PAL_SAFE_FREE(metadata->year);
+
+       return;
+}
+void _util_free_video_meta(video_meta_t *video)
+{
+       MTP_PAL_SAFE_FREE(video->track);
+       return;
+}
diff --git a/src/util/mtp_msgq.c b/src/util/mtp_msgq.c
new file mode 100755 (executable)
index 0000000..ad98fa5
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include "mtp_msgq.h"
+
+/*
+ * FUNCTIONS
+ */
+mtp_bool _util_msgq_init(msgq_id_t *mq_id, mtp_uint32 flags)
+{
+       *mq_id = msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
+       if (*mq_id == -1) {
+               ERR("msgget() Fail");
+               _util_print_error();
+               return FALSE;
+       }
+       return TRUE;
+}
+
+mtp_bool _util_msgq_send(msgq_id_t mq_id, void *buf, mtp_uint32 size,
+               mtp_uint32 flags)
+{
+       if (-1 == msgsnd(mq_id, buf, size, flags)) {
+               ERR("msgsnd() Fail : mq_id = [%d]", mq_id);
+               _util_print_error();
+               return FALSE;
+       }
+       return TRUE;
+}
+
+mtp_bool _util_msgq_receive(msgq_id_t mq_id, void *buf, mtp_uint32 size,
+               mtp_uint32 flags, mtp_int32 *nbytes)
+{
+       int ret = 0;
+
+       if (flags == 1) {
+               ret = msgrcv(mq_id, buf, size, 0, IPC_NOWAIT);
+       } else {
+               ret = msgrcv(mq_id, buf, size, 0, 0);
+       }
+
+       if (ret == -1) {
+               ERR("msgrcv() Fail");
+               _util_print_error();
+               *nbytes = 0;
+               return FALSE;
+       }
+
+       *nbytes = ret;
+       return TRUE;
+}
+
+mtp_bool _util_msgq_deinit(msgq_id_t *msgq_id)
+{
+       if (-1 == msgctl(*msgq_id, IPC_RMID, 0)) {
+               ERR("msgctl(IPC_RMID) Fail");
+               return FALSE;
+       }
+       return TRUE;
+}
+
+mtp_bool _util_msgq_set_size(msgq_id_t mq_id, mtp_uint32 nbytes)
+{
+       struct msqid_ds attr;
+
+       /* Getting the attributes of Message Queue */
+       if (msgctl(mq_id, MSG_STAT, &attr) == -1) {
+               ERR("msgctl(MSG_STAT) Fail");
+               return FALSE;
+       }
+
+       attr.msg_qbytes = nbytes;
+
+       /* Setting the message queue size */
+       if (msgctl(mq_id, IPC_SET, &attr) == -1) {
+               ERR("msgctl(IPC_SET) Fail");
+               return FALSE;
+       }
+       return TRUE;
+}
+
+/*
+ * _util_rcv_msg_from_mq
+ *
+ * This function receives a message pointer from Message Queue
+ * @param[in]  mq_id   Message Queue Id
+ * @param[out] pkt     Shall be assigned with received buffer ptr
+ * @param[out] pkt_len Will hold the length of received data
+ * @param[out] mtype   Will be assigned the type of message received
+ */
+mtp_bool _util_rcv_msg_from_mq(msgq_id_t mq_id, unsigned char **pkt,
+               mtp_uint32 *pkt_len, msg_type_t *mtype)
+{
+       msgq_ptr_t msg = { 0 };
+       mtp_int32 nbytes = 0;
+
+       if (FALSE == _util_msgq_receive(mq_id, (void *)&msg,
+                               sizeof(msgq_ptr_t) - sizeof(long), 0, &nbytes)) {
+               ERR("_util_msgq_receive() Fail : mq_id = [%d]", mq_id);
+               return FALSE;
+       }
+
+       *pkt_len = msg.length;
+       *pkt = msg.buffer;
+       *mtype = msg.mtype;
+
+       return TRUE;
+}
diff --git a/src/util/mtp_support.c b/src/util/mtp_support.c
new file mode 100755 (executable)
index 0000000..b5e01da
--- /dev/null
@@ -0,0 +1,648 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <glib.h>
+#include <glib/gprintf.h>
+#include <unistd.h>
+#include "mtp_support.h"
+#include "ptp_datacodes.h"
+#include "mtp_util.h"
+
+/*
+ * STATIC FUNCTIONS
+ */
+static mtp_char *__util_conv_int_to_hex_str(mtp_int32 int_val, mtp_char *str);
+
+/*
+ * FUNCTIONS
+ */
+void _util_conv_byte_order(void *data, mtp_int32 size)
+{
+       mtp_int32 idx;
+       mtp_uchar temp;
+       mtp_int32 h_size;
+       mtp_uchar *l_data = (mtp_uchar *)data;
+
+       ret_if(data == NULL);
+       retm_if(size <= 1, "size(%d) is invalid", size);
+
+       h_size = size / 2;
+       for (idx = 0; idx < h_size; idx++) {
+               temp = l_data[idx];
+               l_data[idx] = l_data[size - idx - 1];
+               l_data[size - idx - 1] = temp;
+       }
+
+       return;
+}
+
+void _util_conv_byte_order_wstring(mtp_uint16 *wstr, mtp_int32 size)
+{
+       _util_conv_byte_order_gen_str(wstr, size, sizeof(mtp_uint16));
+       return;
+}
+
+void _util_conv_byte_order_gen_str(void *str, mtp_int32 size, mtp_int32 elem_sz)
+{
+       mtp_int32 idx;
+       mtp_int32 f_size = size * elem_sz;
+       mtp_uchar *l_str = (mtp_uchar *)str;
+
+       ret_if(str == NULL);
+       retm_if(elem_sz <= 1, "elem_sz(%d) is invalid", elem_sz);
+
+       for (idx = 0; idx < f_size; idx += elem_sz) {
+               _util_conv_byte_order(&(l_str[idx]), elem_sz);
+       }
+
+       return;
+}
+
+/*
+ * If items_written is greater than or equal to dest_size,
+ * src is truncated when it is copied to dest.
+ */
+mtp_int32 _util_utf16_to_utf8(char *dest, mtp_int32 dest_size,
+               const mtp_wchar *src)
+{
+       gchar *utf8 = NULL;
+       GError *error = NULL;
+       glong items_read = 0;
+       glong items_written = 0;
+       const gunichar2 *utf16 = (const gunichar2 *)src;
+
+       retv_if(src == NULL, 0);
+       retv_if(dest == NULL, 0);
+
+       utf8 = g_utf16_to_utf8(utf16, -1, &items_read, &items_written, &error);
+       if (utf8 == NULL) {
+               ERR("%s\n", error->message);
+               g_error_free(error);
+
+               dest[0] = '\0';
+               items_written = 0;
+       } else {
+               g_strlcpy(dest, (char *)utf8, dest_size);
+               g_free(utf8);
+       }
+
+       return (mtp_int32)items_written;
+}
+
+/*
+ * If items_written is greater than or equal to dest_items,
+ * src is truncated when it is copied to dest.
+ */
+mtp_int32 _util_utf8_to_utf16(mtp_wchar *dest, mtp_int32 dest_items,
+               const char *src)
+{
+       GError *error = NULL;
+       glong items_read = 0;
+       gunichar2 *utf16 = NULL;
+       glong items_written = 0;
+
+       retv_if(src == NULL, 0);
+       retv_if(dest == NULL, 0);
+
+       utf16 = g_utf8_to_utf16(src, -1, &items_read, &items_written, &error);
+       if (utf16 == NULL) {
+               ERR("%s\n", error->message);
+               g_error_free(error);
+               error = NULL;
+
+               dest[0] = (mtp_wchar)'\0';
+               items_written = 0;
+       } else {
+               _util_wchar_ncpy(dest, utf16, dest_items);
+               g_free(utf16);
+       }
+
+       return (mtp_int32)items_written;
+}
+
+
+/*
+ * Copies a unicode string.
+ * @param[in]  src     Null-terminated source string
+ * @param[out] dest    Destination buffer
+ * @return     None
+ */
+void _util_wchar_cpy(mtp_wchar *dest, const mtp_wchar *src)
+{
+       ret_if(src == NULL);
+       ret_if(dest == NULL);
+
+       if (!((int)dest & 0x1) && !((int)src & 0x1)){
+               /* 2-byte aligned */
+               mtp_wchar *temp = dest;
+
+               while ((*temp++ = *src++) != '\0') {
+                       ;       /* DO NOTHING  */
+               }
+       } else {
+               /* not-aligned, byte to byte approach - slow */
+               mtp_char *pc1 = (mtp_char *)dest;
+               mtp_char *pc2 = (mtp_char *)src;
+
+               while (*pc2 || *(pc2 + 1)) {
+                       *pc1 = *pc2;
+                       *(pc1 + 1) = *(pc2 + 1);
+
+                       pc1 += 2;
+                       pc2 += 2;
+               }
+       }
+
+       return;
+}
+
+/*
+ * Copies a unicode string a given numbers of character.
+ * @param[in]  src     Null-terminated source string
+ * @param[out] dest    Destination buffer
+ * @return     None
+ */
+void _util_wchar_ncpy(mtp_wchar *dest, const mtp_wchar *src, unsigned long n)
+{
+       char *pc1 = NULL;
+       char *pc2 = NULL;
+       mtp_wchar *temp = NULL;
+
+       ret_if(src == NULL);
+       ret_if(dest == NULL);
+
+       if (!((int)dest & 0x1) && !((int)src & 0x1)) {  /* 2-byte aligned */
+               temp = dest;
+
+               while (n && (*temp++ = *src++)) {
+                       n--;
+               }
+
+               if (n) {
+                       while (--n) {
+                               *temp++ = 0;
+                       }
+               }
+       } else {                /* not-aligned, byte to byte approach - slow */
+
+               pc1 = (char *)dest;
+               pc2 = (char *)src;
+
+               while (n && (*pc2 || *(pc2 + 1))) {
+                       --n;
+                       *pc1++ = *pc2++;
+                       *pc1++ = *pc2++;
+               }
+
+               if (n) {
+                       while (--n) {
+                               *pc1++ = 0;
+                               *pc1++ = 0;
+                       }
+               }
+       }
+
+       return;
+}
+
+/*
+ * Returns the length of wide character string
+ * @param[in]  src     Wide char string
+ * @return     length
+ */
+size_t _util_wchar_len(const mtp_wchar *s)
+{
+       if (!((int)s & 0x1)) {  /* 2-byte aligned */
+               mtp_wchar *temp = (mtp_wchar *)s;
+
+               while (*temp++) {
+                       /* DO NOTHING */ ;
+               }
+
+               DBG("Length : %d\n", temp - s - 1);
+               return ((size_t)(temp - s - 1));
+       } else {                /* not-aligned, byte to byte approach - slow */
+
+               unsigned char *temp = (unsigned char *)s;
+
+               while (*temp || *(temp + 1)) {
+                       temp += 2;
+               }
+
+               DBG("Length : %d\n", (temp - (unsigned char *)s) / 2);
+               return ((size_t) (temp - (unsigned char *)s) / 2);
+       }
+}
+
+static mtp_char* __util_conv_int_to_hex_str(mtp_int32 int_val, mtp_char *str)
+{
+       mtp_char *nstr = str;
+       mtp_int32 val = int_val;
+       mtp_char hex[] = { "0123456789ABCDEF" };
+
+       retv_if(str == NULL, NULL);
+
+       *nstr++ = '0';
+       *nstr++ = 'x';
+
+       for (val = int_val; val; val <<= 4) {
+               *nstr++ = hex[(val >> (sizeof(int) * 8 - 4)) & 0xF];
+       }
+       *nstr = '\0';
+       return str;
+}
+
+/*
+ * This is very minimal implementation.
+ * Be cautious using this function.
+ */
+mtp_err_t _util_wchar_swprintf(mtp_wchar *mtp_wstr, mtp_int32 size,
+               mtp_char *format, ...)
+{
+       mtp_char *ptr;
+       mtp_wchar wsHex[24];
+       mtp_int32 count = 0;
+       mtp_wchar *wbuf = mtp_wstr;
+       mtp_char *bptr_val = NULL;
+       mtp_wchar *wstr_val = NULL;
+       mtp_int32 int_val = 0, len = 0;
+       mtp_char buf[MTP_MAX_PATHNAME_SIZE + 1];
+
+       va_list arg_list;
+       va_start(arg_list, format);
+       for (ptr = format; *ptr && count < (size - 1); ptr++) {
+               if (*ptr == '%') {
+                       switch (*(ptr + 1)) {
+                       case 'd':
+                               int_val = va_arg(arg_list, int);
+                               wbuf[count++] = (mtp_wchar) (int_val + '0');
+                               ptr++;
+                               break;
+                       case 's':
+                               bptr_val = va_arg(arg_list, char *);
+                               wstr_val = (mtp_wchar *) bptr_val;
+                               len = _util_wchar_len(wstr_val);
+                               if (len + count > size - 1) {
+                                       len = size - 1 - count;
+                                       _util_wchar_ncpy(&wbuf[count], wstr_val,
+                                                       len);
+                               } else {
+                                       _util_wchar_cpy(&wbuf[count], wstr_val);
+                               }
+                               count += len;
+                               ptr++;
+                               break;
+                       case 'x':
+                               int_val = va_arg(arg_list, int);
+                               __util_conv_int_to_hex_str(int_val, buf);
+                               _util_utf8_to_utf16(wsHex,
+                                               sizeof(wsHex) / WCHAR_SIZ, buf);
+                               len = strlen(buf);
+                               if (len + count > size - 1) {
+                                       len = size - 1 - count;
+                                       _util_wchar_ncpy(&wbuf[count], wsHex,
+                                                       len);
+                               } else {
+                                       _util_wchar_cpy(&wbuf[count], wsHex);
+                               }
+                               count += len;
+                               ptr++;
+                               break;
+
+                       default:
+                               DBG("swprintf not handling: %c", *(ptr + 1));
+                               break;
+                       }
+               } else {
+                       wbuf[count++] = (mtp_wchar)(*ptr);
+               }
+       }
+
+       va_end(arg_list);
+       wbuf[count] = (mtp_wchar)'\0';
+       _util_utf16_to_utf8(buf, sizeof(buf), wbuf);
+
+       return MTP_ERROR_NONE;
+}
+
+mtp_uint16 _util_get_fmtcode(const mtp_char *extn)
+{
+       static fmt_code_t fmt_code_table[] = {
+               {"ALB", MTP_FMT_ABSTRACT_AUDIO_ALBUM},
+               {"MP3", PTP_FMT_MP3},
+               {"WMA", MTP_FMT_WMA},
+               {"WMV", MTP_FMT_WMV},
+               {"JPG", PTP_FMT_IMG_EXIF},
+               {"GIF", PTP_FMT_IMG_GIF},
+               {"BMP", PTP_FMT_IMG_BMP},
+               {"PNG", PTP_FMT_IMG_PNG},
+               {"ASF", PTP_FMT_ASF},
+               {"WAV", PTP_FMT_WAVE},
+               {"AVI", PTP_FMT_AVI},
+               {"MPG", PTP_FMT_MPEG},
+               {"TXT", PTP_FMT_TEXT},
+               {"3GP", MTP_FMT_3GP},
+               {"ODF", MTP_FMT_3GP},
+               {"O4A", MTP_FMT_3GP},
+               {"O4V", MTP_FMT_3GP},
+               {"MP4", MTP_FMT_MP4},
+               {"FLAC", MTP_FMT_FLAC},
+               {"", PTP_FMT_UNDEF}
+       };
+
+       fmt_code_t *p = NULL;
+       p = fmt_code_table;
+
+       while (p->fmt_code != PTP_FMT_UNDEF) {
+               if (!strncasecmp(extn, p->extn, strlen(p->extn)))
+                       break;
+
+               p++;
+       }
+
+       /* will return FormatCode or PTP_FORMATCODE_UNDEFINED
+        * if we hit end of list.
+        */
+       return p->fmt_code;
+}
+
+/*
+ * This function gets the file extension.
+ * @param[in]          fileName                Specifies the file name.
+ * @param[out]         file_extn               holds the extension of the file.
+ * @return             Returns TRUE on success and FALSE on failure.
+ */
+mtp_bool _util_get_file_extn(const mtp_char *f_name, mtp_char *f_extn)
+{
+       char *ptr;
+
+       retv_if(NULL == f_name, FALSE);
+       retv_if(NULL == f_extn, FALSE);
+
+       ptr = strrchr(f_name, '.');
+
+       if (ptr != NULL) {
+               g_strlcpy(f_extn, ptr + 1, MTP_MAX_PATHNAME_SIZE);
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
+mtp_bool _util_get_file_name(const mtp_char *fullpath, mtp_char *f_name)
+{
+       mtp_int32 i, j;
+
+       retv_if(f_name == NULL, FALSE);
+       retv_if(fullpath == NULL, FALSE);
+
+       i = strlen(fullpath);
+
+       for (j=0; i >= 0; i--) {
+               if (fullpath[i] == '/') {
+                       g_strlcpy(f_name, &fullpath[i + 1], j);
+                       return TRUE;
+               }
+               j++;
+       }
+       g_strlcpy(f_name, fullpath, j);
+
+       return TRUE;
+}
+/*
+ * This function gives file name without extension.
+ * @param[in]  fullpath        pointer to absolute file path
+ * @param[out] f_name  gets filled with filename w/o extension
+ * @return     True or False based on success or failure
+ */
+mtp_bool _util_get_file_name_wo_extn(const mtp_char *fullpath, mtp_char *f_name)
+{
+       mtp_char *fname_ptr;
+       mtp_uint32 fname_len;
+       mtp_char *extn_ptr = NULL;
+
+       retv_if(f_name == NULL, FALSE);
+       retv_if(fullpath == NULL, FALSE);
+
+       fname_ptr = strrchr(fullpath, '/');
+
+       if (fname_ptr == NULL) {
+               ERR("Invalid File Name");
+               return FALSE;
+       }
+
+       fname_ptr = fname_ptr + sizeof(char);
+       fname_len = strlen(fname_ptr);
+       extn_ptr = strrchr(fname_ptr, '.');
+
+       if (extn_ptr == NULL) {
+               g_strlcpy(f_name, fname_ptr, fname_len + 1);
+               return TRUE;
+       }
+
+       g_strlcpy(f_name, fname_ptr, ((mtp_uint32)(extn_ptr - fname_ptr) + 1));
+       return TRUE;
+}
+
+mtp_bool _util_is_path_len_valid(const mtp_char *path)
+{
+       mtp_uint32 limit = 0;
+       mtp_uint32 mtp_path_len = 0;
+       mtp_uint32 root_path_len = 0;
+
+       static mtp_uint32 max_store_len = 0;
+       static mtp_bool is_initialized = FALSE;
+       static mtp_uint32 internal_store_len = 0;
+       static mtp_uint32 external_store_len = 0;
+
+       retv_if(path == NULL, FALSE);
+
+       if (!is_initialized) {
+               is_initialized = TRUE;
+               internal_store_len = strlen(MTP_STORE_PATH_CHAR);
+               external_store_len = strlen(MTP_EXTERNAL_PATH_CHAR);
+
+               max_store_len = internal_store_len > external_store_len ?
+                       internal_store_len : external_store_len;
+
+               DBG("max store len : [%u]\n", max_store_len);
+       }
+
+       if (!strncmp(path, MTP_STORE_PATH_CHAR, internal_store_len)) {
+               root_path_len = internal_store_len;
+       } else if (!strncmp(path, MTP_EXTERNAL_PATH_CHAR, external_store_len)) {
+               root_path_len = external_store_len;
+       }
+       else {
+               ERR("Unknown store's path : %s\n", path);
+               return FALSE;
+       }
+
+       /* Path len should be calculated except root path(eg. /opt/usr/media) */
+       mtp_path_len = strlen(path) - root_path_len;
+
+       /* MTP_MAX_PATHNAME_SIZE includes maximum length of root path */
+       limit = MTP_MAX_PATHNAME_SIZE - max_store_len;
+
+       if (mtp_path_len > limit) {
+               ERR("Too long path : [%u] > [%u]\n", mtp_path_len, limit);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+mtp_bool _util_create_path(mtp_char *path, mtp_uint32 size, const mtp_char *dir,
+               const mtp_char *filename)
+{
+       mtp_int32 ret = 0;
+       mtp_uint32 len = 0;
+
+       retv_if(dir == NULL, FALSE);
+       retv_if(path == NULL, FALSE);
+       retv_if(filename == NULL, FALSE);
+
+       len = strlen(filename);
+       if (len > MTP_MAX_FILENAME_SIZE) {
+               ERR("filename is too long :[%u] > [%u]\n", len,
+                               MTP_MAX_FILENAME_SIZE);
+               return FALSE;
+       }
+
+       ret = g_snprintf(path, size, "%s/%s", dir, filename);
+       if (ret > size) {
+               ERR("path is truncated");
+               return FALSE;
+       }
+
+       if (_util_is_path_len_valid(path) == FALSE) {
+               ERR("path length exceeds the limit");
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+/*
+ * This function gets the parent path.
+ * @param[in]  fullpath        Pointer to a buffer containing full file path.
+ * @param[out] p_path  Points the buffer to hold parent path.
+ * @return     None
+ */
+void _util_get_parent_path(const mtp_char *fullpath, mtp_char *p_path)
+{
+       mtp_char *ptr = NULL;
+
+       ret_if(NULL == p_path);
+       ret_if(NULL == fullpath);
+
+       ptr = strrchr(fullpath, '/');
+       if (!ptr) {
+               ERR("Path does not have parent path");
+               return;
+       }
+
+       g_strlcpy(p_path, fullpath, (mtp_uint32)(ptr - fullpath) + 1);
+       return;
+}
+
+void _util_conv_wstr_to_guid(mtp_wchar *wstr, mtp_uint64 *guid)
+{
+       mtp_uint32 skip_idx;
+       mtp_uint32 cur_idx;
+       mtp_uint64 temp[2];
+       mtp_int32 count = 0;
+       mtp_int32 cpy_sz = 0;
+
+       ret_if(wstr == NULL);
+       ret_if(guid == NULL);
+
+       while (wstr[count] != 0) {
+               count++;
+       }
+
+       memset(guid, 0, sizeof(temp));
+       skip_idx = sizeof(temp) / sizeof(mtp_wchar);
+
+       for (cur_idx = 0; cur_idx < count; cur_idx += skip_idx) {
+
+               memset(temp, 0, sizeof(temp));
+               cpy_sz = (count - cur_idx) * sizeof(mtp_wchar);
+               if (cpy_sz > sizeof(temp)) {
+                       cpy_sz = sizeof(temp);
+               }
+               memcpy(temp, &(wstr[cur_idx]), cpy_sz);
+               guid[0] += temp[0];
+               guid[1] += temp[1];
+       }
+
+       return;
+}
+
+mtp_bool _util_get_unique_dir_path(const mtp_char *exist_path,
+               mtp_char *new_path, mtp_uint32 new_path_buf_len)
+{
+       mtp_uint32 num_bytes = 0;
+       mtp_uint32 max_value = 1;
+       mtp_uint32 count = 1;
+       mtp_uint32 val = 1;
+       mtp_char *buf = NULL;
+       mtp_uint32 len = strlen(exist_path);
+
+       retv_if(new_path == NULL, FALSE);
+       retv_if(exist_path == NULL, FALSE);
+
+       /* Excluding '_' */
+       num_bytes = new_path_buf_len - len - 1;
+       if (num_bytes <= 0) {
+               ERR("No space to append data[%d]\n", num_bytes);
+               return FALSE;
+       }
+
+       if (num_bytes >= MTP_BUF_SIZE_FOR_INT - 1) {
+               max_value = UINT_MAX;
+       } else {
+               while (count <= num_bytes) {
+                       max_value *= 10;
+                       count++;
+               }
+               DBG("max_value[%u]\n", max_value);
+       }
+
+       buf = (mtp_char *)g_malloc(new_path_buf_len);
+       if (buf == NULL) {
+               ERR("g_malloc Fail");
+               return FALSE;
+       }
+       g_strlcpy(buf, exist_path, new_path_buf_len);
+       while (val < max_value) {
+               /* Including NUL and '_' */
+               g_snprintf(&buf[len], num_bytes + 2, "_%u", val++);
+               if (access(buf, F_OK) < 0) {
+                       goto SUCCESS;
+               }
+       }
+
+       g_free(buf);
+       ERR("Unable to generate Unique Dir Name");
+       return FALSE;
+
+SUCCESS:
+       g_strlcpy(new_path, buf, new_path_buf_len);
+       g_free(buf);
+       DBG_SECURE("Unique dir name[%s]\n", new_path);
+       return TRUE;
+}
diff --git a/src/util/mtp_thread.c b/src/util/mtp_thread.c
new file mode 100755 (executable)
index 0000000..e1f48e3
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <mtp_thread.h>
+
+/*
+ * FUNCTIONS
+ */
+mtp_bool _util_thread_create(pthread_t *tid, const mtp_char *tname,
+               mtp_int32 thread_state, thread_func_t thread_func, void *arg)
+{
+       int error = 0;
+       pthread_attr_t attr;
+
+       retv_if(tname == NULL, FALSE);
+       retv_if(thread_func == NULL, FALSE);
+
+       error = pthread_attr_init(&attr);
+       if (error != 0) {
+               ERR("pthread_attr_init Fail [%d], errno [%d]\n", error, errno);
+               return FALSE;
+       }
+
+       if (thread_state == PTHREAD_CREATE_JOINABLE) {
+               error = pthread_attr_setdetachstate(&attr,
+                               PTHREAD_CREATE_JOINABLE);
+               if (error != 0) {
+                       ERR("pthread_attr_setdetachstate Fail [%d], errno [%d]\n", error, errno);
+                       pthread_attr_destroy(&attr);
+                       return FALSE;
+               }
+       }
+
+       error = pthread_create(tid, &attr, thread_func, arg);
+       if (error != 0) {
+               ERR( "[%s] Thread creation Fail errno [%d]\n", tname, errno);
+               pthread_attr_destroy(&attr);
+               return FALSE;
+       }
+
+       error = pthread_attr_destroy(&attr);
+       if (error != 0) {
+               ERR("pthread_attr_destroy Fail [%d] errno [%d]\n", error, errno);
+       }
+
+       return TRUE;
+}
+
+mtp_bool _util_thread_join(pthread_t tid, void **data)
+{
+       mtp_int32 res = 0;
+
+       res = pthread_join(tid, data);
+       if (res != 0) {
+               ERR("pthread_join Fail res = [%d] for thread [%u] errno [%d]\n",
+                               res, tid, errno);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+mtp_bool _util_thread_cancel(pthread_t tid)
+{
+       mtp_int32 res;
+
+       res = pthread_cancel(tid);
+       if (res != 0) {
+               ERR("pthread_cancel  Fail [%d] errno [%d]\n", tid, errno);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+void _util_thread_exit(void *val_ptr)
+{
+       pthread_exit(val_ptr);
+       return;
+}
diff --git a/src/util/mtp_util.c b/src/util/mtp_util.c
new file mode 100755 (executable)
index 0000000..5b0ee9c
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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 <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <time.h>
+#include <pthread.h>
+#include <tapi_common.h>
+#include <ITapiModem.h>
+#include <system_info.h>
+#include <vconf.h>
+#include <gcrypt.h>
+#include "mtp_util.h"
+#include "mtp_support.h"
+#include "mtp_fs.h"
+
+static phone_state_t g_ph_status = { 0 };
+
+
+void _util_print_error()
+{
+       /*In glibc-2.7, the longest error message string is 50 characters
+         ("Invalid or incomplete multibyte or wide character"). */
+       mtp_char buff[100] = {0};
+
+       strerror_r(errno, buff, sizeof(buff));
+       ERR("Error: [%d]:[%s]\n", errno, buff);
+}
+
+mtp_int32 _util_get_battery_level(void)
+{
+       mtp_int32 result = 0;
+       mtp_int32 battery_level = 100;
+
+       result = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY,
+                       &battery_level);
+       if (result != 0) {
+               ERR("VCONFKEY_SYSMAN_BATTERY_CAPACITY Fail!");
+       }
+       return battery_level;
+}
+
+mtp_bool _util_get_serial(mtp_char *serial, mtp_uint32 len)
+{
+       TapiHandle *handle = NULL;
+       mtp_char *imei_no = NULL;
+       mtp_char *serial_no = NULL;
+       mtp_uint16 i = 0;
+       char hash_value[MD5_HASH_LEN] = { 0 };
+
+       if (serial == NULL || len <= MD5_HASH_LEN * 2) {
+               ERR("serial is null or length is less than (MD5_HASH_LEN * 2)");
+               return FALSE;
+       }
+
+       serial_no = vconf_get_str(VCONFKEY_MTP_SERIAL_NUMBER_STR);
+       if (serial_no == NULL) {
+               ERR("vconf_get Fail for %s\n",
+                               VCONFKEY_MTP_SERIAL_NUMBER_STR);
+               return FALSE;
+       }
+
+       if (strlen(serial_no) > 0) {
+               g_strlcpy(serial, serial_no, len);
+               g_free(serial_no);
+               return TRUE;
+       }
+       g_free(serial_no);
+
+       handle = tel_init(NULL);
+       if (!handle) {
+               ERR("tel_init Fail");
+               return FALSE;
+       }
+
+       imei_no = tel_get_misc_me_imei_sync(handle);
+       if (!imei_no) {
+               ERR("tel_get_misc_me_imei_sync Fail");
+               tel_deinit(handle);
+               return FALSE;
+       }
+
+       tel_deinit(handle);
+
+       gcry_md_hash_buffer(GCRY_MD_MD5, hash_value, imei_no, strlen(imei_no));
+
+       for (i = 0; i < MD5_HASH_LEN; i++) {
+               g_snprintf(&serial[i*2], 3, "%02X", hash_value[i]);
+       }
+
+       if (vconf_set_str(VCONFKEY_MTP_SERIAL_NUMBER_STR, serial) == -1) {
+               ERR("vconf_set Fail for %s\n",
+                               VCONFKEY_MTP_SERIAL_NUMBER_STR);
+               g_free(imei_no);
+               return TRUE;
+       }
+
+       g_free(imei_no);
+       return TRUE;
+}
+
+void _util_get_vendor_ext_desc(mtp_char *vendor_ext_desc, mtp_uint32 len)
+{
+       mtp_int32 ret = SYSTEM_INFO_ERROR_NONE;
+       mtp_char *version = NULL;
+
+       ret_if(len == 0);
+       ret_if(vendor_ext_desc == NULL);
+
+       ret = system_info_get_platform_string(
+               "http://tizen.org/feature/platform.version", &version);
+
+       if (ret != SYSTEM_INFO_ERROR_NONE) {
+               ERR("system_info_get_value_string Fail : 0x%X\n", ret);
+               g_strlcpy(vendor_ext_desc, MTP_VENDOR_EXTENSIONDESC_CHAR, len);
+               return;
+       }
+       g_snprintf(vendor_ext_desc, len, "%stizen.org:%s; ",
+                       MTP_VENDOR_EXTENSIONDESC_CHAR, version);
+       g_free(version);
+       return;
+}
+
+void _util_get_model_name(mtp_char *model_name, mtp_uint32 len)
+{
+       mtp_int32 ret = SYSTEM_INFO_ERROR_NONE;
+       mtp_char *model = NULL;
+
+       ret_if(len == 0);
+       ret_if(model_name == NULL);
+
+       ret = system_info_get_platform_string(
+               "http://tizen.org/system/model_name", &model);
+
+       if (ret != SYSTEM_INFO_ERROR_NONE) {
+               ERR("system_info_get_value_string Fail : 0x%X\n", ret);
+               g_strlcpy(model_name, MTP_DEFAULT_MODEL_NAME, len);
+               return;
+       }
+       g_strlcpy(model_name, model, len);
+       g_free(model);
+       return;
+}
+
+void _util_get_device_version(mtp_char *device_version, mtp_uint32 len)
+{
+       mtp_int32 ret = SYSTEM_INFO_ERROR_NONE;
+       mtp_char *version = NULL;
+       mtp_char *build_info = NULL;
+
+       ret_if(len == 0);
+       ret_if(device_version == NULL);
+
+       ret = system_info_get_platform_string(
+               "http://tizen.org/feature/platform.version", &version);
+
+       if (ret != SYSTEM_INFO_ERROR_NONE) {
+               ERR("system_info_get_value_string Fail : 0x%X\n", ret);
+               g_strlcpy(device_version, MTP_DEFAULT_DEVICE_VERSION, len);
+               return;
+       }
+
+       ret = system_info_get_platform_string(
+               "http://tizen.org/system/build.string", &build_info);
+
+       if (ret != SYSTEM_INFO_ERROR_NONE) {
+               ERR("system_info_get_value_string Fail : 0x%X\n", ret);
+               g_strlcpy(device_version, MTP_DEFAULT_DEVICE_VERSION, len);
+               g_free(version);
+               return;
+       }
+       g_snprintf(device_version, len, "TIZEN %s (%s)", version, build_info);
+       g_free(version);
+       g_free(build_info);
+       return;
+}
+
+void _util_gen_alt_serial(mtp_char *serial, mtp_uint32 len)
+{
+       struct timeval st;
+       mtp_char model_name[MTP_MODEL_NAME_LEN_MAX + 1] = { 0 };
+
+       ret_if(len == 0);
+       ret_if(serial == NULL);
+
+       if (gettimeofday(&st, NULL) < 0) {
+               ERR("gettimeofday Fail");
+               _util_print_error();
+               return;
+       }
+       _util_get_model_name(model_name, sizeof(model_name));
+       g_snprintf(serial, len, "%s-%010ld-%011ld", model_name,
+                       st.tv_sec, st.tv_usec);
+
+       if (vconf_set_str(VCONFKEY_MTP_SERIAL_NUMBER_STR, serial) == -1) {
+               ERR("vconf_set Fail %s\n", VCONFKEY_MTP_SERIAL_NUMBER_STR);
+       }
+
+       return;
+}
+
+void _util_get_usb_status(phone_status_t *val)
+{
+       mtp_int32 ret = 0;
+       mtp_int32 state = 0;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &state);
+       if (ret == -1 || state == VCONFKEY_SYSMAN_USB_DISCONNECTED) {
+               *val = MTP_PHONE_USB_DISCONNECTED;
+               return;
+       }
+
+       *val = MTP_PHONE_USB_CONNECTED;
+       return;
+}
+
+phone_status_t _util_get_local_usb_status(void)
+{
+       return g_ph_status.usb_state;
+}
+
+void _util_set_local_usb_status(const phone_status_t val)
+{
+       g_ph_status.usb_state = val;
+       return;
+}
+
+void _util_get_mmc_status(phone_status_t *val)
+{
+       mtp_int32 ret = 0;
+       mtp_int32 state = 0;
+
+       ret = vconf_get_int(VCONFKEY_SYSMAN_MMC_STATUS, &state);
+       if (ret == -1 || state !=
+                       VCONFKEY_SYSMAN_MMC_MOUNTED) {
+               *val = MTP_PHONE_MMC_NONE;
+               return;
+       }
+
+       *val = MTP_PHONE_MMC_INSERTED;
+       return;
+}
+
+phone_status_t _util_get_local_mmc_status(void)
+{
+       return g_ph_status.mmc_state;
+}
+
+void _util_set_local_mmc_status(const phone_status_t val)
+{
+       g_ph_status.mmc_state = val;
+       return;
+}
+
+void _util_get_usbmode_status(phone_status_t *val)
+{
+       mtp_int32 ret = 0;
+       mtp_int32 state = 0;
+
+       ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT,
+                       &state);
+       if (ret < 0)
+               *val = MTP_PHONE_USB_MODE_OTHER;
+       else
+               *val = state;
+       return;
+}
+
+phone_status_t _util_get_local_usbmode_status(void)
+{
+       return g_ph_status.usb_mode_state;
+}
+
+void _util_set_local_usbmode_status(const phone_status_t val)
+{
+       g_ph_status.usb_mode_state = val;
+       return;
+}