[Feature][task-view-762][FOTA] move the real fota functions to lynq-fota-tool process
Only Configure: No
Affected branch: ZK-first-oem-release
Affected module: FOTA
Is it affected on both ZXIC and MTK: only MTK
Self-test: Yes
Doc Update: No
Change-Id: Ie0661abd3f7b56e56deae2a0099b9070f07aeb08
diff --git a/LYNQ_PUBLIC/IC_meta/mtk/2735/liblynq-fota-run/liblynq-fota-run.bb b/LYNQ_PUBLIC/IC_meta/mtk/2735/liblynq-fota-run/liblynq-fota-run.bb
new file mode 100755
index 0000000..faa12a6
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_meta/mtk/2735/liblynq-fota-run/liblynq-fota-run.bb
@@ -0,0 +1,66 @@
+inherit externalsrc package
+
+DESCRIPTION = "lynq-fota-run.so demo"
+SECTION = "base"
+#LICENSE = "MediaTekProprietary"
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"
+
+DEPENDS += "bootctrl nandapi liblynq-protcl liblynq-log liblynq-uci"
+
+inherit workonsrc
+WORKONSRC = "${TOPDIR}/../LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run"
+
+TARGET_CC_ARCH += "${LDFLAGS}"
+BB_INCLUDE_ADD = "--sysroot=${STAGING_DIR_HOST}"
+BB_LDFLAGS_ADD = "--sysroot=${STAGING_DIR_HOST} -Wl,--hash-style=gnu"
+#Parameters passed to do_compile()
+EXTRA_OEMAKE = "'RAT_CONFIG_C2K_SUPPORT = ${RAT_CONFIG_C2K_SUPPORT}'\
+ 'MTK_MULTI_SIM_SUPPORT = ${MTK_MULTI_SIM_SUPPORT}'\
+ 'TARGET_PLATFORM = ${TARGET_PLATFORM}'"
+
+
+FILES_${PN} = "${base_libdir}/*.so \
+ ${base_bindir}\
+ ${base_sbindir}"
+
+
+FILES_${PN}-dev = "/test \
+ ${includedir}"
+
+FILES_${PN}-doc = "/doc"
+
+FILES_${PN}-dbg ="${base_bindir}/.debug \
+ ${base_libdir}/.debug \
+ ${base_sbindir}/.debug"
+
+INSANE_SKIP_${PN} += "already-stripped"
+INSANE_SKIP_${PN} += "installed-vs-shipped"
+
+
+#INHIBIT_PACKAGE_STRIP = "1"
+do_compile () {
+ if [ "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" ]; then
+ oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"
+ elif [ "${PACKAGE_ARCH}" = "cortexa7hf-neon-vfpv4" ]; then
+ oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"
+ elif [ "${PACKAGE_ARCH}" = "cortexa53hf-neon-fp-armv8" ]; then
+ oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE -mhard-float -mfpu=neon-fp-armv8 -mfloat-abi=hard -mcpu=cortex-a53 -mtune=cortex-a53"
+ else
+ oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu -DTELEPHONYWARE"
+ fi
+}
+
+do_install () {
+ oe_runmake install ROOT=${D}
+
+ if [ -d "${WORKONSRC}" ] ; then
+ install -d ${D}${includedir}/
+ cp -af ${S}/include/ ${D}${includedir}/
+ fi
+}
+
+addtask bachclean
+do_bachclean () {
+ oe_runmake clean
+}
diff --git a/LYNQ_PUBLIC/IC_meta/mtk/2735/lynq-fota-tool/lynq-fota-tool.bb b/LYNQ_PUBLIC/IC_meta/mtk/2735/lynq-fota-tool/lynq-fota-tool.bb
new file mode 100755
index 0000000..a788e78
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_meta/mtk/2735/lynq-fota-tool/lynq-fota-tool.bb
@@ -0,0 +1,36 @@
+inherit externalsrc package
+
+DESCRIPTION = "lynq-fota-tool demo"
+LICENSE = "CLOSED"
+LIC_FILES_CHKSUM = "file://LICENSE;md5=e1696b147d49d491bcb4da1a57173fff"
+DEPENDS += "platform-libs liblynq-fota-run"
+inherit workonsrc
+WORKONSRC = "${TOPDIR}/../LYNQ_PUBLIC/IC_src/mtk/packages/apps/lynq-fota-tool"
+
+TARGET_CC_ARCH += "${LDFLAGS}"
+
+#Parameters passed to do_compile()
+EXTRA_OEMAKE = "'RAT_CONFIG_C2K_SUPPORT = ${RAT_CONFIG_C2K_SUPPORT}'\
+ 'MTK_MULTI_SIM_SUPPORT = ${MTK_MULTI_SIM_SUPPORT}'\
+ 'TARGET_PLATFORM = ${TARGET_PLATFORM}'"
+
+EXTRA_OEMAKE += "'LYNQ_CONFIG_VERSION = ${LYNQ_CONFIG_VERSION}' \
+ 'LYNQ_CONFIG_SW_VERSION = ${LYNQ_CONFIG_SW_VERSION}'"
+
+#INHIBIT_PACKAGE_STRIP = "1"
+do_compile () {
+ if [ "${PACKAGE_ARCH}" = "cortexa7hf-vfp-vfpv4-neon" ]; then
+ oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"
+ elif [ "${PACKAGE_ARCH}" = "cortexa7hf-neon-vfpv4" ]; then
+ oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE"
+ elif [ "${PACKAGE_ARCH}" = "cortexa53hf-neon-fp-armv8" ]; then
+ oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -mhard-float -Wl,--hash-style=gnu -DTELEPHONYWARE -mhard-float -mfpu=neon-fp-armv8 -mfloat-abi=hard -mcpu=cortex-a53 -mtune=cortex-a53"
+ else
+ oe_runmake all ROOT=${STAGING_DIR_HOST} OFLAGS="--sysroot=${STAGING_DIR_HOST} -Os -Wl,--hash-style=gnu -DTELEPHONYWARE"
+ fi
+}
+
+do_install() {
+ install -d ${D}${bindir}/
+ install -m 0755 ${S}/lynq-fota-tool ${D}${bindir}/
+}
diff --git a/LYNQ_PUBLIC/IC_meta/mtk/2735/packagegroups/packagegroup-lynq-mt2735.bb b/LYNQ_PUBLIC/IC_meta/mtk/2735/packagegroups/packagegroup-lynq-mt2735.bb
index 5d637e5..a58e907 100755
--- a/LYNQ_PUBLIC/IC_meta/mtk/2735/packagegroups/packagegroup-lynq-mt2735.bb
+++ b/LYNQ_PUBLIC/IC_meta/mtk/2735/packagegroups/packagegroup-lynq-mt2735.bb
@@ -11,6 +11,7 @@
liblynq-uci \
liblynq-protcl \
liblynq-fota \
+ liblynq-fota-run \
lynq-threadhandle \
lynq-broadcast-receive \
lynq-broadcast-send \
@@ -35,6 +36,7 @@
lynq-at-test \
liblynq-logdata-handle \
lynq-default \
+ lynq-fota-tool \
lynq-logrotate-service \
liblynq-system-own \
lynq-wg870 \
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/MD5/md5.c b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/MD5/md5.c
new file mode 100755
index 0000000..5dd9ff3
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/MD5/md5.c
@@ -0,0 +1,161 @@
+#include "string.h"
+#include "md5.h"
+
+unsigned char PADDING[]={0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+void MD5Init(MD5_CTX *context)
+{
+ context->count[0] = 0;
+ context->count[1] = 0;
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+}
+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen)
+{
+ unsigned int i = 0,index = 0,partlen = 0;
+ index = (context->count[0] >> 3) & 0x3F;
+ partlen = 64 - index;
+ context->count[0] += inputlen << 3;
+ if(context->count[0] < (inputlen << 3))
+ context->count[1]++;
+ context->count[1] += inputlen >> 29;
+
+ if(inputlen >= partlen)
+ {
+ memcpy(&context->buffer[index],input,partlen);
+ MD5Transform(context->state,context->buffer);
+ for(i = partlen;i+64 <= inputlen;i+=64)
+ MD5Transform(context->state,&input[i]);
+ index = 0;
+ }
+ else
+ {
+ i = 0;
+ }
+ memcpy(&context->buffer[index],&input[i],inputlen-i);
+}
+void MD5Final(MD5_CTX *context,unsigned char digest[16])
+{
+ unsigned int index = 0,padlen = 0;
+ unsigned char bits[8];
+ index = (context->count[0] >> 3) & 0x3F;
+ padlen = (index < 56)?(56-index):(120-index);
+ MD5Encode(bits,context->count,8);
+ MD5Update(context,PADDING,padlen);
+ MD5Update(context,bits,8);
+ MD5Encode(digest,context->state,16);
+}
+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len)
+{
+ unsigned int i = 0,j = 0;
+ while(j < len)
+ {
+ output[j] = input[i] & 0xFF;
+ output[j+1] = (input[i] >> 8) & 0xFF;
+ output[j+2] = (input[i] >> 16) & 0xFF;
+ output[j+3] = (input[i] >> 24) & 0xFF;
+ i++;
+ j+=4;
+ }
+}
+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len)
+{
+ unsigned int i = 0,j = 0;
+ while(j < len)
+ {
+ output[i] = (input[j]) |
+ (input[j+1] << 8) |
+ (input[j+2] << 16) |
+ (input[j+3] << 24);
+ i++;
+ j+=4;
+ }
+}
+void MD5Transform(unsigned int state[4],unsigned char block[64])
+{
+ unsigned int a = state[0];
+ unsigned int b = state[1];
+ unsigned int c = state[2];
+ unsigned int d = state[3];
+ unsigned int x[64];
+ MD5Decode(x,block,64);
+ FF(a, b, c, d, x[ 0], 7, 0xd76aa478); /* 1 */
+ FF(d, a, b, c, x[ 1], 12, 0xe8c7b756); /* 2 */
+ FF(c, d, a, b, x[ 2], 17, 0x242070db); /* 3 */
+ FF(b, c, d, a, x[ 3], 22, 0xc1bdceee); /* 4 */
+ FF(a, b, c, d, x[ 4], 7, 0xf57c0faf); /* 5 */
+ FF(d, a, b, c, x[ 5], 12, 0x4787c62a); /* 6 */
+ FF(c, d, a, b, x[ 6], 17, 0xa8304613); /* 7 */
+ FF(b, c, d, a, x[ 7], 22, 0xfd469501); /* 8 */
+ FF(a, b, c, d, x[ 8], 7, 0x698098d8); /* 9 */
+ FF(d, a, b, c, x[ 9], 12, 0x8b44f7af); /* 10 */
+ FF(c, d, a, b, x[10], 17, 0xffff5bb1); /* 11 */
+ FF(b, c, d, a, x[11], 22, 0x895cd7be); /* 12 */
+ FF(a, b, c, d, x[12], 7, 0x6b901122); /* 13 */
+ FF(d, a, b, c, x[13], 12, 0xfd987193); /* 14 */
+ FF(c, d, a, b, x[14], 17, 0xa679438e); /* 15 */
+ FF(b, c, d, a, x[15], 22, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG(a, b, c, d, x[ 1], 5, 0xf61e2562); /* 17 */
+ GG(d, a, b, c, x[ 6], 9, 0xc040b340); /* 18 */
+ GG(c, d, a, b, x[11], 14, 0x265e5a51); /* 19 */
+ GG(b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /* 20 */
+ GG(a, b, c, d, x[ 5], 5, 0xd62f105d); /* 21 */
+ GG(d, a, b, c, x[10], 9, 0x2441453); /* 22 */
+ GG(c, d, a, b, x[15], 14, 0xd8a1e681); /* 23 */
+ GG(b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /* 24 */
+ GG(a, b, c, d, x[ 9], 5, 0x21e1cde6); /* 25 */
+ GG(d, a, b, c, x[14], 9, 0xc33707d6); /* 26 */
+ GG(c, d, a, b, x[ 3], 14, 0xf4d50d87); /* 27 */
+ GG(b, c, d, a, x[ 8], 20, 0x455a14ed); /* 28 */
+ GG(a, b, c, d, x[13], 5, 0xa9e3e905); /* 29 */
+ GG(d, a, b, c, x[ 2], 9, 0xfcefa3f8); /* 30 */
+ GG(c, d, a, b, x[ 7], 14, 0x676f02d9); /* 31 */
+ GG(b, c, d, a, x[12], 20, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH(a, b, c, d, x[ 5], 4, 0xfffa3942); /* 33 */
+ HH(d, a, b, c, x[ 8], 11, 0x8771f681); /* 34 */
+ HH(c, d, a, b, x[11], 16, 0x6d9d6122); /* 35 */
+ HH(b, c, d, a, x[14], 23, 0xfde5380c); /* 36 */
+ HH(a, b, c, d, x[ 1], 4, 0xa4beea44); /* 37 */
+ HH(d, a, b, c, x[ 4], 11, 0x4bdecfa9); /* 38 */
+ HH(c, d, a, b, x[ 7], 16, 0xf6bb4b60); /* 39 */
+ HH(b, c, d, a, x[10], 23, 0xbebfbc70); /* 40 */
+ HH(a, b, c, d, x[13], 4, 0x289b7ec6); /* 41 */
+ HH(d, a, b, c, x[ 0], 11, 0xeaa127fa); /* 42 */
+ HH(c, d, a, b, x[ 3], 16, 0xd4ef3085); /* 43 */
+ HH(b, c, d, a, x[ 6], 23, 0x4881d05); /* 44 */
+ HH(a, b, c, d, x[ 9], 4, 0xd9d4d039); /* 45 */
+ HH(d, a, b, c, x[12], 11, 0xe6db99e5); /* 46 */
+ HH(c, d, a, b, x[15], 16, 0x1fa27cf8); /* 47 */
+ HH(b, c, d, a, x[ 2], 23, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II(a, b, c, d, x[ 0], 6, 0xf4292244); /* 49 */
+ II(d, a, b, c, x[ 7], 10, 0x432aff97); /* 50 */
+ II(c, d, a, b, x[14], 15, 0xab9423a7); /* 51 */
+ II(b, c, d, a, x[ 5], 21, 0xfc93a039); /* 52 */
+ II(a, b, c, d, x[12], 6, 0x655b59c3); /* 53 */
+ II(d, a, b, c, x[ 3], 10, 0x8f0ccc92); /* 54 */
+ II(c, d, a, b, x[10], 15, 0xffeff47d); /* 55 */
+ II(b, c, d, a, x[ 1], 21, 0x85845dd1); /* 56 */
+ II(a, b, c, d, x[ 8], 6, 0x6fa87e4f); /* 57 */
+ II(d, a, b, c, x[15], 10, 0xfe2ce6e0); /* 58 */
+ II(c, d, a, b, x[ 6], 15, 0xa3014314); /* 59 */
+ II(b, c, d, a, x[13], 21, 0x4e0811a1); /* 60 */
+ II(a, b, c, d, x[ 4], 6, 0xf7537e82); /* 61 */
+ II(d, a, b, c, x[11], 10, 0xbd3af235); /* 62 */
+ II(c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /* 63 */
+ II(b, c, d, a, x[ 9], 21, 0xeb86d391); /* 64 */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+}
\ No newline at end of file
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/MD5/md5_encode.c b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/MD5/md5_encode.c
new file mode 100755
index 0000000..918d634
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/MD5/md5_encode.c
@@ -0,0 +1,264 @@
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <log/log.h>
+//xf.li@20230822 add for ab recover start
+#include <errno.h>
+//xf.li@20230822 add for ab recover end
+#include "md5.h"
+#include "mtk_device_wrap.h"
+#include "liblog/lynq_deflog.h"
+#define LOG_TAG "LYNQ_FOTA"
+
+int ota_file_open(char* path, char* flag)
+{
+#if 1
+ if(strcmp(flag, "r") == 0 || strcmp(flag, "rb") == 0)
+ return mtk_device_wrap_open(path, O_RDONLY);
+ else if(strcmp(flag, "r+") == 0 || strcmp(flag, "rb+") == 0)
+ return mtk_device_wrap_open(path, O_RDWR | O_CREAT);
+ else if(strcmp(flag, "w+") == 0 ||strcmp(flag, "wb+") == 0 || strcmp(flag, "w") == 0 || strcmp(flag, "wb") == 0 )
+ return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_TRUNC);
+ else if(strcmp(flag, "a+") == 0 ||strcmp(flag, "ab+") == 0 || strcmp(flag, "a") == 0 || strcmp(flag, "ab") == 0 )
+ return mtk_device_wrap_open(path, O_RDWR | O_CREAT | O_APPEND);
+#endif
+}
+
+
+int ota_file_seek(int handle, int offset, int flag)
+{
+ return mtk_device_wrap_seek(handle,offset,flag);
+}
+
+
+
+int ota_file_read(char* buffer, size_t count, int file)
+{
+ return mtk_device_wrap_read(file,buffer,count);
+}
+
+
+
+void ota_file_close(int handle)
+{
+ mtk_device_wrap_close(handle);
+}
+
+#define MD5_READ_BUFFER_LEN 4*1024
+int lynq_md5_file_verfy(char* filePath, char* file_md5)
+{
+ int ret = -1;
+ int handle;
+
+ LYVERBLOG("[+MD5]:calc file md5: %s\n", filePath);
+ handle = open(filePath, O_RDONLY);
+ LYVERBLOG("[+MD5]:handle:%d\n",handle);
+ if(handle >= 0){
+ {
+ int read_len = 0;
+ unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char decrypt[16];
+ int i;
+ MD5_CTX md5;
+ MD5Init(&md5);
+ //strcpy(buffer,"12345");
+ while ((read_len = read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+ {
+ //printf("readlen:%d\n",read_len);
+ MD5Update(&md5, (unsigned char*)buffer, read_len);
+ memset(buffer,0,sizeof(buffer));
+ }
+ MD5Final(&md5, (unsigned char*)decrypt);
+ memset(buffer, 0, MD5_READ_BUFFER_LEN);
+ for(i = 0; i < 16; i++)
+ {
+ sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);
+ }
+ LYVERBLOG("[+MD5]:md5:%s\n", buffer);
+ LYVERBLOG("[+MD5]:md5:%s\n", file_md5);
+
+ ret = strncmp((const char*)buffer, (const char*)file_md5,32);
+ LYVERBLOG("[+MD5]:ret:%d\n", ret);
+ }
+ close(handle);
+ }
+ return ret;
+}
+//xf.li@20230822 add for ab recover start
+#define MD5_VERFY_ERROR 5
+int lynq_md5_file_verfy_ab(char* filePath, char* file_md5)
+{
+ int ret = -1;
+ int handle;
+
+ RLOGD("[+MD5]:calc file md5: %s\n", filePath);
+ handle = open(filePath, O_RDONLY);
+ RLOGD("[+MD5]:handle:%d\n",handle);
+ if(handle == -1)
+ {
+ RLOGD("[+MD5]: can't open the file, errno is %d\n",errno);
+ }
+ if(handle >= 0)
+ {
+ int read_len = 0;
+ unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char decrypt[16];
+ int i;
+ MD5_CTX md5;
+ MD5Init(&md5);
+ while ((read_len = read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+ {
+ MD5Update(&md5, (unsigned char*)buffer, read_len);
+ memset(buffer,0,sizeof(buffer));
+ usleep(1000);
+ }
+ MD5Final(&md5, (unsigned char*)decrypt);
+ memset(buffer, 0, MD5_READ_BUFFER_LEN);
+ for(i = 0; i < 16; i++)
+ {
+ sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);
+ }
+ RLOGD("[+MD5]:buffer md5:%s\n", buffer);
+ RLOGD("[+MD5]:file_md5 md5:%s\n", file_md5);
+
+ ret = strncmp((const char*)buffer, (const char*)file_md5,32);
+ RLOGD("[+MD5]:ret:%d\n", ret);
+ close(handle);
+ }
+ if(ret != 0)
+ {
+ return MD5_VERFY_ERROR;
+ }
+ return ret;
+}
+int calculate_file_md5_value(char* filePath, unsigned char buffer_out[])
+{
+ //int ret = -1;
+ int handle;
+
+ RLOGD("[+MD5]:calc file md5: %s\n", filePath);
+ handle = open(filePath, O_RDONLY);
+ RLOGD("[+MD5]:handle:%d\n",handle);
+ if(handle == -1)
+ {
+ RLOGD("[+MD5]: can't open the file, errno is %d\n",errno);
+ }
+ if(handle >= 0)
+ {
+ int read_len = 0;
+ unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char decrypt[16];
+ int i;
+ MD5_CTX md5;
+ MD5Init(&md5);
+ while ((read_len = read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+ {
+ MD5Update(&md5, (unsigned char*)buffer, read_len);
+ memset(buffer,0,sizeof(buffer));
+ usleep(1000);
+ }
+ MD5Final(&md5, (unsigned char*)decrypt);
+ memset(buffer, 0, MD5_READ_BUFFER_LEN);
+ for(i = 0; i < 16; i++)
+ {
+ sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);
+ }
+ RLOGD("[+MD5]: md5 of %s : %s\n", filePath, buffer);
+ memcpy(buffer_out, buffer, MD5_READ_BUFFER_LEN);
+ close(handle);
+ }
+ else
+ {
+ return -1;
+ }
+ return 0;
+}
+
+int lynq_md5_two_file_verfy(char* filePath_1, char* filePath_2)
+{
+ int ret = -1;
+ int handle_1, handle_2;
+ unsigned char buffer_1[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char buffer_2[MD5_READ_BUFFER_LEN] = {0};
+
+ ret = calculate_file_md5_value(filePath_1, buffer_1);
+ if(ret < 0)
+ {
+ RLOGD("[+MD5]:calculate file1 md5 value ERROE!!!\n");
+ return ret;
+ }
+ ret = calculate_file_md5_value(filePath_2, buffer_2);
+ if(ret < 0)
+ {
+ RLOGD("[+MD5]:calculate file2 md5 value ERROE!!!\n");
+ return ret;
+ }
+ RLOGD("buffer_1 is %s, buffer_2 is %s\n", buffer_1, buffer_2);
+ ret = strncmp((const char*)buffer_1, (const char*)buffer_2, 32);
+ RLOGD("[+MD5]:strncmp ret:%d\n", ret);
+
+ if(ret != 0)
+ {
+ return MD5_VERFY_ERROR;
+ }
+ return 0;
+}
+//xf.li@20230822 add for ab recover end
+#if 0
+int md5_file_verfy_new(char* filePath, char* file_md5,int packe_len)
+{
+ int ret = -1;
+ int handle;
+ int tatal_packe_len = 0;
+
+ LYVERBLOG("[+MD5]:calc file md5: %s\n", filePath);
+ handle = mtk_device_wrap_open(filePath, O_RDONLY);
+ LYVERBLOG("[+MD5]:handle:%d\n",handle);
+ if(handle >= 0){
+ {
+ int read_len = 0;
+ unsigned char buffer[MD5_READ_BUFFER_LEN] = {0};
+ unsigned char decrypt[16];
+ int i;
+ MD5_CTX md5;
+ MD5Init(&md5);
+ //strcpy(buffer,"12345");
+ tatal_packe_len = packe_len;
+ LYVERBLOG("[+MD5]:tatal_packe_len:%d\n", tatal_packe_len);
+ while ((read_len = mtk_device_wrap_read(handle,buffer, MD5_READ_BUFFER_LEN)) > 0)
+ {
+ //printf("readlen:%d\n",read_len);
+ if(tatal_packe_len >= read_len)
+ {
+ MD5Update(&md5, (unsigned char*)buffer, read_len);
+ tatal_packe_len -= read_len;
+ }
+ else if(tatal_packe_len > 0)
+ {
+ LYVERBLOG("[+MD5]:tatal_packe_len:%d\n", tatal_packe_len);
+ MD5Update(&md5, (unsigned char*)buffer, tatal_packe_len);
+ tatal_packe_len -= read_len;
+ }
+ LYVERBLOG("[+MD5]:tatal_packe_len:%d\n", tatal_packe_len);
+ memset(buffer,0,sizeof(buffer));
+ }
+ MD5Final(&md5, (unsigned char*)decrypt);
+ memset(buffer, 0, MD5_READ_BUFFER_LEN);
+ for(i = 0; i < 16; i++)
+ {
+ sprintf((char*)(buffer + i * 2), "%02x",decrypt[i]);
+ }
+ LYVERBLOG("[+MD5]:md5:%s\n", buffer);
+ LYVERBLOG("[+MD5]:md5:%s\n", file_md5);
+
+ ret = strncmp((const char*)buffer, (const char*)file_md5,32);
+ LYVERBLOG("[+MD5]:ret:%d\n", ret);
+ }
+ mtk_device_wrap_close(handle);
+ }
+ return ret;
+}
+#endif
\ No newline at end of file
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/iot_rock.h b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/iot_rock.h
new file mode 100755
index 0000000..ea557b9
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/iot_rock.h
@@ -0,0 +1,166 @@
+#ifndef _IOT_ROCK_H_
+#define _IOT_ROCK_H_
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+/* public */
+
+#define E_ROCK_SUCCESS (0)
+#define E_ROCK_INVALID_DELTA (-1)
+#define E_ROCK_DELTA_MISMATCH (-2)
+#define E_ROCK_DELTA_CHUNK_MISMATCH (-3)
+#define E_ROCK_READ_DELTA_ERROR (-4)
+#define E_ROCK_READ_BLOCK_ERROR (-11)
+#define E_ROCK_WRITE_BLOCK_ERROR (-12)
+#define E_ROCK_RAM_NOT_ENOUGH (-20)
+#define E_ROCK_INVALID_CTX (-30)
+#define E_ROCK_FOTA_ADDR (-50)
+
+
+#define PATCH_SYSTEM (1)
+#define PATCH_BOOT (2)
+#define PATCH_TEE (3)
+#define PATCH_MD1IMG (4)
+#define PATCH_MD1DSP (5)
+#define PATCH_VBMETA (6)
+#define PATCH_OEMAPP (7)
+#define PATCH_OEMAPP2 (8)
+#define PATCH_MEDMCU (9)
+#define PATCH_SPM (10)
+#define PATCH_PROTECT (11)
+#define PATCH_MCF1 (12)
+#define PATCH_MCF2 (13)
+#define PATCH_MCUPM (14)
+#define PATCH_SSPM (15)
+#define PATCH_DPM (16)
+#define PATCH_PIIMG (17)
+#define PATCH_HSMOS (18)
+#define PATCH_BL2 (19)
+#define PATCH_BL33 (20)
+
+#define FULL_SYSTEM (65)
+#define FULL_BOOT (66)
+#define FULL_TEE (67)
+#define FULL_MD1IMG (68)
+#define FULL_MD1DSP (69)
+#define FULL_VBMETA (70)
+#define FULL_OEMAPP (71)
+#define FULL_OEMAPP2 (72)
+#define FULL_MEDMCU (73)
+#define FULL_SPM (74)
+#define FULL_PROTECT (75)
+#define FULL_MCF1 (76)
+#define FULL_MCF2 (77)
+#define FULL_MCUPM (78)
+#define FULL_SSPM (79)
+#define FULL_DPM (80)
+#define FULL_PIIMG (81)
+#define FULL_HSMOS (82)
+#define FULL_BL2 (83)
+#define FULL_BL33 (84)
+
+
+
+
+
+
+
+
+#define MAX_OTA_ROLE (128)
+#define REAL_OTA_ROLE (20)
+
+
+
+#define MODE_NORMAL 0
+#define MODE_A2B 1
+#define MODE_B2A 2
+
+#define WAIT 0xff
+#define PASS 0
+#define ERROR -1
+
+typedef struct {
+ void* user_context;
+ unsigned int rom_base; // old rom start
+ unsigned char* ram_base; // ram working buffer start
+ unsigned int ram_len; // ram working buffer len
+
+ unsigned int backup_base; // ram backup storage start
+ unsigned int backup_len; // ram backup storage len
+
+ unsigned int update_nvram; // nvram update flag
+
+ int read_rom_directly;
+ int first_run;
+} IOT_UPDATA_CONTEXT;
+
+
+
+
+typedef struct {
+
+ char fota_flag[32]; //fota 标志保留
+ int update_result; //升级结果
+ int ota_run; //
+ char cid[32];
+ char did[32];
+} UPDATE_INFO;
+
+
+typedef struct {
+ int need_update;
+ int check_delta;
+ int check_rom;
+ int update_result;
+
+} UPDATE_STATUS;
+
+
+typedef struct {
+ int ota_run;
+ UPDATE_STATUS update_status[MAX_OTA_ROLE];
+ int update_result;
+ int switch_slot;
+
+} OTA_STATUS;
+
+
+
+
+
+//#define DELTA_HEARD_SIZE (4*5)
+
+//#define DELTA_HEARD_SIZE (4*11 + 4*11)
+#define DELTA_HEARD_SIZE 512
+#define DELTA_FULL_HEARD_SIZE 8
+
+
+
+int iot_patch(IOT_UPDATA_CONTEXT* update_ctx);
+int lynq_read_process(void);
+unsigned int iot_hash(unsigned char *buf,unsigned int len, unsigned int* value);
+int lynq_md5_file_verfy(char* filePath, char* file_md5);
+//xf.li@20230822 add for ab recover start
+int lynq_md5_file_verfy_ab(char* filePath, char* file_md5);
+int calculate_file_md5_value(char* filePath, unsigned char buffer_out[]);
+int lynq_md5_two_file_verfy(char* filePath_1, char* filePath_2);
+//xf.li@20230822 add for ab recover end
+//int md5_file_verfy_new(char* filePath, char* file_md5,int packe_len);
+int lynq_rock_main(int first_run);
+int lynq_fota_func(void);
+int lynq_nand_open(const char *pathname, int flags);
+ssize_t lynq_nand_read(int fd, void *buf, size_t count);
+ssize_t lynq_nand_write(int fd, void *buf, size_t count);
+int lynq_nand_close(int fd);
+int lynq_get_upgrade_status(void);
+void lynq_reboot_device(void);
+int lynq_fota_nrestart(void);
+int lynq_fota_set_addr_value(char *value,int size);
+int lynq_fota_get_addr_value(char *tmp);
+#endif
+
+
+
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/iot_rock_ipl.h b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/iot_rock_ipl.h
new file mode 100755
index 0000000..77c7c2a
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/iot_rock_ipl.h
@@ -0,0 +1,22 @@
+#ifndef _IOT_ROCK_IPL_H_
+#define _IOT_ROCK_IPL_H_
+
+void rock_trace(void* ctx, const char* fmt, ...);
+void rock_progress(void* ctx, int percent);
+int rock_read_block(void* ctx, unsigned char* dest, unsigned int start, unsigned int size);
+int rock_read_delta(void* ctx, unsigned char* dest, unsigned int offset, unsigned int size);
+int rock_write_block(void* ctx, unsigned char* src, unsigned int start, unsigned int size);
+int rock_process_block(void* ctx, unsigned char* data, unsigned int start, unsigned int size);
+int rock_get_blocksize(void* ctx);
+
+int rock_read_file(void* ctx, void* name, unsigned char* dest, unsigned int offset, unsigned int size);
+int rock_write_file(void* ctx, void* name, unsigned char* src, unsigned int offset, unsigned int size);
+
+int rock_delete_file(void* ctx, void* name);
+
+int rock_fatal(void* ctx, int error_code);
+
+int rock_mismatch(void* ctx, unsigned char* buf, unsigned int start, unsigned int size,
+ unsigned int source_hash,unsigned int target_hash);
+#endif
+
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/md5.h b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/md5.h
new file mode 100755
index 0000000..f0e3a1b
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/md5.h
@@ -0,0 +1,48 @@
+#ifndef MD5_H
+#define MD5_H
+
+typedef struct
+{
+ unsigned int count[2];
+ unsigned int state[4];
+ unsigned char buffer[64];
+}MD5_CTX;
+
+
+#define F(x,y,z) ((x & y) | (~x & z))
+#define G(x,y,z) ((x & z) | (y & ~z))
+#define H(x,y,z) (x^y^z)
+#define I(x,y,z) (y ^ (x | ~z))
+#define ROTATE_LEFT(x,n) ((x << n) | (x >> (32-n)))
+#define FF(a,b,c,d,x,s,ac) \
+{ \
+ a += F(b,c,d) + x + ac; \
+ a = ROTATE_LEFT(a,s); \
+ a += b; \
+}
+#define GG(a,b,c,d,x,s,ac) \
+{ \
+ a += G(b,c,d) + x + ac; \
+ a = ROTATE_LEFT(a,s); \
+ a += b; \
+}
+#define HH(a,b,c,d,x,s,ac) \
+{ \
+ a += H(b,c,d) + x + ac; \
+ a = ROTATE_LEFT(a,s); \
+ a += b; \
+}
+#define II(a,b,c,d,x,s,ac) \
+{ \
+ a += I(b,c,d) + x + ac; \
+ a = ROTATE_LEFT(a,s); \
+ a += b; \
+}
+void MD5Init(MD5_CTX *context);
+void MD5Update(MD5_CTX *context,unsigned char *input,unsigned int inputlen);
+void MD5Final(MD5_CTX *context,unsigned char digest[16]);
+void MD5Transform(unsigned int state[4],unsigned char block[64]);
+void MD5Encode(unsigned char *output,unsigned int *input,unsigned int len);
+void MD5Decode(unsigned int *output,unsigned char *input,unsigned int len);
+
+#endif
\ No newline at end of file
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/md5_encode.h b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/md5_encode.h
new file mode 100755
index 0000000..c3e5d38
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/md5_encode.h
@@ -0,0 +1,33 @@
+#ifndef MD5_ENCODE_H_
+#define MD5_ENCODE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+//打开文件
+int ota_file_open(char* path, char* flag);
+//文件偏移位置
+int ota_file_seek(int handle, int offset, int flag);
+//读文件内容
+int ota_file_read(char* buffer, size_t count, int file);
+//关闭文件
+void ota_file_close(int handle);
+
+
+/***
+ * @description: 校验文件的MD5
+ * @param filePath 文件路径
+ * @param file_md5 待校验MD5值
+ * @return 0:校验成功; 其他:校验失败
+ */
+int md5_file_verfy(char* filePath, char* file_md5);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/sha.h b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/sha.h
new file mode 100755
index 0000000..05f9941
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/include/sha.h
@@ -0,0 +1,75 @@
+/* sha.h
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of Google Inc. nor the names of its contributors may
+** be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef _EMBEDDED_SHA_H_
+#define _EMBEDDED_SHA_H_
+
+#include <inttypes.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SHA_CTX {
+ uint64_t count;
+ uint32_t state[5];
+#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+ union {
+ uint8_t b[64];
+ uint32_t w[16];
+ } buf;
+#else
+ uint8_t buf[64];
+#endif
+} SHA_CTX;
+
+void SHA_init(SHA_CTX* ctx);
+void SHA_update(SHA_CTX* ctx, const void* data, int len);
+const uint8_t* SHA_final(SHA_CTX* ctx);
+
+/* Convenience method. Returns digest parameter value. */
+const uint8_t* SHA(const void* data, int len, uint8_t* digest);
+
+#define SHA_DIGEST_SIZE 20
+
+typedef enum check_status_t{
+ ERROR_SHA = -3, // sha1输入参数错误
+ PATCH_ERR = -2, // 检测hash既不等于source_hash也不等于target_hash, 一般错误情况
+ NOT_EXIST_FILE = -1, // 检测文件不存在
+ SOURCE_SUCC = 0, // 检测hash等于目标source_hash, 一般正常情况
+ PATCH_SUCC = 1, // 检测hash等于目标target_hash, up to data
+}Check_status;
+
+int ParseSha1(const char* str, uint8_t* digest);
+
+const uint8_t* ROCK_SHA(const char *file_name, uint8_t *digest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/lib/libiotpatch.a b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/lib/libiotpatch.a
new file mode 100755
index 0000000..023c16e
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/lib/libiotpatch.a
Binary files differ
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/lib/libmd5.a b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/lib/libmd5.a
new file mode 100755
index 0000000..1cebf1f
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/lib/libmd5.a
Binary files differ
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/makefile b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/makefile
new file mode 100755
index 0000000..1bee260
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/makefile
@@ -0,0 +1,79 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fpermissive \
+ -DRIL_SHLIB \
+ -DATCI_PARSE \
+ -DKEEP_ALIVE \
+ -D__LINUX_OS__ \
+ -DECALL_SUPPORT
+
+CFLAGS += -fPIC -O2 $(INCLUDE) -D_LARGEFILE64_SOURCE
+
+$(warning ################# rock ROOT: $(ROOT),includedir:$(includedir))
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I./include \
+ -I$(LOCAL_PATH)/../include \
+ -I$(ROOT)$(includedir)/logger \
+ -I$(ROOT)$(includedir)/liblog \
+ -I$(ROOT)$(includedir)/ftp \
+ -I$(ROOT)$(includedir)/glib-2.0 \
+ -I$(ROOT)$(libdir)/glib-2.0/include \
+
+
+
+LOCAL_LIBS := \
+ -L. \
+ -L./lib \
+ -ldl \
+ -lpthread \
+ -llog \
+ -lstdc++ \
+ -liotpatch \
+ -lmd5 \
+ -lnandapi \
+ -lbootctrl \
+ -llynq-log \
+ -llynq-protcl \
+ -llynq-uci \
+
+SOURCES = $(wildcard *.c wildcard *.h rock_ua/*.c MD5/*c)
+
+EXECUTABLE = liblynq-fota-run.so
+
+OBJECTS=$(SOURCES:.c=.o)
+
+
+.PHONY: build clean install pack_rootfs
+
+all: build
+$(EXECUTABLE): $(OBJECTS)
+ $(CXX) -shared -Wl,--no-undefined $(OBJECTS) $(LOCAL_LIBS) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+ $(CC) $(LOCAL_C_INCLUDES) $(CFLAGS) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+build: $(EXECUTABLE)
+ $(warning ########## build $(EXECUTABLE) ##########)
+
+install:
+ mkdir -p $(ROOT)$(base_libdir)/
+ install $(EXECUTABLE) $(ROOT)$(base_libdir)/
+ mkdir -p $(ROOT)$(includedir)/$(NAME)/sdk
+
+pack_rootfs:
+ mkdir -p $(PACK_INITRAMFS_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_INITRAMFS_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_INITRAMFS_TO)$(base_libdir)/$(EXECUTABLE)
+ mkdir -p $(PACK_TO)$(base_libdir)/
+ cp -af $(EXECUTABLE) $(PACK_TO)$(base_libdir)/
+ $(CROSS)strip $(PACK_TO)$(base_libdir)/$(EXECUTABLE)
+.PHONY: clean
+clean:
+ $(RM) $(OBJECTS) $(EXECUTABLE)
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/rock_ua/rock_ua.c b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/rock_ua/rock_ua.c
new file mode 100755
index 0000000..48e9950
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/rock_ua/rock_ua.c
@@ -0,0 +1,2327 @@
+// 2017-07-31 carota Rock FOTA ua porting file
+
+
+#define ROCK_FOTA_SUPPORT
+
+#ifdef ROCK_FOTA_SUPPORT
+
+
+#include "iot_rock.h"
+#include "iot_rock_ipl.h"
+#include "sha.h"
+#include <log/log.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <stdint.h>
+
+
+#include <hardware/boot_control.h>
+#include <hardware/hardware.h>
+#include <sys/reboot.h>
+
+
+
+#include "liblog/lynq_deflog.h"
+#include "mtk_device_wrap.h"
+#include <include/lynq_uci.h>
+
+#define ROCK_DEFAULT_BLOCK_SIZE 0x40000
+#define ROCK_RAM_LEN (1024*1024)
+
+#define LOG_TAG "LYNQ_FOTA"
+#define ROCK_BACKUP_LEN ROCK_DEFAULT_BLOCK_SIZE
+
+
+#define FILENAME_SIZE 50
+
+
+char partition_filename_a[][FILENAME_SIZE] = {
+ {"/dev/disk/by-partlabel/system_a"},
+ {"/dev/disk/by-partlabel/boot_a"},
+ {"/dev/disk/by-partlabel/tee_a"},
+ {"/dev/disk/by-partlabel/md1img_a"},
+ {"/dev/disk/by-partlabel/md1dsp_a"},
+ {"/dev/disk/by-partlabel/vbmeta_a"},
+ {"/dev/disk/by-partlabel/oemapp_a"},
+ {"/dev/disk/by-partlabel/oemapp2_a"},
+ {"/dev/disk/by-partlabel/medmcu_a"},
+ {"/dev/disk/by-partlabel/spm_a"},
+ {"/dev/disk/by-partlabel/protect_a"},
+ {"/dev/disk/by-partlabel/mcf1_a"},
+ {"/dev/disk/by-partlabel/mcf2_a"},
+ {"/dev/disk/by-partlabel/mcupm_a"},
+ {"/dev/disk/by-partlabel/sspm_a"},
+ {"/dev/disk/by-partlabel/dpm_a"},
+ {"/dev/disk/by-partlabel/pi_img_a"},
+ {"/dev/disk/by-partlabel/hsm_os_a"},
+ {"/dev/disk/by-partlabel/bl2_a"},
+ {"/dev/disk/by-partlabel/bl33_a"}
+};
+
+
+char partition_filename_b[][FILENAME_SIZE] = {
+ {"/dev/disk/by-partlabel/system_b"},
+ {"/dev/disk/by-partlabel/boot_b"},
+ {"/dev/disk/by-partlabel/tee_b"},
+ {"/dev/disk/by-partlabel/md1img_b"},
+ {"/dev/disk/by-partlabel/md1dsp_b"},
+ {"/dev/disk/by-partlabel/vbmeta_b"},
+ {"/dev/disk/by-partlabel/oemapp_b"},
+ {"/dev/disk/by-partlabel/oemapp2_b"},
+ {"/dev/disk/by-partlabel/medmcu_b"},
+ {"/dev/disk/by-partlabel/spm_b"},
+ {"/dev/disk/by-partlabel/protect_b"},
+ {"/dev/disk/by-partlabel/mcf1_b"},
+ {"/dev/disk/by-partlabel/mcf2_b"},
+ {"/dev/disk/by-partlabel/mcupm_b"},
+ {"/dev/disk/by-partlabel/sspm_b"},
+ {"/dev/disk/by-partlabel/dpm_b"},
+ {"/dev/disk/by-partlabel/pi_img_b"},
+ {"/dev/disk/by-partlabel/hsm_os_b"},
+ {"/dev/disk/by-partlabel/bl2_b"},
+ {"/dev/disk/by-partlabel/bl33_b"}
+};
+
+
+
+
+char partition_filename[][FILENAME_SIZE] = {
+ {"system"},
+ {"boot"},
+ {"tee"},
+ {"md1img"},
+ {"md1dsp"},
+ {"vbmeta"},
+ {"oemapp"},
+ {"oemapp2"},
+ {"medmcu"},
+ {"spm"},
+ {"protect"},
+ {"mcf1"},
+ {"mcf2"},
+ {"mcupm"},
+ {"sspm"},
+ {"dpm"},
+ {"pi_img"},
+ {"hsm_os"},
+ {"bl2"},
+ {"bl33"}
+};
+//+10
+
+unsigned int delta_head[128]={0}; //512/4 128/2=64
+
+#define FOTA_DELTA_MTD "/dev/mtd47"
+#define FOTA_UCI_MODULE "lynq_fota"
+#define FOTA_UCI_FILE "lynq_uci"
+#define FOTA_UCI_ADDR "lynq_fota_addr"
+#define FOTA_UCI_STATE "lynq_fota_state"
+
+#define FILE_UPDATE_STATE "/data/.update_status"
+#define FILE_UPDATE_FLAG "/tmp/update_flag"
+#define FILE_FOTA_STATE "/data/.fota_status"
+
+#define NAND_PAGE_SIZE 4096
+
+
+#define BOOTDEV_TYPE_NAND 1
+
+#define BACKUP_ADDR_FLAG 0xffffffff
+#define FILE_BACKUP "/data/.backup"
+
+#define SLOT_A 0
+#define SLOT_B 1
+
+#define FULL_HEAD "full-ota"
+
+//xf.li@20230822 add for ab rollback start
+#define DEV_SYSTEM_A "/dev/disk/by-partlabel/system_a"
+#define DEV_SYSTEM_B "/dev/disk/by-partlabel/system_b"
+
+#define DEV_BOOT_A "/dev/disk/by-partlabel/boot_a"
+#define DEV_BOOT_B "/dev/disk/by-partlabel/boot_b"
+
+#define DEV_SPM_A "/dev/disk/by-partlabel/spm_a"
+#define DEV_SPM_B "/dev/disk/by-partlabel/spm_b"
+
+#define DEV_MD1IMG_A "/dev/disk/by-partlabel/md1img_a"
+#define DEV_MD1IMG_B "/dev/disk/by-partlabel/md1img_b"
+
+#define DEV_TEE_A "/dev/disk/by-partlabel/tee_a"
+#define DEV_TEE_B "/dev/disk/by-partlabel/tee_b"
+
+#define DEV_VBMETA_A "/dev/disk/by-partlabel/vbmeta_a"
+#define DEV_VBMETA_B "/dev/disk/by-partlabel/vbmeta_b"
+
+#define DEV_BL2_A "/dev/disk/by-partlabel/bl2_a"
+#define DEV_BL2_B "/dev/disk/by-partlabel/bl2_b"
+
+#define DEV_BL33_A "/dev/disk/by-partlabel/bl33_a"
+#define DEV_BL33_B "/dev/disk/by-partlabel/bl33_b"
+
+#define DEV_MEDMCU_A "/dev/disk/by-partlabel/medmcu_a"
+#define DEV_MEDMCU_B "/dev/disk/by-partlabel/medmcu_b"
+
+#define DEV_OEMAPP_A "/dev/disk/by-partlabel/oemapp_a"
+#define DEV_OEMAPP_B "/dev/disk/by-partlabel/oemapp_b"
+
+#define DEV_OEMAPP2_A "/dev/disk/by-partlabel/oemapp2_a"
+#define DEV_OEMAPP2_B "/dev/disk/by-partlabel/oemapp2_b"
+
+
+#define DEV_MISC "/dev/disk/by-partlabel/misc"
+
+#define BACKUP_UBI_NUM 31 //max ubi number
+#define MTD_SYSTEM_A 14
+#define MTD_SYSTEM_B 15
+#define MD5_RETRY_TIME 3
+#define MD5_VERFY_ERROR 5
+#define MD5_READ_BUFFER_LEN 4*1024
+#define FOTA_FIRST 0
+#define RECOVER_FIRST 1
+int fota_interrupt = 1;
+//xf.li@20230822 add for ab rollback end
+
+
+//int fd_system_a,fd_system_b,fd_boot_a,fd_boot_b,fd_tee_a,fd_tee_b,fd_bl2,fd_bl33,fd_delta,fd_curr,fd_log,fd_update_status,fd_md1img_a,fd_md1img_b,fd_fota_status,fd_md1dsp_a,fd_md1dsp_b,fd_vbmeta_a,fd_vbmeta_b,fd_oemapp_a,fd_oemapp_b,fd_oemapp2_a,fd_oemapp2_b,fd_medmcu_a,fd_medmcu_b,fd_bl33_a,fd_bl33_b;
+int fd_delta,fd_curr,fd_log,fd_update_status,fd_fota_status;
+int fd_write,fd_read;
+
+static unsigned int delta_offset = 0;
+static unsigned int now_patch = 0;
+unsigned int current_slot = 0;
+unsigned char rock_debug_buffer[512];
+char g_delta_mtd[16];
+int g_addr_flag = 0;
+
+
+OTA_STATUS fota_status;
+UPDATE_INFO up_info;
+
+
+extern const hw_module_t HAL_MODULE_INFO_SYM;
+boot_control_module_t* module;
+
+static void lynq_init_wake_lock_func(void);
+static void lynq_fota_grab_artial_wake_lock(void);
+static void lynq_fota_release_wake_lock(void);
+int check(int sys_size);
+int check_cpu();
+
+static const char hex_chars[] = "0123456789abcdef";
+
+/**
+ * @brief The following is the wake up
+ * start
+ */
+
+#define ANDROID_WAKE_LOCK_NAME "fota-interface"
+
+void *dlHandle_wakelock;
+
+enum {
+ PARTIAL_WAKE_LOCK = 1, // the cpu stays on, but the screen is off
+ FULL_WAKE_LOCK = 2 // the screen is also on
+};
+
+// while you have a lock held, the device will stay on at least at the
+// level you request.
+
+int (*acquire_wake_lock)(int lock, const char* id);
+int (*release_wake_lock)(const char* id);
+
+void convert_hex(unsigned char *sha, unsigned char *shastr)
+{
+ int i;
+ int j = 0;
+ unsigned int c;
+
+ for (i = 0; i < 20; i++) {
+ c = (sha[i] >> 4) & 0x0f;
+ shastr[j++] = hex_chars[c];
+ shastr[j++] = hex_chars[sha[i] & 0x0f];
+ }
+ shastr[40] = '\0';
+}
+
+
+
+
+int rock_mismatch(void* ctx, unsigned char* buf, unsigned int start, unsigned int size,
+ unsigned int source_hash,unsigned int target_hash) {
+
+ return 0;
+}
+
+int rock_fatal(void* ctx, int error_code) {
+ return 0;
+}
+
+void rock_trace(void* ctx, const char* fmt, ...) {
+
+ va_list ap;
+ memset(rock_debug_buffer,0x0,sizeof(rock_debug_buffer));
+ va_start (ap, fmt);
+
+
+ vsnprintf(rock_debug_buffer,sizeof(rock_debug_buffer),fmt,ap);
+ LYDBGLOG("+[UA]: %s",rock_debug_buffer);
+
+
+ va_end (ap);
+
+}
+
+static int save_fota_status()
+{
+ int err;
+ fd_fota_status = open(FILE_FOTA_STATE,O_RDWR | O_CREAT,0777);
+
+ if (fd_fota_status < 0) {
+ err = errno;
+ RLOGD("+[UA]: save_fota_status: Error opening metadata file: %s\n",strerror(errno));
+ return -err;
+ }
+
+ write(fd_fota_status, &fota_status,sizeof(fota_status));
+ sync();
+ close(fd_fota_status);
+}
+
+int lynq_read_process(void)
+{
+ int err;
+ fd_fota_status = open(FILE_FOTA_STATE,O_RDWR | O_CREAT,0777);
+
+ if (fd_fota_status < 0) {
+ err = errno;
+ RLOGD("+[UA]: save_fota_status: Error opening metadata file: %s\n",strerror(errno));
+ return -err;
+ }
+ memset(&fota_status, 0 , sizeof(fota_status));
+ read(fd_fota_status, &fota_status,sizeof(fota_status));
+ sync();
+ close(fd_fota_status);
+ return fota_status.ota_run;
+}
+
+static int save_fota_info()
+{
+ int err;
+ fd_update_status = open(FILE_UPDATE_STATE,O_RDWR);
+
+ if (fd_update_status < 0) {
+ err = errno;
+ RLOGD("+[UA]: save_fota_status: Error opening metadata file: %s\n",strerror(errno));
+ return -err;
+ }
+
+ write(fd_update_status, &up_info, sizeof(fota_status));
+ sync();
+ close(fd_update_status);
+}
+
+
+
+void rock_progress(void* ctx, int percent) {
+ int i = 0;
+ static int tmp_percent = -1;
+ rock_trace(ctx, "rock update progress %d\n", percent);
+
+ if (tmp_percent != percent) {
+ tmp_percent = percent;
+ if (percent > 20) {
+ i = fota_status.ota_run;
+ if (fota_status.update_status[i-1].check_delta != PASS) {
+ fota_status.update_status[i-1].check_delta = PASS;
+ fota_status.update_status[i-1].check_rom= PASS;
+ save_fota_status();
+ }
+ }
+ }
+}
+
+int rock_process_block(void* ctx, unsigned char* data, unsigned int start, unsigned int size){
+
+ int writen = 0;
+ int ret,err;
+
+ if (start == BACKUP_ADDR_FLAG) {
+ int fd_backup = open(FILE_BACKUP,O_RDWR | O_CREAT,0777);
+ while (writen < size) {
+ write(fd_backup,data,ROCK_DEFAULT_BLOCK_SIZE);
+ sync();
+ writen += ROCK_DEFAULT_BLOCK_SIZE;
+ }
+ close(fd_backup);
+ return size;
+ }
+
+ writen = 0;
+
+ if (mtk_device_wrap_seek(fd_write, start, SEEK_SET) < 0) {
+ err = errno;
+ rock_trace(ctx, "mtk_device_wrap_seek write\n");
+ return err;
+ }
+
+ while (writen < size) {
+ ret = mtk_device_wrap_write(fd_write,data+writen, ROCK_DEFAULT_BLOCK_SIZE);
+ writen += ROCK_DEFAULT_BLOCK_SIZE;
+ }
+
+
+ return size;
+}
+
+int rock_write_block(void* ctx, unsigned char* src, unsigned int start, unsigned int size){
+
+#if 0
+
+ int writen = 0;
+ int ret,err;
+
+
+ if (start == BACKUP_ADDR_FLAG) {
+ int fd_backup = open(FILE_BACKUP,O_RDWR | O_CREAT,0777);
+ while (writen < size) {
+ write(fd_backup,src,ROCK_DEFAULT_BLOCK_SIZE);
+ sync();
+ writen += ROCK_DEFAULT_BLOCK_SIZE;
+ }
+ close(fd_backup);
+ return size;
+ }
+
+ writen = 0;
+
+ if (mtk_device_wrap_seek(fd_curr, start, SEEK_SET) < 0) {
+ err = errno;
+ rock_trace(ctx, "mtk_device_wrap_seek write\n");
+ return err;
+ }
+
+ while (writen < size) {
+ ret = mtk_device_wrap_write(fd_curr,src+writen, ROCK_DEFAULT_BLOCK_SIZE);
+ writen += ROCK_DEFAULT_BLOCK_SIZE;
+ }
+
+
+#endif
+
+ return size;
+
+}
+
+int rock_read_block(void* ctx, unsigned char* dest, unsigned int start, unsigned int size){
+
+
+ int ret,err;
+
+
+ if (start == BACKUP_ADDR_FLAG) {
+ int fd_backup = open(FILE_BACKUP,O_RDONLY);
+ read(fd_backup,dest,size);
+ sync();
+ close(fd_backup);
+ return size;
+ }
+
+
+
+ if (mtk_device_wrap_seek(fd_read, start, SEEK_SET) < 0) {
+ err = errno;
+ rock_trace(ctx, "mtk_device_wrap_seek read block err\n");
+ }
+
+ do {
+
+ ret = mtk_device_wrap_read(fd_read, dest, size);
+
+ if (ret == 0) {
+ break;
+ } else if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ err = -errno;
+ rock_trace(ctx,"%s Error reading metadata file\n");
+
+ mtk_device_wrap_close(fd_read);
+
+ return err;
+ }
+ size -= ret;
+ dest += ret;
+ } while(size > 0);
+
+
+ return ret;
+
+
+}
+
+
+int rock_read_delta(void* ctx, unsigned char* dest, unsigned int offset, unsigned int size){
+
+ int ret = 0,err = 0;
+
+ if(g_addr_flag == 1)
+ {
+ if (mtk_device_wrap_seek(fd_delta, offset + delta_offset, SEEK_SET) < 0) {
+ err = -errno;
+ rock_trace(ctx, "mtk_device_wrap_seek df_delta err\n");
+ return err;
+ }
+
+ do {
+
+ ret = mtk_device_wrap_read(fd_delta, dest, size);
+
+ if (ret == 0)
+ {
+ break;
+ }
+ else if (ret < 0)
+ {
+ if (errno == EINTR)
+ {
+ continue;
+ }
+ err = -errno;
+ rock_trace(ctx," Error reading metadata file\n");
+ mtk_device_wrap_close(fd_delta);
+ return err;
+ }
+ size -= ret;
+ dest += ret;
+ } while(size > 0);
+ }
+ else
+ {
+ if (lseek(fd_delta, offset + delta_offset, SEEK_SET) < 0)
+ {
+ err = -errno;
+ rock_trace(ctx, "mtk_device_wrap_seek df_delta err\n");
+ return err;
+ }
+ do {
+ ret = read(fd_delta, dest, size);
+ if (ret == 0)
+ {
+ break;
+ }
+ else if (ret < 0)
+ {
+ if (errno == EINTR)
+ {
+ continue;
+ }
+ err = -errno;
+ rock_trace(ctx," Error reading metadata file\n");
+ close(fd_delta);
+ return err;
+ }
+ size -= ret;
+ dest += ret;
+ } while(size > 0);
+ }
+
+ return ret;
+
+}
+
+int rock_get_blocksize(void* ctx) {
+ return ROCK_DEFAULT_BLOCK_SIZE;
+}
+
+int rock_read_file(void* ctx, void* name, unsigned char* dest, unsigned int offset, unsigned int size){return 0;}
+int rock_write_file(void* ctx, void* name, unsigned char* src, unsigned int offset, unsigned int size){return 0;}
+int rock_delete_file(void* ctx, void* name){return 0;}
+/* ROCK IPL end */
+
+void delete_enter(char data[])
+{
+ char *find = strchr(data, ':');
+ if(find)
+ *find = '\0';
+ return ;
+}
+/*
+int get_delta_mtd(char *delta_mtd)
+{
+ FILE *fp;
+ char mtd_buffer[16] = {0};
+ fp = popen("cat /proc/mtd|grep delta|awk '{print $1}'","r");
+ if(fp == NULL)
+ {
+ RLOGD("get_delta_mtd popen fail\n");
+ return -1;
+ }
+ fgets(mtd_buffer, sizeof(mtd_buffer), fp);
+ if(strlen(mtd_buffer) == 0)
+ {
+ RLOGD("get delta mtd fail\n");
+ pclose(fp);
+ return -1;
+ }
+ delete_enter(mtd_buffer);
+ sprintf(delta_mtd,"/dev/%s", mtd_buffer);
+ RLOGD("delta_mtd:%s\n", delta_mtd);
+ pclose(fp);
+ return 0;
+}
+*/
+
+int get_file_size(void)
+{
+ FILE *stream;
+ stream = fopen("/tmp/fota.delta", "r");
+ long file_size = -1;
+ long cur_offset = ftell(stream);
+ if (cur_offset == -1)
+ {
+ printf("ftell failed :%s\n", strerror(errno));
+ return -1;
+ }
+ if (fseek(stream, 0, SEEK_END) != 0)
+ {
+ printf("fseek failed: %s\n", strerror(errno));
+ return -1;
+ }
+ file_size = ftell(stream);
+ if (file_size == -1)
+ {
+ printf("ftell failed :%s\n", strerror(errno));
+ }
+ if (fseek(stream, cur_offset, SEEK_SET) != 0)
+ {
+ printf("fseek failed: %s\n", strerror(errno));
+ return -1;
+ }
+ fclose(stream);
+ if(file_size >52428800)
+ {
+ return -1;
+ }
+ return 0;
+}
+
+static int init_dev_fd()
+{
+
+ int err;
+ int ret;
+ int result;
+ char lynq_fota_addr[64] = {0};
+ char fota_name[]= "fota.delta";
+ int n;
+ if(0 != lynq_fota_get_addr_value(lynq_fota_addr))
+ {
+ return E_ROCK_FOTA_ADDR;
+ }
+ RLOGD("+[UA]: get fota pack addr: %s\n",lynq_fota_addr);
+
+
+ if(!(strcmp(lynq_fota_addr, "/tmp/fota.delta")))
+ {
+ ret = get_file_size();
+ if(ret != 0)
+ {
+ RLOGE("the delta size over 50M\n");
+ return -1;
+ }
+
+ strcpy(g_delta_mtd, FOTA_DELTA_MTD);
+ result = test_write_delta(lynq_fota_addr, g_delta_mtd);
+ if(result != 0)
+ {
+ RLOGE("fota.delta write into mtd fail !\n");
+ }
+ strcpy(lynq_fota_addr, g_delta_mtd);
+ if(lynq_fota_set_addr_value(lynq_fota_addr,strlen(lynq_fota_addr)))
+ {
+ RLOGE("set addr fail\n");
+ return 1;
+ }
+ RLOGD("+[UA]: get fota pack addr: %s\n", lynq_fota_addr);
+ fd_delta = mtk_device_wrap_open(lynq_fota_addr,O_RDWR);
+
+ if (fd_delta < 0) {
+ err = errno;
+ RLOGE("+[UA]: Error opening fota file: %s\n",strerror(errno));
+ mtk_device_wrap_close(fd_delta);
+ return -err;
+ }
+ g_addr_flag = 1;
+
+ }
+ else if(!(strcmp(lynq_fota_addr, g_delta_mtd)))
+ {
+ fd_delta = mtk_device_wrap_open(lynq_fota_addr,O_RDWR);
+
+ if (fd_delta < 0) {
+ err = errno;
+ RLOGE("+[UA]: Error opening fota file: %s\n",strerror(errno));
+ mtk_device_wrap_close(fd_delta);
+ return -err;
+ }
+ g_addr_flag = 1;
+ }
+ else
+ {
+ fd_delta = open(lynq_fota_addr,O_RDWR);
+
+ if (fd_delta < 0) {
+ err = errno;
+ RLOGE("+[UA]: Error opening fota file: %s\n",strerror(errno));
+ close(fd_delta);
+ return -err;
+ }
+ g_addr_flag = 0;
+
+ }
+
+ fd_update_status = open(FILE_UPDATE_STATE,O_RDWR | O_CREAT,0777);
+ if (fd_update_status < 0) {
+ err = errno;
+ RLOGE("+[UA]: Error opening metadata file: %s\n",strerror(errno));
+ close(fd_update_status);
+ return -err;
+ }
+ memset(&up_info, 0, sizeof(up_info));
+ lseek(fd_update_status,0,SEEK_SET);
+ read(fd_update_status,(unsigned char *)&up_info,sizeof(up_info));
+ close(fd_update_status);
+ return 0;
+}
+
+
+
+
+
+static int close_dev_fd(int fd)
+{
+ close(fd);
+}
+
+
+
+static int reboot_device() {
+
+ reboot(RB_AUTOBOOT);
+
+ while (1) pause();
+}
+
+
+
+int test_write_delta(char *source, char *target)
+{
+ int fd_source,fd_target,size;
+ char buf[32];
+ char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
+ char lynq_fota_addr[64];
+ fd_source = open(source,O_RDONLY);
+
+ if (fd_source < 0) {
+ RLOGE("+[UA]: open source error\n");
+ return 1;
+ }
+
+ fd_target = mtk_device_wrap_open(target,O_RDWR);
+
+ if (fd_target < 0) {
+ mtk_device_wrap_close(fd_target);
+ close(fd_source);
+ RLOGE("+[UA]: open target error\n");
+ return 1;
+ }
+
+ if(!(strcmp(lynq_fota_addr, g_delta_mtd)))
+ {
+ sprintf(buf,"flash_eraseall %s", g_delta_mtd);
+ system(buf);
+ }
+ while(( size = read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0) {
+ mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
+ }
+
+ mtk_device_wrap_close(fd_target);
+ close(fd_source);
+ return 0;
+}
+
+
+int nand_copyto_nand(char *source, char *target)
+{
+ int fd_source,fd_target,size;
+
+ char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
+
+ fd_source = mtk_device_wrap_open(source,O_RDONLY);
+
+ if (fd_source < 0) {
+ RLOGE("+[UA]: open source error\n");
+ return 1;
+ }
+
+ fd_target = mtk_device_wrap_open(target,O_RDWR);
+
+ if (fd_target < 0) {
+ mtk_device_wrap_close(fd_target);
+ mtk_device_wrap_close(fd_source);
+ RLOGE("+[UA]: open target error\n");
+ return 1;
+ }
+
+ while(( size = mtk_device_wrap_read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0) {
+ mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
+ }
+
+ mtk_device_wrap_close(fd_target);
+ mtk_device_wrap_close(fd_source);
+ return 0;
+}
+
+int delta_copyto_nand(unsigned int start,int size)
+{
+
+ char delta_data[NAND_PAGE_SIZE];
+ unsigned int ret = 0;
+ int err;
+
+
+ if(g_addr_flag == 1)
+ {
+ if (mtk_device_wrap_seek(fd_delta, start, SEEK_SET) < 0)
+ {
+ LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
+ return -1;
+ }
+
+ if (mtk_device_wrap_seek(fd_curr, 0, SEEK_SET) < 0)
+ {
+ LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
+ return -1;
+ }
+
+ do {
+ memset(delta_data,0,NAND_PAGE_SIZE);
+ ret = mtk_device_wrap_read(fd_delta, delta_data, NAND_PAGE_SIZE);
+
+ if (ret == 0)
+ {
+ break;
+ }
+ else if (ret < 0)
+ {
+ if (errno == EINTR)
+ {
+ continue;
+ }
+ err = -errno;
+ return err;
+ }
+ size -= NAND_PAGE_SIZE;
+ mtk_device_wrap_write(fd_curr,delta_data,NAND_PAGE_SIZE);
+ //mtk_device_wrap_write(fd_curr,delta_data,ret);
+ } while(size > 0);
+
+ }
+ else
+ {
+ if (lseek(fd_delta, start, SEEK_SET) < 0) {
+ LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
+ return -1;
+ }
+
+ if (mtk_device_wrap_seek(fd_curr, 0, SEEK_SET) < 0) {
+ LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
+ return -1;
+ }
+
+ do {
+ memset(delta_data,0,NAND_PAGE_SIZE);
+ ret = read(fd_delta, delta_data, NAND_PAGE_SIZE);
+
+ if (ret == 0)
+ {
+ break;
+ }
+ else if (ret < 0)
+ {
+ if (errno == EINTR)
+ {
+ continue;
+ }
+ err = -errno;
+ return err;
+ }
+ size -= NAND_PAGE_SIZE;
+ mtk_device_wrap_write(fd_curr,delta_data,NAND_PAGE_SIZE);
+ //mtk_device_wrap_write(fd_curr,delta_data,ret);
+
+ } while(size > 0);
+ }
+
+ return 0;
+}
+
+
+unsigned char ram_buffer[ROCK_RAM_LEN];
+
+int check(int sys_size)
+{
+ int fd;
+ int i=0;
+ int j=0;
+ int num=i;
+ int n = 0;
+ const uint8_t data[] = { 0x74, 0x77, 0x6f, 0x63, 0x6f, 0x72, 0x65};
+ const char * core_flag="twocore\n";
+
+ uint8_t buffer[16];
+
+ if(sys_size == 0)//for only upgrade oemapp and oemapp2
+ {
+ return 0;
+ }
+ n = strlen(core_flag);
+ lseek(fd_delta,520,SEEK_SET);
+ lseek(fd_delta,sys_size,SEEK_CUR);
+ lseek(fd_delta, -1*n, SEEK_CUR);
+ read(fd_delta, buffer, n);
+ lseek(fd_delta,0,SEEK_SET);//file reset
+ if (memcmp(buffer, core_flag, n) == 0)
+ {
+ return 0;
+ }
+ return -1;
+
+}
+
+int check_cpu(void)
+{
+ int i=0;
+ int ret;
+ char buffer[3][64];
+ FILE *fp;
+ char num;
+ fp = popen("od -x /proc/device-tree/chosen/atag,devinfo","r");
+
+ for(i=0;i<3;i++)
+ {
+ fgets(buffer[i], 64, fp);
+ }
+
+ for(i=0;i<3;i++)
+ {
+ RLOGD("buffer[i] = %s\n",buffer[i]);
+ }
+ RLOGD("%c\n", buffer[2][14]);
+
+ num = buffer[2][14];
+
+
+ RLOGE("num=%c\n", num);
+ if(num == '0' || num == '1')
+ {
+ printf("this is four core\n");
+ return 4;
+ }
+ else if(num == '2' || num == '3')
+ {
+ printf("this is two core\n");
+ return 2;
+ }
+ else
+ {
+ RLOGE("this char is error\n");
+ return -1;
+ }
+ pclose(fp);
+
+ return -1;
+}
+
+
+
+static int rock_update_main(unsigned int rom_base, unsigned int backup_base, unsigned int backup_len, int read_rom_directly, int first_run, int switch_slot_flag, int
+reboot_flag, int backup_mode) {
+ int status,err,start,fd;
+ int ret = 0;
+ int i = 0;
+ int retry_cnt = 0;
+ int cpu_flag;
+ IOT_UPDATA_CONTEXT ctx;
+
+ //OTA_STATUS fota_status;
+
+
+ const hw_module_t* hw_module;
+ unsigned int slot;
+
+ unsigned int update_mode = MODE_NORMAL;
+ unsigned int delta_size;
+ unsigned char full_header[9];
+
+ char digest_s[SHA_DIGEST_SIZE];
+ char digest_t[SHA_DIGEST_SIZE];
+ char str_sha[40];
+ char cmd_sys[100];
+ int core_num;
+ int sha_size = 0;
+ int is_need_fullupdate = 0;
+ int fd_partition_a,fd_partition_b;
+//xf.li@20230830 add for ab_recover start
+ fd = open(FILE_UPDATE_FLAG,O_RDWR | O_CREAT,0777);
+ if (fd < 0)
+ {
+ RLOGE("+[UA]: can't open file /tmp/update_flag.\n");
+ return -1;
+ }
+ close(fd);
+//xf.li@20230830 add for ab_recover end
+ memset(&fota_status,0,sizeof(fota_status));
+ fota_status.ota_run = 1;
+ save_fota_status();
+
+ hw_module = &HAL_MODULE_INFO_SYM;
+
+ if (!hw_module ||
+ strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
+ ret = -EINVAL;
+ }
+ if (ret != 0) {
+ RLOGE("+[UA]: Error loading boot_control HAL implementation.\n");
+ return -1;
+ }
+
+ module = (boot_control_module_t*)hw_module;
+ module->init(module);
+
+
+ if (module == NULL) {
+ RLOGE("+[UA]: Error getting bootctrl module.\n");
+ return -1;
+ }
+
+ lynq_init_wake_lock_func();
+ lynq_fota_grab_artial_wake_lock();
+ /************* Bootctrl Init End *************/
+
+ current_slot = module->getCurrentSlot(module);
+
+ int is_successful = module->isSlotMarkedSuccessful(module, current_slot);
+
+ RLOGE("Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
+ if((current_slot != 0)&&(current_slot != 1))
+ {
+ RLOGE("+[UA]: Error getting bootctrl current_slot.\n");
+ return -1;
+ }
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.rom_base = 0;
+ ctx.ram_base =(unsigned char *)&ram_buffer[0];
+ ctx.ram_len = ROCK_RAM_LEN;
+ ctx.backup_base = BACKUP_ADDR_FLAG;
+ //ctx.backup_len = ROCK_DEFAULT_BLOCK_SIZE;
+ ctx.backup_len = 0;
+ ctx.update_nvram = 0;
+ ctx.read_rom_directly = read_rom_directly;
+ //ctx.first_run = first_run;
+ ctx.first_run = 1;
+
+ if(0 != init_dev_fd())
+ {
+ RLOGE("+[UA]: get fota addr error\n");
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return E_ROCK_FOTA_ADDR;
+ }
+
+ RLOGE("+[UA]: up_info.ota_run = %d\n",up_info.ota_run);
+
+#if 0
+ if ((up_info.ota_run>PATCH_BL33)||(up_info.ota_run<PATCH_SYSTEM))
+ {
+ up_info.ota_run = 0;
+ }
+#endif
+ up_info.ota_run = 0;
+ if(backup_mode == 1)
+ {
+ if(current_slot == 0)
+ {
+ update_mode = MODE_A2B;
+ }else
+ {
+ update_mode = MODE_B2A;
+ }
+ }
+ else
+ {
+ update_mode = MODE_NORMAL;
+ }
+
+ RLOGE("+[UA]: up_info.fota_flag = %s\n",up_info.fota_flag);
+ RLOGE("+[UA]: update_mode = %d\n",update_mode);
+
+ memset(&delta_head, 0, sizeof(delta_head));
+ if(g_addr_flag == 1)
+ {
+ RLOGD("fd_delta=%d\n", fd_delta);
+ ret = mtk_device_wrap_read(fd_delta, (char *)&delta_head[0], sizeof(delta_head));
+ if(ret <0)
+ {
+ return -1;
+ }
+ }
+ else
+ {
+ read(fd_delta, (char *)&delta_head[0], sizeof(delta_head));
+ }
+
+
+ delta_size = 0;
+ sha_size = 0;
+ for (i = 0;i<REAL_OTA_ROLE; i++) {
+ if (delta_head[i] > 0) {
+ fota_status.update_status[i].need_update = 1;
+ delta_size+=delta_head[i];
+ }
+ RLOGE("+[UA]: %s,delta size = %d, i=%d\n",partition_filename[i],delta_head[i], i);
+ }
+
+ for(i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE); i++) {
+ if (delta_head[i] > 0) {
+ fota_status.update_status[i].need_update = 1;
+ sha_size+=delta_head[i];
+ }
+ RLOGE("+[UA]: %s,full size = %d, i=%d\n",partition_filename[i-MAX_OTA_ROLE/2],delta_head[i], i);
+ }
+
+ core_num= check_cpu();
+ if(core_num == 2)
+ {
+ cpu_flag = check(delta_head[64]);
+ if(cpu_flag < 0)
+ {
+ RLOGE("cpu core is error\n");
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+ else
+ {
+ RLOGE("cpu core match\n");
+ }
+ }
+ else if(core_num == 4)
+ {
+ RLOGE("the cpu core is four!!!\n");
+ }
+ else
+ {
+ RLOGE("read the cpu core fail");
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+
+ fota_status.switch_slot = WAIT;
+ save_fota_status();
+
+ is_need_fullupdate = 0;
+ if(sha_size>0) {
+ is_need_fullupdate = 1;
+ sha_size+=8;
+ }
+
+ sha_size+=delta_size;
+
+ memset(digest_s,0,SHA_DIGEST_SIZE);
+ memset(digest_t,0,SHA_DIGEST_SIZE);
+ memset(str_sha,0,40);
+ if(g_addr_flag == 1)
+ {
+ ret = mtk_device_wrap_seek(fd_delta, sha_size + sizeof(delta_head), SEEK_SET);
+ if(ret < 0)
+ {
+ RLOGE("mtk_device_wrap_seek fail\n");
+ return -1;
+ }
+ ret = mtk_device_wrap_read(fd_delta, digest_s, SHA_DIGEST_SIZE);
+ if(ret < 0)
+ {
+ RLOGE("mtk_device_wrap_read fail\n");
+ return -1;
+ }
+ }
+ else
+ {
+ lseek(fd_delta, sha_size + sizeof(delta_head), SEEK_SET);
+ read(fd_delta, digest_s, SHA_DIGEST_SIZE);
+ }
+
+ convert_hex(digest_s,str_sha);
+ RLOGE("+[UA]: delta save sha = %s\n",str_sha);
+ if(g_addr_flag == 1)
+ {
+ ROCK_SHA_FILE(fd_delta,sizeof(delta_head),sha_size,digest_t);
+ }
+ else
+ {
+ ROCK_SHA_FILE_COMMON(fd_delta,sizeof(delta_head),sha_size,digest_t);
+ }
+ memset(str_sha,0,40);
+ convert_hex(digest_t,str_sha);
+ RLOGE("+[UA]: delta calc sha = %s\n",str_sha);
+
+ if(memcmp(digest_s,digest_t,SHA_DIGEST_SIZE)==0) {
+
+ RLOGE("sha verify pass\n");
+
+ }else{
+ RLOGE("delta sha verify fial!\n");
+
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+
+ memset(digest_s,0,SHA_DIGEST_SIZE);
+ memset(digest_t,0,SHA_DIGEST_SIZE);
+
+
+ //delta_offset = DELTA_HEARD_SIZE;
+ delta_offset = sizeof(delta_head);
+
+ for(i = 0;i<REAL_OTA_ROLE; i++){ //diff
+ //now_patch = i+1;
+ if (i>0) {
+ delta_offset+=delta_head[i-1];
+ }
+ if((delta_head[i]>0) && (up_info.ota_run<=(i+1))){
+ now_patch = i + 1;
+#if 0
+ if (up_info.ota_run == now_patch) //升级ps断电?
+ {
+ ctx.first_run = 0;
+
+ }else{
+ ctx.first_run = 1;
+ }
+#endif
+ ctx.first_run = 1; //always
+ RLOGD("+[UA]: PATCH %s,ctx.first_run = %d\n", partition_filename[i] ,ctx.first_run);
+ up_info.ota_run = now_patch;
+
+ if(current_slot==SLOT_B) {
+ sprintf(cmd_sys,"flash_eraseall %s",partition_filename_a[i]);
+ }else{
+ sprintf(cmd_sys,"flash_eraseall %s",partition_filename_b[i]);
+ }
+ system(cmd_sys);
+
+
+ fd_partition_a = mtk_device_wrap_open(partition_filename_a[i],O_RDWR);
+ if (fd_partition_a < 0) {
+ err = errno;
+ RLOGE("+[UA]: Error opening id_a[%d] file: %s\n",i,strerror(errno));
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -err;
+ }
+
+ fd_partition_b = mtk_device_wrap_open(partition_filename_b[i],O_RDWR);
+ if (fd_partition_b < 0) {
+ err = errno;
+ RLOGE("+[UA]: Error opening id_b[%d] file: %s\n",i,strerror(errno));
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -err;
+ }
+ if(current_slot==SLOT_B){
+ fd_read = fd_partition_b;
+ fd_write = fd_partition_a;
+ } else {
+ fd_read = fd_partition_a;
+ fd_write = fd_partition_b;
+ }
+
+ fota_status.ota_run = i+1;
+ fota_status.update_status[i].check_delta = WAIT;
+ fota_status.update_status[i].check_rom = WAIT;
+ fota_status.update_status[i].update_result= WAIT;
+
+ save_fota_status();
+
+ up_info.ota_run = i+1;
+ save_fota_info();
+
+ RLOGE("+[UA]: Start upgrading %s.\n",partition_filename[i]);
+ status = iot_patch(&ctx);
+ RLOGE("+[UA]: %s upgrade result:%d\n",partition_filename[i],status);
+
+ //up_info.ota_run = 0;
+
+ //fota_status.ota_run = 0;
+ fota_status.update_status[i].update_result= status;
+ fota_status.update_result= status;
+
+ if((status == 0)||(status ==1))
+ {
+
+ fota_status.update_status[i].check_delta = PASS;
+ fota_status.update_status[i].check_rom = PASS;
+ RLOGE("+[UA]: %s upgrade success!!!\n",partition_filename[i]);
+
+ }else if(status == E_ROCK_INVALID_DELTA) {
+ fota_status.update_status[i].check_delta = ERROR;
+ fota_status.update_status[i].check_rom = WAIT;
+ }else if((status == E_ROCK_DELTA_MISMATCH)||(status == E_ROCK_DELTA_CHUNK_MISMATCH)) {
+ fota_status.update_status[i].check_delta = PASS;
+ fota_status.update_status[i].check_rom = ERROR;
+
+ }else{
+
+ //fota_status.update_status[PATCH_SYSTEM -1].check_delta = PASS;
+ //fota_status.update_status[PATCH_SYSTEM -1].check_rom = WAIT;
+ }
+
+ save_fota_status();
+
+
+ if ((status != 0) &&(status != 1))
+ {
+
+ up_info.fota_flag[0] = 'e';
+ up_info.fota_flag[1] = 'n';
+ up_info.fota_flag[2] = 'd';
+ up_info.update_result = status;
+ up_info.ota_run = 0;
+ save_fota_info();
+
+ mtk_device_wrap_close(fd_read);
+ mtk_device_wrap_close(fd_write);
+
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return status;
+ }
+ mtk_device_wrap_close(fd_read);
+ mtk_device_wrap_close(fd_write);
+
+ }
+
+ }
+
+
+
+ if (is_need_fullupdate == 1)
+ {
+
+ now_patch = 0;
+ up_info.ota_run = 0;
+
+ fota_status.switch_slot = WAIT;
+ save_fota_status();
+
+ if (g_addr_flag == 1)
+ {
+ if (mtk_device_wrap_seek(fd_delta, DELTA_HEARD_SIZE + delta_size, SEEK_SET) < 0)
+ {
+ err = errno;
+ RLOGE("+[UA]: mtk_device_wrap_seek df_delta err\n");
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+ mtk_device_wrap_read(fd_delta, full_header, DELTA_FULL_HEARD_SIZE);
+ }
+ else
+ {
+
+ if (lseek(fd_delta, DELTA_HEARD_SIZE + delta_size, SEEK_SET) < 0)
+ {
+ err = errno;
+ RLOGE("+[UA]: mtk_device_wrap_seek df_delta err\n");
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+ read(fd_delta, full_header, DELTA_FULL_HEARD_SIZE);
+
+ }
+
+ if (memcmp(full_header, "full-ota", DELTA_FULL_HEARD_SIZE) != 0) {
+ RLOGE("+[UA]: invalid full delta header\r\n");
+ up_info.fota_flag[0] = 'e';
+ up_info.fota_flag[1] = 'n';
+ up_info.fota_flag[2] = 'd';
+ up_info.update_result = -1;
+ up_info.ota_run = 0;
+ save_fota_info();
+
+ //for (i = FULL_SYSTEM;i<=FULL_BL33;i++){
+
+ for (i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE);i++){
+ if (fota_status.update_status[i].need_update ==1) {
+ fota_status.ota_run = i;
+ fota_status.update_status[i].check_delta = ERROR;
+ fota_status.update_status[i].check_rom= WAIT;
+ fota_status.update_status[i].update_result= ERROR;
+ }
+ }
+ fota_status.update_result = ERROR;
+ save_fota_status();
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -1;
+ }
+ }
+
+
+
+ delta_offset = DELTA_HEARD_SIZE + delta_size + DELTA_FULL_HEARD_SIZE;
+
+ for(i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE);i++) {
+
+ if (i>MAX_OTA_ROLE/2) {
+ delta_offset+=delta_head[i-1];
+ }
+ if(delta_head[i]>0) {
+
+ if(current_slot==SLOT_B) {
+ sprintf(cmd_sys,"flash_eraseall %s",partition_filename_a[i-MAX_OTA_ROLE/2]);
+ } else {
+ sprintf(cmd_sys,"flash_eraseall %s",partition_filename_b[i-MAX_OTA_ROLE/2]);
+ }
+ system(cmd_sys);
+
+ if(current_slot==SLOT_B) {
+ fd_partition_a = mtk_device_wrap_open(partition_filename_a[i-MAX_OTA_ROLE/2],O_RDWR);
+ if (fd_partition_a < 0) {
+ err = errno;
+ RLOGE("+[UA]: Error opening full id_a[%d] file: %s\n",i,strerror(errno));
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -err;
+ }
+ fd_curr = fd_partition_a;
+ }else{
+ fd_partition_b = mtk_device_wrap_open(partition_filename_b[i-MAX_OTA_ROLE/2],O_RDWR);
+ if (fd_partition_b < 0) {
+ err = errno;
+ RLOGE("+[UA]: Error opening full_id_b[%d] file: %s\n",i,strerror(errno));
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return -err;
+ }
+ fd_curr = fd_partition_b;
+ }
+ fota_status.ota_run = i+1;
+ save_fota_status();
+ up_info.ota_run = i+1;
+ save_fota_info();
+ retry_cnt = 0;
+ RLOGE("+[UA]: Start upgrading %s full.\n",partition_filename[i-MAX_OTA_ROLE/2]);
+ do{
+ status = delta_copyto_nand(delta_offset,delta_head[i]);
+ if(g_addr_flag == 1)
+ {
+ ROCK_SHA_FILE(fd_delta,delta_offset,delta_head[i],digest_s);
+ }
+ else
+ {
+ ROCK_SHA_FILE_COMMON(fd_delta,delta_offset,delta_head[i],digest_s);
+ }
+ ROCK_SHA_FILE(fd_curr,0,delta_head[i],digest_t);
+ retry_cnt++;
+ }while((strncmp(digest_s,digest_t,SHA_DIGEST_SIZE)!=0)&&(retry_cnt <= 3));
+
+ mtk_device_wrap_close(fd_curr);
+
+ RLOGE("+[UA]: %s full retry_cnt = %d\n",partition_filename[i-MAX_OTA_ROLE/2],retry_cnt);
+
+ if (retry_cnt>3) {
+ if (status == 0) {
+ status = retry_cnt;
+ }
+ if(current_slot==SLOT_B) {
+ nand_copyto_nand(partition_filename_b[i-MAX_OTA_ROLE/2],partition_filename_a[i-MAX_OTA_ROLE/2]);
+ }
+ else{
+ nand_copyto_nand(partition_filename_a[i-MAX_OTA_ROLE/2],partition_filename_b[i-MAX_OTA_ROLE/2]);
+ }
+ }
+
+ RLOGE("+[UA]: %s full upgrade result:%d\n",partition_filename[i-MAX_OTA_ROLE/2],status);
+
+ fota_status.update_result = status;
+ fota_status.update_status[i].update_result = status;
+ save_fota_status();
+
+ if (status != 0)
+ {
+
+ up_info.fota_flag[0] = 'e';
+ up_info.fota_flag[1] = 'n';
+ up_info.fota_flag[2] = 'd';
+ up_info.update_result = status;
+ up_info.ota_run = 0;
+ save_fota_info();
+ system("echo fota-interface >/sys/power/wake_unlock");
+ return status;
+ }
+
+ }
+
+ }
+
+
+
+
+ if(update_mode != MODE_NORMAL){ //need backup
+ if(current_slot == SLOT_A) {
+ up_info.fota_flag[0] = 'B';
+ up_info.fota_flag[1] = '-';
+ up_info.fota_flag[2] = 'A';
+
+ }else{
+ up_info.fota_flag[0] = 'A';
+ up_info.fota_flag[1] = '-';
+ up_info.fota_flag[2] = 'B';
+
+ }
+
+ }else{
+ up_info.fota_flag[0] = 'e';
+ up_info.fota_flag[1] = 'n';
+ up_info.fota_flag[2] = 'd';
+
+ }
+
+
+ up_info.update_result = status;
+ up_info.ota_run = 0;
+ save_fota_info();
+
+ //close_dev_fd(fd_curr);
+
+
+
+ close(fd_update_status);
+ sync();
+
+
+ slot = (current_slot == 0) ? 1 : 0;
+
+ RLOGE("+[UA]: slot SLOT = %d\n",slot);
+
+ if(switch_slot_flag==1)
+ {
+ module->setActiveBootSlot(module,slot);
+ RLOGE("+[UA]: upgrade is success!!!!\n");
+ }
+
+ fota_status.ota_run = 0;
+ fota_status.switch_slot = PASS;
+ fota_status.update_result = status;
+ save_fota_status();
+
+ sleep(5);
+ sync();
+ sleep(5);
+
+ system("echo fota-interface >/sys/power/wake_unlock");
+
+ if(reboot_flag==1){
+ reboot_device();
+ }
+
+ return status;
+}
+
+
+
+static void rock_fail_handler()
+{
+ int ret = 0;
+ RLOGD("rock_fail_handler start\n");
+ //ret = rock_update_main(0, 0, 0, 0, 1, 1);
+ if(ret)
+ {
+ RLOGD("fota update fail again!\n");
+ }
+}
+
+/* main entrpoint */
+int lynq_rock_main(int first_run)
+{
+
+ int ret = 0;
+
+
+ ret = rock_update_main(0, 0, 0, 0, first_run, 1, 1, 1);
+ RLOGD("rock_update_main ret = %d\n", ret);
+ if(ret)
+ {
+ RLOGD("fota update fail!\n");
+ }
+ return ret;
+}
+
+#endif
+
+//xf.li@20230403 add for verfy start
+int lynq_file_md5_verfy(char *source, unsigned char *source_md5, char *target)
+{
+ int fd, size, ret, is_system = 0;
+ int need_copy = 1;
+ int system_mtd_num = 0;
+ int system_ubi_num = BACKUP_UBI_NUM;//max ubi number
+ char cmd_ubi_attach[128] = {0};
+ char cmd_ubi_detach[128] = {0};
+ char md5_target_file_patch[128] = {0};
+
+ RLOGD("in lynq_file_md5_verfy, source:%s, target:%s\n", source, target);
+ if(strcmp(source, DEV_SYSTEM_A) == 0 || strcmp(source, DEV_SYSTEM_B) == 0)
+ {
+ RLOGD("verfy system.img\n");
+ is_system = 1;
+ if(strcmp(source, DEV_SYSTEM_A) == 0)
+ {
+ system_mtd_num = MTD_SYSTEM_B;
+ }
+ else if(strcmp(source, DEV_SYSTEM_B) == 0)
+ {
+ system_mtd_num = MTD_SYSTEM_A;
+ }
+ else
+ {
+ RLOGD("source:%s, target:%s\n", source, target);
+ }
+ for( ; system_ubi_num >= 10; system_ubi_num--)//try from ubi31 to ubi10
+ {
+ sprintf(md5_target_file_patch, "/dev/ubi%d", system_ubi_num);
+ RLOGD("ubi_num = %d\n", system_ubi_num);
+ if((access(md5_target_file_patch, F_OK)) == -1)
+ {
+ RLOGD("no the ubi file, can use this ubi.\n");
+ break;
+ }
+ }
+ if(system_ubi_num < 10)
+ {
+ RLOGE("no the ubi file, can use this ubi.\n");
+ return -1;
+ }
+ }
+ //=========================caculate md5sum start=====================
+ if(is_system == 1)
+ {
+ RLOGD("in system caculate\n");
+ RLOGD("system_mtd_num = %d, ubi_num = %d\n", system_mtd_num, system_ubi_num);
+ sprintf(cmd_ubi_attach, "ubiattach /dev/ubi_ctrl -m %d -d %d", system_mtd_num, system_ubi_num);
+ RLOGD("cmd_ubi_attach:%s", cmd_ubi_attach);
+ ret = system(cmd_ubi_attach);
+ if(ret != 0)
+ {
+ RLOGE("ubi attach error!!!\n");
+ return need_copy;
+ }
+ RLOGD("attach over\n");
+ //attach success
+ sprintf(md5_target_file_patch, "/dev/ubi%d_0", system_ubi_num);
+ RLOGD("md5_target_file_patch:%s", md5_target_file_patch);
+ //make sure the ubi volume is exist
+ if((access(md5_target_file_patch, F_OK)) == -1)
+ {
+ RLOGD("no the ubi file.\n");
+ sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
+ ret = system(cmd_ubi_detach);
+ if(ret != 0)
+ {
+ RLOGD("ubi dettach error!!!\n");
+ }
+
+ return need_copy;
+ }
+ //calculate md5sum
+ //ret = lynq_md5_two_file_verfy("/dev/ubi0_0", md5_target_file_patch);
+ ret = lynq_md5_file_verfy_ab(md5_target_file_patch, source_md5);
+ if(ret == MD5_VERFY_ERROR)
+ {
+ //ubidetach
+ sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
+ ret = system(cmd_ubi_detach);
+ if(ret != 0)
+ {
+ RLOGD("ubi dettach error!!!\n");
+ }
+ return need_copy;
+ }
+ if(ret != 0)
+ {
+ //ubidetach
+ sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
+ ret = system(cmd_ubi_detach);
+ if(ret != 0)
+ {
+ RLOGD("ubi dettach error!!!\n");
+ }
+ RLOGD("calculate system error!!!\n");
+ return -1;
+ }
+
+ RLOGD("verfy system.img over\n");
+ }
+ else
+ {
+ RLOGD("verfy else img\n");
+ //calculate md5sum
+ //ret = lynq_md5_two_file_verfy(source, target);
+ ret = lynq_md5_file_verfy_ab(target, source_md5);
+ if(ret == MD5_VERFY_ERROR)
+ {
+ return need_copy;
+ }
+ if(ret != 0)
+ {
+ RLOGD("calculate %s and %s error!!!\n", source, target);
+ return -1;
+ }
+ }
+ //====================caculate md5sum end======================
+ return 0;
+}
+//xf.li@20230403 add for verfy end
+
+
+//xf.li@20230401 add for ab rollback start
+
+int backup_nand_copyto_nand(char *source, char *target)
+{
+ int fd_source, fd_target, size;
+ int ret = -1;
+ int sleep_count = 0;
+ char cmd_erase_target[128] = {0};
+ int retry = MD5_RETRY_TIME;
+ unsigned char source_md5[MD5_READ_BUFFER_LEN] = {0};
+ char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
+ //caclculate source md5 start
+ if(strcmp(source, DEV_SYSTEM_A) == 0 || strcmp(source, DEV_SYSTEM_B) == 0)
+ {
+ RLOGD("backup_nand_copyto_nand: verfy system.img\n");
+
+ ret = calculate_file_md5_value("/dev/ubi0_0", source_md5);
+ if(ret < 0)
+ {
+ RLOGD("[+MD5]:calculate source md5 value ERROE!!!\n");
+ return ret;
+ }
+ RLOGD("source_md5 is %s\n", source_md5);
+ }
+ else
+ {
+ ret = calculate_file_md5_value(source, source_md5);
+ if(ret < 0)
+ {
+ RLOGD("[+MD5]:calculate source md5 value ERROE!!!\n");
+ return ret;
+ }
+ RLOGD("source_md5 is %s\n", source_md5);
+ }
+ //caclculate source md5 end
+ //ret = lynq_file_md5_verfy(source, target);//verfy md5 value
+ ret = lynq_file_md5_verfy(source, source_md5, target);//verfy md5 value
+ RLOGD("+[UA]: md5_file_verfy :ret=%d\n", ret);
+ if(ret == 0)
+ {
+ RLOGD("+[UA]: nand_copyto_nand don't neet copy\n");
+ }
+ for(; ret > 0 && retry > 0; retry--)
+ {
+ //erase nand-target start
+ if(fota_interrupt == FOTA_FIRST && (access(FILE_UPDATE_FLAG, F_OK)) == 0)
+ {
+ RLOGD("+[UA]: fota runing\n");
+ return -1;
+ }
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");//lock
+ RLOGD("+[UA]: ready to flash_erase\n");
+ sprintf(cmd_erase_target, "flash_erase %s 0 0", target);
+ ret = system(cmd_erase_target);
+ release_wake_lock("ab_recover");//unlock
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: erase %s fail\n", target);
+ return -1;
+ }
+ sleep(1);//sleep 1s
+
+ //erase nand-target end
+ RLOGD("+[UA]: ready to copy\n");
+ fd_source = mtk_device_wrap_open(source, O_RDONLY);
+ if (fd_source < 0) {
+ RLOGD("+[UA]: open source error\n");
+ return -1;
+ }
+
+ fd_target = mtk_device_wrap_open(target, O_RDWR);
+ if (fd_target < 0) {
+ RLOGD("+[UA]: open target error\n");
+ return -1;
+ }
+ ret = 0;//init ret
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");//lock
+ while(( size = mtk_device_wrap_read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0)
+ {
+ if(fota_interrupt == FOTA_FIRST && (access(FILE_UPDATE_FLAG, F_OK)) == 0)
+ {
+ RLOGD("+[UA]: fota runing\n");
+ ret = -1;
+ break;
+ }
+ usleep(40000);//sleep 40ms
+ mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
+ usleep(60000);//sleep 60ms
+ sleep_count++;
+ if(sleep_count >= 20)
+ {
+ //unlock
+ release_wake_lock("ab_recover");
+ sleep(1);//sleep 1s
+ //lock
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");
+ sleep_count = 0;
+ RLOGD("+[UA]: try sleep one time");
+ }
+ }
+ release_wake_lock("ab_recover");//unlock
+ RLOGD("+[UA]: copy end\n");
+ mtk_device_wrap_close(fd_target);
+ mtk_device_wrap_close(fd_source);
+ if(ret < 0)
+ {
+ RLOGD("+[UA]: ret < 0\n");
+ return -1;
+ }
+ RLOGD("+[UA]: ready to md5_verfy\n");
+ //ret = lynq_file_md5_verfy(source, target);//verfy md5 value
+ ret = lynq_file_md5_verfy(source, source_md5, target);//verfy md5 value
+ RLOGD("+[UA]: md5_file_verfy :ret=%d\n", ret);
+ if(ret == 0)
+ {
+ RLOGD("+[UA]: nand_copyto_nand copy success\n");
+ break;
+ }
+ }
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: md5_file_verfy FAIL!!!\n");
+ }
+ return ret;
+}
+//xf.li@20230401 add for ab rollback end
+
+//xf.li@20230822 add for ab rollback start
+
+int lynq_backup_main()
+{
+ const hw_module_t* hw_module;
+ hw_module = &HAL_MODULE_INFO_SYM;
+ int is_successful;
+ int ret = 0;
+ if (!hw_module || strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0)
+ {
+ ret = -1;
+ }
+ RLOGD("ret = %d\n", ret);
+ if (ret != 0)
+ {
+ RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
+ return -1;
+ }
+ module = (boot_control_module_t*)hw_module;
+ module->init(module);
+ if (module == NULL)
+ {
+ RLOGD("+[UA]: Error getting bootctrl module.\n");
+ return -1;
+ }
+ lynq_init_wake_lock_func();
+ current_slot = module->getCurrentSlot(module);
+ is_successful = module->isSlotMarkedSuccessful(module, current_slot);
+ RLOGD("+[UA]: Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
+ fota_interrupt = RECOVER_FIRST;
+ if(current_slot==SLOT_B)
+ {
+ ret = backup_nand_copyto_nand(DEV_SPM_B,DEV_SPM_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup spm_a fail\n");
+ return 1;
+ }
+ fota_interrupt = FOTA_FIRST;
+ ret = backup_nand_copyto_nand(DEV_SYSTEM_B,DEV_SYSTEM_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup system_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BOOT_B,DEV_BOOT_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup boot_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_TEE_B,DEV_TEE_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup tee_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_MD1IMG_B,DEV_MD1IMG_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup md1img_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_VBMETA_B,DEV_VBMETA_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup vbmeta_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_MEDMCU_B,DEV_MEDMCU_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup medmcu_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BL2_B,DEV_BL2_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup bl2_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BL33_B,DEV_BL33_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup bl33_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_OEMAPP_B,DEV_OEMAPP_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup oemapp_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_OEMAPP2_B,DEV_OEMAPP2_A);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup oemapp2_a fail\n");
+ return 1;
+ }
+ }
+ else
+ {
+ ret = backup_nand_copyto_nand(DEV_SPM_A,DEV_SPM_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup spm_a fail\n");
+ return 1;
+ }
+ fota_interrupt = FOTA_FIRST;
+ ret = backup_nand_copyto_nand(DEV_SYSTEM_A,DEV_SYSTEM_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup system_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BOOT_A,DEV_BOOT_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup boot_b fail\n");
+ return 1;
+ }
+
+ ret = backup_nand_copyto_nand(DEV_TEE_A,DEV_TEE_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup tee_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_MD1IMG_A,DEV_MD1IMG_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup md1img_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_VBMETA_A,DEV_VBMETA_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup vbmeta_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_MEDMCU_A,DEV_MEDMCU_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup medmcu_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BL2_A,DEV_BL2_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup bl2_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_BL33_A,DEV_BL33_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup bl33_a fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_OEMAPP_A,DEV_OEMAPP_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup oemapp_b fail\n");
+ return 1;
+ }
+ ret = backup_nand_copyto_nand(DEV_OEMAPP2_A,DEV_OEMAPP2_B);
+ if(ret != 0)
+ {
+ RLOGD("+[UA]: backup oemapp2_b fail\n");
+ return 1;
+ }
+ }
+ RLOGD("+[UA]: lynq_backup_main success \n");
+ return 0;
+}
+//xf.li@20230822 add for ab rollback end
+
+
+int lynq_check_oemapp(char* name)
+{
+ FILE *fp;
+ char check_result[64];
+ int ret;
+ if(strcmp(name, "oemapp") == 0)
+ {
+ RLOGD("lynq_check_oemapp oemapp");
+ ret = system("cat /proc/mtd|grep oemapp");
+ if(ret != 0)
+ {
+ return 0;
+ }
+ if(system("df -lh|grep oemapp |grep -v oemapp2") != 0)
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ else if(strcmp(name, "oemapp2") == 0)
+ {
+ RLOGD("lynq_check_oemapp oemapp2");
+ ret = system("cat /proc/mtd|grep oemapp2");
+ if(ret != 0)
+ {
+ return 0;
+ }
+ if(system("df -lh|grep oemapp2") != 0)
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+}
+
+//lt add @2021.9.23 for deal with power down \ backup or upgrade.
+int lynq_fota_func(void)
+{
+ int fd;
+ int first_run = 1;
+ int ret = 0;
+ UPDATE_INFO lynq_up_info;
+ //xf.li@20230822 add for ab backup start
+ unsigned int current_slot, other_slot;
+ int is_other_slot_bootable;
+ const hw_module_t* hw_module;
+ //xf.li@20230822 add for ab backup end
+ RLOGE("[+UP]: ******lynq_fota_func start******\n");
+ //xf.li@20230822 add for ab backup start
+ //----------get current slot and whether other slot is bootable
+ hw_module = &HAL_MODULE_INFO_SYM;
+ if (!hw_module ||
+ strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
+ ret = -EINVAL;
+ }
+ if (ret != 0) {
+ RLOGE("+[UA]: Error loading boot_control HAL implementation.\n");
+ return -1;
+ }
+ module = (boot_control_module_t*)hw_module;
+ module->init(module);
+ if (module == NULL) {
+ RLOGE("+[UA]: Error getting bootctrl module.\n");
+ return -1;
+ }
+ current_slot = module->getCurrentSlot(module);
+ other_slot = (current_slot == 0) ? 1 : 0;
+ is_other_slot_bootable = module->isSlotBootable(module, other_slot);
+ //-----------end
+ RLOGE("current slot:%u, is_other_slot_bootable : %d\n",current_slot, is_other_slot_bootable);
+ //xf.li@20230822 add for ab backup end
+
+ memset(&lynq_up_info, 0, sizeof(lynq_up_info));
+ fd = open(FILE_UPDATE_STATE,O_RDWR | O_CREAT,0777);
+ if (fd < 0)
+ {
+ return -1;
+ }
+ read(fd,(unsigned char *)&lynq_up_info,sizeof(lynq_up_info));
+ close(fd);
+
+ RLOGD("[+UP]: lynq_up_info.ota_run=%d\n",lynq_up_info.ota_run);
+ if((lynq_check_oemapp("oemapp") != 0) || (lynq_check_oemapp("oemapp2") != 0))
+ {
+ RLOGD("ENTER LYNQ_CHECK_OEMAPP\n");
+ system("echo mode 001 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+ system("echo dir 001 1 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+ system("echo out 001 1 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
+ RLOGD("need setUnbootable.\n");
+ module->setSlotAsUnbootable(module,current_slot);
+ RLOGD("+[UA]: setSlotAsUnbootable!!!!\n");
+ sync();
+ if(((lynq_up_info.fota_flag[0]=='A')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='B'))||
+ ((lynq_up_info.fota_flag[0]=='B')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='A')))
+ {
+ RLOGD("mark oemapp mount fail\n");
+ lynq_set_value(FOTA_UCI_MODULE,FOTA_UCI_STATE, "1");
+ }
+ sleep(5);
+ reboot_device();
+ }
+
+ if(lynq_up_info.ota_run != 0)
+ {
+ //Power off, call UA
+ RLOGE("[+UP]: ***Power off, call UA***\n");
+ ret = rock_update_main(0, 0, 0, 0, first_run, 1, 0, 1);
+ RLOGE("rock_update_main ret = %d\n", ret);
+ if(ret)
+ {
+ RLOGE("fota update fail!\n");
+ }
+ }
+
+ if(((lynq_up_info.fota_flag[0]=='A')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='B'))||
+ ((lynq_up_info.fota_flag[0]=='B')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='A')))
+ {
+ //Upgrade the other side and call UA
+ RLOGE("[+UP]: ***Upgrade the other side and call UA***\n");
+ ret = rock_update_main(0, 0, 0, 0, first_run, 0, 0, 0);
+ RLOGE("rock_update_main ret = %d\n", ret);
+ if(ret)
+ {
+ RLOGE("fota update fail!\n");
+ }
+ }
+ //xf.li@20230822 add for ab backup start
+ else if(is_other_slot_bootable == 0)
+ {
+ RLOGE("need backup\n");
+ ret = lynq_backup_main();
+ if(ret != 0)
+ {
+ RLOGE("ERROE: backup fail!!!\n");
+ }
+ else
+ {
+ RLOGE("backup success!!!\n");
+ module->setCompleteBackup(module, current_slot);
+ }
+ }
+ else
+ {
+ RLOGE("Don't need backup\n");
+ }
+ //xf.li@20230822 add for ab backup end
+
+ return 0;
+}
+
+int lynq_nand_open(const char *pathname, int flags)
+{
+// printf("pathname:%s---flags:%d",pathname,flags);
+ return open(pathname,flags);
+}
+
+ssize_t lynq_nand_read(int fd, void *buf, size_t count)
+{
+// printf("rfd:%d---buf:%s---count:%d",fd,buf,count);
+ return read(fd,buf,count);
+}
+
+ssize_t lynq_nand_write(int fd, void *buf, size_t count)
+{
+ // printf("wfd:%d---buf:%s---count:%d",fd,buf,count);
+ return write(fd,buf,count);
+}
+
+int lynq_nand_close(int fd)
+{
+ return close(fd);
+}
+
+/**
+ * @brief Obtain the upgrade result
+ *
+ * @param void
+ * @return 0xff:open file fail,0:upgrade success,1,upgrade wait
+ */
+ int lynq_get_upgrade_status(void)
+{
+ int lynq_state_fd;
+ int lynq_upgrade_wait = 1;
+ OTA_STATUS lynq_ota_status;
+
+ memset(&lynq_ota_status, 0, sizeof(lynq_ota_status));
+
+ lynq_state_fd = open(FILE_FOTA_STATE,O_RDWR | O_CREAT,0777);
+
+ if (lynq_state_fd < 0)
+ {
+ return 0xff;
+ }
+ read(lynq_state_fd,(unsigned char *)&lynq_ota_status,sizeof(lynq_ota_status));
+ close(lynq_state_fd);
+ if((lynq_ota_status.ota_run != 0) && (lynq_ota_status.update_result == 0))
+ {
+ return lynq_upgrade_wait;
+ }
+ return lynq_ota_status.update_result;
+}
+
+/**
+ * @brief reboot device
+ *
+ * @param void
+ * @return void
+ */
+ void lynq_reboot_device(void)
+{
+ reboot_device();
+ return ;
+}
+
+/**
+ * @brief fota no resatrt
+ *
+ * @param void
+ * @return 0:fota success -Other values:fota fail
+ */
+
+int lynq_fota_nrestart(void)
+{
+
+ int ret = 0;
+#if 0
+ printf("-********copy delta ***-\n");
+ test_write_delta("/data/delta",DEV_DELTA);
+#endif
+
+ ret = rock_update_main(0, 0, 0, 0, 1, 1, 0, 1);
+ RLOGD("rock_update_nrestart ret = %d\n", ret);
+ if(ret)
+ {
+ RLOGD("fota update fail!\n");
+ }
+ return ret;
+}
+
+/**
+ * @brief Set the upgrade package address
+ *
+ * @param1 value:fota addr
+ * @param1 szie:fota addr length
+ * @return 0:set success other:set fail
+ */
+int lynq_fota_set_addr_value(char *value,int size)
+{
+ if(size < 64)
+ {
+ return lynq_set_value(FOTA_UCI_MODULE,FOTA_UCI_ADDR, value);
+ }
+ return -1;
+}
+/**
+ * @brief get the upgrade package address
+ *
+ * @param1 value:fota addr
+ * @return 0:get success other:set fail
+ */
+int lynq_fota_get_addr_value(char *tmp)
+{
+ return lynq_get_value(FOTA_UCI_FILE, FOTA_UCI_MODULE,FOTA_UCI_ADDR, tmp);
+}
+
+/**
+ * @brief Porting wakes up the demo content
+ */
+static void lynq_init_wake_lock_func(void)
+{
+ const char *lynqLibPath_WakeLock = "/usr/lib64/libpower.so";
+
+ dlHandle_wakelock = dlopen(lynqLibPath_WakeLock, RTLD_NOW);
+ if (dlHandle_wakelock == NULL)
+ {
+ printf("dlopen lynqLibPath_WakeLock failed: %s", dlerror());
+ exit(EXIT_FAILURE);
+ }
+
+ acquire_wake_lock = (int(*)(int,const char*))dlsym(dlHandle_wakelock, "acquire_wake_lock");
+ if (acquire_wake_lock == NULL) {
+ printf("acquire_wake_lock not defined or exported in %s", lynqLibPath_WakeLock);
+ exit(EXIT_FAILURE);
+ }
+ release_wake_lock = (int(*)( const char*))dlsym(dlHandle_wakelock, "release_wake_lock");
+ if (release_wake_lock == NULL) {
+ printf("release_wake_lock not defined or exported in %s", lynqLibPath_WakeLock);
+ exit(EXIT_FAILURE);
+ }
+ dlerror(); // Clear any previous dlerror
+
+ return;
+}
+
+/**
+ * @brief fota wake lock
+ *
+ * @param1 value:void
+ * @return ;
+ */
+static void lynq_fota_grab_artial_wake_lock(void)
+{
+ acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+}
+
+/**
+ * @brief get the upgrade package address
+ *
+ * @param1 value:void
+ * @return ;
+ */
+static void lynq_fota_release_wake_lock(void)
+{
+ release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+}
+/**
+ * @brief This is the wake up call
+ * end
+ */
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/rock_ua/sha.c b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/rock_ua/sha.c
new file mode 100755
index 0000000..5ac6b53
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota-run/rock_ua/sha.c
@@ -0,0 +1,428 @@
+/* sha.c
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+** * Neither the name of Google Inc. nor the names of its contributors may
+** be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR
+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+** EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+** OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+** WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+** OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+** ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "sha.h"
+
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mtk_device_wrap.h"
+
+// Some machines lack byteswap.h and endian.h. These have to use the
+// slower code, even if they're little-endian.
+
+#if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+
+#include <byteswap.h>
+#include <memory.h>
+
+
+
+// This version is about 28% faster than the generic version below,
+// but assumes little-endianness.
+
+static inline uint32_t ror27(uint32_t val) {
+ return (val >> 27) | (val << 5);
+}
+static inline uint32_t ror2(uint32_t val) {
+ return (val >> 2) | (val << 30);
+}
+static inline uint32_t ror31(uint32_t val) {
+ return (val >> 31) | (val << 1);
+}
+
+static void SHA1_Transform(SHA_CTX* ctx) {
+ uint32_t W[80];
+ register uint32_t A, B, C, D, E;
+ int t;
+
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+
+#define SHA_F1(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = bswap_32(ctx->buf.w[t])) + \
+ (D^(B&(C^D))) + 0x5A827999; \
+ B = ror2(B);
+
+ for (t = 0; t < 15; t += 5) {
+ SHA_F1(A,B,C,D,E,t + 0);
+ SHA_F1(E,A,B,C,D,t + 1);
+ SHA_F1(D,E,A,B,C,t + 2);
+ SHA_F1(C,D,E,A,B,t + 3);
+ SHA_F1(B,C,D,E,A,t + 4);
+ }
+ SHA_F1(A,B,C,D,E,t + 0); // 16th one, t == 15
+
+#undef SHA_F1
+
+#define SHA_F1(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
+ (D^(B&(C^D))) + 0x5A827999; \
+ B = ror2(B);
+
+ SHA_F1(E,A,B,C,D,t + 1);
+ SHA_F1(D,E,A,B,C,t + 2);
+ SHA_F1(C,D,E,A,B,t + 3);
+ SHA_F1(B,C,D,E,A,t + 4);
+
+#undef SHA_F1
+
+#define SHA_F2(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
+ (B^C^D) + 0x6ED9EBA1; \
+ B = ror2(B);
+
+ for (t = 20; t < 40; t += 5) {
+ SHA_F2(A,B,C,D,E,t + 0);
+ SHA_F2(E,A,B,C,D,t + 1);
+ SHA_F2(D,E,A,B,C,t + 2);
+ SHA_F2(C,D,E,A,B,t + 3);
+ SHA_F2(B,C,D,E,A,t + 4);
+ }
+
+#undef SHA_F2
+
+#define SHA_F3(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
+ ((B&C)|(D&(B|C))) + 0x8F1BBCDC; \
+ B = ror2(B);
+
+ for (; t < 60; t += 5) {
+ SHA_F3(A,B,C,D,E,t + 0);
+ SHA_F3(E,A,B,C,D,t + 1);
+ SHA_F3(D,E,A,B,C,t + 2);
+ SHA_F3(C,D,E,A,B,t + 3);
+ SHA_F3(B,C,D,E,A,t + 4);
+ }
+
+#undef SHA_F3
+
+#define SHA_F4(A,B,C,D,E,t) \
+ E += ror27(A) + \
+ (W[t] = ror31(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16])) + \
+ (B^C^D) + 0xCA62C1D6; \
+ B = ror2(B);
+
+ for (; t < 80; t += 5) {
+ SHA_F4(A,B,C,D,E,t + 0);
+ SHA_F4(E,A,B,C,D,t + 1);
+ SHA_F4(D,E,A,B,C,t + 2);
+ SHA_F4(C,D,E,A,B,t + 3);
+ SHA_F4(B,C,D,E,A,t + 4);
+ }
+
+#undef SHA_F4
+
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+}
+
+void SHA_update(SHA_CTX* ctx, const void* data, int len) {
+ int i = ctx->count % sizeof(ctx->buf);
+ const uint8_t* p = (const uint8_t*)data;
+
+ ctx->count += len;
+
+ while (len > sizeof(ctx->buf) - i) {
+ memcpy(&ctx->buf.b[i], p, sizeof(ctx->buf) - i);
+ len -= sizeof(ctx->buf) - i;
+ p += sizeof(ctx->buf) - i;
+ SHA1_Transform(ctx);
+ i = 0;
+ }
+
+ while (len--) {
+ ctx->buf.b[i++] = *p++;
+ if (i == sizeof(ctx->buf)) {
+ SHA1_Transform(ctx);
+ i = 0;
+ }
+ }
+}
+
+
+const uint8_t* SHA_final(SHA_CTX* ctx) {
+ uint64_t cnt = ctx->count * 8;
+ int i;
+
+ SHA_update(ctx, (uint8_t*)"\x80", 1);
+ while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
+ SHA_update(ctx, (uint8_t*)"\0", 1);
+ }
+ for (i = 0; i < 8; ++i) {
+ uint8_t tmp = cnt >> ((7 - i) * 8);
+ SHA_update(ctx, &tmp, 1);
+ }
+
+ for (i = 0; i < 5; i++) {
+ ctx->buf.w[i] = bswap_32(ctx->state[i]);
+ }
+
+ return ctx->buf.b;
+}
+
+#else // #if defined(HAVE_ENDIAN_H) && defined(HAVE_LITTLE_ENDIAN)
+
+#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+static void SHA1_transform(SHA_CTX *ctx) {
+ uint32_t W[80];
+ uint32_t A, B, C, D, E;
+ uint8_t *p = ctx->buf;
+ int t;
+
+ for(t = 0; t < 16; ++t) {
+ uint32_t tmp = *p++ << 24;
+ tmp |= *p++ << 16;
+ tmp |= *p++ << 8;
+ tmp |= *p++;
+ W[t] = tmp;
+ }
+
+ for(; t < 80; t++) {
+ W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+ }
+
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+
+ for(t = 0; t < 80; t++) {
+ uint32_t tmp = rol(5,A) + E + W[t];
+
+ if (t < 20)
+ tmp += (D^(B&(C^D))) + 0x5A827999;
+ else if ( t < 40)
+ tmp += (B^C^D) + 0x6ED9EBA1;
+ else if ( t < 60)
+ tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC;
+ else
+ tmp += (B^C^D) + 0xCA62C1D6;
+
+ E = D;
+ D = C;
+ C = rol(30,B);
+ B = A;
+ A = tmp;
+ }
+
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+}
+
+void SHA_update(SHA_CTX *ctx, const void *data, int len) {
+ int i = ctx->count % sizeof(ctx->buf);
+ const uint8_t* p = (const uint8_t*)data;
+
+ ctx->count += len;
+
+ while (len--) {
+ ctx->buf[i++] = *p++;
+ if (i == sizeof(ctx->buf)) {
+ SHA1_transform(ctx);
+ i = 0;
+ }
+ }
+}
+const uint8_t *SHA_final(SHA_CTX *ctx) {
+ uint8_t *p = ctx->buf;
+ uint64_t cnt = ctx->count * 8;
+ int i;
+
+ SHA_update(ctx, (uint8_t*)"\x80", 1);
+ while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) {
+ SHA_update(ctx, (uint8_t*)"\0", 1);
+ }
+ for (i = 0; i < 8; ++i) {
+ uint8_t tmp = cnt >> ((7 - i) * 8);
+ SHA_update(ctx, &tmp, 1);
+ }
+
+ for (i = 0; i < 5; i++) {
+ uint32_t tmp = ctx->state[i];
+ *p++ = tmp >> 24;
+ *p++ = tmp >> 16;
+ *p++ = tmp >> 8;
+ *p++ = tmp >> 0;
+ }
+
+ return ctx->buf;
+}
+
+#endif // endianness
+
+void SHA_init(SHA_CTX* ctx) {
+ ctx->state[0] = 0x67452301;
+ ctx->state[1] = 0xEFCDAB89;
+ ctx->state[2] = 0x98BADCFE;
+ ctx->state[3] = 0x10325476;
+ ctx->state[4] = 0xC3D2E1F0;
+ ctx->count = 0;
+}
+
+/* Convenience function */
+const uint8_t* SHA(const void *data, int len, uint8_t *digest) {
+ const uint8_t *p;
+ int i;
+
+ SHA_CTX ctx;
+ SHA_init(&ctx);
+ SHA_update(&ctx, data, len);
+ p = SHA_final(&ctx);
+ for (i = 0; i < SHA_DIGEST_SIZE; ++i) {
+ digest[i] = *p++;
+ }
+ return digest;
+}
+
+#define NAND_PAGE_SIZE_SHA 4096
+
+const uint8_t* ROCK_SHA_FILE_COMMON(int fd_sha, int offset,int totle_size, uint8_t *digest) {
+ const uint8_t *p;
+ int i = 0;
+ //int fd_sha;
+ int size = 0;
+ int totale_size_common = totle_size;
+ char data[NAND_PAGE_SIZE_SHA];
+
+
+ lseek(fd_sha, offset, SEEK_SET);
+ SHA_CTX ctx;
+ SHA_init(&ctx);
+
+ do{
+ if(totale_size_common >= NAND_PAGE_SIZE_SHA)
+ {
+ size = read(fd_sha,data,NAND_PAGE_SIZE_SHA);
+ }
+ else
+ {
+ size = read(fd_sha,data,totale_size_common);
+ }
+ if (size == 0){
+ break;
+ }
+ SHA_update(&ctx, data, size);
+ totale_size_common -= size;
+
+ }while(totale_size_common>0);
+ p = SHA_final(&ctx);
+ for (i = 0; i < SHA_DIGEST_SIZE; ++i)
+ {
+ digest[i] = *p++;
+ }
+ return digest;
+}
+
+const uint8_t* ROCK_SHA_FILE(int fd_sha, int offset,int totle_size, uint8_t *digest) {
+ const uint8_t *p;
+ int i = 0;
+ //int fd_sha;
+ int size = 0;
+ int totale_size_file = totle_size;
+ char data[NAND_PAGE_SIZE_SHA];
+
+
+ mtk_device_wrap_seek(fd_sha, offset, SEEK_SET);
+ SHA_CTX ctx;
+ SHA_init(&ctx);
+
+ do{
+ if(totale_size_file >= NAND_PAGE_SIZE_SHA)
+ {
+ size = mtk_device_wrap_read(fd_sha,data,NAND_PAGE_SIZE_SHA);
+ }
+ else
+ {
+ size = mtk_device_wrap_read(fd_sha,data,totale_size_file);
+ }
+ if (size == 0){
+ break;
+ }
+ SHA_update(&ctx, data, size);
+ totale_size_file -= size;
+
+ }while(totale_size_file>0);
+ p = SHA_final(&ctx);
+ for (i = 0; i < SHA_DIGEST_SIZE; ++i)
+ {
+ digest[i] = *p++;
+ }
+ return digest;
+}
+
+
+
+// Take a string 'str' of 40 hex digits and parse it into the 20
+// byte array 'digest'. 'str' may contain only the digest or be of
+// the form "<digest>:<anything>". Return 0 on success, -1 on any
+// error.
+int ParseSha1(const char* str, uint8_t* digest) {
+ int i;
+ const char* ps = str;
+ uint8_t* pd = digest;
+ for (i = 0; i < SHA_DIGEST_SIZE * 2; ++i, ++ps) {
+ int digit;
+ if (*ps >= '0' && *ps <= '9') {
+ digit = *ps - '0';
+ } else if (*ps >= 'a' && *ps <= 'f') {
+ digit = *ps - 'a' + 10;
+ } else if (*ps >= 'A' && *ps <= 'F') {
+ digit = *ps - 'A' + 10;
+ } else {
+ return -1;
+ }
+ if (i % 2 == 0) {
+ *pd = digit << 4;
+ } else {
+ *pd |= digit;
+ ++pd;
+ }
+ }
+ if (*ps != '\0') return -1;
+ return 0;
+}
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c
index 49ebfcc..160ccec 100755
--- a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-fota/rock_ua/rock_ua.c
@@ -19,7 +19,7 @@
#include <string.h>
#include <dlfcn.h>
#include <stdint.h>
-
+#include <pthread.h>
#include <hardware/boot_control.h>
#include <hardware/hardware.h>
@@ -117,7 +117,6 @@
unsigned int delta_head[128]={0}; //512/4 128/2=64
-
#define FOTA_DELTA_MTD "/dev/mtd47"
#define FOTA_UCI_MODULE "lynq_fota"
#define FOTA_UCI_FILE "lynq_uci"
@@ -194,6 +193,7 @@
int fd_delta,fd_curr,fd_log,fd_update_status,fd_fota_status;
int fd_write,fd_read;
+static pthread_mutex_t s_update_main_mutex;
static unsigned int delta_offset = 0;
static unsigned int now_patch = 0;
unsigned int current_slot = 0;
@@ -635,7 +635,7 @@
ret = get_file_size();
if(ret != 0)
{
- RLOGD("the delta size over 50M\n");
+ RLOGE("the delta size over 50M\n");
return -1;
}
@@ -643,12 +643,12 @@
result = test_write_delta(lynq_fota_addr, g_delta_mtd);
if(result != 0)
{
- RLOGD("fota.delta write into mtd fail !\n");
+ RLOGE("fota.delta write into mtd fail !\n");
}
strcpy(lynq_fota_addr, g_delta_mtd);
if(lynq_fota_set_addr_value(lynq_fota_addr,strlen(lynq_fota_addr)))
{
- RLOGD("set addr fail\n");
+ RLOGE("set addr fail\n");
return 1;
}
RLOGD("+[UA]: get fota pack addr: %s\n", lynq_fota_addr);
@@ -656,7 +656,7 @@
if (fd_delta < 0) {
err = errno;
- RLOGD("+[UA]: Error opening fota file: %s\n",strerror(errno));
+ RLOGE("+[UA]: Error opening fota file: %s\n",strerror(errno));
mtk_device_wrap_close(fd_delta);
return -err;
}
@@ -669,7 +669,7 @@
if (fd_delta < 0) {
err = errno;
- RLOGD("+[UA]: Error opening fota file: %s\n",strerror(errno));
+ RLOGE("+[UA]: Error opening fota file: %s\n",strerror(errno));
mtk_device_wrap_close(fd_delta);
return -err;
}
@@ -681,7 +681,7 @@
if (fd_delta < 0) {
err = errno;
- RLOGD("+[UA]: Error opening fota file: %s\n",strerror(errno));
+ RLOGE("+[UA]: Error opening fota file: %s\n",strerror(errno));
close(fd_delta);
return -err;
}
@@ -692,7 +692,7 @@
fd_update_status = open(FILE_UPDATE_STATE,O_RDWR | O_CREAT,0777);
if (fd_update_status < 0) {
err = errno;
- RLOGD("+[UA]: Error opening metadata file: %s\n",strerror(errno));
+ RLOGE("+[UA]: Error opening metadata file: %s\n",strerror(errno));
close(fd_update_status);
return -err;
}
@@ -732,7 +732,7 @@
fd_source = open(source,O_RDONLY);
if (fd_source < 0) {
- RLOGD("+[UA]: open source error\n");
+ RLOGE("+[UA]: open source error\n");
return 1;
}
@@ -741,7 +741,7 @@
if (fd_target < 0) {
mtk_device_wrap_close(fd_target);
close(fd_source);
- RLOGD("+[UA]: open target error\n");
+ RLOGE("+[UA]: open target error\n");
return 1;
}
@@ -769,7 +769,7 @@
fd_source = mtk_device_wrap_open(source,O_RDONLY);
if (fd_source < 0) {
- RLOGD("+[UA]: open source error\n");
+ RLOGE("+[UA]: open source error\n");
return 1;
}
@@ -778,7 +778,7 @@
if (fd_target < 0) {
mtk_device_wrap_close(fd_target);
mtk_device_wrap_close(fd_source);
- RLOGD("+[UA]: open target error\n");
+ RLOGE("+[UA]: open target error\n");
return 1;
}
@@ -931,7 +931,7 @@
num = buffer[2][14];
- RLOGD("num=%c\n", num);
+ RLOGE("num=%c\n", num);
if(num == '0' || num == '1')
{
printf("this is four core\n");
@@ -944,7 +944,7 @@
}
else
{
- RLOGD("this char is error\n");
+ RLOGE("this char is error\n");
return -1;
}
pclose(fp);
@@ -985,7 +985,7 @@
fd = open(FILE_UPDATE_FLAG,O_RDWR | O_CREAT,0777);
if (fd < 0)
{
- RLOGD("+[UA]: can't open file /tmp/update_flag.\n");
+ RLOGE("+[UA]: can't open file /tmp/update_flag.\n");
return -1;
}
close(fd);
@@ -1001,7 +1001,7 @@
ret = -EINVAL;
}
if (ret != 0) {
- RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
+ RLOGE("+[UA]: Error loading boot_control HAL implementation.\n");
return -1;
}
@@ -1010,7 +1010,7 @@
if (module == NULL) {
- RLOGD("+[UA]: Error getting bootctrl module.\n");
+ RLOGE("+[UA]: Error getting bootctrl module.\n");
return -1;
}
@@ -1022,8 +1022,12 @@
int is_successful = module->isSlotMarkedSuccessful(module, current_slot);
- RLOGD("Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
-
+ RLOGE("Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
+ if((current_slot != 0) && (current_slot != 1))
+ {
+ RLOGE("+[UA]: Error getting bootctrl current_slot.\n");
+ return -1;
+ }
memset(&ctx, 0, sizeof(ctx));
ctx.rom_base = 0;
@@ -1039,12 +1043,12 @@
if(0 != init_dev_fd())
{
- RLOGD("+[UA]: get fota addr error\n");
+ RLOGE("+[UA]: get fota addr error\n");
system("echo fota-interface >/sys/power/wake_unlock");
return E_ROCK_FOTA_ADDR;
}
- RLOGD("+[UA]: up_info.ota_run = %d\n",up_info.ota_run);
+ RLOGE("+[UA]: up_info.ota_run = %d\n",up_info.ota_run);
#if 0
if ((up_info.ota_run>PATCH_BL33)||(up_info.ota_run<PATCH_SYSTEM))
@@ -1068,13 +1072,18 @@
update_mode = MODE_NORMAL;
}
- RLOGD("+[UA]: up_info.fota_flag = %s\n",up_info.fota_flag);
- RLOGD("+[UA]: update_mode = %d\n",update_mode);
+ RLOGE("+[UA]: up_info.fota_flag = %s\n",up_info.fota_flag);
+ RLOGE("+[UA]: update_mode = %d\n",update_mode);
memset(&delta_head, 0, sizeof(delta_head));
if(g_addr_flag == 1)
{
- mtk_device_wrap_read(fd_delta, (char *)&delta_head[0], sizeof(delta_head));
+ RLOGD("fd_delta=%d\n", fd_delta);
+ ret = mtk_device_wrap_read(fd_delta, (char *)&delta_head[0], sizeof(delta_head));
+ if(ret <0)
+ {
+ return -1;
+ }
}
else
{
@@ -1089,7 +1098,7 @@
fota_status.update_status[i].need_update = 1;
delta_size+=delta_head[i];
}
- RLOGD("+[UA]: %s,delta size = %d, i=%d\n",partition_filename[i],delta_head[i], i);
+ RLOGE("+[UA]: %s,delta size = %d, i=%d\n",partition_filename[i],delta_head[i], i);
}
for(i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE); i++) {
@@ -1097,7 +1106,7 @@
fota_status.update_status[i].need_update = 1;
sha_size+=delta_head[i];
}
- RLOGD("+[UA]: %s,full size = %d, i=%d\n",partition_filename[i-MAX_OTA_ROLE/2],delta_head[i], i);
+ RLOGE("+[UA]: %s,full size = %d, i=%d\n",partition_filename[i-MAX_OTA_ROLE/2],delta_head[i], i);
}
core_num= check_cpu();
@@ -1106,22 +1115,22 @@
cpu_flag = check(delta_head[64]);
if(cpu_flag < 0)
{
- RLOGD("cpu core is error\n");
+ RLOGE("cpu core is error\n");
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
}
else
{
- RLOGD("cpu core match\n");
+ RLOGE("cpu core match\n");
}
}
else if(core_num == 4)
{
- RLOGD("the cpu core is four!!!\n");
+ RLOGE("the cpu core is four!!!\n");
}
else
{
- RLOGD("read the cpu core fail");
+ RLOGE("read the cpu core fail");
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
}
@@ -1142,8 +1151,18 @@
memset(str_sha,0,40);
if(g_addr_flag == 1)
{
- mtk_device_wrap_seek(fd_delta, sha_size + sizeof(delta_head), SEEK_SET);
- mtk_device_wrap_read(fd_delta, digest_s, SHA_DIGEST_SIZE);
+ ret = mtk_device_wrap_seek(fd_delta, sha_size + sizeof(delta_head), SEEK_SET);
+ if(ret < 0)
+ {
+ RLOGE("mtk_device_wrap_seek fail\n");
+ return -1;
+ }
+ ret = mtk_device_wrap_read(fd_delta, digest_s, SHA_DIGEST_SIZE);
+ if(ret < 0)
+ {
+ RLOGE("mtk_device_wrap_read fail\n");
+ return -1;
+ }
}
else
{
@@ -1152,7 +1171,7 @@
}
convert_hex(digest_s,str_sha);
- RLOGD("+[UA]: delta save sha = %s\n",str_sha);
+ RLOGE("+[UA]: delta save sha = %s\n",str_sha);
if(g_addr_flag == 1)
{
ROCK_SHA_FILE(fd_delta,sizeof(delta_head),sha_size,digest_t);
@@ -1163,14 +1182,14 @@
}
memset(str_sha,0,40);
convert_hex(digest_t,str_sha);
- RLOGD("+[UA]: delta calc sha = %s\n",str_sha);
+ RLOGE("+[UA]: delta calc sha = %s\n",str_sha);
if(memcmp(digest_s,digest_t,SHA_DIGEST_SIZE)==0) {
- RLOGD("sha verify pass\n");
+ RLOGE("sha verify pass\n");
}else{
- RLOGD("delta sha verify fial!\n");
+ RLOGE("delta sha verify fial!\n");
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
@@ -1214,7 +1233,7 @@
fd_partition_a = mtk_device_wrap_open(partition_filename_a[i],O_RDWR);
if (fd_partition_a < 0) {
err = errno;
- RLOGD("+[UA]: Error opening id_a[%d] file: %s\n",i,strerror(errno));
+ RLOGE("+[UA]: Error opening id_a[%d] file: %s\n",i,strerror(errno));
system("echo fota-interface >/sys/power/wake_unlock");
return -err;
}
@@ -1222,7 +1241,7 @@
fd_partition_b = mtk_device_wrap_open(partition_filename_b[i],O_RDWR);
if (fd_partition_b < 0) {
err = errno;
- RLOGD("+[UA]: Error opening id_b[%d] file: %s\n",i,strerror(errno));
+ RLOGE("+[UA]: Error opening id_b[%d] file: %s\n",i,strerror(errno));
system("echo fota-interface >/sys/power/wake_unlock");
return -err;
}
@@ -1244,9 +1263,9 @@
up_info.ota_run = i+1;
save_fota_info();
- RLOGD("+[UA]: Start upgrading %s.\n",partition_filename[i]);
+ RLOGE("+[UA]: Start upgrading %s.\n",partition_filename[i]);
status = iot_patch(&ctx);
- RLOGD("+[UA]: %s upgrade result:%d\n",partition_filename[i],status);
+ RLOGE("+[UA]: %s upgrade result:%d\n",partition_filename[i],status);
//up_info.ota_run = 0;
@@ -1259,7 +1278,7 @@
fota_status.update_status[i].check_delta = PASS;
fota_status.update_status[i].check_rom = PASS;
- RLOGD("+[UA]: %s upgrade success!!!\n",partition_filename[i]);
+ RLOGE("+[UA]: %s upgrade success!!!\n",partition_filename[i]);
}else if(status == E_ROCK_INVALID_DELTA) {
fota_status.update_status[i].check_delta = ERROR;
@@ -1316,7 +1335,7 @@
if (mtk_device_wrap_seek(fd_delta, DELTA_HEARD_SIZE + delta_size, SEEK_SET) < 0)
{
err = errno;
- RLOGD("+[UA]: mtk_device_wrap_seek df_delta err\n");
+ RLOGE("+[UA]: mtk_device_wrap_seek df_delta err\n");
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
}
@@ -1328,7 +1347,7 @@
if (lseek(fd_delta, DELTA_HEARD_SIZE + delta_size, SEEK_SET) < 0)
{
err = errno;
- RLOGD("+[UA]: mtk_device_wrap_seek df_delta err\n");
+ RLOGE("+[UA]: mtk_device_wrap_seek df_delta err\n");
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
}
@@ -1337,7 +1356,7 @@
}
if (memcmp(full_header, "full-ota", DELTA_FULL_HEARD_SIZE) != 0) {
- RLOGD("+[UA]: invalid full delta header\r\n");
+ RLOGE("+[UA]: invalid full delta header\r\n");
up_info.fota_flag[0] = 'e';
up_info.fota_flag[1] = 'n';
up_info.fota_flag[2] = 'd';
@@ -1384,7 +1403,7 @@
fd_partition_a = mtk_device_wrap_open(partition_filename_a[i-MAX_OTA_ROLE/2],O_RDWR);
if (fd_partition_a < 0) {
err = errno;
- RLOGD("+[UA]: Error opening full id_a[%d] file: %s\n",i,strerror(errno));
+ RLOGE("+[UA]: Error opening full id_a[%d] file: %s\n",i,strerror(errno));
system("echo fota-interface >/sys/power/wake_unlock");
return -err;
}
@@ -1393,7 +1412,7 @@
fd_partition_b = mtk_device_wrap_open(partition_filename_b[i-MAX_OTA_ROLE/2],O_RDWR);
if (fd_partition_b < 0) {
err = errno;
- RLOGD("+[UA]: Error opening full_id_b[%d] file: %s\n",i,strerror(errno));
+ RLOGE("+[UA]: Error opening full_id_b[%d] file: %s\n",i,strerror(errno));
system("echo fota-interface >/sys/power/wake_unlock");
return -err;
}
@@ -1404,7 +1423,7 @@
up_info.ota_run = i+1;
save_fota_info();
retry_cnt = 0;
- RLOGD("+[UA]: Start upgrading %s full.\n",partition_filename[i-MAX_OTA_ROLE/2]);
+ RLOGE("+[UA]: Start upgrading %s full.\n",partition_filename[i-MAX_OTA_ROLE/2]);
do{
status = delta_copyto_nand(delta_offset,delta_head[i]);
if(g_addr_flag == 1)
@@ -1421,7 +1440,7 @@
mtk_device_wrap_close(fd_curr);
- RLOGD("+[UA]: %s full retry_cnt = %d\n",partition_filename[i-MAX_OTA_ROLE/2],retry_cnt);
+ RLOGE("+[UA]: %s full retry_cnt = %d\n",partition_filename[i-MAX_OTA_ROLE/2],retry_cnt);
if (retry_cnt>3) {
if (status == 0) {
@@ -1435,7 +1454,7 @@
}
}
- RLOGD("+[UA]: %s full upgrade result:%d\n",partition_filename[i-MAX_OTA_ROLE/2],status);
+ RLOGE("+[UA]: %s full upgrade result:%d\n",partition_filename[i-MAX_OTA_ROLE/2],status);
fota_status.update_result = status;
fota_status.update_status[i].update_result = status;
@@ -1496,12 +1515,12 @@
slot = (current_slot == 0) ? 1 : 0;
- RLOGD("+[UA]: slot SLOT = %d\n",slot);
+ RLOGE("+[UA]: slot SLOT = %d\n",slot);
if(switch_slot_flag==1)
{
module->setActiveBootSlot(module,slot);
- RLOGD("+[UA]: upgrade is success!!!!\n");
+ RLOGE("+[UA]: upgrade is success!!!!\n");
}
fota_status.ota_run = 0;
@@ -1540,21 +1559,29 @@
{
int ret = 0;
-
-#if 0
-
- printf("-********copy delta ***-\n");
- test_write_delta("/data/delta",DEV_DELTA);
-
-#endif
-
- ret = rock_update_main(0, 0, 0, 0, first_run, 1, 1, 1);
- RLOGD("rock_update_main ret = %d\n", ret);
- if(ret)
+ int exit_status = 0;
+ pthread_mutex_lock(&s_update_main_mutex);
+ ret = system("lynq-fota-tool 1");
+ pthread_mutex_unlock(&s_update_main_mutex);
+ RLOGE("rock_update_main ret = %d\n", ret);
+ if (WIFEXITED(ret))
+ {
+ exit_status = WEXITSTATUS(ret);
+ if(exit_status != 0)
{
- RLOGD("fota update fail!\n");
+ ret = exit_status -256;
}
- return ret;
+
+ RLOGE("rock_update_main exit_status: %d\n", ret);
+ }
+ else
+ {
+ RLOGE("rock_update_main core dump\n");
+ ret = -1;
+ }
+
+
+ return ret;
}
#endif
@@ -2041,7 +2068,7 @@
int is_other_slot_bootable;
const hw_module_t* hw_module;
//xf.li@20230822 add for ab backup end
- RLOGD("[+UP]: ******lynq_fota_func start******\n");
+ RLOGE("[+UP]: ******lynq_fota_func start******\n");
//xf.li@20230822 add for ab backup start
//----------get current slot and whether other slot is bootable
hw_module = &HAL_MODULE_INFO_SYM;
@@ -2050,20 +2077,20 @@
ret = -EINVAL;
}
if (ret != 0) {
- RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
+ RLOGE("+[UA]: Error loading boot_control HAL implementation.\n");
return -1;
}
module = (boot_control_module_t*)hw_module;
module->init(module);
if (module == NULL) {
- RLOGD("+[UA]: Error getting bootctrl module.\n");
+ RLOGE("+[UA]: Error getting bootctrl module.\n");
return -1;
}
current_slot = module->getCurrentSlot(module);
other_slot = (current_slot == 0) ? 1 : 0;
is_other_slot_bootable = module->isSlotBootable(module, other_slot);
//-----------end
- RLOGD("current slot:%u, is_other_slot_bootable : %d\n",current_slot, is_other_slot_bootable);
+ RLOGE("current slot:%u, is_other_slot_bootable : %d\n",current_slot, is_other_slot_bootable);
//xf.li@20230822 add for ab backup end
memset(&lynq_up_info, 0, sizeof(lynq_up_info));
@@ -2096,16 +2123,15 @@
reboot_device();
}
-
if(lynq_up_info.ota_run != 0)
{
//Power off, call UA
- RLOGD("[+UP]: ***Power off, call UA***\n");
+ RLOGE("[+UP]: ***Power off, call UA***\n");
ret = rock_update_main(0, 0, 0, 0, first_run, 1, 0, 1);
- RLOGD("rock_update_main ret = %d\n", ret);
+ RLOGE("rock_update_main ret = %d\n", ret);
if(ret)
{
- RLOGD("fota update fail!\n");
+ RLOGE("fota update fail!\n");
}
}
@@ -2113,35 +2139,35 @@
((lynq_up_info.fota_flag[0]=='B')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='A')))
{
//Upgrade the other side and call UA
- RLOGD("[+UP]: ***Upgrade the other side and call UA***\n");
+ RLOGE("[+UP]: ***Upgrade the other side and call UA***\n");
ret = rock_update_main(0, 0, 0, 0, first_run, 0, 0, 0);
- RLOGD("rock_update_main ret = %d\n", ret);
+ RLOGE("rock_update_main ret = %d\n", ret);
if(ret)
{
- RLOGD("fota update fail!\n");
+ RLOGE("fota update fail!\n");
}
}
//xf.li@20230822 add for ab backup start
else if(is_other_slot_bootable == 0)
{
- RLOGD("need backup\n");
+ RLOGE("need backup\n");
ret = lynq_backup_main();
if(ret != 0)
{
- RLOGD("ERROE: backup fail!!!\n");
+ RLOGE("ERROE: backup fail!!!\n");
}
else
{
- RLOGD("backup success!!!\n");
+ RLOGE("backup success!!!\n");
module->setCompleteBackup(module, current_slot);
}
}
else
{
- RLOGD("Don't need backup\n");
+ RLOGE("Don't need backup\n");
}
//xf.li@20230822 add for ab backup end
-
+
return 0;
}
@@ -2220,17 +2246,26 @@
{
int ret = 0;
-#if 0
- printf("-********copy delta ***-\n");
- test_write_delta("/data/delta",DEV_DELTA);
-#endif
-
- ret = rock_update_main(0, 0, 0, 0, 1, 1, 0, 1);
- RLOGD("rock_update_nrestart ret = %d\n", ret);
- if(ret)
+ int exit_status = 0;
+ pthread_mutex_lock(&s_update_main_mutex);
+ ret = system("lynq-fota-tool 0");
+ pthread_mutex_unlock(&s_update_main_mutex);
+ if (WIFEXITED(ret))
{
- RLOGD("fota update fail!\n");
+ exit_status = WEXITSTATUS(ret);
+ if(exit_status != 0)
+ {
+ ret = exit_status -256;
+ }
+
+ RLOGE("lynq_fota_nrestart exit_status: %d\n", ret);
}
+ else
+ {
+ RLOGE("lynq_fota_nrestart core dump\n");
+ ret = -1;
+ }
+
return ret;
}
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-ftp-fota/lib_wapper/lynq-ftp-fota-wapper.c b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-ftp-fota/lib_wapper/lynq-ftp-fota-wapper.c
index c48adca..1dcaab8 100755
--- a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-ftp-fota/lib_wapper/lynq-ftp-fota-wapper.c
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-ftp-fota/lib_wapper/lynq-ftp-fota-wapper.c
@@ -171,11 +171,28 @@
{
int ret = 0;
char cmd[1024] = {0};
+ int exit_status = 0;
RLOGE("+[UA]: cy rock_update_main\n");
sprintf(cmd, "lynq-ftp-fota-tool %d %d %d %d %d %d %d %d", rom_base, backup_base, backup_len, read_rom_directly, first_run, switch_slot_flag, reboot_flag, backup_mode);
pthread_mutex_lock(&s_update_main_mutex);
ret = system(cmd);
pthread_mutex_unlock(&s_update_main_mutex);
+ if (WIFEXITED(ret))
+ {
+ exit_status = WEXITSTATUS(ret);
+ if(exit_status != 0)
+ {
+ ret = exit_status -256;
+ }
+
+ RLOGE("rock_update_main exit_status: %d\n", ret);
+ }
+ else
+ {
+ RLOGE("rock_update_main core dump\n");
+ ret = -1;
+ }
+
return ret;
}
diff --git a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-ftp-fota/rock_ua/rock_ua.cpp b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-ftp-fota/rock_ua/rock_ua.cpp
index aaa36da..0ede8f1 100755
--- a/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-ftp-fota/rock_ua/rock_ua.cpp
+++ b/LYNQ_PUBLIC/IC_src/mtk/lib/liblynq-ftp-fota/rock_ua/rock_ua.cpp
@@ -1059,7 +1059,11 @@
int is_successful = module->isSlotMarkedSuccessful(module, current_slot);
RLOGD("Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
-
+ if((current_slot != 0)&&(current_slot != 1))
+ {
+ RLOGE("+[UA]: get current slot fail\n");
+ return -1;
+ }
memset(&ctx, 0, sizeof(ctx));
diff --git a/LYNQ_PUBLIC/IC_src/mtk/packages/apps/lynq-fota-tool/lynq_fota_tool.c b/LYNQ_PUBLIC/IC_src/mtk/packages/apps/lynq-fota-tool/lynq_fota_tool.c
new file mode 100755
index 0000000..904c69d
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/packages/apps/lynq-fota-tool/lynq_fota_tool.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/un.h>
+#include <include/iot_rock.h>
+
+
+
+
+int main(int argc, char** argv)
+{
+
+ int ret = 0;
+ int first_run=1;
+ if(argc <= 1)
+ {
+ return -1;
+ }
+ if (strcmp(argv[1],"0") == 0)
+ {
+ ret = lynq_fota_nrestart();
+ }
+ else if(strcmp(argv[1],"1") == 0)
+ {
+ ret = lynq_rock_main(first_run);
+ }
+ else
+ {
+ return -1;
+ }
+
+
+ return ret;
+
+}
diff --git a/LYNQ_PUBLIC/IC_src/mtk/packages/apps/lynq-fota-tool/makefile b/LYNQ_PUBLIC/IC_src/mtk/packages/apps/lynq-fota-tool/makefile
new file mode 100644
index 0000000..8c3edc9
--- /dev/null
+++ b/LYNQ_PUBLIC/IC_src/mtk/packages/apps/lynq-fota-tool/makefile
@@ -0,0 +1,44 @@
+SHELL = /bin/sh
+RM = rm -f
+
+LOCAL_CFLAGS := -Wall \
+ -g -Os \
+ -flto \
+ -fpermissive \
+ -fPIC \
+
+
+
+LOCAL_CFLAGS += -DLYNQ_SW_INSIDE_VERSION=\"$(LYNQ_CONFIG_VERSION)\"
+LOCAL_CFLAGS += -DLYNQ_SW_VERSION=\"$(LYNQ_CONFIG_SW_VERSION)\"
+
+LOCAL_PATH = .
+
+LOCAL_C_INCLUDES = \
+ -I. \
+ -I$(ROOT)$(includedir)/logger \
+ -I$(ROOT)$(includedir)/liblog \
+
+
+LOCAL_LIBS := \
+ -L. \
+ -ldl \
+ -lpthread \
+ -llynq-fota-run \
+
+SOURCES = $(wildcard *.c)
+
+EXECUTABLE = lynq-fota-tool
+
+OBJECTS=$(SOURCES:.c=.o)
+all: $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+ $(CXX) $(OBJECTS) $(LOCAL_LIBS) $(LOCAL_CFLAGS) $(LOCAL_C_INCLUDES) -o $@
+
+%.o : %.c
+ $(CC) $(LOCAL_C_INCLUDES) $(LOCAL_CFLAGS) $(LOCAL_LIBS) -o $@ -c $<
+
+.PHONY: clean
+clean:
+ $(RM) $(OBJECTS) $(EXECUTABLE)