Initial codes of tota-ua 06/138706/3
authorSunmin Lee <sunm.lee@samsung.com>
Thu, 13 Jul 2017 01:44:28 +0000 (10:44 +0900)
committerSunmin Lee <sunm.lee@samsung.com>
Fri, 14 Jul 2017 10:04:11 +0000 (19:04 +0900)
Change-Id: Iffdb362865f9dfbef2aeccf79cf760e09634c4c3

37 files changed:
CMakeLists.txt [new file with mode: 0755]
LICENSE [new file with mode: 0755]
fota_gui/CMakeLists.txt [new file with mode: 0755]
fota_gui/fota_common.h [new file with mode: 0755]
fota_gui/fota_fbinfo.h [new file with mode: 0755]
fota_gui/fota_gr.c [new file with mode: 0755]
fota_gui/fota_gr.h [new file with mode: 0755]
fota_gui/fota_gr_direct.c [new file with mode: 0755]
fota_gui/fota_gr_direct.h [new file with mode: 0755]
fota_gui/fota_gui_main.c [new file with mode: 0755]
fota_gui/fota_gui_test.c [new file with mode: 0755]
fota_gui/fota_log.h [new file with mode: 0755]
fota_gui/fota_png.c [new file with mode: 0755]
fota_gui/fota_png.h [new file with mode: 0755]
fota_gui/fota_show_img.c [new file with mode: 0755]
fota_gui/tdm-if.c [new file with mode: 0755]
fota_gui/tdm-if.h [new file with mode: 0755]
packaging/tota-ua.spec [new file with mode: 0755]
packaging/tota.spec [deleted file]
res/rpi3/images/dummy.png [new file with mode: 0644]
sign_verify/CMakeLists.txt [new file with mode: 0755]
sign_verify/verify_delta.c [new file with mode: 0755]
src/common/fota_cfg.c [new file with mode: 0755]
src/common/fota_cfg.h [new file with mode: 0755]
src/common/fota_common.h [new file with mode: 0755]
src/common/fota_log.c [new file with mode: 0755]
src/common/fota_log.h [new file with mode: 0755]
src/common/fota_tar.h [new file with mode: 0755]
src/common/fota_util.c [new file with mode: 0755]
src/common/fota_util.h [new file with mode: 0755]
src/common/mmc_io.c [new file with mode: 0755]
src/common/mmc_io.h [new file with mode: 0755]
src/rpi3/ua.c [new file with mode: 0644]
src/rpi3/ua.h [new file with mode: 0644]
ss_engine/SS_FSUpdate.c [new file with mode: 0755]
ss_engine/SS_FSUpdate.h [new file with mode: 0755]
tota-ua.manifest [new file with mode: 0755]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..683cee5
--- /dev/null
@@ -0,0 +1,100 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(fota C)
+
+IF("${FOTA_PARTITION_TYPE}" STREQUAL "PART_RPI3")
+SET(MODELDIR "rpi3")
+ELSE()
+SET(MODELDIR "rpi3")
+ENDIF("${FOTA_PARTITION_TYPE}" STREQUAL "PART_RPI3")
+
+SET(SRCS
+       src/common/fota_cfg.c
+       #src/common/fota_tar.c
+       src/common/fota_util.c
+       src/common/fota_log.c
+       src/common/mmc_io.c
+       ss_engine/SS_FSUpdate.c
+       src/${MODELDIR}/ua.c
+)
+
+
+
+STRING(FIND ${CMAKE_C_FLAGS} "mfloat-abi=hard" IFFOUND1)
+STRING(FIND ${CMAKE_C_FLAGS} "mhard-float" IFFOUND2)
+
+IF(${IFFOUND1} GREATER 0 OR ${IFFOUND2} GREATER 0)
+       MESSAGE("hard")
+       SET(LIBS
+               libtota.a
+       )
+ELSE(${IFFOUND1} GREATER 0 OR ${IFFOUND2} GREATER 0)
+       MESSAGE("soft")
+    SET(LIBS
+               libtota.a
+    )
+ENDIF(${IFFOUND1} GREATER 0 OR ${IFFOUND2} GREATER 0)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/common)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/${MODELDIR})
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/ss_engine)
+LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/ss_engine)
+
+
+SET(VENDOR "samsung")
+SET(PACKAGE ${PROJECT_NAME})
+SET(PKGNAME "${PACKAGE}")
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(BINDIR "${PREFIX}/bin")
+SET(PKGDIR "${PREFIX}/share/fota")
+SET(RESDIR "${PKGDIR}/res")
+SET(CFGDIR "${PKGDIR}/config")
+SET(EXECNAME "delta.ua")
+
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+       SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED
+       libsmack
+       tota
+       openssl
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DVENDOR=\"${VENDOR}\"")
+ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE}\"")
+ADD_DEFINITIONS("-DPACKAGE_NAME=\"${PKGNAME}\"")
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DRESDIR=\"${RESDIR}\"")
+
+#SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
+
+ADD_EXECUTABLE(${EXECNAME} ${SRCS})
+TARGET_LINK_LIBRARIES(${EXECNAME} ${pkgs_LDFLAGS} ${LIBS})
+
+INSTALL(TARGETS ${EXECNAME} DESTINATION ${BINDIR})
+INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/res/${MODELDIR}/images DESTINATION ${RESDIR})
+# LICENSE file
+ADD_SUBDIRECTORY(fota_gui)
+
diff --git a/LICENSE b/LICENSE
new file mode 100755 (executable)
index 0000000..9c13a9b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,204 @@
+Copyright (c) 2000 - 2011 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
diff --git a/fota_gui/CMakeLists.txt b/fota_gui/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..619cf34
--- /dev/null
@@ -0,0 +1,78 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+#set( CMAKE_VERBOSE_MAKEFILE on )
+
+SET(GUI_SRCS
+       fota_gui_main.c
+       fota_gr.c
+       fota_png.c
+       tdm-if.c 
+ )
+
+SET(SHOWIMG_SRCS
+       fota_show_img.c
+       fota_png.c
+       tdm-if.c 
+ )
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(BINDIR "${PREFIX}/bin")
+SET(FOTA_GUI "fota_gui")
+SET(FOTA_GUI_TEST "fota_gui_test")
+SET(FOTA_SHOW_IMG "fota_show_img")
+
+
+STRING(FIND ${CMAKE_C_FLAGS} "mfloat-abi=hard" IFFOUND1)
+STRING(FIND ${CMAKE_C_FLAGS} "mhard-float" IFFOUND2)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+       SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(gui_pkgs REQUIRED
+       libtbm
+       libtdm
+       libpng
+)
+
+FOREACH(flag ${gui_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+
+SET(GUI_SRCS ${GUI_SRCS} fota_gr_direct.c)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-D${FOTA_PARTITION_TYPE}")
+
+#SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
+
+ADD_EXECUTABLE(${FOTA_GUI} ${GUI_SRCS})
+TARGET_LINK_LIBRARIES(${FOTA_GUI} ${gui_pkgs_LDFLAGS} ${LIBS})
+
+ADD_EXECUTABLE(${FOTA_GUI_TEST} fota_gui_test.c)
+
+ADD_EXECUTABLE(${FOTA_SHOW_IMG} ${SHOWIMG_SRCS})
+TARGET_LINK_LIBRARIES(${FOTA_SHOW_IMG} ${gui_pkgs_LDFLAGS} ${LIBS})
+
+INSTALL(TARGETS ${FOTA_GUI} DESTINATION ${BINDIR})
+INSTALL(TARGETS ${FOTA_GUI_TEST} DESTINATION ${BINDIR})
+INSTALL(TARGETS ${FOTA_SHOW_IMG} DESTINATION ${BINDIR})
+
+
diff --git a/fota_gui/fota_common.h b/fota_gui/fota_common.h
new file mode 100755 (executable)
index 0000000..b8de243
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __FOTA_COMMON_H__
+#define __FOTA_COMMON_H__
+
+
+#include <stdio.h>
+#include "fota_log.h"
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+typedef u32 size_t;
+
+typedef signed long sl32;
+typedef unsigned long ul32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#define UNUSED(x) (void)(x)
+
+#endif /* __FOTA_COMMON_H__ */
diff --git a/fota_gui/fota_fbinfo.h b/fota_gui/fota_fbinfo.h
new file mode 100755 (executable)
index 0000000..4b87fea
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __FOTA_FBINFO_H__
+#define __FOTA_FBINFO_H__
+
+typedef struct _FbInfo {
+       unsigned char *buf;
+       unsigned sz;
+       int w;
+       int h;
+} FbInfo;
+
+#endif /* __FOTA_FBINFO_H__ */
+
diff --git a/fota_gui/fota_gr.c b/fota_gui/fota_gr.c
new file mode 100755 (executable)
index 0000000..8787e34
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 "fota_gr.h"
+#if defined(USE_CAIRO)
+#include "fota_gr_cairo.h"
+#else
+#include "fota_gr_direct.h"
+#endif
+
+/*-----------------------------------------------------------------------------
+  fota_gr_init
+ ----------------------------------------------------------------------------*/
+int fota_gr_init(void)
+{
+#if defined(USE_CAIRO)
+       return fota_gr_cairo_init();
+#else
+       return fota_gr_direct_init();
+#endif
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gr_deinit
+ ----------------------------------------------------------------------------*/
+void fota_gr_deinit(void)
+{
+#if defined(USE_CAIRO)
+       fota_gr_cairo_deinit();
+#else
+       fota_gr_direct_deinit();
+#endif
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gr_clear_screen
+ ----------------------------------------------------------------------------*/
+void fota_gr_clear_screen(u32 color)
+{
+#if defined(USE_CAIRO)
+       fota_gr_cairo_clear_screen(color);
+#else
+       fota_gr_direct_clear_screen(color);
+#endif
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gr_update_progress
+ ----------------------------------------------------------------------------*/
+void fota_gr_update_progress(int percent)
+{
+#if defined(USE_CAIRO)
+       fota_gr_cairo_update_progress(percent);
+#else
+       fota_gr_direct_update_progress(percent);
+#endif
+}
+
diff --git a/fota_gui/fota_gr.h b/fota_gui/fota_gr.h
new file mode 100755 (executable)
index 0000000..fff1337
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __FOTA_GR_H__
+#define __FOTA_GR_H__
+
+#include "fota_common.h"
+
+extern int fota_gr_init(void);
+extern void fota_gr_deinit(void);
+extern void fota_gr_update_progress(int percent);
+extern void fota_gr_clear_screen(u32 color);
+
+
+#endif /* __FOTA_GR_H__ */
+
diff --git a/fota_gui/fota_gr_direct.c b/fota_gui/fota_gr_direct.c
new file mode 100755 (executable)
index 0000000..a9d8ff9
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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.
+ */
+
+/*****************************************************************************
+** header files
+*****************************************************************************/
+#include <stdlib.h>
+#include <string.h>
+
+#include "fota_common.h"
+#include "fota_png.h"
+
+
+
+#define COLOR_RED                      0xFF0000
+#define COLOR_GREEN                    0xFF00
+#define COLOR_BLUE                     0x00FF
+#define COLOR_WHITE                    0xFFFFFF
+#define COLOR_BLACK                    0x0000
+#define COLOR_GRAY                     0xAAAAAA
+#define COLOR_LIGHTGRAY                        0xDE39
+
+
+#define G_OFFSET_X             100
+#define G_OFFSET_Y             200
+
+#define PROGRESSBAR_WIDTH      400
+#define PROGRESSBAR_HEIGHT     25
+
+#define PROGRESSBAR_START_X    (40 + G_OFFSET_X)
+#define PROGRESSBAR_START_Y    (550 + G_OFFSET_Y)
+
+
+#define MAX_PATH 256
+
+#if !defined(RESDIR)
+#define RESDIR                 "/usr/share/fota/res"
+#endif
+#define IMG_BASE       RESDIR "/images/"
+
+#define MAIN_IMG_NAME          "A07_firmware_update.png"
+#define PROGRESS1_IMG_NAME     "A07_progress_bar.png"
+#define PROGRESS2_IMG_NAME     "A07_progress_bg.png"
+#define NUM_IMG_PREFIX         "A07_num_"
+#define PERCENT_IMG_NAME       "A07_percent.png"
+
+/*****************************************************************************
+** global variables
+*****************************************************************************/
+FbInfo s_fbi;
+FbInfo s_fbi_local;
+
+/*-----------------------------------------------------------------------------
+  _gr_direct_fill_rect
+ ----------------------------------------------------------------------------*/
+static void _gr_direct_fill_rect(FbInfo *fbi, s32 x, s32 y, s32 w, s32 h, u32 color )
+{
+       unsigned int *fb_buf_int = NULL;
+       unsigned int *fb_buf_cur = NULL;
+       s32 dx = 0;
+       s32 dy = 0;
+       s32 wb = 0;
+
+       if (NULL == fbi)
+               return;
+
+       dx = w;
+       dy = h;
+       wb = w * sizeof(u32);
+
+       fb_buf_int = (unsigned int *)fbi->buf;
+       fb_buf_int += y * fbi->w + x;
+       fb_buf_cur = fb_buf_int;
+
+       while (dx--) {
+               *fb_buf_cur++ = color;
+       }
+
+       fb_buf_cur -= w;
+       fb_buf_cur += fbi->w;
+       dy--;
+       while (dy--) {
+               memcpy((void*)fb_buf_cur, (void*)fb_buf_int, wb);
+               fb_buf_cur += fbi->w;
+       }
+
+}
+
+/*-----------------------------------------------------------------------------
+  _gr_direct_clear_screen
+ ----------------------------------------------------------------------------*/
+static void _gr_direct_clear_screen(FbInfo *fbi, u32 color )
+{
+       unsigned int *fb_buf_int = NULL;
+       unsigned int *fb_buf_cur = NULL;
+       s32 dx = 0;
+       s32 dy = 0;
+       s32 w = 0;
+
+       if (NULL == fbi)
+               return;
+
+       dx = fbi->w;
+       dy = fbi->h;
+       w = fbi->w * sizeof(u32);
+
+       fb_buf_int = (unsigned int *)fbi->buf;
+       fb_buf_cur = fb_buf_int;
+
+       while (dx--) {
+               *fb_buf_cur++ = color;
+       }
+
+       dy--;
+       while (dy--) {
+               memcpy((void*)fb_buf_cur, (void*)fb_buf_int, w);
+               fb_buf_cur += fbi->w;
+       }
+}
+
+/*-----------------------------------------------------------------------------
+  _gr_direct_draw_text
+ ----------------------------------------------------------------------------*/
+static void _gr_direct_draw_text(FbInfo *fbi, int x1, int y1, char* str, int len)
+{
+       int i = 0;
+       int w = 0;
+       char ch;
+       char img_name[256];
+
+       for (i=0; i<len; i++) {
+               ch = *(str + i);
+               if ((ch >= '0') && (ch <= '9')) {
+                       sprintf(img_name, "%s%s%c.png", IMG_BASE, NUM_IMG_PREFIX,ch);
+                       w = 20;
+               } else if (ch == '%') {
+                       sprintf(img_name, "%s%s", IMG_BASE, PERCENT_IMG_NAME);
+                       w = 29;
+               } else {
+                       continue;
+               }
+
+               if (read_png_file(img_name) < 0) {
+                       continue;
+               }
+
+               draw_png_img_xy(fbi, x1, y1);
+               release_png_res();
+
+               x1 += w;
+       }
+}
+
+/*-----------------------------------------------------------------------------
+  _gr_direct_draw_prog_text
+ ----------------------------------------------------------------------------*/
+static void _gr_direct_draw_prog_text(FbInfo *fbi, int percent)
+{
+       char str_percent[256];
+
+       if (percent <= 0) {
+               percent = 0;
+       }
+
+       if (percent > 100) {
+               percent = 100;
+       }
+
+       sprintf(str_percent, "%d%%", percent);
+       _gr_direct_fill_rect(fbi, 320, 751, 200, 32, COLOR_BLACK);
+       _gr_direct_draw_text(fbi, 320, 751, str_percent, strlen(str_percent));
+}
+
+/*-----------------------------------------------------------------------------
+  _gr_direct_draw_prog_img
+ ----------------------------------------------------------------------------*/
+static void _gr_direct_draw_prog_img(FbInfo *fbi, int percent)
+{
+       int img_x = 0;
+       int img_y = 0;
+       int x;
+       int shaft_max;
+       int shaft;
+
+       if (read_png_file(IMG_BASE PROGRESS1_IMG_NAME) < 0) {
+               return;
+       }
+
+       if (percent <= 0) {
+               return;
+       }
+
+       if (percent > 100) {
+               percent = 100;
+       }
+
+       /* left part */
+       img_x = 36;
+       img_y = 696;
+       draw_png_img_clip_xy(fbi, img_x, img_y, 0, 0, 17, 27);
+
+       /* middle part */
+#if 0
+       for (x=36+17; x<=648+17; x+=2) {
+               draw_png_img_clip_xy(fbi, x, img_y, 17, 0, 2, 27);
+       }
+#endif
+
+       /* drawing range calculation : 0(1%), max(100%)*/
+       shaft_max = 648 - 17 - 17;
+       shaft = shaft_max * (percent - 1) / 99;
+
+       for (x=36+17; x<(36+17+shaft); x+=2) {
+               draw_png_img_clip_xy(fbi, x, img_y, 17, 0, 2, 27);
+       }
+
+       /* right part */
+       img_x = 36+17+shaft;
+       img_y = 696;
+       draw_png_img_clip_xy(fbi, img_x, img_y, 19, 0, 17, 27);
+
+       release_png_res();
+}
+
+
+/*-----------------------------------------------------------------------------
+  _gr_direct_draw_prog_bg_img
+ ----------------------------------------------------------------------------*/
+static void _gr_direct_draw_prog_bg_img(FbInfo *fbi)
+{
+       int img_x = 0;
+       int img_y = 0;
+       int x;
+
+       if (read_png_file(IMG_BASE PROGRESS2_IMG_NAME) < 0) {
+               return;
+       }
+
+       img_x = 36;
+       img_y = 696;
+       draw_png_img_xy(fbi, img_x, img_y);
+
+       img_x = 648;
+       img_y = 696;
+       draw_png_img_xy(fbi, img_x, img_y);
+
+       for (x=36+17; x<=648+17; x+=2) {
+               draw_png_img_clip_xy(fbi, x, img_y, 17, 0, 2, 27);
+       }
+
+       release_png_res();
+}
+
+/*-----------------------------------------------------------------------------
+  _gr_direct_draw_main_img
+ ----------------------------------------------------------------------------*/
+static void _gr_direct_draw_main_img(FbInfo *fbi)
+{
+       int img_x = 0;
+       int img_y = 0;
+
+       if (read_png_file(IMG_BASE MAIN_IMG_NAME) < 0) {
+               return;
+       }
+
+       img_x = (fbi->w - 456)/2;
+       img_y = 212;
+
+       draw_png_img_xy(fbi, img_x, img_y);
+       release_png_res();
+
+}
+
+/*-----------------------------------------------------------------------------
+  _gr_direct_update_screen
+ ----------------------------------------------------------------------------*/
+static void _gr_direct_update_screen()
+{
+       tdm_if_buffer_update(s_fbi.buf);
+       tdm_if_display_update();
+}
+
+/*-----------------------------------------------------------------------------
+  __init_screen
+ ----------------------------------------------------------------------------*/
+static void __init_screen(FbInfo *fbi)
+{
+       _gr_direct_clear_screen(fbi, COLOR_BLACK);
+
+       _gr_direct_draw_main_img(fbi);
+
+       _gr_direct_draw_prog_bg_img(fbi);
+
+       _gr_direct_draw_prog_text(fbi, 0);
+
+       _gr_direct_update_screen();
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gr_direct_update_progress
+ ----------------------------------------------------------------------------*/
+void fota_gr_direct_update_progress(int percent)
+{
+       _gr_direct_draw_prog_img(&s_fbi, percent);
+       _gr_direct_draw_prog_text(&s_fbi, percent);
+       _gr_direct_update_screen();
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gr_direct_clear_screen
+ ----------------------------------------------------------------------------*/
+void fota_gr_direct_clear_screen(u32 color)
+{
+       _gr_direct_clear_screen(&s_fbi, color);
+       _gr_direct_update_screen();
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gr_direct_init
+ ----------------------------------------------------------------------------*/
+int fota_gr_direct_init(void)
+{
+       unsigned char *buf = NULL;
+
+       if (tdm_if_display_init() < 0) {
+               return -1;
+       }
+
+       tdm_if_lcd_off();
+
+       s_fbi.w = tdm_if_display_width();
+       s_fbi.h = tdm_if_display_height();
+       s_fbi.sz = tdm_if_display_bufsize();
+
+       buf = malloc(s_fbi.sz);
+       if (NULL == buf) {
+               LOG("Not enough memory (s_fbi.sz = %d)\n", s_fbi.sz);
+               tdm_if_display_deinit();
+               return -1;
+       }
+       s_fbi.buf = buf;
+
+       __init_screen(&s_fbi);
+
+       _gr_direct_update_screen();
+
+       tdm_if_lcd_on();
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gr_direct_deinit
+ ----------------------------------------------------------------------------*/
+void fota_gr_direct_deinit(void)
+{
+       if (s_fbi.buf) {
+               free(s_fbi.buf);
+               s_fbi.buf = NULL;
+       }
+       tdm_if_display_deinit();
+}
diff --git a/fota_gui/fota_gr_direct.h b/fota_gui/fota_gr_direct.h
new file mode 100755 (executable)
index 0000000..9bfd890
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __FOTA_GR_DIRECT_H__
+#define __FOTA_GR_DIRECT_H__
+
+#include "fota_common.h"
+
+extern int fota_gr_direct_init(void);
+extern void fota_gr_direct_deinit(void);
+extern void fota_gr_direct_clear_screen(u32 color);
+extern void fota_gr_direct_update_progress(int percent);
+
+#endif /* __FOTA_GR_DIRECT_H__ */
diff --git a/fota_gui/fota_gui_main.c b/fota_gui/fota_gui_main.c
new file mode 100755 (executable)
index 0000000..8c92ac5
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <error.h>
+
+#include "fota_common.h"
+#include "fota_gr.h"
+
+
+#define SERV_PATH "/tmp/FotaGuiSocket"
+
+
+unsigned int __log_level__ =
+       (LOG_DEBUG | LOG_FLASH | LOG_FILE | LOG_FUNCS | LOG_GUI | LOG_REDBEND | LOG_INFO);
+FILE *__log_out_file__;
+
+int s_prog_percent = 0;
+int s_last_prog_percent = 0;
+
+
+typedef struct {
+       char cmd_name[64];
+       int argc;
+       char argv[3][64];
+}sock_cmd;
+
+typedef struct {
+       int ack;
+       char ack_desc[256];
+}sock_ack;
+
+#define CMD_SUCCESS    0
+#define CMD_ERROR      -1
+#define        MISSING_PARAM   -2
+
+int do_exit = 0;
+int run_command(sock_cmd * recvbuff, sock_ack * sendbuff, int connfd)
+{
+       char cmd[100];
+       int argc = 0, ret = -1;
+       int val = 0;
+
+       memset(cmd, 0x00, sizeof(cmd));
+       strncpy(cmd, recvbuff->cmd_name, sizeof(cmd)-1);
+       argc = recvbuff->argc;
+
+       if (!strcmp(cmd, "draw_progress")) {
+               LOG("draw_progress selected\n");
+               if (argc != 1) {
+                       sendbuff->ack = MISSING_PARAM;
+                       strcpy(sendbuff->ack_desc, "Missing parameter");
+                       ret = send(connfd, sendbuff, sizeof(sock_ack), 0);
+               } else {
+                       LOG("argv[0]: %s\n", recvbuff->argv[0]);
+                       ret = CMD_SUCCESS;
+                       sendbuff->ack = ret;
+                       strcpy(sendbuff->ack_desc, "Command recieved");
+                       ret = send(connfd, sendbuff, sizeof(sock_ack), 0);
+
+                       val = atoi(recvbuff->argv[0]);
+                       if (val < 0)
+                               val = 0;
+                       else if (val > 100)
+                               val = 100;
+
+                       s_prog_percent = val;
+                       fota_gr_update_progress(s_prog_percent);
+                       s_last_prog_percent = s_prog_percent;
+               }
+       } else if (!strcmp(cmd, "draw_end")) {
+               LOG("draw_end selected\n");
+               if (argc != 0) {
+                       sendbuff->ack = MISSING_PARAM;
+                       strcpy(sendbuff->ack_desc, "Missing parameter");
+                       ret = send(connfd, sendbuff, sizeof(sock_ack), 0);
+               } else {
+                       LOG("argv[0]: %s\n", recvbuff->argv[0]);
+                       ret = CMD_SUCCESS;
+                       sendbuff->ack = ret;
+                       strcpy(sendbuff->ack_desc, "Command recieved");
+                       ret = send(connfd, sendbuff, sizeof(sock_ack), 0);
+                       do_exit = 1;
+               }
+       } else {
+               LOG("Command Not Found \n");
+               sendbuff->ack = MISSING_PARAM;
+               strcpy(sendbuff->ack_desc, "Command Not found");
+               ret = send(connfd, sendbuff, sizeof(sock_ack), 0);
+       }
+
+       return ret;
+}
+
+int main(int argc, char **argv)
+{
+       int connfd = 0, sockfd = 0;
+       socklen_t slen, clen;
+       struct sockaddr_un saddr, caddr;
+       int cnt, done;
+       sock_cmd *recvbuff = NULL;
+       sock_ack *sendbuff = NULL;
+
+       if (fota_gr_init() < 0) {
+               LOG("fota_gr_init() failed.\n");
+               return -1;
+       }
+
+       fota_gr_update_progress(s_prog_percent);
+       s_last_prog_percent = s_prog_percent;
+
+       recvbuff = malloc(sizeof(sock_cmd));
+       if (recvbuff == NULL) {
+               LOG("memory allocation failed:\n");
+               return -1;
+       }
+
+       sendbuff = malloc(sizeof(sock_ack));
+       if (sendbuff == NULL) {
+               LOG("memory allocation failed:\n");
+               return -1;
+       }
+
+       sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (sockfd <= 0) {
+               LOG("invalide sockfd\n");
+               return -1;
+       }
+
+       memset((char *)&saddr, 0, sizeof(saddr));
+       saddr.sun_family = AF_UNIX;
+       strcpy(saddr.sun_path, SERV_PATH);
+       saddr.sun_path[sizeof(SERV_PATH)] = '\0';
+       slen = sizeof(saddr);
+
+       unlink(SERV_PATH);
+       if (bind(sockfd, (const struct sockaddr *)&saddr, slen) < 0) {
+               LOG("bind fail\n");
+               return -1;
+       }
+
+       if (chmod(SERV_PATH, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0)        /* 0777 */
+               LOG("failed to change the socket permission");
+
+       if (listen(sockfd, 5) < 0) {
+               LOG("listen fail\n");
+               return -1;
+       }
+
+       while(1) {
+               clen = sizeof(caddr);
+               connfd = accept(sockfd, (struct sockaddr *)&caddr, &clen);
+               if (connfd < 0) {
+                       LOG("accept! \n");
+                       return -1;
+               }
+
+               LOG("Client Connected...\n");
+
+               done = 0;
+               do {
+                       cnt = 0;
+                       cnt = recv(connfd, recvbuff, sizeof(sock_cmd), 0);
+                       if (cnt <= 0) {
+                               if (cnt < 0) {
+                                       perror("recv!");
+                               }
+                               done = 1;
+                       }
+
+                       if (!done) {
+                               if (run_command(recvbuff, sendbuff, connfd) < 0)
+                                       done = 1;
+                       }
+
+               } while (!done);
+
+               close(connfd);
+
+               if (do_exit)
+                       break;
+       }
+
+       close(sockfd);
+
+       fota_gr_deinit();
+
+       return 0;
+}
diff --git a/fota_gui/fota_gui_test.c b/fota_gui/fota_gui_test.c
new file mode 100755 (executable)
index 0000000..b6f775d
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define LOG                    printf
+
+#define SERV_PATH "/tmp/FotaGuiSocket"
+
+typedef struct {
+       char cmd_name[64];
+       int argc;
+       char argv[3][64];
+}sock_cmd;
+
+typedef struct {
+       int ack;
+       char ack_desc[256];
+}sock_ack;
+
+#define CMD_SUCCESS    0
+#define CMD_ERROR      -1
+#define        MISSING_PARAM   -2
+
+int sockfd = 0;
+int initcomplete = 0;
+sock_cmd *sendbuff = NULL;
+sock_ack *recvbuff = NULL;
+
+int sock_init(void)
+{
+       int len, ret;
+       struct sockaddr_un serv_addr;
+
+       LOG("\n sock_init \n");
+       sendbuff = malloc(sizeof(sock_cmd));
+       if (sendbuff == NULL) {
+               LOG("memory allocation failed:%s\n", __FUNCTION__);
+               return -1;
+       }
+
+       recvbuff = malloc(sizeof(sock_ack));
+       if (recvbuff == NULL) {
+               LOG("memory allocation failed:%s\n", __FUNCTION__);
+               return -1;
+       }
+
+       sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (sockfd < 0) {
+               perror("\n Error : socket Failed \n");
+               return -1;
+       }
+       bzero((char *)&serv_addr, sizeof(serv_addr));
+       serv_addr.sun_family = AF_UNIX;
+       strcpy(serv_addr.sun_path, SERV_PATH);
+       len = sizeof(serv_addr);
+
+       ret = connect(sockfd, (struct sockaddr *)&serv_addr, len);
+       if (ret < 0) {
+               LOG("\n Error : Connect Failed \n");
+               return -1;
+       }
+
+       initcomplete = 1;
+       return ret;
+}
+
+void sock_deinit(void)
+{
+       LOG("%s \n", __func__);
+
+       close(sockfd);
+       free(sendbuff);
+       free(recvbuff);
+       initcomplete = 0;
+}
+
+int sock_cmd_progress(int percent_progress)
+{
+       int result = 0;
+
+       LOG("%s \n", __func__);
+       if (!initcomplete) {
+               LOG("sock_init unsuccessful \n");
+               return -1;
+       }
+
+       memset(sendbuff, 0, sizeof(sock_cmd));
+       memset(recvbuff, 0xFF, sizeof(sock_ack));
+
+       strcpy(sendbuff->cmd_name, "draw_progress");
+       sendbuff->argc = 1;
+       snprintf(sendbuff->argv[0], 63, "%d", percent_progress);
+       LOG("sendbuff->argv[0] = %s \n", sendbuff->argv[0]);
+
+       result = write(sockfd, sendbuff, sizeof(sock_cmd));
+       if (result < 0) {
+               LOG(" Write Failed! \n");
+               return -1;
+       }
+
+       result = read(sockfd, recvbuff, sizeof(sock_ack));
+       recvbuff->ack_desc[255] = 0x00;
+       if (recvbuff->ack != CMD_SUCCESS || result < 0) {
+               LOG(" Fail %s ret(%d)\n", recvbuff->ack_desc, recvbuff->ack);
+               return -1;
+       } else
+               LOG("%s ret(%d)\n", recvbuff->ack_desc, recvbuff->ack);
+
+       return recvbuff->ack;
+}
+
+int sock_cmd_end(void)
+{
+       int result = 0;
+
+       LOG("%s \n", __func__);
+       if (!initcomplete) {
+               LOG("sock_init unsuccessful \n");
+               return -1;
+       }
+
+       memset(sendbuff, 0, sizeof(sock_cmd));
+       memset(recvbuff, 0xFF, sizeof(sock_ack));
+
+       strcpy(sendbuff->cmd_name, "draw_end");
+       sendbuff->argc = 0;
+
+       result = write(sockfd, sendbuff, sizeof(sock_cmd));
+       if (result < 0) {
+               LOG(" Write Failed! \n");
+               return -1;
+       }
+
+       result = read(sockfd, recvbuff, sizeof(sock_ack));
+       recvbuff->ack_desc[255] = 0x00;
+       if (recvbuff->ack != CMD_SUCCESS || result < 0) {
+               LOG(" Fail %s ret(%d)\n", recvbuff->ack_desc, recvbuff->ack);
+               return -1;
+       } else
+               LOG("%s ret(%d)\n", recvbuff->ack_desc, recvbuff->ack);
+
+       return recvbuff->ack;
+}
+
+int main(int argc, char **argv)
+{
+       int ret = -1;
+       int percent = 0;
+
+       if (argc != 2) {
+               LOG("Invalid argc = %d\n", argc);
+               return -1;
+       }
+
+       if (sock_init() < 0) {
+               LOG("sock_init() failed\n");
+               return -1;
+       }
+
+       percent = atoi(argv[1]);
+       if (percent == -1) {
+               ret = sock_cmd_end();
+       } else {
+               ret = sock_cmd_progress(percent);
+       }
+       LOG("ret = %d\n", ret);
+
+       sock_deinit();
+
+       return 0;
+}
+
+
diff --git a/fota_gui/fota_log.h b/fota_gui/fota_log.h
new file mode 100755 (executable)
index 0000000..b02af3c
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __FOTA_LOG_H__
+#define __FOTA_LOG_H__
+
+#include <stdio.h>
+
+/*
+ * DEBUGGING FEATURE
+ */
+
+extern unsigned int __log_level__;
+extern FILE *__log_out_file__;
+
+#define LOG_INFO       (1<<8)
+#define LOG_REDBEND    (1<<7)
+#define LOG_FUNCS      (1<<6)
+#define LOG_GUI                (1<<5)
+#define LOG_DEBUG      (1<<4)
+#define LOG_FILE       (1<<3)
+#define LOG_FLASH      (1<<2)
+
+#define LOG_PRFIX      "FOTA_GUI"
+
+#define DEBUG_STDOUT
+//#define DEBUG_FILE
+
+#ifdef DEBUG_STDOUT
+#define LOGE(s, args...) printf(LOG_PRFIX "/ERROR(%s)  " s, __func__, ##args) // Error log
+#define LOGL(mask, s, args...) do{if((mask) & __log_level__) \
+       printf(LOG_PRFIX "/(%s): " s,__func__, ##args);}while(0)
+#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args)
+
+#elif defined(DEBUG_FILE)
+#define LOGE(s, args...) fprintf(__log_out_file__, LOG_PRFIX "/ERROR(%s)  " s, __func__, ##args)
+#define LOGL(mask, s, args...) do{if((mask) & __log_level__) \
+       fprintf(__log_out_file__, LOG_PRFIX "/(%s): " s ,__func__, ##args);}while(0)
+#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args)
+
+#elif defined(DEBUG_STDOUT_FILE) // debug printf
+#define LOGE(s, args...) do {\
+                                               printf(LOG_PRFIX "/ERROR(%s)  " s, __func__, ##args);\
+                                               fprintf(__log_out_file__, LOG_PRFIX "/ERROR(%s)  " s, __func__, ##args);\
+                                       }while(0)
+#define LOGL(mask, s, args...) do{ \
+                                               if((mask) & __log_level__){\
+                                                       printf(LOG_PRFIX "/(%s): " s ,__func__, ##args);\
+                                                   fprintf(__log_out_file__, LOG_PRFIX "/(%s): " s,__func__, ##args);\
+                                               }\
+                                       }while(0)
+#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args)
+
+#else
+#define LOGE(s, args...)
+#define LOGL(mask, s, args...)
+#define LOG(s, args...)
+
+#endif
+
+
+#endif /* __FOTA_LOG_H__ */
+
diff --git a/fota_gui/fota_png.c b/fota_gui/fota_png.c
new file mode 100755 (executable)
index 0000000..a31a70f
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 <stdlib.h>
+#include <png.h>
+#include "fota_common.h"
+#include "fota_png.h"
+
+int png_img_width;
+int png_img_height;
+/* clear screen based on img size */
+//int png_img_width_batt_normal;
+//int png_img_height_batt_normal;
+
+png_byte color_type;
+png_byte bit_depth;
+
+png_structp png_ptr;
+png_infop info_ptr;
+int number_of_passes;
+png_bytep *row_pointers;
+
+/*-----------------------------------------------------------------------------
+  read_png_file()
+ ----------------------------------------------------------------------------*/
+int read_png_file(char *file_name)
+{
+       char header[8];         /* 8 is the maximum size that can be checked */
+       int y;
+       size_t rn;
+
+       /* open file and test for it being a png */
+       FILE *fp = fopen(file_name, "rb");
+       if (!fp) {
+               LOG("[read_png_file] File %s could not be opened"
+                       " for reading \n", file_name);
+               return -1;
+       }
+
+       rn = fread(header, 1, 8, fp);
+       if (rn != 8) {
+               LOG("fread() read num mismatch\n");
+       }
+       if (png_sig_cmp((png_bytep)header, 0, 8)) {
+               fclose(fp);
+               LOG("[read_png_file] File %s is not recognized"
+                       " as a PNG file \n", file_name);
+               return -1;
+       }
+
+       /* initialize stuff */
+       png_ptr =
+           png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       if (!png_ptr) {
+               fclose(fp);
+               LOG("[read_png_file] png_create_read_struct failed \n");
+               return -1;
+       }
+
+       info_ptr = png_create_info_struct(png_ptr);
+       if (!info_ptr) {
+               png_destroy_read_struct(&png_ptr, NULL, NULL);
+               fclose(fp);
+               LOG("[read_png_file] png_create_info_struct failed \n");
+               return -1;
+       }
+
+       if (setjmp(png_jmpbuf(png_ptr))) {
+               png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+               fclose(fp);
+               LOG("[read_png_file] Error during init_io \n");
+               return -1;
+       }
+
+       png_init_io(png_ptr, fp);
+       png_set_sig_bytes(png_ptr, 8);
+       png_read_info(png_ptr, info_ptr);
+
+       png_img_width = png_get_image_width(png_ptr, info_ptr);
+       png_img_height = png_get_image_height(png_ptr, info_ptr);
+       color_type = png_get_color_type(png_ptr, info_ptr);
+       bit_depth = png_get_bit_depth(png_ptr, info_ptr);
+
+       number_of_passes = png_set_interlace_handling(png_ptr);
+       png_read_update_info(png_ptr, info_ptr);
+
+       /* read file */
+       if (setjmp(png_jmpbuf(png_ptr))) {
+               png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+               fclose(fp);
+               LOG("[read_png_file] Error during read_image \n");
+               return -1;
+       }
+
+       row_pointers = (png_bytep *) malloc(sizeof(png_bytep)*png_img_height);
+       for (y = 0; y < png_img_height; y++)
+               row_pointers[y] = (png_byte *) malloc(png_get_rowbytes(png_ptr, info_ptr));
+
+       png_read_image(png_ptr, row_pointers);
+
+       fclose(fp);
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------------
+  draw_png_img_clip_xy()
+  - x1, y1 : cordinate on canvas (fb)
+  - cx, cy, cw, ch : image clip (rect on image)
+ ----------------------------------------------------------------------------*/
+void draw_png_img_clip_xy(FbInfo *fbi, int x1, int y1, int cx, int cy, int cw, int ch)
+{
+       unsigned int *fb_buf_cur = NULL;
+       int bpp;
+       int x, y;
+       /* temp patch - lcd resoultion for qualcomm */
+
+       fb_buf_cur = (unsigned int *)fbi->buf;
+
+       /* check out range */
+       if ((x1 + cw > fbi->w) ||
+           (y1 + ch > fbi->h)) {
+               LOG("[%s] output range exceeds frame buffer range \n", __func__);
+               return;
+       }
+
+       if ((cw > png_img_width) || (ch > png_img_height)) {
+               LOG("[%s] clip range exceeds image range \n", __func__);
+               return;
+       }
+
+       if (color_type == PNG_COLOR_TYPE_RGB)
+               bpp = 3;
+       else if (color_type == PNG_COLOR_TYPE_RGBA)
+               bpp = 4;
+       else {
+               LOG("[draw_png_img_xy] png type does not match RGB or RGBA \n");
+               return;
+       }
+       /* temp patch - lcd resoultion for qualcomm */
+       fb_buf_cur += (y1 * (fbi->w));
+       fb_buf_cur += x1;
+       for (y = 0; y < ch; y++) {
+               png_byte *row = (png_byte *) row_pointers[cy + y];
+               if (bit_depth == 8) {
+                       row += (bpp * cx);
+               } else if (bit_depth == 16) {
+                       row += (bpp * 2 * cx);
+               }
+               for (x = 0; x < cw; x++) {
+                       if (bpp == 3) {
+                               if (bit_depth == 8) {
+                                       (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+                                           (row[0] << 16) | (row[1] << 8) | (row[2]);
+                                       row += bpp;
+                               } else if (bit_depth == 16) {
+                                       (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+                                           (row[0] << 16) | (row[2] << 8) | (row[4]);
+                                       row += bpp*2;
+                               }
+                       } else if (bpp == 4) {
+                               if (bit_depth == 8) {
+                                       if (row[3] != 0) {
+                                               char r1, g1, b1, a1;
+                                               char r2, g2, b2, a2;
+                                               char r3, g3, b3, a3;
+                                               // background pixel
+                                               b1 = ((*fb_buf_cur)&0x000000ff);
+                                               g1 = ((*fb_buf_cur)&0x0000ff00)>>8;
+                                               r1 = ((*fb_buf_cur)&0x00ff0000)>>16;
+                                               a1 = ((*fb_buf_cur)&0xff000000)>>24;
+                                               // new pixel
+                                               r2 = row[0];
+                                               g2 = row[1];
+                                               b2 = row[2];
+                                               a2 = row[3];
+                                               // blended pixel
+                                               r3 = (r2 * a2 + r1 * (0xff - a2)) >> 8 ;
+                                               g3 = (g2 * a2 + g1 * (0xff - a2)) >> 8;
+                                               b3 = (b2 * a2 + b1 * (0xff - a2)) >> 8;
+                                               a3 = a1;
+                                               (*fb_buf_cur) = (a3 << 24) |
+                                                   (r3 << 16) | (g3 << 8) | (b3);
+                                       }
+                                       row += bpp;
+                               } else if (bit_depth == 16) {
+                                       if (row[6] != 0) {
+                                               short r1, g1, b1, a1;
+                                               short r2, g2, b2, a2;
+                                               char r3, g3, b3, a3;
+                                               // background pixel
+                                               b1 = ((*fb_buf_cur)&0x000000ff)<<8;
+                                               g1 = ((*fb_buf_cur)&0x0000ff00);
+                                               r1 = ((*fb_buf_cur)&0x00ff0000)>>8;
+                                               a1 = ((*fb_buf_cur)&0xff000000)>>16;
+                                               // new pixel
+                                               r2 = (row[0]<<8) + row[1];
+                                               g2 = (row[2]<<8) + row[3];
+                                               b2 = (row[4]<<8) + row[5];
+                                               a2 = (row[6]<<8) + row[7];
+                                               // blended pixel
+                                               r3 = (r2 * a2 + r1 * (0xffff - a2)) >> 24;
+                                               g3 = (g2 * a2 + g1 * (0xffff - a2)) >> 24;
+                                               b3 = (b2 * a2 + b1 * (0xffff - a2)) >> 24;
+                                               a3 = a1 >> 8;
+                                               (*fb_buf_cur) = (a3 << 24) |
+                                                       (r3 << 16) | (g3 << 8) | (b3);
+                                       }
+                                       row += bpp*2;
+                               }
+                       }
+                       fb_buf_cur++;
+               }
+               fb_buf_cur -= cw;
+               fb_buf_cur += fbi->w;/* temp patch - lcd resoultion for qualcomm */
+       }
+
+}
+
+/*-----------------------------------------------------------------------------
+  draw_png_img_xy()
+ ----------------------------------------------------------------------------*/
+void draw_png_img_xy(FbInfo *fbi, int x1, int y1)
+{
+       unsigned int *fb_buf_cur = NULL;
+       int bpp;
+       int x, y;
+       /* temp patch - lcd resoultion for qualcomm */
+
+       fb_buf_cur = (unsigned int *)fbi->buf;
+
+       /* check out range */
+       if ((x1 + png_img_width > fbi->w) ||
+           (y1 + png_img_height > fbi->h)) {
+               LOG("[draw_png_img_xy] output range exceeds frame buffer range \n");
+               return;
+       }
+
+       if (color_type == PNG_COLOR_TYPE_RGB)
+               bpp = 3;
+       else if (color_type == PNG_COLOR_TYPE_RGBA)
+               bpp = 4;
+       else {
+               LOG("[draw_png_img_xy] png type does not match RGB or RGBA \n");
+               return;
+       }
+       /* temp patch - lcd resoultion for qualcomm */
+       fb_buf_cur += (y1 * (fbi->w));
+       fb_buf_cur += x1;
+       for (y = 0; y < png_img_height; y++) {
+               png_byte *row = (png_byte *) row_pointers[y];
+               for (x = 0; x < png_img_width; x++) {
+                       if (bpp == 3) {
+                               if (bit_depth == 8) {
+                                       (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+                                           (row[0] << 16) | (row[1] << 8) | (row[2]);
+                                       row += bpp;
+                               } else if (bit_depth == 16) {
+                                       (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+                                           (row[0] << 16) | (row[2] << 8) | (row[4]);
+                                       row += bpp*2;
+                               }
+                       } else if (bpp == 4) {
+                               if (bit_depth == 8) {
+                                       if (row[3] != 0) {
+                                               char r1, g1, b1, a1;
+                                               char r2, g2, b2, a2;
+                                               char r3, g3, b3, a3;
+                                               // background pixel
+                                               b1 = ((*fb_buf_cur)&0x000000ff);
+                                               g1 = ((*fb_buf_cur)&0x0000ff00)>>8;
+                                               r1 = ((*fb_buf_cur)&0x00ff0000)>>16;
+                                               a1 = ((*fb_buf_cur)&0xff000000)>>24;
+                                               // new pixel
+                                               r2 = row[0];
+                                               g2 = row[1];
+                                               b2 = row[2];
+                                               a2 = row[3];
+                                               // blended pixel
+                                               r3 = (r2 * a2 + r1 * (0xff - a2)) >> 8 ;
+                                               g3 = (g2 * a2 + g1 * (0xff - a2)) >> 8;
+                                               b3 = (b2 * a2 + b1 * (0xff - a2)) >> 8;
+                                               a3 = a1;
+                                               (*fb_buf_cur) = (a3 << 24) |
+                                                   (r3 << 16) | (g3 << 8) | (b3);
+                                       }
+                                       row += bpp;
+                               } else if (bit_depth == 16) {
+                                       if (row[6] != 0) {
+                                               short r1, g1, b1, a1;
+                                               short r2, g2, b2, a2;
+                                               char r3, g3, b3, a3;
+                                               // background pixel
+                                               b1 = ((*fb_buf_cur)&0x000000ff)<<8;
+                                               g1 = ((*fb_buf_cur)&0x0000ff00);
+                                               r1 = ((*fb_buf_cur)&0x00ff0000)>>8;
+                                               a1 = ((*fb_buf_cur)&0xff000000)>>16;
+                                               // new pixel
+                                               r2 = (row[0]<<8) + row[1];
+                                               g2 = (row[2]<<8) + row[3];
+                                               b2 = (row[4]<<8) + row[5];
+                                               a2 = (row[6]<<8) + row[7];
+                                               // blended pixel
+                                               r3 = (r2 * a2 + r1 * (0xffff - a2)) >> 24;
+                                               g3 = (g2 * a2 + g1 * (0xffff - a2)) >> 24;
+                                               b3 = (b2 * a2 + b1 * (0xffff - a2)) >> 24;
+                                               a3 = a1 >> 8;
+                                               (*fb_buf_cur) = (a3 << 24) |
+                                                       (r3 << 16) | (g3 << 8) | (b3);
+                                       }
+                                       row += bpp*2;
+                               }
+                       }
+                       fb_buf_cur++;
+               }
+               fb_buf_cur -= png_img_width;
+               fb_buf_cur += fbi->w;/* temp patch - lcd resoultion for qualcomm */
+       }
+
+}
+
+/*-----------------------------------------------------------------------------
+  draw_png_mask_xy()
+  - draw pixel only when alpha>0 of given png image
+ ----------------------------------------------------------------------------*/
+void draw_png_mask_xy(FbInfo *fbi, int x1, int y1, char r, char g, char b)
+{
+       unsigned int *fb_buf_cur = NULL;
+       int bpp;
+       int x, y;
+       /* temp patch - lcd resoultion for qualcomm */
+
+       fb_buf_cur = (unsigned int *)fbi->buf;
+
+       /* check out range */
+       if ((x1 + png_img_width > fbi->w) ||
+           (y1 + png_img_height > fbi->h)) {
+               LOG("[draw_png_img_xy] output range exceeds frame buffer range \n");
+               return;
+       }
+
+       if (color_type == PNG_COLOR_TYPE_RGB) {
+               bpp = 3;
+               LOG("[draw_png_img_xy] PNG_COLOR_TYPE_RGB : no mask channel \n");
+               return;
+       } else if (color_type == PNG_COLOR_TYPE_RGBA)
+               bpp = 4;
+       else {
+               LOG("[draw_png_img_xy] png type does not match RGB or RGBA \n");
+               return;
+       }
+       /* temp patch - lcd resoultion for qualcomm */
+       fb_buf_cur += (y1 * (fbi->w));
+       fb_buf_cur += x1;
+       for (y = 0; y < png_img_height; y++) {
+               png_byte *row = (png_byte *) row_pointers[y];
+               for (x = 0; x < png_img_width; x++) {
+                       if (bpp == 4) {
+                               if (bit_depth == 8) {
+                                       if (row[3] != 0) {
+                                               (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+                                                       (r << 16) | (g << 8) | (b);
+                                       }
+                                       row += bpp;
+                               } else if (bit_depth == 16) {
+                                       if (row[6] != 0) {
+                                               (*fb_buf_cur) = ((*fb_buf_cur)&0xff000000) |
+                                                       (r << 16) | (g << 8) | (b);
+                                       }
+                                       row += bpp*2;
+                               }
+                       }
+                       fb_buf_cur++;
+               }
+               fb_buf_cur -= png_img_width;
+               fb_buf_cur += fbi->w;/* temp patch - lcd resoultion for qualcomm */
+       }
+
+}
+
+/*-----------------------------------------------------------------------------
+  release_png_res()
+ ----------------------------------------------------------------------------*/
+void release_png_res(void)
+{
+       int y;
+
+       for (y = 0; y < png_img_height; y++)
+               free((void *)row_pointers[y]);
+       free((void *)row_pointers);
+
+       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
+}
+
+
+
diff --git a/fota_gui/fota_png.h b/fota_gui/fota_png.h
new file mode 100755 (executable)
index 0000000..4d2a525
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __FOTA_PNG_H__
+#define __FOTA_PNG_H__
+
+#include "fota_fbinfo.h"
+
+extern int read_png_file(char *file_name);
+extern void draw_png_img_xy(FbInfo *fbi, int x1, int y1);
+extern void draw_png_img_clip_xy(FbInfo *fbi, int x1, int y1, int cx, int cy, int cw, int ch);
+extern void draw_png_mask_xy(FbInfo *fbi, int x1, int y1, char r, char g, char b);
+extern void release_png_res(void);
+
+
+#endif /* __FOTA_PNG_H__ */
diff --git a/fota_gui/fota_show_img.c b/fota_gui/fota_show_img.c
new file mode 100755 (executable)
index 0000000..c70a407
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <error.h>
+
+#include "fota_common.h"
+#include "fota_png.h"
+#include "fota_fbinfo.h"
+#include "tdm-if.h"
+
+FbInfo s_fbi;
+int s_img_x = 0;
+int s_img_y = 0;
+char s_img_path[1024];
+
+unsigned int __log_level__ =
+    (LOG_DEBUG | LOG_FLASH | LOG_FILE | LOG_FUNCS | LOG_GUI | LOG_REDBEND | LOG_INFO);
+
+/*-----------------------------------------------------------------------------
+  _gr_update_screen
+ ----------------------------------------------------------------------------*/
+static void _gr_update_screen()
+{
+       tdm_if_buffer_update(s_fbi.buf);
+       tdm_if_display_update();
+}
+
+/*-----------------------------------------------------------------------------
+  _gr_direct_draw_main_img
+ ----------------------------------------------------------------------------*/
+static void _gr_draw_img(FbInfo *fbi, char *img_path, int img_x, int img_y)
+{
+       if (read_png_file(img_path) < 0) {
+               return;
+       }
+
+       draw_png_img_xy(fbi, img_x, img_y);
+       release_png_res();
+
+}
+
+/*-----------------------------------------------------------------------------
+  _gr_init
+ ----------------------------------------------------------------------------*/
+int _gr_init(void)
+{
+       unsigned char *buf = NULL;
+
+       if (tdm_if_display_init() < 0) {
+               return -1;
+       }
+
+       s_fbi.w = tdm_if_display_width();
+       s_fbi.h = tdm_if_display_height();
+       s_fbi.sz = tdm_if_display_bufsize();
+
+       buf = malloc(s_fbi.sz);
+       if (NULL == buf) {
+               LOG("Not enough memory (s_fbi.sz = %d)\n", s_fbi.sz);
+               tdm_if_display_deinit();
+               return -1;
+       }
+       s_fbi.buf = buf;
+
+       _gr_draw_img(&s_fbi, s_img_path, s_img_x, s_img_y);
+
+       _gr_update_screen();
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------------
+  _gr_deinit
+ ----------------------------------------------------------------------------*/
+void _gr_deinit(void)
+{
+       if (s_fbi.buf) {
+               free(s_fbi.buf);
+               s_fbi.buf = NULL;
+       }
+       tdm_if_display_deinit();
+}
+
+int main(int argc, char **argv)
+{
+       if (argc != 4) 
+               return -1;
+
+       s_img_x = atoi(argv[1]);
+       s_img_y = atoi(argv[2]);
+       snprintf(s_img_path, sizeof(s_img_path)-1, "%s", argv[3]);
+
+       if (_gr_init() < 0) {
+               return -1;
+       }
+
+       return 0;
+}
diff --git a/fota_gui/tdm-if.c b/fota_gui/tdm-if.c
new file mode 100755 (executable)
index 0000000..6aa03ce
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 <stdbool.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/poll.h>
+#include <sys/time.h>
+#include "tdm-if.h"
+#include "fota_common.h"
+
+#define LOGD LOG
+
+tdm_if_disp s_st_disp;
+
+static void tdm_if_display_commit_handler_cb(tdm_output *output, unsigned int sequence,
+                                                 unsigned int tv_sec, unsigned int tv_usec,
+                                                 void *user_data)
+{
+    LOGD("commit_handle_cb!!\n");
+
+    return ;
+}
+
+int tdm_if_display_init(void)
+{
+       int color = 0;
+       int buf_cnt;
+       tdm_if_disp *st_disp = &s_st_disp;
+       tdm_error err = TDM_ERROR_NONE;
+
+       tdm_output *output = NULL;
+       tdm_output_type output_type = TDM_OUTPUT_TYPE_Unknown;
+       tdm_output_conn_status conn_status = TDM_OUTPUT_CONN_STATUS_DISCONNECTED;
+       const tdm_output_mode *output_mode;
+       int output_count=0;
+
+       tdm_info_layer layer_info;
+
+       tbm_surface_info_s surf_info;
+
+       int i=0;
+
+       LOGD("start");
+
+       st_disp->disp = tdm_display_init(&err);
+       if (!st_disp->disp){
+           LOGD("failed to init tdm_display. error num = %d\n", err);
+           goto exit;
+       }
+
+       err = tdm_display_get_fd(st_disp->disp, &st_disp->tdm_fd);
+       if (err != TDM_ERROR_NONE)
+       {
+           LOGD("failed to get tdm fd. error num = %d\n", err);
+           goto exit;
+       }
+
+       st_disp->drm_fd = tdm_helper_get_fd("TDM_DRM_MASTER_FD");
+       if (st_disp->drm_fd == -1 )
+       {
+           LOGD("failed to get tdm fd. error num = %d\n", err);
+           goto exit;
+       }
+
+       err = tdm_display_get_output_count(st_disp->disp, &output_count);
+       if (err != TDM_ERROR_NONE)
+       {
+           LOGD("failed to get output count. error num = %d\n", err);
+           goto exit;
+       }
+
+       for(i=0; i<output_count; i++)
+       {
+           output = tdm_display_get_output(st_disp->disp, i, &err);
+           if (err != TDM_ERROR_NONE)
+           {
+               LOGD("failed to get outout. error num = %d\n", err);
+               goto exit;
+           }
+
+           err = tdm_output_get_output_type(output, &output_type);
+           if (err != TDM_ERROR_NONE)
+           {
+               LOGD("failed to get output type. error num = %d\n", err);
+               goto exit;
+           }
+
+           err = tdm_output_get_conn_status(output, &conn_status);
+           if (err != TDM_ERROR_NONE)
+           {
+               LOGD("failed to get output connection status. error num = %d\n", err);
+               goto exit;
+           }
+
+           LOGD("output_type=%d  conn_status=%d\n", output_type, conn_status);
+           if ((output_type == TDM_OUTPUT_TYPE_LVDS) || (output_type == TDM_OUTPUT_TYPE_DSI))
+           {
+               int cnt=0;
+               err = tdm_output_get_available_modes(output, &output_mode, &cnt);
+               if (err != TDM_ERROR_NONE)
+               {
+                   LOGD("failed to get output available modes. error num = %d\n", err);
+                   goto exit;
+               }
+
+               /* GET MODE INFO */
+               st_disp->output = output;
+               st_disp->width = output_mode->hdisplay;
+               st_disp->height = output_mode->vdisplay;
+
+               unsigned int width_mm = 0;
+               unsigned int height_mm = 0;
+               err = tdm_output_get_physical_size(output, &width_mm, &height_mm);
+               LOGD("TDM_OUTPUT_MODE:name[%s] mode:wh[%d %d] mm[%d %d]",
+                       output_mode->name, st_disp->width, st_disp->height, width_mm, height_mm);
+
+               break;
+           }
+       }
+
+       /* MEMORY ALLOCATION */
+       st_disp->bufmgr = tbm_bufmgr_init(st_disp->drm_fd);
+       if (!st_disp->bufmgr){
+           LOGD("failed to tbm_bufmgr_init\n");
+           goto exit;
+       }
+
+       st_disp->buffer_size = st_disp->width * st_disp->height * RGB32_PITCH;
+       st_disp->stride = st_disp->width * RGB32_PITCH;
+
+       surf_info.width = st_disp->width;
+       surf_info.height = st_disp->height;
+       surf_info.format = TBM_FORMAT_ARGB8888;
+       surf_info.bpp = 32;
+       surf_info.size = st_disp->buffer_size;
+       surf_info.num_planes = 1;
+       surf_info.planes[0].size = st_disp->buffer_size;
+       surf_info.planes[0].offset = 0;
+       surf_info.planes[0].stride = st_disp->stride;
+
+       for (buf_cnt = 0; buf_cnt < MAX_BUF; buf_cnt++) {
+           st_disp->bo[buf_cnt] = tbm_bo_alloc(st_disp->bufmgr, st_disp->buffer_size, TBM_BO_SCANOUT );
+           if (!st_disp->bo[buf_cnt]){
+               LOGD("failed to tbm_bo_alloc\n");
+               goto exit;
+           }
+
+           st_disp->bo_handle[buf_cnt] = tbm_bo_map(st_disp->bo[buf_cnt], TBM_DEVICE_CPU, TBM_OPTION_WRITE);
+           st_disp->buffer[buf_cnt] = st_disp->bo_handle[buf_cnt].ptr;
+           st_disp->handle[buf_cnt] = tbm_bo_get_handle(st_disp->bo[buf_cnt], TBM_DEVICE_2D).u32;
+
+           memset(st_disp->buffer[buf_cnt], color, st_disp->stride * st_disp->height);
+
+           tbm_bo_unmap(st_disp->bo[buf_cnt]);
+
+           st_disp->surf[buf_cnt] = tbm_surface_internal_create_with_bos(&surf_info, &st_disp->bo[buf_cnt], 1);
+           if (!st_disp->surf[buf_cnt]){
+               LOGD("failed to create tbm_surface!!\n");
+               goto exit;
+           }
+       }
+
+       /* SET LAYER */
+       tdm_layer_capability layer_caps;
+       tdm_layer *tmp_layer = NULL;
+       for(i=0; i<output_count; i++)
+       {
+           tmp_layer = tdm_output_get_layer(st_disp->output, output_count, &err);
+           tdm_layer_get_capabilities(tmp_layer, &layer_caps);
+           if (layer_caps & TDM_LAYER_CAPABILITY_PRIMARY)
+               break;
+       }
+
+       if (!tmp_layer)
+       {
+           LOGD("failed to get output layer. error num = %d\n", err);
+           goto exit;
+       }
+
+       st_disp->layer = tmp_layer;
+
+       layer_info.src_config.size.h = st_disp->width;
+       layer_info.src_config.size.v = st_disp->height;
+       layer_info.src_config.pos.x = 0;
+       layer_info.src_config.pos.y = 0;
+       layer_info.src_config.pos.w = st_disp->width;
+       layer_info.src_config.pos.h = st_disp->height;
+       layer_info.src_config.format = TBM_FORMAT_ARGB8888;
+       layer_info.dst_pos.x = 0;
+       layer_info.dst_pos.y = 0;
+       layer_info.dst_pos.w = st_disp->width;
+       layer_info.dst_pos.h = st_disp->height;
+       layer_info.transform = TDM_TRANSFORM_NORMAL;
+
+       err = tdm_layer_set_info(st_disp->layer, &layer_info);
+       if (err != TDM_ERROR_NONE)
+       {
+           LOGD("failed to get output layer. error num = %d\n", err);
+           goto exit;
+       }
+
+       st_disp->current_buf_id = 0;
+
+       LOGD("done\n");
+       return 0;
+exit:
+       tdm_if_display_deinit();
+       return -1;
+}
+
+void tdm_if_display_deinit(void)
+{
+       int buf_cnt = 0;
+       tdm_if_disp *st_disp = &s_st_disp;
+
+       if (st_disp->disp != NULL)
+       {
+           /* RELEASE RESOURCE */
+           for (buf_cnt = 0; buf_cnt < MAX_BUF; buf_cnt++) {
+               if (st_disp->surf[buf_cnt] != NULL)
+                   tbm_surface_destroy(st_disp->surf[buf_cnt]);
+
+               if (st_disp->bo[buf_cnt] != NULL)
+                   tbm_bo_unref(st_disp->bo[buf_cnt]);
+           }
+
+           if (st_disp->bufmgr != NULL)
+               tbm_bufmgr_deinit(st_disp->bufmgr);
+           st_disp->bufmgr = NULL;
+
+           tdm_display_deinit(st_disp->disp);
+           st_disp->disp = NULL;
+       }
+}
+
+int tdm_if_display_width(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+       return st_disp->width;
+}
+
+int tdm_if_display_height(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+       return st_disp->height;
+}
+
+int tdm_if_display_bufsize(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+       return st_disp->buffer_size;
+}
+
+void tdm_if_buffer_update(unsigned char *buffer)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+       int buf_cnt = st_disp->current_buf_id;
+       memcpy(st_disp->buffer[buf_cnt], buffer, st_disp->stride * st_disp->height);
+}
+
+void tdm_if_display_update(void)
+{
+       /* DISPLAY UPDATE */
+       int buf_cnt = 0;
+       tdm_if_disp *st_disp = &s_st_disp;
+
+       buf_cnt = st_disp->current_buf_id;
+       st_disp->current_buf_id = (++st_disp->current_buf_id)%MAX_BUF;
+
+       tdm_layer_set_buffer(st_disp->layer, st_disp->surf[buf_cnt]);
+
+       // TODO: sync or async??
+       tdm_output_commit(st_disp->output, 1, tdm_if_display_commit_handler_cb, st_disp);
+
+       return ;
+}
+void tdm_if_lcd_on(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+
+       /* SET DPMS ON */
+    LOGD("DPMS ON!\n");
+    tdm_output_set_dpms(st_disp->output, TDM_OUTPUT_DPMS_ON);
+
+    return ;
+}
+
+void tdm_if_lcd_off(void)
+{
+       tdm_if_disp *st_disp = &s_st_disp;
+
+       /* SET DPMS OFF */
+    LOGD("DPMS OFF!\n");
+    tdm_output_set_dpms(st_disp->output, TDM_OUTPUT_DPMS_OFF);
+
+    return ;
+}
diff --git a/fota_gui/tdm-if.h b/fota_gui/tdm-if.h
new file mode 100755 (executable)
index 0000000..8693dba
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __TDM_IF_H__
+#define __TDM_IF_H__
+
+#include <tdm.h>
+#include <tbm_bufmgr.h>
+#include <tdm_helper.h>
+#include <tbm_surface.h>
+#include <tbm_surface_internal.h>
+
+#define MAX_BUF 2
+#define RGB32_BPP 32
+#define RGB32_PITCH 4
+
+typedef struct _tdm_if_disp {
+       tdm_display *disp;
+       tdm_output *output;
+       tdm_layer *layer;
+       tdm_pp *pp;
+       int tdm_fd;
+       int drm_fd;
+       tbm_surface_h surf[MAX_BUF];
+       tbm_surface_h pp_surf[MAX_BUF];
+       tbm_bufmgr bufmgr;
+       unsigned int handle[MAX_BUF];
+       tbm_bo bo[MAX_BUF];
+       tbm_bo_handle bo_handle[MAX_BUF];
+       void *buffer[MAX_BUF];
+       int buffer_size;
+       int width;
+       int height;
+       int stride;
+       int current_buf_id;
+} tdm_if_disp;
+
+typedef enum {
+       FRONT_BUFFER = 0,
+       BACK_BUFFER
+} BUFFER_TYPE;
+
+extern tdm_if_disp s_disp;
+
+int tdm_if_display_init(void);
+void tdm_if_display_deinit(void);
+void tdm_if_display_update(void);
+int tdm_if_display_width(void);
+int tdm_if_display_height(void);
+int tdm_if_display_bufsize(void);
+
+void tdm_if_buffer_update(unsigned char *buffer);
+
+void tdm_if_lcd_on(void);
+void tdm_if_lcd_off(void);
+
+#endif /* __TDM_IF_H__ */
diff --git a/packaging/tota-ua.spec b/packaging/tota-ua.spec
new file mode 100755 (executable)
index 0000000..2808a8a
--- /dev/null
@@ -0,0 +1,68 @@
+Name:          tota-ua
+Summary:       fota update agent
+ExclusiveArch:         %{arm}
+Version:       0.1.0
+Release:       1
+Group:         System
+License:       Apache-2.0
+Source0:       %{name}-%{version}.tar.gz
+
+BuildRequires: cmake
+BuildRequires:  pkgconfig(libtbm)
+BuildRequires:  pkgconfig(libtdm)
+BuildRequires:  pkgconfig(libsmack)
+BuildRequires:  pkgconfig(libpng)
+BuildRequires:  pkgconfig(libssl)
+BuildRequires:  pkgconfig(tota)
+BuildRequires:  pkgconfig(openssl)
+
+Requires:      %{name}-compat = %{version}-%{release}
+Recommends:    %{name}-target_rpi3 = %{version}-%{release}
+
+%description
+Fota update agent which update firmware using delta files
+
+%package target_rpi3
+Summary:       TOTA update agent for RPi3 target
+Provides:      %{name}-compat = %{version}-%{release}
+%description target_rpi3
+TOTA update agent binary targeting RPi3 target.
+
+%prep
+%setup -q
+
+
+%build
+export LDFLAGS+="-Wl,--rpath=%{_prefix}/lib -Wl,--as-needed"
+LDFLAGS="$LDFLAGS"
+
+mkdir -p build_rpi3
+pushd build_rpi3
+%cmake .. \
+       -DCMAKE_INSTALL_PREFIX=%{_prefix} \
+       -DFOTA_PARTITION_TYPE="PART_RPI3"
+
+make %{?jobs:-j%jobs}
+popd
+
+%install
+rm -rf %{buildroot}
+
+pushd build_rpi3
+%make_install
+mv %{buildroot}%{_bindir}/delta.ua %{buildroot}%{_bindir}/delta.ua.rpi3
+popd
+
+%post target_rpi3
+mv %{_bindir}/delta.ua.rpi3 %{_bindir}/delta.ua
+
+%post
+
+%files
+%license LICENSE
+%manifest tota-ua.manifest
+
+%files target_rpi3
+%defattr(-,root,root,-)
+%{_prefix}/share/fota
+%{_prefix}/bin/*
diff --git a/packaging/tota.spec b/packaging/tota.spec
deleted file mode 100644 (file)
index 5721cf4..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-%define keepstatic 1
-
-Name:          tota
-Summary:       Tizen OTA update
-Version:       1.0.0
-Release:       1
-Group:         System/Service
-License:       BSD-3-Clause and BSD-2-Clause and LGPL-2.1+ and MIT and SAMSUNG
-Source0:       %{name}-%{version}.tar.gz
-
-%description
-Tizen OTA(over-the-air) update package.
-This package provides update agent.
-
-%package rpi3
-Summary:       Tizen OTA update for RPi3
-
-%description rpi3
-Tizen OTA(over-the-air) update package.
-This package provides RPi3 target specific files.
-
-%prep
-%setup -q
-
-%build
-
-%install
-
-%files
-
-%files rpi3
diff --git a/res/rpi3/images/dummy.png b/res/rpi3/images/dummy.png
new file mode 100644 (file)
index 0000000..d0eec47
--- /dev/null
@@ -0,0 +1 @@
+This is not a used file.
diff --git a/sign_verify/CMakeLists.txt b/sign_verify/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..fa4e69a
--- /dev/null
@@ -0,0 +1,56 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+#set( CMAKE_VERBOSE_MAKEFILE on )
+
+SET(VERIFY_SRCS
+       verify_delta.c
+)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(BINDIR "${PREFIX}/bin")
+SET(VERIFYUTIL "verify_delta")
+
+
+STRING(FIND ${CMAKE_C_FLAGS} "mfloat-abi=hard" IFFOUND1)
+STRING(FIND ${CMAKE_C_FLAGS} "mhard-float" IFFOUND2)
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+       SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(verify_pkgs REQUIRED
+       openssl
+)
+
+FOREACH(flag ${verify_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-D${FOTA_PARTITION_TYPE}")
+
+#SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
+
+ADD_EXECUTABLE(${VERIFYUTIL} ${VERIFY_SRCS})
+TARGET_LINK_LIBRARIES(${VERIFYUTIL} ${verify_pkgs_LDFLAGS})
+
+
+INSTALL(TARGETS ${VERIFYUTIL} DESTINATION ${BINDIR})
+
+
diff --git a/sign_verify/verify_delta.c b/sign_verify/verify_delta.c
new file mode 100755 (executable)
index 0000000..e800b77
--- /dev/null
@@ -0,0 +1,454 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/err.h>
+
+#define _DEBUG_ERROR(s, args...)               printf(s "\n", ##args)
+#define _DEBUG_WARNING(s, args...)             printf(s "\n", ##args)
+#define _DEBUG_INFO(s, args...)                printf(s "\n", ##args)
+
+#define _INNER_FUNC_ENTER
+#define _INNER_FUNC_EXIT
+
+
+typedef struct timeval timestamp;
+
+int verify_FOTA_image(const char *cacert_path, const char *path);
+
+
+int main(int argc, char **argv)
+{
+       int ret = 0;
+
+       if (argc != 3) {
+               _DEBUG_WARNING("Usage: %s {cert file} {data file}" , argv[0]);
+               return -1;
+       }
+
+       ret = verify_FOTA_image(argv[1], argv[2]);
+       if (ret == 0) {
+          _DEBUG_INFO("verify_FOTA_image succed!!");
+       } else {
+          _DEBUG_WARNING("verify_FOTA_image failed [%d]" , ret);
+          ret = -1;
+       }
+
+       return ret;
+}
+
+
+static void get_ts1(timestamp *ts)
+{
+    gettimeofday((struct timeval *) ts, NULL);
+}
+
+static long e_ts2(timestamp *start, timestamp *end)
+{
+    return (end->tv_sec - start->tv_sec) * 1000 + (end->tv_usec
+            - start->tv_usec) / 1000;
+}
+
+
+static X509 *load_cert_mem(const unsigned char *cert_data, const int cert_len)
+{
+   _INNER_FUNC_ENTER;
+    X509 *cert = 0;
+    BIO *cert_bio = 0;
+
+    if (!(cert_bio = BIO_new_mem_buf(
+            (unsigned char *)cert_data, cert_len))) {
+        _DEBUG_ERROR("BIO mem error");
+        goto end;
+    }
+    cert = d2i_X509_bio(cert_bio, NULL);
+
+end:
+    if (cert_bio)
+        BIO_free(cert_bio);
+
+   _INNER_FUNC_EXIT;
+   return cert;
+}
+
+static int check(X509_STORE *ctx, X509 *cert)
+{
+   _INNER_FUNC_ENTER;
+    int ret = -140;
+    X509_STORE_CTX *csc = 0;
+
+    csc = X509_STORE_CTX_new();
+    if (csc == NULL) {
+        _DEBUG_ERROR("X509 csc is null");
+        goto end;
+    }
+
+    ret = -141;
+    X509_STORE_set_flags(ctx, 0);
+    if(!X509_STORE_CTX_init(csc, ctx, cert, 0)) {
+        _DEBUG_ERROR("X509 store ctx init failed");
+        goto end;
+    }
+
+    if (X509_verify_cert(csc) != 1) {
+        _DEBUG_ERROR("err: %s", X509_verify_cert_error_string(csc->error));
+        //fprintf(stderr,"MDFPP_E: %s\n", X509_verify_cert_error_string(csc->error));
+        ret = -142;
+        goto end;
+    }
+
+    ret = 0;
+end:
+    if (csc)
+        X509_STORE_CTX_free(csc);
+
+   _INNER_FUNC_EXIT;
+    return ret;
+}
+
+static X509 *verify_certificate(const unsigned char *certdata, unsigned int certlength,
+        const char* CAfile, int *result)
+{
+   _INNER_FUNC_ENTER;
+    int ret = -130;
+    X509_STORE *cert_ctx=NULL;
+    X509_LOOKUP *lookup=NULL;
+    X509 *cert = 0;
+
+    cert_ctx = X509_STORE_new();
+    if (cert_ctx == NULL) {
+      _DEBUG_ERROR("cert_ctx is NULL");
+      goto end;
+    }
+
+    OpenSSL_add_all_algorithms();
+
+    ret = -131;
+    lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file());
+    if (lookup == NULL) {
+        _DEBUG_ERROR("X509 lookup is NULL");
+        goto end;
+    }
+
+    ret = -132;
+    if(!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_ASN1)) {
+        _DEBUG_ERROR("X509 load file failed");
+        goto end;
+    }
+
+    ret = -133;
+    lookup=X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
+    if (lookup == NULL) {
+        _DEBUG_ERROR("X509 add lookup failed");
+        goto end;
+    }
+
+    X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
+
+    ret = -134;
+    cert = load_cert_mem(certdata, certlength);
+    if (cert == NULL) {
+        _DEBUG_ERROR("cannot load cert from mem");
+        goto end;
+    }
+
+    ret = check(cert_ctx, cert);
+
+end:
+    if (cert_ctx)
+        X509_STORE_free(cert_ctx);
+
+    *result = ret;
+   _INNER_FUNC_EXIT;
+    return cert;
+}
+
+typedef struct fota_sign_info {
+    unsigned char SECSIG[4];
+
+    //uint16_t x509size;
+    unsigned int x509size;
+
+    unsigned char crypt;
+    unsigned char hash;
+    unsigned char padding;
+    unsigned char salt;
+    unsigned char size;
+    unsigned char reserved[5];
+    unsigned char *sig;
+    unsigned int sig_size;
+} FOTA_SIGN_INFO;
+
+static int verify_signature(int fd, size_t length, EVP_PKEY *pkey,
+        unsigned char *sig, int siglen, const EVP_MD *md)
+{
+    _INNER_FUNC_ENTER;
+    unsigned char buffer[32*1024];
+    EVP_MD_CTX *md_ctx;
+    EVP_PKEY_CTX *ctx;
+    size_t readreq = 32*1024;
+    size_t readbytes = readreq;
+    unsigned char md_value[64] = {0};
+    int md_size = 0;
+    size_t totalbytes = 0;
+
+    // Init hash
+    md_ctx = EVP_MD_CTX_create();
+    EVP_DigestInit_ex(md_ctx, md, NULL);
+
+    // Calc hash
+    lseek(fd, 0, SEEK_SET);
+    while (totalbytes < length) {
+        if (totalbytes + readreq >= length)
+            readreq = length - totalbytes;
+        readbytes = read(fd, buffer, readreq);
+
+        if(EVP_DigestUpdate(md_ctx, buffer, readbytes) != 1) { // Prevent 47917 - adding the return value check.
+           _INNER_FUNC_EXIT;
+           return -101;
+        }
+        totalbytes += readbytes;
+    }
+    EVP_DigestFinal(md_ctx, md_value, (unsigned int *)&md_size);
+
+    EVP_MD_CTX_destroy(md_ctx);
+
+    // Init signature algorithm
+    ctx = EVP_PKEY_CTX_new(pkey, NULL);
+    if (!ctx) {
+        _INNER_FUNC_EXIT;
+        return -101;
+    }
+    if (EVP_PKEY_verify_init(ctx) <= 0) {
+        _INNER_FUNC_EXIT;
+        return -102;
+    }
+    if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) <= 0) {
+        _INNER_FUNC_EXIT;
+        return -103;
+    }
+    if (EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, -2) <= 0) {
+        _INNER_FUNC_EXIT;
+        return -104;
+    }
+    if (EVP_PKEY_CTX_set_signature_md(ctx, md) <= 0) {
+        _INNER_FUNC_EXIT;
+        return -105;
+    }
+
+    // ret == 1 indicates success, 0 verify failure and < 0 for some other error.
+    if (EVP_PKEY_verify(ctx, sig, siglen, md_value, md_size) != 1) {
+//        SLOGE("Signature verification failed\n");
+        _INNER_FUNC_EXIT;
+        return -106;
+    }
+
+    // success
+    _INNER_FUNC_EXIT;
+    return 0;
+}
+
+int verify_FOTA_image(const char *cacert_path, const char *path)
+{
+    _INNER_FUNC_ENTER;
+    int ret = -110;
+    X509 *cert = 0;
+    EVP_PKEY *pkey;
+    int fd = 0;
+    int rd = 0;
+    int length = 0;
+    off_t offset = 0;
+    unsigned char buffer[4096];
+    int cmtsize = 0;
+    int old_sigsize = 0;
+    unsigned char *x509 = 0;
+    FOTA_SIGN_INFO fota_sign_info;
+    const EVP_MD *md;
+    timestamp s, e;
+
+    if (!cacert_path || !path) {
+        _INNER_FUNC_EXIT;
+        return -111;
+    }
+    if (strlen(cacert_path) > 64) {
+        _INNER_FUNC_EXIT;
+        return -112;
+    }
+    if (strlen(path) > 64) {
+        _INNER_FUNC_EXIT;
+        return -113;
+    }
+
+    /*
+     * Prepare OpenSSL
+     */
+    OpenSSL_add_all_digests();
+
+    pkey = EVP_PKEY_new();
+
+    /*
+     * Load Certificate
+     */
+    fd = open(path, O_RDONLY, 0644);
+    if (fd < 0) {
+        _DEBUG_WARNING("Warning: Failed to open %s : %s",
+                path, strerror(errno));
+        _INNER_FUNC_EXIT;
+        return -114;
+    }
+
+    /*
+     * Goto Footer
+     */
+    if( (length = lseek(fd, 0, SEEK_END)) == -1){
+        _DEBUG_ERROR("lseek error is %d", errno);
+        ret = -115;
+        goto end;
+    }
+
+    if( lseek(fd, length - 6, SEEK_SET) == -1){
+        _DEBUG_ERROR("lseek error is %d", errno);
+        ret = -116;
+        goto end;
+    }
+
+    if ((rd = read(fd, buffer, 6)) != 6) {
+        ret = -117;
+        goto end;
+    }
+    // check footer constant
+    if (buffer[2] != 0xff || buffer[3] != 0xff) {
+        ret = -118;
+        goto end;
+    }
+    // calc comment size and start offset of sig
+    old_sigsize = (buffer[1] << 8) + buffer[0];
+    cmtsize = (buffer[5] << 8) + buffer[4];
+
+    /*
+     * Goto Zip Comments
+     */
+    // original string comments 'signed by SignApk" : 18 bytes
+    // FOTA sig header : 16 bytes
+    // FOTA sig : 256 bytes
+    // Certificate : variable (1~2k)
+    // original signature: variable
+    if( lseek(fd, length - cmtsize, SEEK_SET) == -1){
+        _DEBUG_ERROR("lseek error is %d", errno);
+        ret = -119;
+        goto end;
+    }
+
+       if( (cmtsize-old_sigsize) < 0 || (unsigned int)(cmtsize-old_sigsize) > sizeof(buffer)){
+        ret = -119;
+        goto end;
+    }
+
+    if ((rd = read(fd, buffer, cmtsize-old_sigsize)) != (int)(cmtsize-old_sigsize)) {
+        _DEBUG_ERROR("invalid comments size = %d", rd);
+        ret = -120;
+        goto end;
+    }
+
+    // Goto FOTA signature
+    // check FOTA signature header
+    offset = strlen("signed by SignApk") + 1;
+    // copy header
+    memcpy((void *)&fota_sign_info, buffer+offset, 16);
+
+    // assign buffer
+    fota_sign_info.sig = buffer+offset+16;
+
+    if (fota_sign_info.SECSIG[0] != 0x53 ||
+            fota_sign_info.SECSIG[1] != 0x45 ||
+            fota_sign_info.SECSIG[2] != 0x43 ||
+            fota_sign_info.SECSIG[3] != 0x53) {
+        _DEBUG_WARNING("invalid FOTA signature");
+        ret = -121;
+        goto end;
+    }
+    // get signature size
+    switch (fota_sign_info.size) {
+        default:
+            fota_sign_info.sig_size = 256;
+            break;
+    }
+    // get x509 buffer
+    x509 = buffer + offset + 16 + fota_sign_info.sig_size;
+
+    /*
+     * Verify Certificate
+     */
+    get_ts1(&s);
+    cert = verify_certificate(x509, fota_sign_info.x509size,
+            cacert_path, &ret);
+    get_ts1(&e);
+    if (!cert || ret) {
+        _DEBUG_ERROR("verify_certificate failed with %d", ret);
+        ret = -122;
+        goto end;
+    }
+
+    _DEBUG_INFO("Certificate verified OK (%ldms)", e_ts2(&s, &e));
+    //_DEBUG_INFO("Certificate verified OK", e_ts2(&s, &e));
+
+    /*
+     * Signature verification
+     */
+    get_ts1(&s);
+    switch (fota_sign_info.hash) {
+        default:
+
+        md = EVP_get_digestbyname("SHA512");
+        break;
+    }
+    pkey = X509_get_pubkey(cert);
+       if ( (length - cmtsize - 2) < 0) {              // Fixed for prevent. CID:48010
+        _DEBUG_ERROR("length is wrong!!");
+        ret = -123;
+        goto end;
+       }
+    ret = verify_signature(fd, (size_t)(length - cmtsize - 2)/*size of comment length field*/,
+            pkey, fota_sign_info.sig, fota_sign_info.sig_size, md);
+    get_ts1(&e);
+    if(ret != 0) {
+        _DEBUG_ERROR("Signature verified NOK(%d) (%ldms)", ret, e_ts2(&s, &e));
+    } else {
+        _DEBUG_INFO("Signature verified OK (%ldms)", e_ts2(&s, &e));
+    }
+
+end:
+    if (pkey)
+        EVP_PKEY_free(pkey);
+    if (cert)
+        X509_free(cert);
+    if (fd)
+        close(fd);
+
+    return ret;
+}
+
diff --git a/src/common/fota_cfg.c b/src/common/fota_cfg.c
new file mode 100755 (executable)
index 0000000..23747e2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 "fota_cfg.h"
+
+char fota_cfg_str[EN_CFG_MAX][CFG_MAX_LEN];
+
+void fota_cfg_str_load(void)
+{
+       strncpy(fota_cfg_str[EN_CFG_SUPPORT_FB], "1", CFG_MAX_LEN-1);
+       strncpy(fota_cfg_str[EN_CFG_SUPPORT_DRM], "0", CFG_MAX_LEN-1);
+       strncpy(fota_cfg_str[EN_CFG_DEV_FB], "/dev/fb0", CFG_MAX_LEN-1);
+       strncpy(fota_cfg_str[EN_CFG_DEV_DRM_NAME], "exynos", CFG_MAX_LEN-1);
+}
+
diff --git a/src/common/fota_cfg.h b/src/common/fota_cfg.h
new file mode 100755 (executable)
index 0000000..0afd301
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __FOTA_CFG_H__
+#define __FOTA_CFG_H__
+
+#define CFG_MAX_LEN                    1024
+
+enum {
+       EN_CFG_SUPPORT_FB,
+       EN_CFG_SUPPORT_DRM,
+       EN_CFG_DEV_FB,
+       EN_CFG_DEV_DRM_NAME,
+       EN_CFG_MAX
+};
+
+extern char fota_cfg_str[EN_CFG_MAX][CFG_MAX_LEN];
+
+
+extern void fota_cfg_str_load(void);
+
+
+
+#endif /* __FOTA_FB_H__ */
+
+
diff --git a/src/common/fota_common.h b/src/common/fota_common.h
new file mode 100755 (executable)
index 0000000..c766a70
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __FOTA_COMMON_H__
+#define __FOTA_COMMON_H__
+
+
+#include <stdio.h>
+#include "fota_log.h"
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+typedef u32 size_t;
+
+typedef signed long sl32;
+typedef unsigned long ul32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#ifndef HEAP_PROFILING
+       //#define HEAP_PROFILING;
+#endif
+#define UNUSED(x) (void)(x)
+
+struct tar_Data {
+    int itemSize;
+    int itemOffset;
+    int itemName[256];
+    struct tar_Data *nextnode;
+};
+typedef struct tar_Data tar_Data_t;
+
+#endif                          /* __FOTA_COMMON_H__ */
diff --git a/src/common/fota_log.c b/src/common/fota_log.c
new file mode 100755 (executable)
index 0000000..3e078f4
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 <stdio.h>
+#include <stdarg.h>
+
+long curr_offset = 0;
+long next_offset = 0;
+long cut_offset = 0;
+long max_logfile_size = (2*1024*1024);
+
+/*-----------------------------------------------------------------------------
+  log_printf
+ ----------------------------------------------------------------------------*/
+int log_printf(FILE* log_fp, char* format_str, ...)
+{
+       int ret = 0;
+       char log_str[4096];
+       int len;
+       int wlen;
+       va_list list;
+
+       va_start(list, format_str);
+       vsprintf(log_str, format_str, list);
+       va_end(list);
+
+       len = strlen(log_str);
+       next_offset = curr_offset + len;
+
+       if (next_offset <= max_logfile_size) {
+               wlen = len;
+               if (fwrite(log_str, 1, wlen, log_fp) != wlen) {
+                       ret = -1;
+                       goto exit;
+               }
+               curr_offset = next_offset;
+               if (curr_offset == max_logfile_size) {
+                       rewind(log_fp);
+                       curr_offset = 0;
+               }
+       } else {
+               cut_offset = max_logfile_size - curr_offset;
+               wlen = cut_offset;
+               if (fwrite(log_str, 1, wlen, log_fp) != wlen) {
+                       ret = -1;
+                       goto exit;
+               }
+               rewind(log_fp);
+               wlen = next_offset - max_logfile_size;
+               if (fwrite(log_str+cut_offset, 1, wlen, log_fp) != wlen) {
+                       ret = -1;
+                       goto exit;
+               }
+               curr_offset = next_offset - max_logfile_size;
+       }
+
+exit:
+       return ret;
+}
+
+/*-----------------------------------------------------------------------------
+  truncate_log_file
+ ----------------------------------------------------------------------------*/
+void truncate_log_file(char *log_path, int size_kb)
+{
+       FILE *log_fp;
+
+       if (size_kb == 0) {
+               log_fp = fopen(log_path, "w");
+               if (log_fp == NULL) {
+                       perror("file open error\n");
+               } else {
+                       fclose(log_fp);
+               }
+       }
+
+       sync();
+}
+
+
diff --git a/src/common/fota_log.h b/src/common/fota_log.h
new file mode 100755 (executable)
index 0000000..828228c
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __FOTA_LOG_H__
+#define __FOTA_LOG_H__
+
+#include <stdio.h>
+
+/*
+ * DEBUGGING FEATURE
+ */
+
+extern unsigned int __log_level__;
+extern FILE *__log_out_file__;
+extern int log_printf(FILE* log_fp, char* format_str, ...);
+extern void truncate_log_file(char *log_path, int size_kb);
+
+
+#define LOG_INFO       (1<<8)
+#define LOG_ENGINE     (1<<7)
+#define LOG_FUNCS      (1<<6)
+#define LOG_GUI                (1<<5)
+#define LOG_DEBUG      (1<<4)
+#define LOG_FILE       (1<<3)
+#define LOG_FLASH      (1<<2)
+#define LOG_SSENGINE  LOG_ENGINE
+
+//#define DEBUG_STDOUT
+#define DEBUG_FILE
+
+#ifdef DEBUG_STDOUT
+#define LOGE(s, args...) printf("UA/ERROR(%s)  " s, __func__, ##args) // Error log
+#define LOGL(mask, s, args...) do{if((mask) & __log_level__) printf("UA/(%s): " s,__func__, ##args);}while(0)
+#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args)
+
+#elif defined(DEBUG_FILE)
+#define LOGE(s, args...) (void)log_printf(__log_out_file__, "UA/ERROR(%s)  " s, __func__, ##args)
+#define LOGL(mask, s, args...) do{if((mask) & __log_level__) (void)log_printf(__log_out_file__, "UA/(%s): " s ,__func__, ##args);}while(0)
+#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args)
+
+#elif defined(DEBUG_STDOUT_FILE) // debug printf
+#define LOGE(s, args...) do {\
+                                               printf("UA/ERROR(%s)  " s, __func__, ##args);\
+                                               (void)log_printf(__log_out_file__, "UA/ERROR(%s)  " s, __func__, ##args);\
+                                       }while(0)
+#define LOGL(mask, s, args...) do{ \
+                                               if((mask) & __log_level__){\
+                                                       printf("UA/(%s): " s ,__func__, ##args);\
+                                                   (void)log_printf(__log_out_file__, "UA/(%s): " s,__func__, ##args);\
+                                               }\
+                                       }while(0)
+#define LOG(s, args...) LOGL(LOG_DEBUG, s, ##args)
+
+#else
+#define LOGE(s, args...)
+#define LOGL(mask, s, args...)
+#define LOG(s, args...)
+
+#endif
+
+
+#endif /* __FOTA_LOG_H__ */
+
diff --git a/src/common/fota_tar.h b/src/common/fota_tar.h
new file mode 100755 (executable)
index 0000000..d82df1f
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 _FOTA_TAR_H_
+#define _FOTA_TAR_H_
+
+ int tar_get_item_offset(char* tar, char* item);
+
+ int tar_get_item_size(char* tar, char* item);
+
+ int tar_get_cfg_data(char* tar, char* item, char *buf, int buflen);
+
+ int tar_get_folder_size(char* tar, char* item);
+#endif /* _FOTA_TAR_H_ */
diff --git a/src/common/fota_util.c b/src/common/fota_util.c
new file mode 100755 (executable)
index 0000000..b5a6a3d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 <errno.h>
+
+int s_fd_stdin = -1;
+int s_fd_stdout = -1;
+int s_fd_stderr = -1;
+
+static int set_default_stdio(int flags, int nfd)
+{
+       int fd, r;
+
+       fd = open("/dev/null", flags|O_NOCTTY);
+       if (fd < 0)
+               return -errno;
+
+       if (fd == nfd) {
+               return fd;
+       } else {
+               r = dup2(fd, nfd) < 0 ? -errno : nfd;
+               close(fd);
+               return r;
+       }
+}
+
+void _init_stdio(void)
+{
+       s_fd_stdin = set_default_stdio(O_RDONLY, STDIN_FILENO);
+
+       s_fd_stdout = set_default_stdio(O_WRONLY, STDOUT_FILENO);
+
+       s_fd_stderr = set_default_stdio(O_WRONLY, STDERR_FILENO);
+}
+
+void _exit_stdio(void)
+{
+       if (s_fd_stdin >=0)
+               close(s_fd_stdin);
+
+       if (s_fd_stdout >=0)
+               close(s_fd_stdout);
+
+       if (s_fd_stderr >=0)
+               close(s_fd_stderr);
+}
diff --git a/src/common/fota_util.h b/src/common/fota_util.h
new file mode 100755 (executable)
index 0000000..932247c
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 _FOTA_UTIL_H_
+#define _FOTA_UTIL_H_
+
+extern void _init_stdio(void);
+extern void _exit_stdio(void);
+
+#endif /* _FOTA_UTIL_H_ */
+
diff --git a/src/common/mmc_io.c b/src/common/mmc_io.c
new file mode 100755 (executable)
index 0000000..2ddbda9
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 _LARGEFILE64_SOURCE
+
+/*-----------------------------------------------------------------------------
+  include files
+ ----------------------------------------------------------------------------*/
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "fota_common.h"
+#include "mmc_io.h"
+
+/*-----------------------------------------------------------------------------
+  definitions
+ ----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+  type definitions
+ ----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+  enum definitions
+ ----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+  variables
+ ----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+  mmc_dev_open
+ ----------------------------------------------------------------------------*/
+int mmc_dev_open(char *dev_name, int flag)
+{
+       int fd;
+
+       fd = open(dev_name, flag);
+       if (fd < 0) {
+               LOG("[%s] open() fail ...\n", __FUNCTION__);
+               return -1;
+       }
+
+       return fd;
+}
+
+/*-----------------------------------------------------------------------------
+  mmc_dev_close
+ ----------------------------------------------------------------------------*/
+int mmc_dev_close(int dev_fd)
+{
+       int ret;
+
+       ret = close(dev_fd);
+       if (ret < 0) {
+               LOG("[%s] close() fail ...\n", __FUNCTION__);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------------
+  mmc_dev_sector_read
+
+  - offset: sector unit
+ ----------------------------------------------------------------------------*/
+int mmc_dev_sector_seek(int dev_fd, int sector_offset)
+{
+       loff_t start_offset;
+       loff_t ret;
+
+       start_offset = (loff_t) sector_offset *SECTOR_SIZE;
+       ret = lseek64(dev_fd, start_offset, SEEK_SET);
+       if (ret < 0) {
+               LOG("[%s] lseek64() fail ...\n", __FUNCTION__);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------------
+  mmc_dev_sector_read
+
+  - start : start sector number
+  - count : number of sectors to read
+  - buf size should not less than count * SECTOR_SIZE
+ ----------------------------------------------------------------------------*/
+int mmc_dev_sector_read(int dev_fd, int start, int count, void *buf)
+{
+       loff_t start_offset;
+       ssize_t byte_to_read;
+       ssize_t byte_read;
+       int ret;
+
+       start_offset = (loff_t) start *SECTOR_SIZE;
+       ret = lseek64(dev_fd, start_offset, SEEK_SET);
+       if (ret < 0) {
+               LOG("[%s] lseek64() fail ...\n", __FUNCTION__);
+               return -1;
+       }
+
+       byte_to_read = count * SECTOR_SIZE;
+       byte_read = read(dev_fd, buf, byte_to_read);
+       if (byte_read < byte_to_read) {
+               LOG("[%s] read() fail ...\n", __FUNCTION__);
+               return -1;
+       }
+
+       return byte_read;
+}
+
+/*-----------------------------------------------------------------------------
+  mmc_dev_sector_write
+
+  - start : start sector number
+  - count : number of sectors to write
+  - buf size should not less than count * SECTOR_SIZE
+ ----------------------------------------------------------------------------*/
+int mmc_dev_sector_write(int dev_fd, int start, int count, void *buf)
+{
+       loff_t start_offset;
+       ssize_t byte_to_write;
+       ssize_t byte_written;
+       int ret;
+
+       start_offset = start * SECTOR_SIZE;
+       ret = lseek64(dev_fd, start_offset, SEEK_SET);
+       if (ret < 0) {
+               LOG("[%s] lseek64() fail ...\n", __FUNCTION__);
+               return -1;
+       }
+
+       byte_to_write = count * SECTOR_SIZE;
+       byte_written = write(dev_fd, buf, byte_to_write);
+       if (byte_written < byte_to_write) {
+               LOG("[%s] write() fail ...\n", __FUNCTION__);
+               return -1;
+       }
+
+       return byte_written;
+}
+
+/*-----------------------------------------------------------------------------
+  mmc_dev_sector_read_current
+
+  - same as mmc_dev_sector_read() but not assign start offset.
+ ----------------------------------------------------------------------------*/
+int mmc_dev_sector_read_current(int dev_fd, int count, void *buf)
+{
+       ssize_t byte_to_read;
+       ssize_t byte_read;
+
+       byte_to_read = count * SECTOR_SIZE;
+       byte_read = read(dev_fd, buf, byte_to_read);
+       if (byte_read < byte_to_read) {
+               LOG("[%s] read() fail ...\n", __FUNCTION__);
+               return -1;
+       }
+
+       return byte_read;
+}
+
+/*-----------------------------------------------------------------------------
+  mmc_dev_sector_write_current
+
+  - same as mmc_dev_sector_write() but not assign start offset.
+ ----------------------------------------------------------------------------*/
+int mmc_dev_sector_write_current(int dev_fd, int count, void *buf)
+{
+       ssize_t byte_to_write;
+       ssize_t byte_written;
+
+       byte_to_write = count * SECTOR_SIZE;
+       byte_written = write(dev_fd, buf, byte_to_write);
+       if (byte_written < byte_to_write) {
+               LOG("[%s] read() fail ...\n", __FUNCTION__);
+               return -1;
+       }
+
+       return byte_written;
+}
diff --git a/src/common/mmc_io.h b/src/common/mmc_io.h
new file mode 100755 (executable)
index 0000000..8d37206
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __MMC_IO_H__
+#define __MMC_IO_H__
+/*-----------------------------------------------------------------------------
+  include files
+ ----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+  definitions
+ ----------------------------------------------------------------------------*/
+#define SECTOR_SIZE             512
+#define SECTOR_SIZE_SHIFT       9
+
+/*-----------------------------------------------------------------------------
+  type definitions
+ ----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+  enum definitions
+ ----------------------------------------------------------------------------*/
+
+/*-----------------------------------------------------------------------------
+  function declaration
+ ----------------------------------------------------------------------------*/
+extern int mmc_dev_open(char* dev_name, int flag);
+extern int mmc_dev_close(int dev_fd);
+extern int mmc_dev_sector_seek(int dev_fd, int sector_offset);
+extern int mmc_dev_sector_read(int dev_fd, int start, int count, void* buf);
+extern int mmc_dev_sector_write(int dev_fd, int start, int count, void* buf);
+extern int mmc_dev_sector_read_current(int dev_fd, int count, void* buf);
+extern int mmc_dev_sector_write_current(int dev_fd, int count, void* buf);
+
+
+
+#endif /* __MMC_IO_H__ */
diff --git a/src/rpi3/ua.c b/src/rpi3/ua.c
new file mode 100644 (file)
index 0000000..efbc570
--- /dev/null
@@ -0,0 +1,1676 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/reboot.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "SS_Common.h"
+#include "fota_common.h"
+#include "ua.h"
+#include "mmc_io.h"
+#include "fota_cfg.h"
+#include "fota_tar.h"
+#include "fota_util.h"
+#include "SS_UPI.h"
+
+#define MAX_CFG_LEN    4096
+
+#define RAMDISK_PATH   "/opt/usr/data/fota"
+
+#define FOTA_GUI_INTERFACE             "/usr/bin/fota_gui_test"
+#define FOTA_GUI_MAIN          "/usr/bin/fota_gui"
+
+int ua_op_mode = UA_OP_MODE_FG;
+
+static char fota_result[MAX_FILE_PATH];
+static char fota_cause[MAX_FILE_PATH];
+static char fota_status_path[MAX_FILE_PATH];
+static char delta_folder[MAX_FILE_PATH];
+static char delta_path[MAX_FILE_PATH];
+static char log_folder[MAX_FILE_PATH];
+static char result_folder[MAX_FILE_PATH];
+static char temp_folder[MAX_FILE_PATH];
+
+
+static ua_part_info_t def_part_info[UA_PARTI_MAX] = {
+       { "KERNEL",  "boot.img/",        "", 0 },
+       { "ROOTFS",  "rootfs.img/",      "", 0 },
+       { "SYSDATA", "system-data.img/", "", 0 },
+       { "USER",    "user.img/",        "", 0 },
+       { "MODULE",  "modules.img/",     "", 0 },
+};
+
+static ua_update_cfg_t def_update_cfg[UA_PARTI_MAX] = {
+       { DELTA_FS, UA_KERNEL,  0, 0 },
+       { DELTA_FS, UA_ROOTFS,  0, 0 },
+       { DELTA_FS, UA_SYSDATA, 0, 0 },
+       { DELTA_FS, UA_USER,    0, 0 },
+       { DELTA_FS, UA_MODULE,  0, 0 },
+};
+
+static ua_part_info_t s_part_info[UA_PARTI_MAX];
+
+static ua_update_cfg_t s_update_cfg[UA_PARTI_MAX];
+
+static ua_update_data_t s_update_data[UA_PARTI_MAX] = {
+       { 0, 0, 0, 0, 0, 0, NULL, NULL },
+       { 0, 0, 0, 0, 0, 0, NULL, NULL },
+       { 0, 0, 0, 0, 0, 0, NULL, NULL },
+       { 0, 0, 0, 0, 0, 0, NULL, NULL },
+       { 0, 0, 0, 0, 0, 0, NULL, NULL },
+};
+
+static int g_verify_error[] = {
+       [UA_KERNEL]  = UPI_KERNEL_VERIFY_ERROR,
+       [UA_ROOTFS]  = UPI_ROOTFS_VERIFY_ERROR,
+       [UA_SYSDATA] = UPI_SYSDATA_VERIFY_ERROR,
+       [UA_USER]    = UPI_USER_VERIFY_ERROR,
+       [UA_MODULE]  = UPI_MODULE_VERIFY_ERROR,
+};
+
+static int g_update_error[] = {
+       [UA_KERNEL]  = UPI_KERNEL_UPDATE_ERROR,
+       [UA_ROOTFS]  = UPI_ROOTFS_UPDATE_ERROR,
+       [UA_SYSDATA] = UPI_SYSDATA_UPDATE_ERROR,
+       [UA_USER]    = UPI_USER_UPDATE_ERROR,
+       [UA_MODULE]  = UPI_MODULE_UPDATE_ERROR,
+};
+
+static int s_part_num = 0;
+
+static int s_initrd_version = 1;
+static ua_delta_info_t s_delta_info;
+unsigned int __log_level__ =
+    (LOG_DEBUG | LOG_FLASH | LOG_FILE | LOG_FUNCS | LOG_GUI | LOG_ENGINE | LOG_INFO);
+FILE *__log_out_file__;
+
+static void save_result(int result);
+static void save_cause(int cause);
+static int get_last_update_status(void);
+/*-----------------------------------------------------------------------------
+  _system_cmd_wait
+ ----------------------------------------------------------------------------*/
+int _system_cmd_wait(const char *command)
+{
+
+       int pid = 0;
+       int status = 0;
+       char* const environ[2] = {"DISPLAY=:0", NULL };
+
+       if (command == NULL)
+               return -1;
+
+       pid = fork();
+
+       if (pid == -1)
+               return -1;
+
+       if (pid == 0) {
+               char *argv[4];
+               argv[0] = "sh";
+               argv[1] = "-c";
+               argv[2] = (char*)command;
+               argv[3] = 0;
+               execve("/bin/sh", argv, environ);
+               exit(127);
+       }
+
+       do {
+               if (waitpid(pid, &status, 0) == -1) {
+                       if (errno != EINTR)
+                               return -1;
+               } else {
+                       return status;
+               }
+       } while(1);
+}
+
+/*-----------------------------------------------------------------------------
+  _system_cmd_nowait
+ ----------------------------------------------------------------------------*/
+int _system_cmd_nowait(const char *command)
+{
+
+       int pid = 0;
+       char* const environ[] = {
+               "DISPLAY=:0",
+               "TBM_DISPLAY_SERVER=1",
+               "XDG_RUNTIME_DIR=/run",
+               NULL };
+
+       if (command == NULL)
+               return -1;
+
+       pid = fork();
+
+       if (pid == -1)
+               return -1;
+
+       if (pid == 0) {
+               char *argv[4];
+               argv[0] = "sh";
+               argv[1] = "-c";
+               argv[2] = (char*)command;
+               argv[3] = 0;
+               execve("/bin/sh", argv, environ);
+               exit(127);
+       }
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------------
+  check_existence
+ ----------------------------------------------------------------------------*/
+long check_existence(const char *file_path)
+{
+       struct stat statbuf;
+       char filename[MAX_FILE_PATH];
+
+       LOG("%s: %s\n",__func__ , file_path);
+       if (strncpy(filename, file_path, strlen(file_path) + 1) == NULL) {
+               LOG("strncpy error=%s\n", filename);
+               return 0;
+       }
+       if (stat(filename, &statbuf)) {
+               if (ENOENT == errno) {
+                       char err[1024];
+                       LOG("stat %s: %s\n", filename, strerror_r(errno, err, sizeof(err)));
+                       return 0;
+               }
+       }
+       LOG("%s: statbuf.st_size = %d\n",__func__ , (int)statbuf.st_size);
+       return statbuf.st_size;
+}
+
+/*-----------------------------------------------------------------------------
+  make_temp_file
+ ----------------------------------------------------------------------------*/
+void make_temp_file(char *temp_file)
+{
+       FILE *fp;
+       int i = 0, temp = 0;
+
+       LOG("Make %s file\n", temp_file);
+
+       fp = fopen(temp_file, "wb");
+       if (!fp) {
+               LOGE("failed to fopen\n");
+               return;
+       }
+       for (i = 0; i < TEMP_SIZE; i++)
+               fwrite(&temp, sizeof(int), 1, fp);
+       fclose(fp);
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gui_update_progress
+ ----------------------------------------------------------------------------*/
+void fota_gui_update_progress(int percent)
+{
+       int ret = 0;
+       char cmd[1024];
+       static int s_percent = -1;
+
+       if (percent > s_percent) {
+               s_percent = percent;
+       } else {
+               return;
+       }
+       snprintf(cmd, sizeof(cmd)-1, "%s %d", FOTA_GUI_INTERFACE, percent);
+
+       ret = _system_cmd_wait(cmd);
+       LOG("ret = %d\n", ret);
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gui_update_end
+ ----------------------------------------------------------------------------*/
+void fota_gui_update_end(void)
+{
+       int ret = 0;
+       char cmd[1024];
+
+       snprintf(cmd, sizeof(cmd)-1, "%s %d", FOTA_GUI_INTERFACE, -1);
+
+       ret = _system_cmd_wait(cmd);
+       LOG("ret = %d\n", ret);
+}
+
+/*-----------------------------------------------------------------------------
+  fota_gui_progress
+ ----------------------------------------------------------------------------*/
+void fota_gui_progress(void * pbUserData, unsigned long uPercent)
+{
+       int percent;
+       ua_dataSS_t *ua_data = (ua_dataSS_t *)pbUserData;
+       ua_update_data_t *ua_update_data = ua_data->update_data;
+
+       if (ua_op_mode == UA_OP_MODE_BG) {
+               return;
+       }
+
+       LOGL(LOG_FUNCS|LOG_GUI, "%s: ++ uPercent(%lu%%), config->weight=%lu\n", __func__,
+               uPercent, (long unsigned int)ua_update_data->weight);
+
+       if(uPercent == 100) {
+               percent = ua_update_data->weight_offset + ua_update_data->weight;
+       } else {
+               percent = ua_update_data->weight_offset + (ua_update_data->weight * uPercent / 100);
+       }
+
+       /* re-arrange progress percentage betwen scout & update */
+       if (ua_data->ua_operation == UI_OP_SCOUT) {
+               percent = percent / 5;
+       } else if ((ua_data->ua_operation == UI_OP_SCOUT_UPDATE)
+               || (ua_data->ua_operation == UI_OP_UPDATE)) {
+               percent = 20 + percent * 4 / 5;
+       }
+
+       fota_gui_update_progress(percent);      /* update progress bar and text */
+
+       LOGL(LOG_FUNCS|LOG_GUI, "-- uPercent=%lu, Print Percent(%d%%)\n", uPercent, percent);
+}
+
+/*-----------------------------------------------------------------------------
+  _launch_fota_gui_process
+ ----------------------------------------------------------------------------*/
+void _launch_fota_gui_process(void)
+{
+       _system_cmd_nowait(FOTA_GUI_MAIN);
+       sleep(1);
+}
+
+/*-----------------------------------------------------------------------------
+  write_data_to_blkdev
+  - blk_start : start sector number
+  - blk_cnt : number of sectors to write
+  - data length should be blk_cnt x SECTOR_SIZE
+ ----------------------------------------------------------------------------*/
+int write_data_to_blkdev(char* dev_name, int blk_start, int blk_cnt, char* data)
+{
+       int fd_mmc;
+
+       LOG("%s: entered start offset=%d sectos, size=%d sectos\n",  dev_name, blk_start, blk_cnt);
+       /* destination MMC device open */
+       fd_mmc = mmc_dev_open(dev_name, O_RDWR);
+       if (fd_mmc < 0) {
+               LOG("mmc_dev_open() fail ...\n");
+               return FAIL;
+       }
+
+       if (mmc_dev_sector_write(fd_mmc, blk_start, blk_cnt, data) < 0) {
+               LOG("mmc_dev_sector_write() fail ...\n");
+               mmc_dev_close(fd_mmc);
+               return FAIL;
+       }
+
+       mmc_dev_close(fd_mmc);
+       LOG("%s: leaved\n", __func__);
+
+       return SUCCESS;
+}
+
+
+/*-----------------------------------------------------------------------------
+  write_full_image
+ ----------------------------------------------------------------------------*/
+static int write_full_image(ua_part_info_t *ua_part_info, ua_update_data_t *ua_update_data, int part_idx)
+{
+       int ret = SUCCESS;
+       int blk_start = 0;
+       int blk_cnt = 0;
+       int read_count = 0, data_length = 0;
+       char* data = NULL;
+       int bin_size = 0, offset = 0;
+
+       FILE *fp;
+
+       LOG("ua_delta_path=%s, ua_subject_name=%s\n", ua_update_data->ua_delta_path, ua_part_info->ua_subject_name);
+
+       fp = fopen(ua_update_data->ua_delta_path, "r");
+       if (!fp) {
+               LOGE("open file %s failed.\n",  ua_update_data->ua_delta_path);
+               return FAIL;
+       }
+
+       bin_size = tar_get_item_size(ua_update_data->ua_delta_path, ua_part_info->ua_subject_name);
+       if (bin_size <= 0) {
+               LOGE("bin_size=%d\n", bin_size);
+               fclose(fp);
+               return FAIL;
+       }
+       offset = tar_get_item_offset(ua_update_data->ua_delta_path, ua_part_info->ua_subject_name);
+       if (offset < 0) {
+               LOGE("offset=%d\n", offset);
+               fclose(fp);
+               return FAIL;
+       }
+
+       blk_cnt = ((bin_size-1)/SECTOR_SIZE)+1;
+       data_length = blk_cnt * SECTOR_SIZE;
+       LOG("bin_size=%d, data_length=%d\n", bin_size, data_length);
+
+       if (fseek(fp,  offset,  SEEK_SET) < 0) {
+               LOGE("fseek() fail\n");
+               fclose(fp);
+               return FAIL;
+       }
+
+       data = malloc(data_length);
+       if (data) {
+               read_count = fread(data, 1, bin_size, fp);
+               LOG("read file read_count=%d byte, blk_cnt=%d\n",  read_count, blk_cnt);
+               if (read_count != bin_size) {
+                       LOGE("error in read size\n");
+                       if (data) {
+                               free(data);
+                       }
+                       if (fp) {
+                               fclose(fp);
+                       }
+                       return FAIL;
+               }
+
+               if (write_data_to_blkdev(ua_part_info->ua_blk_name,
+                               blk_start, blk_cnt, data) != SUCCESS) {
+                       LOGE("error in write_data_to_blkdev()\n" );
+                       ret = FAIL;
+               }
+
+               if (data) {
+                       free(data);
+               }
+       }
+
+       if (fp) {
+               fclose(fp);
+       }
+
+       LOG("%s leaved\n", __func__);
+
+       return ret;
+}
+
+/*-----------------------------------------------------------------------------
+  verify_Full_Image
+ ----------------------------------------------------------------------------*/
+int verify_Full_Image(int part_idx)
+{
+       int ret = SUCCESS;
+       ua_dataSS_t ua_dataSS;
+       ua_part_info_t *ua_part_info = &s_part_info[part_idx];
+       ua_update_cfg_t *ua_update_cfg = &s_update_cfg[part_idx];
+       ua_update_data_t *ua_update_data = &s_update_data[part_idx];
+       ua_delta_info_t *ua_delta_info= &s_delta_info;
+       ua_dataSS.parti_info = ua_part_info;
+       ua_dataSS.update_cfg = ua_update_cfg;
+       ua_dataSS.update_data = ua_update_data;
+       ua_dataSS.update_delta=ua_delta_info;
+       ua_dataSS.ua_operation = UI_OP_SCOUT;
+       ua_dataSS.ui_progress = fota_gui_progress;
+
+       if (ua_update_data->ua_delta_path != NULL){
+               //commenting for now as FIXNV2 verification fails as nvitem changes after boot in device
+               //should use skip_verify for such cases
+               ret = SUCCESS;//SS_IMGVerfiyPartition(&ua_dataSS);
+               fota_gui_progress(&ua_dataSS, 100);
+       }
+       return ret;
+
+}
+
+/*-----------------------------------------------------------------------------
+  update_Full_Image
+ ----------------------------------------------------------------------------*/
+int update_Full_Image(int part_idx)
+{
+       int ret = FAIL;
+       ua_dataSS_t ua_data;
+       ua_part_info_t *ua_part_info = &s_part_info[part_idx];
+       ua_update_cfg_t *ua_update_cfg = &s_update_cfg[part_idx];
+       ua_update_data_t *ua_update_data = &s_update_data[part_idx];
+
+       ua_data.parti_info = ua_part_info;
+       ua_data.update_cfg = ua_update_cfg;
+       ua_data.update_data = ua_update_data;
+       ua_data.ui_progress = fota_gui_progress;
+       ua_data.ua_operation = UI_OP_UPDATE;
+
+       LOG("%s entered\n", __func__);
+
+       ret = write_full_image(ua_part_info, ua_update_data, part_idx);
+       if(ret != SUCCESS)
+       {
+               LOGE("%s entered\n", __func__);
+               goto CleanUp;
+       }
+
+       fota_gui_progress(&ua_data, 100);       /* display completion of update_Sbl */
+
+ CleanUp:
+
+       LOG("%s leaved ret=%d\n", __func__, ret);
+       return ret;
+}
+
+/*-----------------------------------------------------------------------------
+  verify_Delta_FS
+ ----------------------------------------------------------------------------*/
+int verify_Delta_FS(int part_idx)
+{
+       int ret = SUCCESS;
+
+       ua_dataSS_t ua_dataSS;
+       ua_part_info_t *ua_part_info = &s_part_info[part_idx];
+       ua_update_cfg_t *ua_update_cfg = &s_update_cfg[part_idx];
+       ua_update_data_t *ua_update_data = &s_update_data[part_idx];
+       ua_delta_info_t *ua_delta_info= &s_delta_info;
+       ua_dataSS.parti_info = ua_part_info;
+       ua_dataSS.update_cfg = ua_update_cfg;
+       ua_dataSS.update_data = ua_update_data;
+       ua_dataSS.update_delta=ua_delta_info;
+       ua_dataSS.ua_operation = UI_OP_SCOUT;
+       ua_dataSS.ui_progress = fota_gui_progress;
+       if (ua_update_data->ua_delta_path != NULL) {
+               LOG("Verifying %s \n", ua_dataSS.parti_info->ua_parti_name);
+               ret = SS_FSVerifyPartition(&ua_dataSS, part_idx);
+       }
+
+       return ret;
+}
+
+/*-----------------------------------------------------------------------------
+  update_Delta_FS
+ ----------------------------------------------------------------------------*/
+int update_Delta_FS(int part_idx, unsigned long ui32Operation)
+{
+       int ret = SUCCESS;
+       ua_dataSS_t ua_dataSS;
+       ua_part_info_t *ua_part_info = &s_part_info[part_idx];
+       ua_update_cfg_t *ua_update_cfg = &s_update_cfg[part_idx];
+       ua_update_data_t *ua_update_data = &s_update_data[part_idx];
+       ua_delta_info_t *ua_delta_info= &s_delta_info;
+       ua_dataSS.parti_info = ua_part_info;
+       ua_dataSS.update_cfg = ua_update_cfg;
+       ua_dataSS.update_data = ua_update_data;
+       ua_dataSS.update_delta=ua_delta_info;
+       ua_dataSS.ua_operation = ui32Operation;
+       ua_dataSS.ui_progress = fota_gui_progress;
+
+       if (ua_update_data->ua_delta_path != NULL) {
+               ret=SS_FSUpdatemain(&ua_dataSS,part_idx);
+       }
+
+       return ret;
+}
+
+/*-----------------------------------------------------------------------------
+  verify_Delta_IMG
+ ----------------------------------------------------------------------------*/
+int verify_Delta_IMG(int part_idx)
+{
+       int ret = SUCCESS;
+       ua_dataSS_t ua_dataSS;
+
+       ua_part_info_t *ua_part_info = &s_part_info[part_idx];
+       ua_update_cfg_t *ua_update_cfg = &s_update_cfg[part_idx];
+       ua_update_data_t *ua_update_data = &s_update_data[part_idx];
+       ua_delta_info_t *ua_delta_info= &s_delta_info;
+       ua_dataSS.parti_info = ua_part_info;
+       ua_dataSS.update_cfg = ua_update_cfg;
+       ua_dataSS.update_data = ua_update_data;
+       ua_dataSS.update_delta=ua_delta_info;
+       ua_dataSS.ua_operation = UI_OP_SCOUT;
+       ua_dataSS.ui_progress = fota_gui_progress;
+
+       if (ua_update_data->ua_delta_path != NULL){
+               ret = SS_IMGVerfiyPartition(&ua_dataSS);
+       }
+
+       return ret;
+}
+
+/*-----------------------------------------------------------------------------
+  update_Delta_IMG
+ ----------------------------------------------------------------------------*/
+int update_Delta_IMG(int part_idx, unsigned long ui32Operation)
+{
+       int ret = SUCCESS;
+       ua_dataSS_t ua_dataSS;
+       ua_part_info_t *ua_part_info = &s_part_info[part_idx];
+       ua_update_cfg_t *ua_update_cfg = &s_update_cfg[part_idx];
+       ua_update_data_t *ua_update_data = &s_update_data[part_idx];
+       ua_delta_info_t *ua_delta_info= &s_delta_info;
+       ua_dataSS.parti_info = ua_part_info;
+       ua_dataSS.update_cfg = ua_update_cfg;
+       ua_dataSS.update_data = ua_update_data;
+       ua_dataSS.update_delta=ua_delta_info;
+       ua_dataSS.ua_operation = ui32Operation;
+       ua_dataSS.ui_progress = fota_gui_progress;
+       ua_dataSS.write_data_to_blkdev=write_data_to_blkdev;
+       if (ua_update_data->ua_delta_path != NULL) {
+               ret = SS_IMGUpdatemain(&ua_dataSS, DELTA_IMG);
+               }
+       return ret;
+}
+//RAMDISK.delta for recovery FS.
+#ifdef SS_RECOVERYRAMDISK
+
+int verify_RecoveryDelta_IMG(int part_idx)
+{
+       int ret = SUCCESS;
+       ua_dataSS_t ua_dataSS;
+       ua_part_info_t *ua_part_info = &s_part_info[part_idx];
+       ua_update_cfg_t *ua_update_cfg = &s_update_cfg[part_idx];
+       ua_update_data_t *ua_update_data = &s_update_data[part_idx];
+       ua_delta_info_t *ua_delta_info= &s_delta_info;
+       ua_dataSS.parti_info = ua_part_info;
+       ua_dataSS.update_cfg = ua_update_cfg;
+       ua_dataSS.update_data = ua_update_data;
+       ua_dataSS.update_delta=ua_delta_info;
+       ua_dataSS.ua_operation = UI_OP_SCOUT;
+       ua_dataSS.ui_progress = fota_gui_progress;
+
+       if (ua_update_data->ua_delta_path != NULL) {
+               ret = SS_IMGVerfiyPartition(&ua_dataSS);
+               }
+
+       return ret;
+}
+
+
+int update_RecoveryDelta_IMG(int part_idx, int update_type)
+{
+       int ret = SUCCESS;
+       ua_dataSS_t ua_dataSS;
+       ua_part_info_t *ua_part_info = &s_part_info[part_idx];
+       ua_update_cfg_t *ua_update_cfg = &s_update_cfg[part_idx];
+       ua_update_data_t *ua_update_data = &s_update_data[part_idx];
+       ua_delta_info_t *ua_delta_info= &s_delta_info;
+       ua_dataSS.parti_info = ua_part_info;
+       ua_dataSS.update_cfg = ua_update_cfg;
+       ua_dataSS.update_data = ua_update_data;
+       ua_dataSS.update_delta=ua_delta_info;
+       ua_dataSS.update_data->ua_temp_path = malloc(MAX_FILE_PATH);
+       ua_dataSS.ua_operation = UI_OP_SCOUT_UPDATE;
+       ua_dataSS.ui_progress = fota_gui_progress;
+       if (ua_update_data->ua_delta_path != NULL && ua_dataSS.update_data->ua_temp_path) {
+               snprintf(ua_dataSS.update_data->ua_temp_path, MAX_FILE_PATH, "%s/%s", RAMDISK_PATH, ua_dataSS.parti_info->ua_parti_name);
+               LOG("update_RecoveryDelta_IMG() [%s] temp path [%s]\n", ua_dataSS.parti_info->ua_parti_name,ua_dataSS.update_data->ua_temp_path);
+               ret = SS_IMGUpdatemain(&ua_dataSS, update_type);        //PASS temp path whr file has to be written, Once written it should be UNLINKED after upgrade.
+               }
+       return ret;
+}
+
+#endif
+
+/*-----------------------------------------------------------------------------
+  set_data_weight
+ ----------------------------------------------------------------------------*/
+/* set data weight using data size minimum:1 total: 100 */
+static void set_data_weight(unsigned int total_data_size)
+{
+       int i = 0, big = 0, weight = 0, total_weight = 0;
+
+       LOG("%s entered, total_data_size=%u\n", __func__, total_data_size);
+
+       for (i = 0; i < s_part_num; i++) {
+               if(s_update_data[i].exist_check)
+               {
+                       s_update_data[i].weight = 100 * (unsigned long long)s_update_data[i].data_size / total_data_size;
+
+                       if(s_update_data[i].weight == 0) {
+                               s_update_data[i].weight = 1;
+                       }
+
+                       if(weight < s_update_data[i].weight) {
+                               weight = s_update_data[i].weight;
+                               big = i;
+                       }
+
+                       total_weight += s_update_data[i].weight;
+               }
+
+               LOG("[%d] exist_check=%d, weight=%u total_weight=%u\n",
+                       i, s_update_data[i].exist_check, s_update_data[i].weight, total_weight);
+       }
+
+       if(total_weight < 100) {
+               s_update_data[big].weight += (100 - total_weight);
+       } else {
+               s_update_data[big].weight -= (total_weight - 100);
+       }
+
+       LOG("[big: %d] weight=%u\n", big, s_update_data[big].weight);
+
+       LOG("%s leaved\n", __func__);
+}
+
+/*-----------------------------------------------------------------------------
+  set_data_weight_offset
+ ----------------------------------------------------------------------------*/
+static void set_data_weight_offset(void)
+{
+       int i = 0, k = 0;
+
+       LOG("%s entered\n", __func__);
+
+       for (i = 0; i < s_part_num; i++) {
+               for(k = 0; k < i; k++) {
+                       s_update_data[i].weight_offset += s_update_data[k].weight;
+               }
+               LOG("s_update_data[%d].weight_offset=%u\n", i, s_update_data[i].weight_offset);
+       }
+
+       LOG("%s leaved\n", __func__);
+}
+
+/*-----------------------------------------------------------------------------
+  read_from_file
+ ----------------------------------------------------------------------------*/
+int read_from_file(const char *path, char *buf, size_t size)
+{
+       int fd;
+       ssize_t count;
+
+       if (!path)
+               return -1;
+
+       if (size == 0) {
+               return 0;
+       }
+
+       fd = open(path, O_RDONLY, 0);
+       LOG("open '%s'\n", path);
+       if (fd == -1) {
+               LOG("Could not open '%s'", path);
+               return -1;
+       }
+
+       count = read(fd, buf, size);
+       if (count > 0) {
+               count = (count < (ssize_t)size) ? count : ((ssize_t)size - 1);
+               while (count > 0 && buf[count - 1] == '\n')
+                       count--;
+               buf[count] = '\0';
+       } else {
+               buf[0] = '\0';
+       }
+       LOG("read '%s'\n", buf);
+
+       close(fd);
+
+       return (int)count;
+}
+
+
+/*-----------------------------------------------------------------------------
+  write_to_file
+ ----------------------------------------------------------------------------*/
+/* size is the contents size, not buf size
+   buf size should be larger than contents size */
+int write_to_file(const char *path, char *buf, size_t size)
+{
+       int fd;
+       ssize_t count;
+
+       if (!path)
+               return -1;
+
+       fd = open(path, O_WRONLY | O_CREAT, S_IRWXU);
+       LOG("open '%s'\n", path);
+
+       if (fd == -1) {
+               LOG("Could not open '%s'\n", path);
+               return -1;
+       }
+
+       count = write(fd, buf, size);
+       LOG("write '%s'\n", buf);
+
+       if (fsync(fd) < 0) {
+               LOG("fsync failed.\n");
+       }
+
+       close(fd);
+
+       if (size != count) {
+               LOG("Could not write to '%s'\n", path);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------------
+  write_num_to_file
+ ----------------------------------------------------------------------------*/
+int write_num_to_file(const char *path, int num)
+{
+       char num_str[16];
+
+       snprintf(num_str, sizeof(num_str), "%d", num);
+       return write_to_file(path, num_str, strlen(num_str));
+}
+
+/*-----------------------------------------------------------------------------
+  remove_last_update_status
+ ----------------------------------------------------------------------------*/
+static void remove_last_update_status(void)
+{
+       /*
+           remove status file.
+       */
+       int ret = -1;
+       ret = unlink(fota_status_path);
+       LOGL(LOG_DEBUG, "delete %s return %d\n", fota_status_path, ret);
+}
+
+/*-----------------------------------------------------------------------------
+  get_last_update_status
+ ----------------------------------------------------------------------------*/
+static int get_last_update_status(void)
+{
+       /*
+           if status file does not exist, status = UP_START_NONE.
+           if status file exist, read status from file.
+       */
+       char buf[256];
+       int status = UP_START_NONE;
+
+       if (check_existence(fota_status_path) == 0) {
+               return UP_START_NONE;
+       }
+
+       if (read_from_file(fota_status_path, buf, sizeof(buf)) < 0) {
+               return UP_START_NONE;
+       }
+
+       status = atoi(buf);
+       if ((status > UP_START_NONE) && (status < UP_START_MAX)) {
+               return status;
+       } else {
+               return UP_START_NONE;
+       }
+}
+
+/*-----------------------------------------------------------------------------
+  set_last_update_status
+ ----------------------------------------------------------------------------*/
+static void set_last_update_status(int status)
+{
+       /*
+           if status file exist, write status to file.
+           if status file does not exist, create file and write status to file.
+       */
+       write_num_to_file(fota_status_path, status);
+}
+
+/*-----------------------------------------------------------------------------
+  get_time_stamp
+ ----------------------------------------------------------------------------*/
+static char ts[256];
+static void get_time_stamp(void)
+{
+       struct timeval tv;
+       int sec, msec;
+
+       gettimeofday(&tv, NULL);
+       sec = (int) tv.tv_sec;
+       msec = (int) (tv.tv_usec / 1000);
+       snprintf(ts, sizeof(ts), "%06d.%03d", sec % 100000, msec);
+}
+
+/*-----------------------------------------------------------------------------
+  update_all
+ ----------------------------------------------------------------------------*/
+int update_all()
+{
+       int i, data_count = 0, ret = FAIL;
+       unsigned long total_data_size = 0;
+       int cause = 0;
+       int item_size = 0;
+       int last_update_status = UP_START_NONE;
+       int update_status = UP_START_NONE;
+       int part_idx = UA_PARTI_MAX;
+       int err_idx = UA_PARTI_MAX;
+       unsigned int update_type = 0;
+       unsigned long ui32Operation = UI_OP_SCOUT;
+
+       LOG("%s entered\n", __func__);
+
+       data_count = 0;
+
+       for (i = 0; i < s_part_num; i++) {
+               item_size = tar_get_item_size(s_update_data[i].ua_delta_path, s_part_info[i].ua_subject_name);
+               if(item_size > 0) {
+                       s_update_data[i].data_size = (unsigned int)item_size;
+               } else {
+                       s_update_data[i].data_size = 0;
+               }
+               LOGL(LOG_DEBUG, "s_update_data[%d].data_size=%lu, ua_delta_path=%s, "
+                       "ua_blk_name = %s, ua_subject_name=%s\n",
+                       i,
+                       (long unsigned int)s_update_data[i].data_size,
+                       s_update_data[i].ua_delta_path,
+                       s_part_info[i].ua_blk_name,
+                       s_part_info[i].ua_subject_name);
+
+               if (s_update_data[i].data_size) {
+                       data_count++;
+
+                       s_update_data[i].exist_check = 1;
+                       total_data_size += s_update_data[i].data_size;
+
+                       LOGL(LOG_DEBUG,
+                            "Check Delta : part_idx(%d), file_path(%s), total data cnt(%lu)\n",
+                            i, s_update_data[i].ua_delta_path,
+                             (long unsigned int)data_count);
+               }
+       }
+
+       LOG("data_count=%lu, total_data_size=%lu\n",
+               (long unsigned int)data_count, (long unsigned int)total_data_size);
+       if (data_count == 0) {
+               ret = UPI_DELTACOUNT_ERROR;
+               sleep(3);
+
+               goto CleanUp;
+       }
+       LOG(" set weight to draw progressive bar.....\n");
+       set_data_weight(total_data_size);
+       set_data_weight_offset();
+
+       for (i = 0; i < s_part_num; i++) {
+               LOG("s_part_info[%s].ua_delta_path = %s ua_subject_name=%s\n",
+                       s_part_info[i].ua_parti_name,
+                       s_update_data[i].ua_delta_path,
+                       s_part_info[i].ua_subject_name);
+       }
+
+       last_update_status = get_last_update_status();
+
+       /* Verify */
+       if (last_update_status == UP_START_NONE) {
+               for (part_idx = 0; part_idx < s_part_num; part_idx++) {
+                       if (s_update_data[part_idx].data_size > 0) {
+                               get_time_stamp();
+                               LOG("[%s] Verify %s ..............................................................\n", ts,
+                                       s_part_info[part_idx].ua_parti_name);
+
+                               update_type = s_update_cfg[part_idx].update_type;
+                               if (update_type == FULL_IMG)
+                                       ret = verify_Full_Image(part_idx);
+                               else if (update_type == DELTA_IMG)
+                                       ret = verify_Delta_IMG(part_idx);
+                               else if (update_type == DELTA_FS)
+                                       ret = verify_Delta_FS(part_idx);
+                               else if (update_type == EXTRA)
+                                       ret = verify_RecoveryDelta_IMG(part_idx);
+                               else
+                                       ret = -1;
+
+                               if (ret != OK) {
+                                       cause = ret;
+                                       err_idx = s_update_cfg[part_idx].part_idx;
+                                       ret = g_verify_error[err_idx];
+                                       LOG("%s verify fail", s_part_info[part_idx].ua_parti_name);
+                                       goto CleanUp;
+                               }
+                               s_update_data[part_idx].verify_check = 1;
+                       }
+               }
+
+       }
+
+       get_time_stamp();
+       LOG("[%s] Verify End ..............................................................\n", ts);
+
+       /* Update */
+       for (part_idx = 0; part_idx < s_part_num; part_idx++) {
+               update_status = part_idx;
+               if (last_update_status <= update_status) {
+                       if (last_update_status == update_status) {
+                               ui32Operation = UI_OP_SCOUT_UPDATE;
+                       } else {
+                               ui32Operation = UI_OP_UPDATE;
+                       }
+
+                       if (s_update_data[part_idx].data_size > 0) {
+                               get_time_stamp();
+                               LOG("[%s] Update %s ..............................................................\n", ts,
+                                       s_part_info[part_idx].ua_parti_name);
+
+                               set_last_update_status(update_status);
+
+                               update_type = s_update_cfg[part_idx].update_type;
+                               if (update_type == FULL_IMG)
+                                       ret = update_Full_Image(part_idx);
+                               else if (update_type == DELTA_IMG)
+                                       ret = update_Delta_IMG(part_idx, ui32Operation);
+                               else if (update_type == DELTA_FS)
+                                       ret = update_Delta_FS(part_idx, ui32Operation);
+                               else if (update_type == EXTRA) //TOTA
+                                       ret = update_RecoveryDelta_IMG(part_idx, DELTA_IMG);
+                               else
+                                       ret = -1;
+
+                               if (ret != OK) {
+                                       cause = ret;
+                                       err_idx = s_update_cfg[part_idx].part_idx;
+                                       ret = g_update_error[err_idx];
+                                       LOG("%s update fail", s_part_info[part_idx].ua_parti_name);
+                                       goto CleanUp;
+                               }
+                               s_update_data[part_idx].update_check = 1;
+                       }
+               }
+       }
+
+       get_time_stamp();
+       LOG("[%s] Update End ..............................................................\n", ts);
+
+ CleanUp:
+       if(ret != OK)
+               save_cause(cause);
+
+       return ret;
+}
+
+/*-----------------------------------------------------------------------------
+  log_init
+ ----------------------------------------------------------------------------*/
+void log_init(void)
+{
+       char log_file[MAX_FILE_PATH];
+
+       snprintf(log_file, sizeof(log_file), "%s%s", log_folder, LOG_FILE_PATH);
+
+       __log_out_file__ = fopen(log_file, "w");
+       if (__log_out_file__ == NULL) {
+               perror("file open error\n");
+               return;
+       }
+
+       get_time_stamp();
+       LOG("===== log start [%s] =====\n", ts);
+}
+
+/*-----------------------------------------------------------------------------
+  log_deinit
+ ----------------------------------------------------------------------------*/
+void log_deinit(void)
+{
+       get_time_stamp();
+       LOG("===== log end [%s] =====\n", ts);
+
+       if(__log_out_file__)
+       {
+               fclose(__log_out_file__);
+               __log_out_file__ = NULL;
+       }
+
+       sync();
+}
+
+/*-----------------------------------------------------------------------------
+  print_error_cause
+ ----------------------------------------------------------------------------*/
+static void print_error_cause(int error)
+{
+       switch(error) {
+               case E_SS_PKG_CORRUPTED:
+               case E_SS_SOURCE_CORRUPTED: /* not used */
+               case E_SS_IMGBADDELTA:
+               case E_SS_FSBADDELTA:
+                       LOG("Corrupted firmware update package, did not store correctly.  Detected, for example, by mismatched CRCs between actual and expected.");
+                       break;
+               case E_SS_BAD_PARAMS:
+                       LOG("Wrong Firmware Update Package delivered to device based on current device characteristics");
+                       break;
+               case E_SS_INVALID_DP_HEADER:
+               case E_SS_INVALID_DP_WRONG_SIGNATURE:
+                       LOG("Failure to positively validate digital signature of firmware update package");
+                       break;
+               case E_SS_PKG_TOO_LONG: /* not used */
+                       LOG("Firmware Update Package is Not Acceptable");
+                       break;
+               case E_SS_NOT_ENOUGH_RAM:
+               case E_SS_MALLOC_ERROR:
+                       LOG("The update fails because there isn't sufficient memory to update the device.");
+                       break;
+               case E_SS_FSSRCBACKUPFAILED:
+               case E_SS_IMGSRCBACKUPFAILED:
+               case E_SS_IMGRECOVERYWRITEFAILED:
+               case E_SS_IMGFLASHWRITEFAIL:
+               case E_SS_WRITE_ERROR:
+               case E_SS_FSFAILEDTOBACKUPPATCHINFO:
+               case E_SS_FSBADATTRIBUTES:
+                       LOG("The update failed because writing data to the device was unsuccessful.");
+                       break;
+               case E_SS_FSSRCCURRUPTED:
+               case E_SS_IMGSRCCURRUPTED:
+               case E_SS_IMGSHA_MISMATCH:
+               case E_SS_FSSHA_MISMATCH:
+               case E_SS_FSFAILEDTOPARSEDELTACNT:
+               case E_SS_FSFAILEDTOOPENPATCHINFO:
+               case E_SS_FSFAILEDTOPARSEDELTAINFO:
+                       LOG("The update failed because data was corrupted during update of device.");
+                       break;
+               default:
+                       LOG("another error");
+                       break;
+               }
+}
+
+/*
+<Corrupted Firmware Update Package>
+Corrupted firmware update package, did not store correctly.  Detected, for example, by mismatched CRCs between actual and expected.
+E_RB_PKG_CORRUPTED(0x8000000D)
+E_RB_PKG_NOT_AUTHORIZED(0x8000000E): not used
+
+<Firmware Update Package-Device Mismatch>
+Wrong Firmware Update Package delivered to device based on current device characteristics
+E_RB_BAD_PARAMS(0x800000002)
+E_RB_WRONG_UPI_VER(0x80000011):not used
+E_RB_WRONG_UPI_UPDATE(0x80000012): not used
+E_RB_UPDATE_SECTOR_SIG(0x80000013): not used
+
+<Failed Firmware Update Package Validation>
+Failure to positively validate digital signature of firmware update package
+E_RB_NON_DP_FORMAT_NOT_SUPPORTED(0x8001001A)
+E_RB_INVALID_DP_HEADER(0x80010025)
+E_RB_INVALID_DP_WRONG_SIGNATURE(0x80010026)
+E_RB_INVALID_DP(0x80010027)
+
+<Firmware Update Package Not Acceptable>
+Firmware Update Package is Not Acceptable
+E_RB_PKG_TOO_SHORT(0x8000000B) not used
+E_RB_PKG_TOO_LONG(0x8000000C) not used
+E_RB_PKG_NOT_AUTHORIZED(0x8000000F)
+
+<Firmware update fails due to device out of memory>
+The update fails because there isn\A1\AFt sufficient memory to update the device.
+E_RB_NOT_ENOUGH_RAM(0x8000001E)
+*/
+/*-----------------------------------------------------------------------------
+  save_cause
+ ----------------------------------------------------------------------------*/
+void save_cause(int cause)
+{
+       char return_char[20];
+       FILE *result_fp;
+
+       LOG("%s entered, 0x%x\n", __func__, cause);
+
+       print_error_cause(cause);
+
+       if ((result_fp = fopen(fota_cause, "w")) == NULL) {
+               LOG("cause file open fail\n");
+               return;
+       }
+
+       snprintf(return_char, sizeof(return_char), "%x", cause);
+       fwrite(return_char, strlen(return_char), 1, result_fp);
+       fclose(result_fp);
+
+       if (s_initrd_version == 0) {
+               if ((result_fp = fopen("/opt/data/fota/cause", "w")) == NULL) {
+                       LOG("cause file open fail\n");
+                       return;
+               }
+
+               snprintf(return_char, sizeof(return_char), "%x", cause);
+               fwrite(return_char, strlen(return_char), 1, result_fp);
+               fclose(result_fp);
+       }
+
+       LOG("%s leaved!\n", __func__);
+}
+
+/*-----------------------------------------------------------------------------
+  save_result
+ ----------------------------------------------------------------------------*/
+void save_result(int result)
+{
+       char return_char[20];
+       FILE *result_fp;
+
+       LOG("%s entered, result=0x%x\n", __func__, result);
+
+       if ((result_fp = fopen(fota_result, "w")) == NULL) {
+               LOG("result file open fail\n");
+               return;
+       }
+
+       snprintf(return_char, sizeof(return_char), "%x", result);
+       fwrite(return_char, strlen(return_char), 1, result_fp);
+       fclose(result_fp);
+
+       if (s_initrd_version == 0) {
+               if ((result_fp = fopen("/opt/data/fota/result", "w")) == NULL) {
+                       LOG("result file open fail\n");
+                       return;
+               }
+
+               snprintf(return_char, sizeof(return_char), "%x", result);
+               fwrite(return_char, strlen(return_char), 1, result_fp);
+               fclose(result_fp);
+       }
+
+       LOG("%s leaved!\n", __func__);
+
+       return;
+}
+
+/*-----------------------------------------------------------------------------
+  fota_path_init
+ ----------------------------------------------------------------------------*/
+int fota_path_init(void)
+{
+       int i;
+       int ret;
+
+       if (strlen(delta_folder) > MAX_FILE_PATH - 15) {
+               LOG("FOTA path is too long\n");
+               return FAIL;
+       }
+
+       for(i = 0; i < s_part_num; i++) {
+               s_update_data[i].ua_delta_path = malloc(MAX_FILE_PATH);
+               snprintf(s_update_data[i].ua_delta_path, MAX_FILE_PATH, "%s/%s", delta_folder, DEFAULT_DELTA_NAME);
+               //s_update_data[i].ua_temp_path = malloc(MAX_FILE_PATH);
+               //sprintf(s_update_data[i].ua_temp_path, "%s/fota_temp_%s", delta_folder, s_part_info[i].ua_parti_name);
+       }
+
+       snprintf(fota_result, sizeof(fota_result), "%s/%s", result_folder, "result");
+       snprintf(fota_cause, sizeof(fota_cause), "%s/%s", result_folder, "cause");
+       snprintf(fota_status_path, sizeof(fota_status_path), "%s/%s", result_folder, UP_STATUS_FILE);
+
+       if (s_initrd_version == 0) {
+               ret = mkdir("/opt/data/fota", S_IRUSR | S_IWUSR | S_IXUSR |
+                       S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
+               if (ret == 0 || ((ret == -1) && (errno == EEXIST))) {
+                       LOG("mkdir(/opt/data/fota) ok\n");
+               } else {
+                       LOG("mkdir(/opt/data/fota) fail\n");
+               }
+       }
+
+       for(i = 0; i < s_part_num; i++) {
+               LOG("s_part_info[UA_%s].ua_delta_path=%s\n",
+                       s_part_info[i].ua_parti_name,
+                       s_update_data[i].ua_delta_path);
+       }
+
+       return SUCCESS;
+}
+
+/*-----------------------------------------------------------------------------
+  fota_path_deinit
+ ----------------------------------------------------------------------------*/
+void fota_path_deinit(void)
+{
+       int i;
+       for(i = 0; i < s_part_num; i++) {
+               if(s_update_data[i].ua_delta_path) {
+                       free(s_update_data[i].ua_delta_path);
+                       s_update_data[i].ua_delta_path = NULL;
+               }
+               if(s_update_data[i].ua_temp_path) {
+                       free(s_update_data[i].ua_temp_path);
+                       s_update_data[i].ua_temp_path = NULL;
+               }
+       }
+}
+
+/*-----------------------------------------------------------------------------
+  check_ua_op_mode
+ ----------------------------------------------------------------------------*/
+int check_ua_op_mode(int argc, char **argv)
+{
+       if (argc == 3) {
+               ua_op_mode = UA_OP_MODE_FG;
+               return 0;
+       } else if (argc == 4) {
+               if (argv[3][0] == '0') {
+                       ua_op_mode = UA_OP_MODE_FG;
+                       return 0;
+               } else if (argv[3][0] == '1') {
+                       ua_op_mode = UA_OP_MODE_BG;
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+/*-----------------------------------------------------------------------------
+  remove_temp_files
+ ----------------------------------------------------------------------------*/
+void remove_temp_files(void)
+{
+       int ret = 0;
+       int i;
+       char *ua_temp_path;
+       struct stat sbuf;
+
+       for(i = 0; i < s_part_num; i++) {
+               ua_temp_path = s_update_data[i].ua_temp_path;
+               if (NULL == ua_temp_path)
+                       continue;
+
+               ret = lstat(ua_temp_path, &sbuf);
+               if (ret < 0) {
+                       ret = stat(ua_temp_path, &sbuf);
+                       if (ret < 0) {
+                               LOG("stat failed with return value: %d errno: %d\n", ret, errno);
+                               continue;
+                       }
+               }
+
+               if (S_ISDIR(sbuf.st_mode)) {
+                       ret = rmdir(ua_temp_path);
+                       if (ret < 0) {
+                               LOG("rmdir(%s) failed with return value: %d errno: %d\n", ua_temp_path, ret, errno);
+                       }
+               } else {
+                       ret = unlink(ua_temp_path);
+                       if (ret < 0) {
+                               LOG("unlink(%s) failed with return value: %d errno: %d\n", ua_temp_path, ret, errno);
+                       }
+               }
+       }
+}
+
+/*-----------------------------------------------------------------------------
+  get_update_type
+ ----------------------------------------------------------------------------*/
+int get_update_type(char* part_name)
+{
+       if (strcmp(part_name, "FULL_IMG") == 0)
+               return FULL_IMG;
+       if (strcmp(part_name, "DELTA_IMG") == 0)
+               return DELTA_IMG;
+       if (strcmp(part_name, "DELTA_FS") == 0)
+               return DELTA_FS;
+
+       return EXTRA;
+}
+
+/*-----------------------------------------------------------------------------
+  get_part_idx
+ ----------------------------------------------------------------------------*/
+int get_part_idx(char* part_name)
+{
+       int i;
+
+       for(i = UA_PARTI_START; i < UA_PARTI_MAX; i++) {
+               if (strcmp(part_name, def_part_info[i].ua_parti_name) == 0) {
+                       return i;
+               }
+       }
+
+       return UA_PARTI_MAX;
+}
+
+/*-----------------------------------------------------------------------------
+  fota_blkid_update
+ ----------------------------------------------------------------------------*/
+int fota_blkid_update(void)
+{
+       char part_tbl_path[MAX_FILE_PATH];
+       FILE *fp;
+       int num_part;
+       int i, j;
+       int id;
+       char part_name[256];
+       char blk_name[256];
+
+       memset((void*)part_tbl_path, 0x00, sizeof(part_tbl_path));
+       snprintf(part_tbl_path, sizeof(part_tbl_path)-1, "%s/%s", temp_folder, PART_TBL_FILE);
+
+       fp = fopen(part_tbl_path, "r");
+       if (fp == NULL) {
+               LOG("fail to open partition table\n");
+               return 1;
+       }
+
+       if ((fscanf(fp, "%d", &num_part)<0)||(num_part<=0)||(num_part>=MAX_PART_TBL_ITEM)) {
+               LOG("fail to fscanf() or num_part is 0\n");
+               fclose(fp);
+               return -1;
+       }
+       for (i=0; i<num_part; i++) {
+               if (fscanf(fp, "%d %32s", &id, part_name) < 0) {
+                       LOG("fail to fscanf()\n");
+                       break;
+               }
+               LOG("%s [%d]\n", part_name, id);
+               for(j = 0; j < s_part_num; j++) {
+                       if (strcmp(s_part_info[j].ua_parti_name, part_name) == 0) {
+                               memset((void*)blk_name, 0x00, sizeof(blk_name));
+                               snprintf(blk_name, sizeof(blk_name)-1, "/dev/mmcblk0p%d", id);
+                               s_part_info[j].ua_blk_name = strdup(blk_name);
+                       }
+               }
+       }
+
+       fclose(fp);
+
+       return 0;
+}
+
+/*-----------------------------------------------------------------------------
+  fota_configure_update
+ ----------------------------------------------------------------------------*/
+int fota_configure_update(void)
+{
+       char cfg_data[MAX_CFG_LEN];
+       int data_size = -1;
+       char* line = NULL;
+       char* field = NULL;
+       char* ctx1 = NULL;
+       char* ctx2 = NULL;
+       int line_num = 0;
+       int field_num = 0;
+       char* part_name = NULL;
+       char* subj_name = NULL;
+       int update_type = EXTRA;
+       int part_idx = UA_PARTI_MAX;
+       char *blk_name = NULL;
+       int blk_offset = 0;
+       int src_img_size=0;
+       int trg_img_size=0;
+       char *src_img_sha1=NULL;
+       char *trg_img_sha1=NULL;
+       memset((void*)cfg_data, 0x00, sizeof(cfg_data));
+
+       data_size = tar_get_cfg_data(delta_path, UPDATTE_CFG_FILE, cfg_data, MAX_CFG_LEN);
+       if (data_size <= 0) {
+               LOG("tar_get_cfg_data() fail\n");
+               return -1;
+       }
+
+       line_num = 0;
+       line = strtok_r(cfg_data, "\n", &ctx1);
+       while (line) {
+               part_name = NULL;
+               subj_name = NULL;
+               update_type = EXTRA;
+               part_idx = UA_PARTI_MAX;
+               blk_name = NULL;
+               blk_offset = 0;
+               src_img_size=0;
+               trg_img_size=0;
+               src_img_sha1=NULL;
+               trg_img_sha1=NULL;
+
+               field_num = 0;
+               field = strtok_r(line, "\t", &ctx2);
+               while (field) {
+                       switch (field_num) {
+                               case 0:
+                                       part_name = strdup(field);
+                                       part_idx = get_part_idx(field);
+                                       break;
+                               case 1:
+                                       subj_name = strdup(field);
+                                       break;
+                               case 2:
+                                       update_type = get_update_type(field);
+                                       break;
+                               case 3:
+                                       blk_name = strdup(field);
+                                       break;
+                               case 4:
+                                       blk_offset = atoi(field);
+                                       break;
+                               case 5:
+                                       src_img_size=atoi(field);
+                                       break;
+                               case 6:
+                                       trg_img_size=atoi(field);
+                                       break;
+                               case 7:
+                                       src_img_sha1=strdup(field);
+                                       break;
+                               case 8:
+                                       trg_img_sha1=strdup(field);
+                                       break;
+                       }
+                       field_num++;
+                       LOG("%s,", field);
+                       field = strtok_r(NULL, "\t", &ctx2);
+               }
+               LOG("\n");
+if(!part_name)
+       return -1;
+               if (update_type != EXTRA
+#ifdef SS_RECOVERYRAMDISK
+               || (0==strcmp(part_name, "RAMDISK2"))
+#endif
+) {
+                       s_part_info[line_num].ua_parti_name = part_name;
+                       s_part_info[line_num].ua_subject_name = subj_name;
+                       s_part_info[line_num].ua_blk_name = blk_name;
+                       s_part_info[line_num].ua_blk_offset = blk_offset;
+
+                       s_update_cfg[line_num].update_type = update_type;
+                       s_update_cfg[line_num].part_idx = part_idx;
+               s_update_cfg[line_num].soure_img_size= src_img_size;
+               s_update_cfg[line_num].target_img_size= trg_img_size;
+               s_update_cfg[line_num].soure_sha1=src_img_sha1;
+               s_update_cfg[line_num].target_sha1=trg_img_sha1;
+
+                       line_num++;
+               } else {
+                       if (part_name)  free(part_name);
+                       if (subj_name)  free(subj_name);
+                       if (blk_name)   free(blk_name);
+               }
+               line = strtok_r(NULL, "\n", &ctx1);
+       }
+
+       LOG("Effective cfg line num = %d\n", line_num);
+
+       return line_num;
+}
+
+/*-----------------------------------------------------------------------------
+  main
+
+  argv[1] : directory path for delta file
+  argv[2] : directory path for log file, result file, temp file
+  argv[3] : operation mode ("0" or none : Foreground Mode, "1" : Background Mode)
+ ----------------------------------------------------------------------------*/
+int main(int argc, char **argv)
+{
+       char ver_str[MAX_PATH];
+       int ret = FAIL;
+
+       _init_stdio();
+
+       /* check whether FG mode or BG mode */
+       if (check_ua_op_mode(argc, argv) < 0) {
+               ret = UPI_INVALID_PARAM_ERROR;
+               goto Results;
+       }
+
+       if (strcmp(argv[1], "/system") == 0) {
+               s_initrd_version = 0;
+       }
+
+       if (s_initrd_version == 0) {
+               memset(delta_folder, 0x00, sizeof(delta_folder));
+               snprintf(delta_folder, sizeof(delta_folder)-1, "%s", argv[2]);
+               snprintf(delta_path, sizeof(delta_path), "%s/%s", delta_folder, DEFAULT_DELTA_NAME);
+
+               memset(temp_folder, 0x00, sizeof(temp_folder));
+               snprintf(temp_folder, sizeof(temp_folder)-1, "%s", delta_folder);
+       } else {
+               memset(delta_folder, 0x00, sizeof(delta_folder));
+               snprintf(delta_folder, sizeof(delta_folder)-1, "%s", argv[1]);
+               snprintf(delta_path, sizeof(delta_path), "%s/%s", delta_folder, DEFAULT_DELTA_NAME);
+
+               memset(temp_folder, 0x00, sizeof(temp_folder));
+               snprintf(temp_folder, sizeof(temp_folder)-1, "%s", argv[2]);
+       }
+
+       memset(log_folder, 0x00, sizeof(log_folder));
+       snprintf(log_folder, sizeof(log_folder)-1, "%s", temp_folder);
+
+       memset(result_folder, 0x00, sizeof(result_folder));
+       snprintf(result_folder, sizeof(result_folder)-1, "%s", temp_folder);
+
+       _launch_fota_gui_process();
+
+       log_init();
+       fota_cfg_str_load();
+
+       /* Check fota folder path */
+       if(check_existence(delta_folder) == 0) {
+               ret = UPI_DELTA_PATH_ERROR;
+               goto Results;
+       }
+
+       /* load update configuration */
+       ret = fota_configure_update();
+       if (ret > 0) {
+               s_part_num = ret;
+       } else {
+               LOG("Update Configuration fail. Use default.\n");
+               memcpy(s_part_info, def_part_info, sizeof(s_part_info));
+               memcpy(s_update_cfg, def_update_cfg, sizeof(s_update_cfg));
+               s_part_num = UA_PARTI_MAX;
+       }
+
+       /* load block device number at run-time */
+       ret = fota_blkid_update();
+       if (ret < 0) {
+               LOG("fota_blkid_update() fail\n");
+               ret = UPI_PARTINFO_ERROR;
+               goto Results;
+       }
+
+       ret = fota_path_init();
+       if (ret == FAIL) {
+               ret = UPI_DELTA_PATH_LENGTH_ERROR;
+               goto Results;
+       }
+
+       LOG("<<<<<<<<<<< log_init >>>>>>>>>>>>\n");
+
+       /* UPI version check */
+
+       if(S_SS_SUCCESS == SS_GetUPIVersion((unsigned char*)ver_str)) {
+               LOG("<<<<<<<<< TOTA Update Agent %s >>>>>>>>>>>>\n", ver_str);
+       } else {
+               LOG("[SS_GetUPIVersion fail] \n");
+               ret = UPI_VERSION_ERROR;
+               goto Results;
+       }
+
+       /* Main Update Routine : Scout & Update */
+       ret = update_all();
+       LOG("[update_all ret=%d]\n", ret);
+
+ Results:
+       LOG("Result=%d\n", ret);
+       save_result(ret);
+       remove_last_update_status();
+       //remove_temp_files(); //TOTA
+
+       switch (ret) {
+       /* GUI not initialized */
+       case UPI_INVALID_PARAM_ERROR:
+       case UPI_DELTA_PATH_ERROR:
+               log_deinit();
+               _exit_stdio();
+               return -1;
+       case UPI_GUI_INIT_ERROR:
+               fota_path_deinit();
+               log_deinit();
+               _exit_stdio();
+               return -1;
+       /* GUI initialized */
+       case UPI_VERSION_ERROR:
+       case UPI_DELTACOUNT_ERROR:
+
+       case UPI_BOOT_VERIFY_ERROR:
+       case UPI_SBOOT_VERIFY_ERROR:
+       case UPI_FIXNV2_VERIFY_ERROR:
+       case UPI_PARAM_VERIFY_ERROR:
+       case UPI_ROOTFS_VERIFY_ERROR:
+       case UPI_CSC_VERIFY_ERROR:
+       case UPI_KERNEL_VERIFY_ERROR:
+       case UPI_MODULE_VERIFY_ERROR:
+       case UPI_MODEM_VERIFY_ERROR:
+       case UPI_DSP_VERIFY_ERROR:
+       case UPI_WCNMODEM_VERIFY_ERROR:
+       case UPI_RAMDISK1_VERIFY_ERROR:
+       case UPI_SYSDATA_VERIFY_ERROR:
+       case UPI_USER_VERIFY_ERROR:
+
+       case UPI_BOOT_UPDATE_ERROR:
+       case UPI_SBOOT_UPDATE_ERROR:
+       case UPI_FIXNV2_UPDATE_ERROR:
+       case UPI_PARAM_UPDATE_ERROR:
+       case UPI_ROOTFS_UPDATE_ERROR:
+       case UPI_CSC_UPDATE_ERROR:
+       case UPI_KERNEL_UPDATE_ERROR:
+       case UPI_MODULE_UPDATE_ERROR:
+       case UPI_MODEM_UPDATE_ERROR:
+       case UPI_DSP_UPDATE_ERROR:
+       case UPI_WCNMODEM_UPDATE_ERROR:
+       case UPI_RAMDISK1_UPDATE_ERROR:
+       case UPI_SYSDATA_UPDATE_ERROR:
+       case UPI_USER_UPDATE_ERROR:
+
+               sleep(1);
+               fota_gui_update_end();
+               fota_path_deinit();
+               log_deinit();
+               _exit_stdio();
+               return -1;
+       case SUCCESS:
+               sleep(1);
+               fota_gui_update_end();
+               fota_path_deinit();
+               log_deinit();
+               _exit_stdio();
+               unlink(delta_path);
+               return 0;
+       default:
+               LOG("!!! Not expected ret (= %d)\n", ret);
+       }
+
+       _exit_stdio();
+       return -1;
+}
diff --git a/src/rpi3/ua.h b/src/rpi3/ua.h
new file mode 100644 (file)
index 0000000..a2870d8
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 __UA_H__
+#define __UA_H__
+
+#include <stdio.h>
+
+/*
+ * FEATURE
+ */
+
+//#define USE_POST_UPDATE
+//#define USE_DELTA_DOWNLOAD
+//#define USE_DUALSBL
+
+#define BOOT_PATH "/boot"
+#define LOG_FILE_PATH "/last_update.log"
+#define MAX_FILE_PATH           512
+#define MAX_PART_NAME           32
+
+#define PART_TBL_FILE "part_tbl.txt"
+#define MAX_PART_TBL_ITEM              50
+
+/*
+ * FOTA Adaptaion header
+ */
+
+#define ERROR -1 // 0XFFFFFFFF
+
+#define INVALID    0
+#define VALID      1
+#define TRUE 1
+#define FALSE 0
+#define OK 0
+#define SUCCESS 0
+#define FAIL 1
+#define RESTORING 2
+
+#define UPI_DELTA_PATH_ERROR                   0xFDAA
+#define UPI_DELTA_PATH_LENGTH_ERROR    0xFDAB
+
+#define UPI_GUI_INIT_ERROR                             0xFDBA
+#define UPI_VERSION_ERROR                              0xFDBB
+
+#define UPI_BOOT_VERIFY_ERROR                  0xFDC1
+#define UPI_SBOOT_VERIFY_ERROR         0xFDC2
+#define UPI_FIXNV2_VERIFY_ERROR                0xFDC3
+#define UPI_PARAM_VERIFY_ERROR         0xFDC6
+#define UPI_ROOTFS_VERIFY_ERROR                0xFDC7
+#define UPI_CSC_VERIFY_ERROR                   0xFDC8
+#define UPI_KERNEL_VERIFY_ERROR                0xFDC9
+#define UPI_MODULE_VERIFY_ERROR                0xFDCA
+#define UPI_MODEM_VERIFY_ERROR         0xFDCB
+#define UPI_DSP_VERIFY_ERROR                   0xFDCC
+#define UPI_WCNMODEM_VERIFY_ERROR              0xFDCD
+#define UPI_RAMDISK1_VERIFY_ERROR              0xFDCE
+#define UPI_SYSDATA_VERIFY_ERROR               0xFDCF
+#define UPI_USER_VERIFY_ERROR          0xFDD0
+
+#define UPI_BOOT_UPDATE_ERROR                  0xFDD1
+#define UPI_SBOOT_UPDATE_ERROR         0xFDD2
+#define UPI_FIXNV2_UPDATE_ERROR                0xFDD3
+#define UPI_PARAM_UPDATE_ERROR         0xFDD6
+#define UPI_ROOTFS_UPDATE_ERROR                0xFDD7
+#define UPI_CSC_UPDATE_ERROR                   0xFDD8
+#define UPI_KERNEL_UPDATE_ERROR                0xFDD9
+#define UPI_MODULE_UPDATE_ERROR                0xFDDA
+#define UPI_MODEM_UPDATE_ERROR         0xFDDB
+#define UPI_DSP_UPDATE_ERROR                   0xFDDC
+#define UPI_WCNMODEM_UPDATE_ERROR              0xFDDD
+#define UPI_RAMDISK1_UPDATE_ERROR              0xFDDE
+#define UPI_SYSDATA_UPDATE_ERROR               0xFDDF
+#define UPI_USER_UPDATE_ERROR          0xFDE0
+
+#define UPI_INVALID_PARAM_ERROR                0xFDEA
+#define UPI_STATUSFLAG_ERROR                   0xFDEB
+#define UPI_DELTACOUNT_ERROR                   0xFDEC
+#define UPI_PARTINFO_ERROR                             0xFDED
+
+/* UPI_NO_DELTA_ERROR and UPI_NO_UA_ERROR may be set by ua launching script */
+#define UPI_NO_DELTA_ERROR                     0xFDFA
+#define UPI_NO_UA_ERROR                        0xFDFB
+
+#define TEMP_SIZE          0x40000
+
+#define DEFAULT_DELTA_NAME             "delta.tar"
+#define UPDATTE_CFG_FILE               "update.cfg"
+
+#define UI_OP_SCOUT_UPDATE             0
+#define UI_OP_SCOUT                    1
+#define UI_OP_UPDATE                   3
+#define SS_RECOVERYRAMDISK
+enum {
+       UA_OP_MODE_FG = 0,
+       UA_OP_MODE_BG
+};
+
+typedef enum {
+       UA_KERNEL = 0,
+       UA_ROOTFS,
+       UA_SYSDATA,
+       UA_USER,
+       UA_MODULE,
+       UA_PARTI_MAX
+} UA_PART_IDX;
+#define UA_PARTI_START 0
+
+#define UP_STATUS_FILE         "UP.STATUS"
+typedef enum {
+       UP_START_NONE = 0,
+       UP_START_KERNEL,
+       UP_START_ROOTFS,
+       UP_START_SYSDATA,
+       UP_START_USER,
+       UP_START_MODULE,
+       UP_START_MAX
+} UP_STATUS;
+
+typedef enum {
+       FULL_IMG,
+       DELTA_IMG,
+       DELTA_FS,
+       EXTRA
+} UA_DATA_FORMAT;
+
+typedef enum{
+       UA_MODE_SCOUT_UPDATE,
+       UA_MODE_SCOUT,
+       UA_MODE_VERIFYTARGET,
+       UA_MODE_UPDATE,
+       UA_MODE_SUPPLYIMFOM=200
+} UA_OPERATION_MODE;
+
+typedef struct _ua_update_data_t {
+       unsigned int exist_check;
+       unsigned int verify_check;
+       unsigned int update_check;
+       unsigned int weight; // the sum of weight should be 100
+       unsigned int weight_offset; // start offset
+       unsigned int data_size; // byte
+       char *ua_delta_path; // it will be allocated to copy delta file path, need to free memory
+       char *ua_temp_path; // it will be allocated to copy delta file path, need to free memory
+} ua_update_data_t;
+
+typedef struct _ua_update_cfg_t {
+       unsigned int update_type;
+       unsigned int part_idx;
+       int skip_verify;
+       int skip_update;
+       int soure_img_size;//TOTA
+       int target_img_size;
+       char *soure_sha1;
+       char *target_sha1;
+} ua_update_cfg_t;
+
+typedef struct _ua_part_info_t {
+       char *ua_parti_name;
+       char *ua_subject_name;
+       char *ua_blk_name;
+       int  ua_blk_offset;
+} ua_part_info_t;
+
+// User data structure
+typedef struct _ua_data_t {    // partition operations
+       ua_part_info_t *parti_info;
+       ua_update_cfg_t *update_cfg;
+       ua_update_data_t *update_data;
+       unsigned long ua_operation;
+
+       int (*ua_op_read_block)(void *, unsigned char*, unsigned long, unsigned long);
+       int (*ua_op_write_block)(void *, unsigned char*, unsigned long);
+       void (*ui_progress)(void *, unsigned long);
+} ua_data_t;
+
+
+typedef struct _ua_delta_info_t {
+       char ua_patch_path[MAX_FILE_PATH];
+       char ua_patch_info[MAX_FILE_PATH];
+       char ua_delta_path[MAX_FILE_PATH];
+       char ua_attrib_path[MAX_FILE_PATH];
+} ua_delta_info_t;
+
+
+typedef struct _ua_dataSS_t {  // partition operations
+       ua_part_info_t *parti_info;
+       ua_update_cfg_t *update_cfg;
+       ua_update_data_t *update_data;
+       ua_delta_info_t *update_delta;
+       unsigned long ua_operation;
+       void (*ui_progress)(void *, unsigned long);
+       int (*write_data_to_blkdev)(char* , int , int , char* );
+} ua_dataSS_t;
+void log_deinit(void);
+#endif
diff --git a/ss_engine/SS_FSUpdate.c b/ss_engine/SS_FSUpdate.c
new file mode 100755 (executable)
index 0000000..cb03e4c
--- /dev/null
@@ -0,0 +1,1244 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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 _XOPEN_SOURCE 500
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/smack.h>
+#include <sys/wait.h>
+
+#include <ftw.h>
+#include <sys/xattr.h>
+#include "SS_Common.h"
+
+#include "fota_common.h"
+#include "ua.h"
+
+/************************************************************
+ *                     common functions
+ ************************************************************/
+void SS_create_dir(char *pathname, int mode)
+{
+    char *p;
+    int r;
+
+    /* Strip trailing '/' */
+    if (pathname[strlen(pathname) - 1] == '/')
+        pathname[strlen(pathname) - 1] = '\0';
+
+    /* Try creating the directory. */
+    r = mkdir(pathname, mode);
+
+    if (r != 0) {
+        /* On failure, try creating parent directory. */
+        p = strrchr(pathname, '/');
+        if (p != NULL) {
+            *p = '\0';
+            SS_create_dir(pathname, 0755);
+            *p = '/';
+            r = mkdir(pathname, mode);
+        }
+    }
+    if (r != 0) {
+        if (r != EEXIST && r != -1)
+            LOG("Could not create directory [%s] Error[%d]\n", pathname, r);
+    }
+}
+
+
+void SS_unicode_to_char(const char *src, char *dest)
+{
+       if (src == NULL) {
+               return;
+       }
+
+       strcpy(dest, src);
+}
+
+void SS_char_to_unicode(const char *src, char *dest)
+{
+       if (src == NULL) {
+               return;
+       }
+
+       strcpy(dest, src);
+}
+
+long SS_recursive_folder_creater(const char *path, const mode_t mode)
+{
+       int ret = 0;
+       int offset = 0;
+       char temppath[MAX_PATH] = { '\0' };
+
+       LOGL(LOG_SSENGINE, "path: %s\n", path);
+
+       if ((offset = strlen(path)) == 0) // For counting back until the '/' delimiter
+               return -1;      //if from some reason we got to the end return error!!!.
+
+       while (path[offset] != '/')     // get to the next '/' place
+               offset--;
+
+       strncpy(temppath, path, offset);        // copy one depth below till and without the char '/'
+       LOGL(LOG_SSENGINE, " temppath: %s\n", temppath);
+       ret = mkdir(temppath, mode);
+       LOGL(LOG_SSENGINE, " mkdir result: %d errno: %d\n", ret, errno);
+
+       if (ret == 0 || ((ret == -1) && (errno == EEXIST))) {
+               return 0;       //meaning the depth creation is success.
+       } else if ((ret == -1) && (errno == ENOENT)) {
+               if ((ret = SS_recursive_folder_creater(temppath, mode)) == 0);
+                       ret = mkdir(temppath, mode);
+               return ret;
+       } else {
+               return -1;
+       }
+}
+
+long
+SS_CopyFile(void *pbUserData,
+           const char *strFromPath, const char *strToPath)
+{
+       int fd1, fd2;
+       int readCount = 0, writeCount = 0;
+       char buf[1 << 15];      // copy 32KB wise
+       int ret = 0;
+
+       char path1[MAX_PATH] = { '\0' };
+       char path2[MAX_PATH] = { '\0' };
+
+       if (!strFromPath || !strToPath) {
+               LOGE("NULL file name find. Abort.\n");
+               return -1;
+       }
+
+       SS_unicode_to_char((const char *)strFromPath, (char *)path1);
+       SS_unicode_to_char((const char *)strToPath, (char *)path2);
+
+       //LOGL(LOG_SSENGINE, "%s -> %s \n", path1, path2);
+
+       fd1 = open(path1, O_RDONLY);
+       if (fd1 < 0)
+               return E_SS_OPENFILE_ONLYR;
+       ret = SS_OpenFile(pbUserData, strToPath, ONLY_W, (long *)&fd2);
+       if (ret != S_SS_SUCCESS || fd2 < 0) {
+               close(fd1);
+               LOGE(" SS_OpenFile fail leaved path1:%s | path2:%s\n", path1, path1);
+               return E_SS_WRITE_ERROR;
+       }
+
+       while ((readCount = read(fd1, buf, sizeof(buf))) > 0) {
+               writeCount = write(fd2, buf, readCount);
+               if (writeCount != readCount) {
+                       LOGE(" read %d, but write %d, abort.\n", readCount,
+                            writeCount);
+                       ret = E_SS_WRITE_ERROR;
+                       break;
+               }
+       }
+
+       close(fd1);
+       fsync(fd2);
+       close(fd2);
+       //LOGL(LOG_INFO, " leaved path1:%s | path2:%s\n", path1, path2);
+
+       return ret;
+}
+
+long SS_DeleteFile(void *pbUserData, const char *strPath)
+{
+       char path[MAX_PATH] = { '\0' };
+       int ret = 0;
+
+       SS_unicode_to_char((const char *)strPath, (char *)path);
+       //LOGL(LOG_SSENGINE, "%s\n", path);
+       ret = unlink(path);
+       if (ret == 0)
+               return S_SS_SUCCESS;
+
+       LOGE("failed to delete path [%s] unlink value: %d, errno: %d\n", path, ret, errno);
+       if (ret < 0 && errno == ENOENT)
+               return S_SS_SUCCESS;
+       return E_SS_DELETEFILE;
+}
+
+int SS_unlink_cbf(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf)
+{
+       int rv = remove(fpath);//returns zero on success and -1 on failure
+
+       if (rv){
+               perror(fpath);
+               LOGE("path : %s, remove value: %d, errno: %d\n",fpath, rv, errno);
+       }
+       return rv;
+}
+long SS_DeleteFolder(void *pbUserData, const char *strPath)
+{
+       //runs till either tree is exhausted or when unlink_cbf returns non zero value.
+       return ((long)nftw(strPath, SS_unlink_cbf, 64, FTW_DEPTH | FTW_PHYS) == 0) ? S_SS_SUCCESS : E_SS_FAILURE;
+
+}
+
+long SS_DeleteFolderEmpty(void *pbUserData, const char *strPath)
+{
+
+       int ret = 0;
+       char path[MAX_PATH] = { '\0' };
+
+       SS_unicode_to_char((const char *)strPath, (char *)path);
+       //LOGL(LOG_REDBEND, "%s\n", path);
+       ret = rmdir(path);
+       if ((ret == 0)
+           || ((ret < 0) && ((errno == ENOENT) || (errno == ENOTEMPTY)))) {
+               LOGL(LOG_SSENGINE, "rmdir value: %d, errno: %d\n", ret, errno);
+               return S_SS_SUCCESS;
+       }
+       LOGE("rmdir value: %d, errno: %d\n", ret, errno);
+       return E_SS_FAILURE;
+}
+
+long SS_CreateFolder(void *pbUserData, const char *strPath)
+{
+       mode_t mode = 0;
+       int ret = 0;
+       char path[MAX_PATH] = { '\0' };
+
+       SS_unicode_to_char((const char *)strPath, (char *)path);
+       mode = S_IRUSR /*Read by owner */  |
+           S_IWUSR /*Write by owner */  |
+           S_IXUSR /*Execute by owner */  |
+           S_IRGRP /*Read by group */  |
+           S_IWGRP /*Write by group */  |
+           S_IXGRP /*Execute by group */  |
+           S_IROTH /*Read by others */  |
+           S_IWOTH /*Write by others */  |
+           S_IXOTH /*Execute by others */ ;
+
+       LOGL(LOG_SSENGINE, "%s, mode:0x%x\n", path, mode);
+
+       ret = mkdir(path, mode);
+
+       if (ret == 0 || ((ret == -1) && (errno == EEXIST))) {
+               return S_SS_SUCCESS;
+       } else if ((ret == -1) && (errno == ENOENT))    //maybe multi directory problem
+       {
+               //do//Recursive Function
+               //{
+               ret = SS_recursive_folder_creater(path, mode);
+               if (ret == S_SS_SUCCESS) {
+                       ret = mkdir(path, mode);        //After creating all the depth Directories we try to create the Original one again.
+                       if (ret == 0)
+                               return S_SS_SUCCESS;
+                       else
+                               return E_SS_FAILURE;
+               } else {
+                       return E_SS_FAILURE;
+               }
+               //}
+               //while(ret != 0);
+
+       } else {
+               return E_SS_FAILURE;
+       }
+}
+
+mode_t SS_get_mode(E_RW_TYPE wFlag)
+{
+       switch (wFlag) {
+       case ONLY_R:
+               //LOGL(LOG_SSENGINE, " RDONLY \n");
+               return O_RDONLY;
+       case ONLY_W:
+               //LOGL(LOG_SSENGINE, " WRONLY \n");
+               return O_WRONLY | O_CREAT;
+       case BOTH_RW:
+               //LOGL(LOG_SSENGINE, " RDWR \n");
+               return O_RDWR | O_CREAT;
+       default:
+               //LOGL(LOG_SSENGINE, " Unknown \n");
+               return 0;
+       }
+}
+
+long
+SS_OpenFile(void *pbUserData,
+           const char *strPath, E_RW_TYPE wFlag, long *pwHandle)
+{
+       mode_t mode;
+       char path[MAX_PATH] = { '\0' };
+
+       SS_unicode_to_char((const char *)strPath, (char *)path);
+
+       mode = SS_get_mode(wFlag);
+       //LOGL(LOG_SSENGINE, "Path:%s  wFlag:%d  Mode:%d\n", path, wFlag, mode);
+
+       if(mode & O_CREAT) {
+               //LOGL(LOG_SSENGINE, " open() S_IRWXU\n");
+               *pwHandle = open(path, mode, S_IRWXU);
+       } else {
+               //LOGL(LOG_SSENGINE, " open() %d\n", mode);
+               *pwHandle = open(path, mode);
+       }
+       if (*pwHandle == -1) {
+               *pwHandle = 0;
+               LOGE(" First open() with error %d\n", errno);
+               if (wFlag == ONLY_R) {
+                       LOGE(" error in ONLY_R return E_SS_OPENFILE_ONLYR\n");
+                       return E_SS_OPENFILE_ONLYR;
+               }
+
+               //if  we need to open the file for write or read/write then we need to create the folder (in case it does not exist)
+               if ((wFlag != ONLY_R) && (errno == ENOENT)) {
+                       char dir[MAX_PATH] = { '\0' };
+                       char dirShort[MAX_PATH] = { '\0' };
+                       int i = 0;
+                       //copy the full file path to directory path variable
+                       while (path[i] != '\0') {
+                               dir[i] = path[i];
+                               i++;
+                       }
+                       LOGL(LOG_SSENGINE, " copy dir[]=%s\n", dir);
+                       //search for the last '/' char
+                       while (dir[i--] != '/') ;
+                       dir[i + 1] = '\0';
+
+                       SS_char_to_unicode((const char *)dir,
+                                       (char *)dirShort);
+
+                       if (SS_CreateFolder(pbUserData, dirShort)) {
+                               LOGE(" Fail create folder, Leave SS_OpenFile\n");
+                               return E_SS_OPENFILE_WRITE;
+                       }
+
+                       *pwHandle = open(path, mode);
+                       if (*pwHandle == -1) {
+                               *pwHandle = 0;
+                               LOGE(" After successful creating folder, fail open() with error %d\n", errno);
+                               return E_SS_OPENFILE_WRITE;
+                       }
+               } else {
+                       LOG(" fail open() *pwHandle:%ld\n", *pwHandle);
+                       return E_SS_OPENFILE_WRITE;
+               }
+       }
+
+       //LOGL(LOG_SSENGINE, " Successful open() *pwHandle:%ld\n", *pwHandle);
+
+       return S_SS_SUCCESS;
+}
+
+long SS_ResizeFile(void *pbUserData, long wHandle, SS_UINT32 dwSize)
+{
+       int ret = 0;
+
+       LOGL(LOG_SSENGINE, "handle %ld, dwSize %d\n", wHandle, errno);
+
+       if (wHandle)
+               ret = ftruncate(wHandle, dwSize);
+       else
+               ret = E_SS_RESIZEFILE;
+
+       LOGL(LOG_SSENGINE, "ret %d handle %ld %d\n", ret, wHandle, errno);
+
+       return ret;
+}
+
+long SS_CloseFile(void *pbUserData, long wHandle)
+{
+       int ret = 0;
+       LOGL(LOG_SSENGINE, "wHandle = %ld\n", wHandle);
+
+       if (wHandle) {
+               ret = fsync(wHandle);
+               if (ret < 0) {
+                       LOG(" fsync Failed with return value: %d\n", ret);
+                       return E_SS_WRITE_ERROR;
+               }
+               LOG(" fsync after write: %d\n", ret);
+               ret = close(wHandle);
+       }
+
+       if (ret == 0)
+               return S_SS_SUCCESS;
+
+       return E_SS_CLOSEFILE_ERROR;
+}
+
+long
+SS_WriteFile(void *pbUserData,
+            long wHandle,
+            SS_UINT32 dwPosition,
+            unsigned char *pbBuffer, SS_UINT32 dwSize)
+{
+       int ret = 0;
+
+       LOGL(LOG_SSENGINE, "Handle:%ld , Pos:%u , Size: %u\n", wHandle,
+            dwPosition, dwSize);
+
+       ret = lseek(wHandle, dwPosition, SEEK_SET);
+       if (ret < 0) {
+               LOGE(" lseek failed with return value: %d\n", ret);
+               LOGL(LOG_SSENGINE, "lseek errno=%d\n", errno);
+               return E_SS_WRITE_ERROR;
+       }
+
+       ret = write(wHandle, pbBuffer, dwSize);
+       if (ret < 0 || ret != dwSize) {
+               LOGE(" Failed with return value: %d\n", ret);
+               LOGL(LOG_SSENGINE, "ret=%d, dwSize=%u write errno=%d\n",
+                       ret, (unsigned int)dwSize, errno);
+               return E_SS_WRITE_ERROR;
+       }
+       LOGL(LOG_SSENGINE, "leave Bytes Write: %d\n", ret);
+
+       return S_SS_SUCCESS;
+}
+
+long SS_MoveFile(void *pbUserData, const char *strFromPath,
+                const char *strToPath)
+{
+       int ret = 0;
+       struct stat sbuf;
+       char path1[MAX_PATH] = { '\0' };
+       char path2[MAX_PATH] = { '\0' };
+
+       if (!strFromPath || !strToPath) {
+               return -1;      //should never happen
+       }
+
+       SS_unicode_to_char(strFromPath, (char *)path1);
+       SS_unicode_to_char(strToPath, (char *)path2);
+
+       LOGL(LOG_INFO, "entered path1:%s | path2:%s\n", path1, path2);
+       ret = stat(path1, &sbuf);
+       if (ret < 0) {
+                       LOGE("stat failed with return value: %d errno: %d\n",  ret, errno);
+                       return E_SS_FAILURE;
+       }
+       ret = rename(path1, path2);
+       if (ret < 0) {
+               LOGL(LOG_INFO, "rename fail with code [%d], try to create dir if errno is 2\n", errno);
+               if (errno == 2) {
+                       char * file_name = strrchr(path2,'/');
+                       *file_name = '\0';
+                       SS_create_dir(path2,0755);
+                       *file_name = '/';
+                       ret = rename(path1, path2);
+                       if (ret < 0) {
+                               LOGE("Move failed, error code [%d]",errno);
+                               return E_SS_WRITE_ERROR;
+                               }
+               }
+               else if (errno == 18){ //EXDEV 18  /* Cross-device link */
+                       //Moving file across partitions if mount point is different (Extremely rare)
+                       ret = (int)SS_CopyFile(NULL, path1, path2);
+                       if (ret != S_SS_SUCCESS) {
+                               LOGE("failed to copy file [%s] result [%d]\n", path1, ret);
+                               return E_SS_WRITE_ERROR;
+                       }
+                       ret = unlink(path1);
+                       if (ret != 0) {
+                               LOGE("failed to unlink [%s] code [%d]\n", path1, errno);
+                               return E_SS_WRITE_ERROR;
+                       }
+               }
+               else{
+                       LOGE("Move failed, error code [%d]",errno);
+                       return E_SS_WRITE_ERROR;
+               }
+       }
+       LOGL(LOG_INFO, "leaved path1:%s | path2:%s\n", path1, path2);
+       return S_SS_SUCCESS;
+}
+long SS_SyncFile(void *pbUserData, long wHandle)
+{
+       return (-1 == fsync(wHandle)) ? E_SS_FAILURE : S_SS_SUCCESS;
+}
+
+long
+SS_ReadFile(void *pbUserData,
+           long wHandle,
+           SS_UINT32 dwPosition,
+           unsigned char *pbBuffer, SS_UINT32 dwSize)
+{
+       int ret = 0;
+
+#if 0
+       LOG(" %s: Handle:%ld , Pos:%u , Size: %u", __func__, wHandle,
+              dwPosition, dwSize);
+#endif
+       ret = lseek(wHandle, dwPosition, SEEK_SET);
+       if (ret < 0) {
+               LOGE("Handle:%ld , Pos:%u , Size: %u", wHandle, dwPosition,
+                    dwSize);
+               LOGE("lseek failed with return value: %d\n", ret);
+               return E_SS_READ_ERROR;
+       }
+       ret = read(wHandle, pbBuffer, dwSize);
+       if (ret < 0) {
+               LOGE("Handle:%ld , Pos:%u , Size: %u", wHandle, dwPosition,
+                    dwSize);
+               LOGE("read failed with return value: %d\n", ret);
+               return E_SS_READ_ERROR;
+       }
+
+       if (ret != dwSize && ((ret + dwPosition) != (unsigned long)SS_GetFileSize(pbUserData, wHandle)))
+               return E_SS_READ_ERROR;
+
+#if 0
+       LOGL(LOG_DEBUG, "Bytes Read: %d\n", ret);
+#endif
+       return S_SS_SUCCESS;
+}
+
+long SS_GetFileSize(void *pbUserData, long wHandle)
+{
+       int ret = 0;
+
+
+       ret = lseek(wHandle, 0, SEEK_END);
+
+       if (ret == -1) {
+               LOGE(" lseek errno: %d\n", errno);
+               return E_SS_READFILE_SIZE;
+       }
+       LOGL(LOG_SSENGINE, "handle=%d  Returning Size = %ld(0x%x)\n",
+               (int)wHandle, (long int)ret, ret);
+
+       return ret;
+}
+
+long SS_Unlink(void *pbUserData, char *pLinkName)
+{
+       int ret = 0;
+       char path[MAX_PATH] = { '\0' };
+       //enumFileType fileType = FT_REGULAR_FILE;
+
+
+       SS_unicode_to_char((const char *)pLinkName, (char *)path);
+
+       ret = unlink(path);
+       if (ret < 0 && errno != ENOENT) {
+               LOGE("unlink failed with return value: %d\n", ret);
+               return E_SS_FAILURE;
+       }
+       LOGL(LOG_SSENGINE, "unlink with return value: %d\n", ret);
+
+       return S_SS_SUCCESS;
+}
+
+long
+SS_VerifyLinkReference(void *pbUserData,
+                      char *pLinkName,
+                      char *pReferenceFileName)
+{
+       int ret = 0;
+       char path[MAX_PATH] = { '\0' };
+       char linkedpath[MAX_PATH] = { '\0' };
+       char refpath[MAX_PATH] = { '\0' };
+
+
+       SS_unicode_to_char((const char *)pLinkName, (char *)path);
+       SS_unicode_to_char((const char *)pReferenceFileName, (char *)refpath);
+
+       ret = readlink(path, linkedpath, MAX_PATH);
+       if (ret < 0) {
+               LOGE("readlink failed with return value: %d\n", ret);
+               return E_SS_FAILURE;
+       }
+
+       if ((memcmp(&linkedpath, &refpath, ret)) != 0) {
+               LOGE("not same linked path\n");
+               return E_SS_FAILURE;
+       }
+       LOGL(LOG_SSENGINE, "same linked path\n");
+
+       return S_SS_SUCCESS;
+}
+
+long
+SS_Link(void *pbUserData, char *pLinkName, char *pReferenceFileName)
+{
+       int ret = 0;
+       char sympath[MAX_PATH] = { '\0' };
+       char refpath[MAX_PATH] = { '\0' };
+       //enumFileType fileType = FT_SYMBOLIC_LINK;
+       struct stat sbuf;
+
+       SS_unicode_to_char((const char *)pLinkName, (char *)sympath);
+       SS_unicode_to_char((const char *)pReferenceFileName, (char *)refpath);
+
+       ret = symlink(refpath, sympath);
+       if (ret != 0) {
+               LOGE(" symlink failed with return value: %d, errno: %d\n", ret,errno);
+
+               if (errno == EEXIST) {
+                       ret = lstat(sympath, &sbuf);
+                       LOGL(LOG_SSENGINE, "symlink LSTAT with return value: %d\n", ret);
+                       if (ret >= 0) {
+                                       if (S_ISREG(sbuf.st_mode)) {
+                                       LOGL(LOG_SSENGINE, " stat->st_mode = regular file, To be deleted and create a LINK \n");
+                                       SS_DeleteFile(pbUserData,sympath);
+                                       SS_Link(pbUserData, pLinkName, pReferenceFileName);
+                                       }
+                               }
+                       if (SS_VerifyLinkReference(pbUserData, pLinkName
+                               , pReferenceFileName) == S_SS_SUCCESS) {
+                               return S_SS_SUCCESS;
+                       }
+                       else
+                               return E_SS_FAILURE;
+               }
+               else if(errno == ENOENT )//to handle cases where new symlink points to a new symlink yet to be created
+                       return errno;
+               else
+                       return E_SS_FAILURE;
+       }
+       //LOGL(LOG_SSENGINE, "symlink with return value: %d\n", ret);
+
+       return S_SS_SUCCESS;
+}
+
+long SS_GetFileType(void *pbUserData,
+                   char *pLinkName, enumFileType * fileType)
+{
+       int ret = 0;
+       char path[MAX_PATH] = { '\0' };
+       struct stat sbuf;
+
+       //LOGL(LOG_SSENGINE, "\n");
+       SS_unicode_to_char((const char *)pLinkName, (char *)path);
+
+       ret = lstat(path, &sbuf);
+       if (ret < 0) {
+               ret = stat(path, &sbuf);
+               if (ret < 0) {
+                       LOGE("stat failed with return value: %d errno: %d\n",
+                            ret, errno);
+                       *fileType = FT_MISSING;
+                       return S_SS_SUCCESS;
+               }
+       }
+       //LOGL(LOG_SSENGINE, " sbuf.st_mode: %d\n", sbuf.st_mode);
+       //LOGL(LOG_SSENGINE, " S_ISREG(sbuf.st_mode): %d\n", S_ISREG(sbuf.st_mode));
+       //LOGL(LOG_SSENGINE, " S_ISLNK(sbuf.st_mode): %d\n",  S_ISLNK(sbuf.st_mode));
+
+       if (S_ISLNK(sbuf.st_mode)) {
+               //LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n");
+               *fileType = FT_SYMBOLIC_LINK;
+               return S_SS_SUCCESS;
+       }
+
+       if (S_ISREG(sbuf.st_mode)) {
+               //LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n");
+               *fileType = FT_REGULAR_FILE;
+               return S_SS_SUCCESS;
+       }
+
+       if (S_ISDIR(sbuf.st_mode)) {
+               //LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n");
+               *fileType = FT_FOLDER;
+               return S_SS_SUCCESS;
+       }
+       LOGE("failed to lstat, err : %d\n", ret);
+       return E_SS_FAILURE;
+}
+
+char SS_a2ch(int value)
+{
+       char set_value = 0;
+
+       LOGL(LOG_SSENGINE, "%d\n", value);
+
+       switch (value) {
+       case '1':
+               set_value = 0x01;
+               break;
+       case '2':
+               set_value = 0x02;
+               break;
+       case '3':
+               set_value = 0x03;
+               break;
+       case '4':
+               set_value = 0x04;
+               break;
+       case '5':
+               set_value = 0x05;
+               break;
+       case '6':
+               set_value = 0x06;
+               break;
+       case '7':
+               set_value = 0x07;
+               break;
+       case '8':
+               set_value = 0x08;
+               break;
+       case '9':
+               set_value = 0x09;
+               break;
+       case '0':
+               set_value = 0x00;
+               break;
+       default:
+               LOGL(LOG_SSENGINE, "Wrong attribute value: %d\n", value);
+
+       }
+       LOGL(LOG_SSENGINE, "SS_a2ch : %c\n", set_value);
+
+       return set_value;
+}
+
+void SS_chtoa(int value, char *str)
+{
+       char *pStr = str;
+
+       LOGL(LOG_SSENGINE, "%d\n", value);
+
+       switch (value) {
+       case 1:
+               *pStr = '1';
+               break;
+       case 2:
+               *pStr = '2';
+               break;
+       case 3:
+               *pStr = '3';
+               break;
+       case 4:
+               *pStr = '4';
+               break;
+       case 5:
+               *pStr = '5';
+               break;
+       case 6:
+               *pStr = '6';
+               break;
+       case 7:
+               *pStr = '7';
+               break;
+       case 8:
+               *pStr = '8';
+               break;
+       case 9:
+               *pStr = '9';
+               break;
+       case 0:
+               *pStr = '0';
+               break;
+       default:
+               LOGL(LOG_SSENGINE, "Wrong attribute value: %d\n", value);
+       }
+}
+
+/*!
+ *******************************************************************************
+ * Set file attributes.<p>
+ *
+ * The file attributes token (\a ui8pAttribs) is defined at generation time.
+ * If attributes are not defined explicitly, they are given the following,
+ * OS-dependent values:
+ * \li Windows: _redbend_ro_ for R/O files, _redbend_rw_ for R/W files
+ * \li Linux: _redbend_oooooo:xxxx:yyyy indicating the file mode, uid, and gid
+ *             (uid and gid use capitalized hex digits as required)
+ *
+ * \param      pbUserData              Optional opaque data-structure to pass to IPL
+ *                                                     functions
+ * \param      ui16pFilePath   File path
+ * \param      ui32AttribSize  Size of \a ui8pAttribs
+ * \param      ui8pAttribs             Attributes to set
+ *
+ * \return     S_SS_SUCCESS on success or &lt; 0 on error
+ *******************************************************************************
+ */
+
+long SS_SetFileAttributes(const char *ui16pFilePath,
+                         const SS_UINT32 ui32AttribSize,
+                         const unsigned char *ui8pAttribs)
+{
+       static char tmpAttribs[512];
+       static char tmpSmackAttribs[512];
+       char *tp;
+       char *endstr;
+       char *smack_value, *psmack;
+       uid_t setUserID = 0;
+       gid_t setGroupID = 0;
+       mode_t setFileMode = 0;
+       const char attrDelim[2] = ":";
+
+       char setFilePath[MAX_PATH] = { '\0' };
+       struct stat sbuf;
+       int ret = 0;
+       char *smack_attr_pos = NULL;
+#if defined(FEATURE_SUPPORT_CAPABILITY)
+       int has_cap = 0;
+       char cap_raw[100];
+       int cap_len;
+       /*ACL */
+       int has_acl = 0;
+       char acl_raw[256];
+       int acl_len;
+
+#endif
+       if (NULL == ui16pFilePath) {
+               LOGL(LOG_SSENGINE, "ui16pFilePath NULL [error]\n");
+               return E_SS_BAD_PARAMS;
+       } else if (NULL == ui8pAttribs) {
+               LOGL(LOG_SSENGINE, "ui8pAttribs NULL [error]\n");
+               return E_SS_BAD_PARAMS;
+       } else if (0 == ui32AttribSize) {
+               LOGL(LOG_SSENGINE, "ui32AttribSize 0\n");
+               return S_SS_SUCCESS;
+       }
+
+       SS_unicode_to_char((const char *)ui16pFilePath, (char *)setFilePath);
+
+       ret = lstat(setFilePath, &sbuf);
+       if (ret < 0) {
+               ret = stat(setFilePath, &sbuf);
+               if (ret < 0) {
+                       LOGL(LOG_SSENGINE, " stat failed with return value: %d\n", ret);
+                       return E_SS_FAILURE;
+               } else {
+                               if (S_ISLNK(sbuf.st_mode)) {
+                                       LOGL(LOG_SSENGINE, " stat->st_mode = symbolic link file\n");
+//        return S_RB_SUCCESS; // sybolic link should be set mode.
+                               }
+                               if (S_ISREG(sbuf.st_mode)) {
+                                       LOGL(LOG_SSENGINE, " stat->st_mode = regular file\n");
+                               }
+                               if (S_ISDIR(sbuf.st_mode)) {
+                                       LOGL(LOG_SSENGINE, " stat->st_mode = directory\n");
+                               }
+               }
+
+               LOGL(LOG_SSENGINE, "ui16pFilePath = %s\n", setFilePath);
+               LOGL(LOG_SSENGINE, "ui32AttribSize = %u\n", ui32AttribSize);
+               LOGL(LOG_SSENGINE, "ui8pAttribs = %s\n", ui8pAttribs);
+
+       }
+       memset(tmpAttribs, 0x0, sizeof(tmpAttribs));
+       memcpy(tmpAttribs, ui8pAttribs, (size_t) ui32AttribSize-1);
+       smack_attr_pos = tmpAttribs;
+       tp = strtok(tmpAttribs, attrDelim);
+
+       // Get FileMode
+       if (tp != NULL) {
+               smack_attr_pos += strlen(tp);
+               smack_attr_pos++;
+               setFileMode = strtol(tp, &endstr, 8);
+               tp = strtok(NULL, attrDelim);
+       }
+       // Get UserID
+       if (tp != NULL) {
+               smack_attr_pos += strlen(tp);
+               smack_attr_pos++;
+               setUserID = (uid_t) strtol(tp, &endstr, 10);
+               tp = strtok(NULL, attrDelim);
+       }
+       // Get GroupID
+       if (tp != NULL) {
+               smack_attr_pos += strlen(tp);
+               smack_attr_pos++;
+               setGroupID = (gid_t) strtol(tp, &endstr, 10);
+       }
+#if defined(FEATURE_SUPPORT_CAPABILITY)
+       // Get Capability
+       has_cap = 0;
+       if (*smack_attr_pos != '\0') {
+               char *cap_mark = "capability=0x";
+               int cap_mark_len = strlen(cap_mark);
+               psmack = strstr(smack_attr_pos, cap_mark);
+               if(psmack) {
+                       int cap_hex_len;
+                       int i;
+                       char ch1, ch2;
+                       int raw1, raw2;
+
+                       tp = strstr(psmack, ":");
+                       smack_attr_pos = tp + 1;
+                       memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
+                       memcpy(tmpSmackAttribs, psmack+cap_mark_len,
+                               (int)tp - (int)psmack - cap_mark_len);
+
+                       // convert hexadecimal into raw data
+                       cap_hex_len = strlen(tmpSmackAttribs);
+                       cap_len = cap_hex_len/2;
+                       memset(cap_raw, 0x00, sizeof(cap_raw));
+                       for (i=0; i<cap_len; i++) {
+                               ch1 = tmpSmackAttribs[i*2];
+                               ch2 = tmpSmackAttribs[i*2+1];
+                               if ((ch1 >= '0')&&(ch1 <= '9'))         raw1 = ch1 - '0';
+                               else if ((ch1 >= 'a')&&(ch1 <= 'f'))            raw1 = ch1 - 'a' + 10;
+                               else if ((ch1 >= 'A')&&(ch1 <= 'F'))            raw1 = ch1 - 'A' + 10;
+                               else raw1 = 0;
+                               if ((ch2 >= '0')&&(ch2 <= '9'))         raw2 = ch2 - '0';
+                               else if ((ch2 >= 'a')&&(ch2 <= 'f'))            raw2 = ch2 - 'a' + 10;
+                               else if ((ch2 >= 'A')&&(ch2 <= 'F'))            raw2 = ch2 - 'A' + 10;
+                               else raw2 = 0;
+
+                               cap_raw[i] = raw1*16 + raw2;
+                       }
+                       LOGL(LOG_SSENGINE, "[Cap] %s (cap_len=%d)\n", tmpSmackAttribs, cap_len);
+                       has_cap = 1;
+               }
+
+       }
+       // Get ACL
+       has_acl = 0;
+       if (*smack_attr_pos != '\0') {
+               char *acl_mark = "acl_access=0x";
+               int acl_mark_len = strlen(acl_mark);
+               psmack = strstr(smack_attr_pos, acl_mark);
+               if(psmack) {
+                       int acl_hex_len;
+                       int i;
+                       char ch1, ch2;
+                       int raw1, raw2;
+
+                       tp = strstr(psmack, ":");
+                       smack_attr_pos = tp + 1;
+                       memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
+                       memcpy(tmpSmackAttribs, psmack+acl_mark_len,
+                               (int)tp - (int)psmack - acl_mark_len);
+
+                       // convert hexadecimal into raw data
+                       acl_hex_len = strlen(tmpSmackAttribs);
+                       acl_len = acl_hex_len/2;
+                       memset(acl_raw, 0x00, sizeof(acl_raw));
+                       for (i=0; i<acl_len; i++) {
+                               ch1 = tmpSmackAttribs[i*2];
+                               ch2 = tmpSmackAttribs[i*2+1];
+                               if ((ch1 >= '0')&&(ch1 <= '9'))         raw1 = ch1 - '0';
+                               else if ((ch1 >= 'a')&&(ch1 <= 'f'))            raw1 = ch1 - 'a' + 10;
+                               else if ((ch1 >= 'A')&&(ch1 <= 'F'))            raw1 = ch1 - 'A' + 10;
+                               else raw1 = 0;
+                               if ((ch2 >= '0')&&(ch2 <= '9'))         raw2 = ch2 - '0';
+                               else if ((ch2 >= 'a')&&(ch2 <= 'f'))            raw2 = ch2 - 'a' + 10;
+                               else if ((ch2 >= 'A')&&(ch2 <= 'F'))            raw2 = ch2 - 'A' + 10;
+                               else raw2 = 0;
+
+                               acl_raw[i] = raw1*16 + raw2;
+                       }
+                       LOG("[ACL] %s (acl_len=%d)\n", tmpSmackAttribs, acl_len);
+                       has_acl = 1;
+               }
+
+       }
+
+#endif
+       // Get Smack value -> Set Smack value
+       if (*smack_attr_pos != '\0') {
+               smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_ACCESS);
+               smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_EXEC);
+               smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_MMAP);
+               smack_lsetlabel(setFilePath, NULL, SMACK_LABEL_TRANSMUTE);
+
+               psmack = strstr(smack_attr_pos, "access=\"");
+               if(psmack) {
+                       memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
+                       memcpy(tmpSmackAttribs, psmack, strlen(psmack));
+                       smack_value = strtok(tmpSmackAttribs, "\"");
+                       if (smack_value) {
+                               smack_value = strtok(NULL, "\"");
+                               //LOGL(LOG_SSENGINE, "[SMACK_LABEL_ACCESS] smack_value=%s\n", smack_value);
+                               if(smack_value) {
+                                       ret = smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_ACCESS);
+                                       if (ret < 0)
+                                               LOGL(LOG_SSENGINE, "smack_lsetlabel() failed\n");
+                               }
+                       }
+               }
+               psmack = strstr(smack_attr_pos, "execute=\"");
+               if(psmack) {
+                       memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
+                       memcpy(tmpSmackAttribs, psmack, strlen(psmack));
+                       smack_value = strtok(tmpSmackAttribs, "\"");
+                       if (smack_value) {
+                               smack_value = strtok(NULL, "\"");
+                               //LOGL(LOG_SSENGINE, "[SMACK_LABEL_EXEC] smack_value=%s\n", smack_value);
+                               if(smack_value) {
+                                       ret = smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_EXEC);
+                                       if (ret < 0)
+                                               LOGL(LOG_SSENGINE, "smack_lsetlabel() failed\n");
+                               }
+                       }
+               }
+               psmack = strstr(smack_attr_pos, "mmap=\"");
+               if(psmack) {
+                       memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
+                       memcpy(tmpSmackAttribs, psmack, strlen(psmack));
+                       smack_value = strtok(tmpSmackAttribs, "\"");
+                       if (smack_value) {
+                               smack_value = strtok(NULL, "\"");
+                               //LOGL(LOG_SSENGINE, "[SMACK_LABEL_MMAP] smack_value=%s\n", smack_value);
+                               if(smack_value) {
+                                       ret = smack_lsetlabel(setFilePath, smack_value, SMACK_LABEL_MMAP);
+                                       if (ret < 0)
+                                               LOGL(LOG_SSENGINE, "smack_lsetlabel() failed\n");
+                               }
+                       }
+               }
+               psmack = strstr(smack_attr_pos, "transmute=\"");
+               if(psmack) {
+                       memset(tmpSmackAttribs, 0x0, sizeof(tmpSmackAttribs));
+                       memcpy(tmpSmackAttribs, psmack, strlen(psmack));
+                       smack_value = strtok(tmpSmackAttribs, "\"");
+                       if (smack_value) {
+                               smack_value = strtok(NULL, "\"");
+                               //LOGL(LOG_SSENGINE, "[SMACK_LABEL_TRANSMUTE] smack_value=%s\n", smack_value);
+                               if(smack_value) {
+                                       if (strcasecmp(smack_value, "TRUE")==0) {
+                                               ret = smack_lsetlabel(setFilePath, "1", SMACK_LABEL_TRANSMUTE);
+                                       } else {
+                                               ret = smack_lsetlabel(setFilePath, "0", SMACK_LABEL_TRANSMUTE);
+                                       }
+                                       if (ret < 0)
+                                               LOGL(LOG_SSENGINE, "smack_lsetlabel() failed\n");
+                               }
+                       }
+               }
+       }
+
+       // Set UserID,GroupID
+       if (lchown(setFilePath, setUserID, setGroupID)) {
+               // debug start
+               LOGL(LOG_SSENGINE,  "%s chown error\n", __func__);
+               LOGL(LOG_SSENGINE,  "%s setUserID = %d\n", __func__, setUserID);
+               LOGL(LOG_SSENGINE,  "%s setGroupID = %d\n", __func__, setGroupID);
+               LOGL(LOG_SSENGINE,  "%s chown errno = %d\n", __func__, errno);
+               // debug end
+
+               return E_SS_FAILURE;
+       }
+
+       // mode is always 0777 at symlink file. It doesn't need to call chmod().
+       if (S_ISLNK(sbuf.st_mode)) {
+               LOGL(LOG_SSENGINE,  " stat->st_mode = symbolic link file\n");
+               return S_SS_SUCCESS;
+       }
+
+       if (chmod(setFilePath, setFileMode)) {
+               LOGL(LOG_SSENGINE,  "%s chmod error\n", __func__);
+               return E_SS_FAILURE;
+       }
+#if defined(FEATURE_SUPPORT_CAPABILITY)
+       if (has_cap)  {
+               if (setxattr(setFilePath, "security.capability", (void*)cap_raw, cap_len, 0) < 0) {
+                       LOGL(LOG_SSENGINE, "cap setxattr() failed: %s\n", strerror(errno));
+               }
+       }
+
+       if (has_acl)  {
+               if (setxattr(setFilePath, "system.posix_acl_access", (void*)acl_raw, acl_len, 0) < 0) {
+                       LOGL(LOG_SSENGINE, "Acl setxattr() failed: %s\n", strerror(errno));
+               }
+               //LOG("Acl setxattr() :")asfd
+       }
+#endif
+
+       //LOGL(LOG_SSENGINE,  "%s SUCCESS\n", __func__);
+
+       return S_SS_SUCCESS;
+}
+
+
+long SS_CompareFileAttributes(void *pbUserData,
+                             char *pFilePath,
+                             unsigned char *pAdditionalAttribs,
+                             unsigned long iAddiInfoSize)
+{
+       return S_SS_SUCCESS;
+}
+
+
+
+#define MAX_INT 0xefffffff
+
+/* vrm functions */
+long
+SS_GetAvailableFreeSpace(void *pbUserData, const char *partition_name,
+                        SS_UINT32 *available_flash_size)
+{
+//     *available_flash_size = MAX_INT;
+/*
+#define IDENT_SBL          "sbl"
+#define IDENT_PLATFORM     "platform"
+#define IDENT_BOOT     "boot"
+*/
+       int result = 0;
+       char path[MAX_PATH] = { '\0' };
+
+       SS_unicode_to_char(partition_name, (char *)path);
+       //LOGL(LOG_SSENGINE, "Enter %s path=%s\n", __func__, path);
+       struct statfs vfs;
+
+       //LOGL(LOG_SSENGINE, "path=%s\n", path);
+       result = statfs(path, &vfs);
+       if (result < 0 )
+       {
+               LOGE("failed to fstatfs, err : %d errno: %d\n", result, errno);
+               return -1;
+       }
+
+       *available_flash_size = vfs.f_bsize * vfs.f_bavail;
+       if(*available_flash_size == 0)
+               {
+               *available_flash_size = 0x80000; //Same as Legecy RB
+       LOGE("available_flash_size=%u(vfs.f_bsize=%d vfs.f_bavail=%d\n",
+               (unsigned int)*available_flash_size, (int)vfs.f_bsize, (int)vfs.f_bavail);
+                       return 0; // Same as Legecy RB
+               }
+       return 0;
+}
+
+#ifdef HEAP_PROFILING
+       int max_mem;
+       int cur_mem;
+#endif
+/*******[ Multiprocess API sample implementation ]******/
+void *SS_Malloc(SS_UINT32 size)
+{
+       void *p = malloc(size);
+
+       if (p)
+               memset(p, 0, size);
+#ifdef HEAP_PROFILING
+       cur_mem += size;
+       if(cur_mem > max_mem ){
+               max_mem = cur_mem;
+               LOGL(LOG_SSENGINE,"New chunk [%d] assigned making heap [%d]\n",size,cur_mem);
+       }
+#endif
+
+       return p;
+}
+
+void SS_Free(void *pMemBlock)
+{
+#ifdef HEAP_PROFILING
+       cur_mem -= malloc_usable_size(pMemBlock);
+       LOGL(LOG_SSENGINE,"Old chunk [%d] removed making heap [%d]\n",malloc_usable_size(pMemBlock),cur_mem);
+#endif
+       if(pMemBlock)
+               free(pMemBlock);
+}
+
+SS_UINT32 SS_GetMaxNumProcess(void *user)
+{
+       return SAMPLE_PROCS_NUM;
+}
+
+void* SS_WaitForProcess(const void *handle, SS_UINT32* process_exit_code)
+{
+       pid_t pid;
+       *process_exit_code = 0;
+
+       // processes
+       if (handle)
+               #ifdef _NOEXEC_
+               pid = waitpid((pid_t)handle, (int *)process_exit_code, 0);
+               #else
+               pid = wait((int*)process_exit_code);
+               #endif
+
+       else
+               pid = wait((int*)process_exit_code);
+
+       if (pid < 0)
+               return NULL;
+
+       if (!WIFEXITED(*process_exit_code))
+       {
+               *process_exit_code = (char)WTERMSIG(*process_exit_code);
+               LOG("Wait Error\n");
+       }
+       else
+               *process_exit_code = (char)WEXITSTATUS(*process_exit_code);
+
+       return (void*)pid;
+}
+unsigned long SS_GetMaxProcRamSize(void *user)
+{
+       return UA_RAM_SIZE;
+}
+
+void* SS_RunProcess(void *pbUserData, int argc, char* argv[])
+{
+       pid_t child_pid;
+
+       #ifdef _NOEXEC_
+       child_pid = fork();
+       #else
+       child_pid = vfork();
+       #endif
+
+       if (child_pid == -1) {
+               LOG("Fork failed.\n");
+               return (void *)-1;
+       }
+
+       // This is the child
+       if (child_pid == 0)
+       {
+               #ifdef _NOEXEC_
+               #ifdef _TIZEN_REDBEND//bota
+               SS_HandleProcessRequest(pbUserData, argc, argv);
+               #endif
+               LOGL(LOG_SSENGINE, "SS_RunProcess was called - SS_HandleProcessRequest\n");
+               exit(0);
+               #else
+
+               char **params = NULL;
+               int i;
+
+               params = (char **)SS_Malloc((argc+EXTRA_ARGS) *sizeof(char*));
+               if (!params)
+               {
+                       LOG("params allocation failed\n");
+                       return NULL;
+               }
+               // prepare child data, as it's forbidden to change data after vfork
+               params[0] = strdup(((sample_userdata*)user)->exec_path);
+               params[1] = strdup("handle_run_process");
+               params[2] = strdup(((sample_userdata*)user)->delta_path);
+
+               for (i=0; i < argc; i++)
+                       params[i+EXTRA_ARGS] = strdup(argv[i]);
+
+               // no need to free allocated memory - execv takes care of it
+               execv(params[0], (char**)params);
+               _exit(-1); // if we're here, execv has failed
+               #endif
+       }
+       else
+       {
+               return (void *)child_pid;
+       }
+}
+
+
+
diff --git a/ss_engine/SS_FSUpdate.h b/ss_engine/SS_FSUpdate.h
new file mode 100755 (executable)
index 0000000..041cfaf
--- /dev/null
@@ -0,0 +1,407 @@
+/*
+ * tota-ua
+ *
+ * Copyright (c) 2017 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.
+ */
+
+/*!
+ *******************************************************************************
+ * \file       SS_FileSystemUpdate.h
+ *
+ * \brief      UPI FS Update API
+ *******************************************************************************
+ */
+#ifndef _SS_FILESYSTEM_UPDATE_H_
+#define _SS_FILESYSTEM_UPDATE_H_
+
+#include "SS_Engine_Update.h"
+#include "SS_Engine_Errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*!
+ * File access modes
+ */
+typedef enum tag_RW_TYPE{
+       ONLY_R,         //!< Read-only
+       ONLY_W,         //!< Write-only
+       BOTH_RW         //!< Read-write
+}E_RW_TYPE;
+
+/*!
+ *******************************************************************************
+ * Copy file.<p>
+ *
+ * Must create the path to the new file as required. Must overwrite any contents
+ * in the old file, if any. Must check if the source file is a symbolic link.
+ * If it is, instead create a new symbolic link using \ref SS_Link.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      strFromPath     Path to old file
+ * \param      strToPath       Path to new file
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_CopyFile(
+       void* pbUserData,
+       const char* strFromPath,
+       const char* strToPath
+);
+
+
+/*!
+ *******************************************************************************
+ * Move (rename) file.<p>
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      strFromPath     Path to old file location
+ * \param      strToPath       Path to new file location
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_MoveFile(
+       void* pbUserData,
+       const char* strFromPath,
+       const char* strToPath
+);
+
+/*!
+ *******************************************************************************
+ * Delete file.<p>
+ *
+ * Must return success if the file is deleted or didn't exist.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      strPath         Path to file
+ *
+ * \return     S_SS_SUCCESS on success, E_SS_DELETEFILE if the file cannot be
+ *                     deleted, or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_DeleteFile( void* pbUserData, const char* strPath );
+
+
+
+/*!
+ *******************************************************************************
+ * Delete folder.<p>
+ *
+ * Must return success if the folder is now deleted or didn't exist.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      strPath         Path to folder
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_DeleteFolder( void* pbUserData, const char* strPath );
+
+
+
+/*!
+ *******************************************************************************
+ * Create folder.<p>
+ *
+ * Must return success if the folder is created or already existsed. It is
+ * recommended that the new folder's attributes are a copy of its parent's
+ * attributes.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      strPath         Path to folder
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_CreateFolder( void* pbUserData, const char* strPath );
+
+
+
+/*!
+ *******************************************************************************
+ * Open file.<p>
+ *
+ * Must create the the file (and the path to the file) if it doesn't exist. Must
+ * open in binary mode.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      strPath         Path to file
+ * \param      wFlag           Read/write mode, an \ref E_RW_TYPE value
+ * \param      pwHandle        (out) File handle
+ *
+ * \return     S_SS_SUCCESS on success, E_SS_OPENFILE_ONLYR if attempting to open a
+ *                     non-existant file in R/O mode, E_SS_OPENFILE_WRITE if there is an
+ *                     error opening a file for writing, or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_OpenFile(
+       void*                                   pbUserData,
+       const char*     strPath,
+       E_RW_TYPE                               wFlag,
+       long*                                   pwHandle
+);
+
+
+
+/*!
+ *******************************************************************************
+ * Set file size.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      wHandle         File handle
+ * \param      dwSize          New file size
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_ResizeFile(
+       void* pbUserData,
+       long wHandle,
+       SS_UINT32 dwSize
+);
+
+
+
+/*!
+ *******************************************************************************
+ * Close file.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      wHandle         File handle
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_CloseFile(
+       void* pbUserData,
+       long wHandle
+);
+
+
+
+/*!
+ *******************************************************************************
+ * Write data to a specified position within a file.<p>
+ *
+ * Must return success if the block is written or at least resides in
+ * non-volatile memory. Use \ref SS_SyncFile to commit the file to storage.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      wHandle         File handle
+ * \param      dwPosition      Position within the file to which to write
+ * \param      pbBuffer        Data to write
+ * \param      dwSize          Size of \a pbBuffer
+ *
+ * \return     S_SS_SUCCESS on success, or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_WriteFile(
+       void*                   pbUserData,
+       long                    wHandle,
+       SS_UINT32       dwPosition,
+       unsigned char*  pbBuffer,
+       SS_UINT32       dwSize
+);
+
+/*!
+ *******************************************************************************
+ * Commit file to storage.<p>
+ *
+ * Generally called after \ref SS_WriteFile.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      wHandle         File handle
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+long SS_SyncFile(
+       void*                   pbUserData,
+       long                    wHandle
+);
+
+
+/*!
+ *******************************************************************************
+ * Read data from a specified position within a file.
+ * If fewer bytes than requested are available in the specified position, this
+ * function should read up to the end of file and return S_SS_SUCCESS.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      wHandle         File handle
+ * \param      dwPosition      Position within the file from which to read
+ * \param      pbBuffer        Buffer to contain data
+ * \param      dwSize          Size of data to read
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+
+long SS_ReadFile(
+       void*                   pbUserData,
+       long                    wHandle,
+       SS_UINT32       dwPosition,
+       unsigned char*  pbBuffer,
+       SS_UINT32       dwSize
+);
+
+
+/*!
+ *******************************************************************************
+ * Get file size.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      wHandle         File handle
+ *
+ * \return     File size, -1 if file not found, or &lt; -1 on error
+ *******************************************************************************
+ */
+long SS_GetFileSize(
+       void*   pbUserData,
+       long    wHandle
+);
+
+/*!
+ *******************************************************************************
+ * Get free space of a mounted file system.
+ *
+ * \param      pbUserData                              Optional opaque data-structure to pass to
+ *                                                                     IPL functions
+ * \param      path                                Name of any directory within the mounted
+ *                                                                     file system
+ * \param      available_flash_size    (out) Available space
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+long SS_GetAvailableFreeSpace(void *pbUserData, const char *path, SS_UINT32 *available_flash_size);
+
+/*!
+ *******************************************************************************
+ * Remove symbolic link.<p>
+ *
+ * Must return an error if the file does not exist or is not a symbolic link.<p>
+ *
+ * If your platform does not support symbolic links, you do not need to
+ * implement this.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      pLinkName       Link
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+long SS_Unlink(void *pbUserData, char *pLinkName);
+
+/*!
+ *******************************************************************************
+ * Create symbolic link.<p>
+ *
+ * Must create the path to the link as required. If a file already exists at the
+ * named location, must return success if the file is a symbolic link or an
+ * error if the file is a regular file. The non-existance of the target of the
+ * link must NOT cause an error.<p>
+ *
+ * If your platform does not support symbolic links, you do not need to
+ * implement this.
+ *
+ * \param      pbUserData                      Optional opaque data-structure to pass to IPL
+ *                                                             functions
+ * \param      pLinkName                       Path to the link file to create
+ * \param      pReferenceFileName      Path to which to point the link
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+long SS_Link(void *pbUserData, char *pLinkName, char *pReferenceFileName);
+
+/*!
+ *******************************************************************************
+ * Set file attributes.<p>
+ *
+ * The file attributes token (\a ui8pAttribs) is defined at generation time.
+ * If attributes are not defined explicitly, they are given the following,
+ * OS-dependent values:
+ * \li Windows: _redbend_ro_ for R/O files, _redbend_rw_ for R/W files
+ * \li Linux: _redbend_oooooo:xxxx:yyyy indicating the file mode, uid, and gid
+ *             (uid and gid use capitalized hex digits as required)
+ *
+ * \param      pbUserData              Optional opaque data-structure to pass to IPL
+ *                                                     functions
+ * \param      ui16pFilePath   File path
+ * \param      ui32AttribSize  Size of \a ui8pAttribs
+ * \param      ui8pAttribs             Attributes to set
+ *
+ * \return     S_SS_SUCCESS on success or &lt; 0 on error
+ *******************************************************************************
+ */
+
+long SS_SetFileAttributes(const char *ui16pFilePath,
+                         const SS_UINT32 ui32AttribSize,
+                         const unsigned char *ui8pAttribs);
+
+/*!
+ *******************************************************************************
+ * Print status and debug information.
+ *
+ * \param      pbUserData      Optional opaque data-structure to pass to IPL
+ *                                             functions
+ * \param      aFormat         A NULL-terminated printf-like string with support for
+ *                                             the following tags:
+ *                                             \li %x:  Hex number
+ *                                             \li %0x: Hex number with leading zeros
+ *                                             \li %u:  Unsigned decimal
+ *                                             \li %s:  NULL-terminated string
+ * \param      ...                     Strings to insert in \a aFormat
+ *
+ * \return     S_SS_SUCCESS on success or an \ref SS_vRM_Errors.h error code
+ *******************************************************************************
+ */
+SS_UINT32 SS_Trace(
+       void*           pbUserData,
+       const char*     aFormat,
+       ...
+);
+
+#ifdef __cplusplus
+       }
+#endif /* __cplusplus */
+
+#endif
diff --git a/tota-ua.manifest b/tota-ua.manifest
new file mode 100755 (executable)
index 0000000..1b29af6
--- /dev/null
@@ -0,0 +1,9 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+       <assign>
+               <filesystem path="/usr/bin/*" exec_label="none" />
+       </assign>
+</manifest>
+