13d0407baSopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
23d0407baSopenharmony_ci/*
33d0407baSopenharmony_ci * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd
43d0407baSopenharmony_ci */
53d0407baSopenharmony_ci
63d0407baSopenharmony_ci#include <errno.h>
73d0407baSopenharmony_ci#include <memory.h>
83d0407baSopenharmony_ci#include <stdint.h>
93d0407baSopenharmony_ci#include <stdio.h>
103d0407baSopenharmony_ci#include <stdlib.h>
113d0407baSopenharmony_ci#include <stdbool.h>
123d0407baSopenharmony_ci#include <sys/stat.h>
133d0407baSopenharmony_ci#include <time.h>
143d0407baSopenharmony_ci
153d0407baSopenharmony_ci/**
163d0407baSopenharmony_ci * \brief	   SHA-1 context structure
173d0407baSopenharmony_ci */
183d0407baSopenharmony_citypedef struct
193d0407baSopenharmony_ci{
203d0407baSopenharmony_ci    unsigned long total[2];	/*!< number of bytes processed	*/
213d0407baSopenharmony_ci    unsigned long state[5];	/*!< intermediate digest state	*/
223d0407baSopenharmony_ci    unsigned char buffer[64];	/*!< data block being processed */
233d0407baSopenharmony_ci}
243d0407baSopenharmony_cisha1_context;
253d0407baSopenharmony_ci
263d0407baSopenharmony_ci/*
273d0407baSopenharmony_ci * 32-bit integer manipulation macros (big endian)
283d0407baSopenharmony_ci */
293d0407baSopenharmony_ci#ifndef GET_UINT32_BE
303d0407baSopenharmony_ci#define GET_UINT32_BE(n,b,i) {				\
313d0407baSopenharmony_ci	(n) = ( (unsigned long) (b)[(i)    ] << 24 )	\
323d0407baSopenharmony_ci	    | ( (unsigned long) (b)[(i) + 1] << 16 )	\
333d0407baSopenharmony_ci	    | ( (unsigned long) (b)[(i) + 2] <<  8 )	\
343d0407baSopenharmony_ci	    | ( (unsigned long) (b)[(i) + 3]       );	\
353d0407baSopenharmony_ci}
363d0407baSopenharmony_ci#endif
373d0407baSopenharmony_ci#ifndef PUT_UINT32_BE
383d0407baSopenharmony_ci#define PUT_UINT32_BE(n,b,i) {				\
393d0407baSopenharmony_ci	(b)[(i)    ] = (unsigned char) ( (n) >> 24 );	\
403d0407baSopenharmony_ci	(b)[(i) + 1] = (unsigned char) ( (n) >> 16 );	\
413d0407baSopenharmony_ci	(b)[(i) + 2] = (unsigned char) ( (n) >>  8 );	\
423d0407baSopenharmony_ci	(b)[(i) + 3] = (unsigned char) ( (n)       );	\
433d0407baSopenharmony_ci}
443d0407baSopenharmony_ci#endif
453d0407baSopenharmony_ci
463d0407baSopenharmony_ci/*
473d0407baSopenharmony_ci * SHA-1 context setup
483d0407baSopenharmony_ci */
493d0407baSopenharmony_cistatic
503d0407baSopenharmony_civoid sha1_starts (sha1_context * ctx)
513d0407baSopenharmony_ci{
523d0407baSopenharmony_ci	ctx->total[0] = 0;
533d0407baSopenharmony_ci	ctx->total[1] = 0;
543d0407baSopenharmony_ci
553d0407baSopenharmony_ci	ctx->state[0] = 0x67452301;
563d0407baSopenharmony_ci	ctx->state[1] = 0xEFCDAB89;
573d0407baSopenharmony_ci	ctx->state[2] = 0x98BADCFE;
583d0407baSopenharmony_ci	ctx->state[3] = 0x10325476;
593d0407baSopenharmony_ci	ctx->state[4] = 0xC3D2E1F0;
603d0407baSopenharmony_ci}
613d0407baSopenharmony_ci
623d0407baSopenharmony_cistatic void sha1_process(sha1_context *ctx, const unsigned char data[64])
633d0407baSopenharmony_ci{
643d0407baSopenharmony_ci	unsigned long temp, W[16], A, B, C, D, E;
653d0407baSopenharmony_ci
663d0407baSopenharmony_ci	GET_UINT32_BE (W[0], data, 0);
673d0407baSopenharmony_ci	GET_UINT32_BE (W[1], data, 4);
683d0407baSopenharmony_ci	GET_UINT32_BE (W[2], data, 8);
693d0407baSopenharmony_ci	GET_UINT32_BE (W[3], data, 12);
703d0407baSopenharmony_ci	GET_UINT32_BE (W[4], data, 16);
713d0407baSopenharmony_ci	GET_UINT32_BE (W[5], data, 20);
723d0407baSopenharmony_ci	GET_UINT32_BE (W[6], data, 24);
733d0407baSopenharmony_ci	GET_UINT32_BE (W[7], data, 28);
743d0407baSopenharmony_ci	GET_UINT32_BE (W[8], data, 32);
753d0407baSopenharmony_ci	GET_UINT32_BE (W[9], data, 36);
763d0407baSopenharmony_ci	GET_UINT32_BE (W[10], data, 40);
773d0407baSopenharmony_ci	GET_UINT32_BE (W[11], data, 44);
783d0407baSopenharmony_ci	GET_UINT32_BE (W[12], data, 48);
793d0407baSopenharmony_ci	GET_UINT32_BE (W[13], data, 52);
803d0407baSopenharmony_ci	GET_UINT32_BE (W[14], data, 56);
813d0407baSopenharmony_ci	GET_UINT32_BE (W[15], data, 60);
823d0407baSopenharmony_ci
833d0407baSopenharmony_ci#define S(x,n)	((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
843d0407baSopenharmony_ci
853d0407baSopenharmony_ci#define R(t) (						\
863d0407baSopenharmony_ci	temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^	\
873d0407baSopenharmony_ci	       W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],	\
883d0407baSopenharmony_ci	( W[t & 0x0F] = S(temp,1) )			\
893d0407baSopenharmony_ci)
903d0407baSopenharmony_ci
913d0407baSopenharmony_ci#define P(a,b,c,d,e,x)	{				\
923d0407baSopenharmony_ci	e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);	\
933d0407baSopenharmony_ci}
943d0407baSopenharmony_ci
953d0407baSopenharmony_ci	A = ctx->state[0];
963d0407baSopenharmony_ci	B = ctx->state[1];
973d0407baSopenharmony_ci	C = ctx->state[2];
983d0407baSopenharmony_ci	D = ctx->state[3];
993d0407baSopenharmony_ci	E = ctx->state[4];
1003d0407baSopenharmony_ci
1013d0407baSopenharmony_ci#define F(x,y,z) (z ^ (x & (y ^ z)))
1023d0407baSopenharmony_ci#define K 0x5A827999
1033d0407baSopenharmony_ci
1043d0407baSopenharmony_ci	P (A, B, C, D, E, W[0]);
1053d0407baSopenharmony_ci	P (E, A, B, C, D, W[1]);
1063d0407baSopenharmony_ci	P (D, E, A, B, C, W[2]);
1073d0407baSopenharmony_ci	P (C, D, E, A, B, W[3]);
1083d0407baSopenharmony_ci	P (B, C, D, E, A, W[4]);
1093d0407baSopenharmony_ci	P (A, B, C, D, E, W[5]);
1103d0407baSopenharmony_ci	P (E, A, B, C, D, W[6]);
1113d0407baSopenharmony_ci	P (D, E, A, B, C, W[7]);
1123d0407baSopenharmony_ci	P (C, D, E, A, B, W[8]);
1133d0407baSopenharmony_ci	P (B, C, D, E, A, W[9]);
1143d0407baSopenharmony_ci	P (A, B, C, D, E, W[10]);
1153d0407baSopenharmony_ci	P (E, A, B, C, D, W[11]);
1163d0407baSopenharmony_ci	P (D, E, A, B, C, W[12]);
1173d0407baSopenharmony_ci	P (C, D, E, A, B, W[13]);
1183d0407baSopenharmony_ci	P (B, C, D, E, A, W[14]);
1193d0407baSopenharmony_ci	P (A, B, C, D, E, W[15]);
1203d0407baSopenharmony_ci	P (E, A, B, C, D, R (16));
1213d0407baSopenharmony_ci	P (D, E, A, B, C, R (17));
1223d0407baSopenharmony_ci	P (C, D, E, A, B, R (18));
1233d0407baSopenharmony_ci	P (B, C, D, E, A, R (19));
1243d0407baSopenharmony_ci
1253d0407baSopenharmony_ci#undef K
1263d0407baSopenharmony_ci#undef F
1273d0407baSopenharmony_ci
1283d0407baSopenharmony_ci#define F(x,y,z) (x ^ y ^ z)
1293d0407baSopenharmony_ci#define K 0x6ED9EBA1
1303d0407baSopenharmony_ci
1313d0407baSopenharmony_ci	P (A, B, C, D, E, R (20));
1323d0407baSopenharmony_ci	P (E, A, B, C, D, R (21));
1333d0407baSopenharmony_ci	P (D, E, A, B, C, R (22));
1343d0407baSopenharmony_ci	P (C, D, E, A, B, R (23));
1353d0407baSopenharmony_ci	P (B, C, D, E, A, R (24));
1363d0407baSopenharmony_ci	P (A, B, C, D, E, R (25));
1373d0407baSopenharmony_ci	P (E, A, B, C, D, R (26));
1383d0407baSopenharmony_ci	P (D, E, A, B, C, R (27));
1393d0407baSopenharmony_ci	P (C, D, E, A, B, R (28));
1403d0407baSopenharmony_ci	P (B, C, D, E, A, R (29));
1413d0407baSopenharmony_ci	P (A, B, C, D, E, R (30));
1423d0407baSopenharmony_ci	P (E, A, B, C, D, R (31));
1433d0407baSopenharmony_ci	P (D, E, A, B, C, R (32));
1443d0407baSopenharmony_ci	P (C, D, E, A, B, R (33));
1453d0407baSopenharmony_ci	P (B, C, D, E, A, R (34));
1463d0407baSopenharmony_ci	P (A, B, C, D, E, R (35));
1473d0407baSopenharmony_ci	P (E, A, B, C, D, R (36));
1483d0407baSopenharmony_ci	P (D, E, A, B, C, R (37));
1493d0407baSopenharmony_ci	P (C, D, E, A, B, R (38));
1503d0407baSopenharmony_ci	P (B, C, D, E, A, R (39));
1513d0407baSopenharmony_ci
1523d0407baSopenharmony_ci#undef K
1533d0407baSopenharmony_ci#undef F
1543d0407baSopenharmony_ci
1553d0407baSopenharmony_ci#define F(x,y,z) ((x & y) | (z & (x | y)))
1563d0407baSopenharmony_ci#define K 0x8F1BBCDC
1573d0407baSopenharmony_ci
1583d0407baSopenharmony_ci	P (A, B, C, D, E, R (40));
1593d0407baSopenharmony_ci	P (E, A, B, C, D, R (41));
1603d0407baSopenharmony_ci	P (D, E, A, B, C, R (42));
1613d0407baSopenharmony_ci	P (C, D, E, A, B, R (43));
1623d0407baSopenharmony_ci	P (B, C, D, E, A, R (44));
1633d0407baSopenharmony_ci	P (A, B, C, D, E, R (45));
1643d0407baSopenharmony_ci	P (E, A, B, C, D, R (46));
1653d0407baSopenharmony_ci	P (D, E, A, B, C, R (47));
1663d0407baSopenharmony_ci	P (C, D, E, A, B, R (48));
1673d0407baSopenharmony_ci	P (B, C, D, E, A, R (49));
1683d0407baSopenharmony_ci	P (A, B, C, D, E, R (50));
1693d0407baSopenharmony_ci	P (E, A, B, C, D, R (51));
1703d0407baSopenharmony_ci	P (D, E, A, B, C, R (52));
1713d0407baSopenharmony_ci	P (C, D, E, A, B, R (53));
1723d0407baSopenharmony_ci	P (B, C, D, E, A, R (54));
1733d0407baSopenharmony_ci	P (A, B, C, D, E, R (55));
1743d0407baSopenharmony_ci	P (E, A, B, C, D, R (56));
1753d0407baSopenharmony_ci	P (D, E, A, B, C, R (57));
1763d0407baSopenharmony_ci	P (C, D, E, A, B, R (58));
1773d0407baSopenharmony_ci	P (B, C, D, E, A, R (59));
1783d0407baSopenharmony_ci
1793d0407baSopenharmony_ci#undef K
1803d0407baSopenharmony_ci#undef F
1813d0407baSopenharmony_ci
1823d0407baSopenharmony_ci#define F(x,y,z) (x ^ y ^ z)
1833d0407baSopenharmony_ci#define K 0xCA62C1D6
1843d0407baSopenharmony_ci
1853d0407baSopenharmony_ci	P (A, B, C, D, E, R (60));
1863d0407baSopenharmony_ci	P (E, A, B, C, D, R (61));
1873d0407baSopenharmony_ci	P (D, E, A, B, C, R (62));
1883d0407baSopenharmony_ci	P (C, D, E, A, B, R (63));
1893d0407baSopenharmony_ci	P (B, C, D, E, A, R (64));
1903d0407baSopenharmony_ci	P (A, B, C, D, E, R (65));
1913d0407baSopenharmony_ci	P (E, A, B, C, D, R (66));
1923d0407baSopenharmony_ci	P (D, E, A, B, C, R (67));
1933d0407baSopenharmony_ci	P (C, D, E, A, B, R (68));
1943d0407baSopenharmony_ci	P (B, C, D, E, A, R (69));
1953d0407baSopenharmony_ci	P (A, B, C, D, E, R (70));
1963d0407baSopenharmony_ci	P (E, A, B, C, D, R (71));
1973d0407baSopenharmony_ci	P (D, E, A, B, C, R (72));
1983d0407baSopenharmony_ci	P (C, D, E, A, B, R (73));
1993d0407baSopenharmony_ci	P (B, C, D, E, A, R (74));
2003d0407baSopenharmony_ci	P (A, B, C, D, E, R (75));
2013d0407baSopenharmony_ci	P (E, A, B, C, D, R (76));
2023d0407baSopenharmony_ci	P (D, E, A, B, C, R (77));
2033d0407baSopenharmony_ci	P (C, D, E, A, B, R (78));
2043d0407baSopenharmony_ci	P (B, C, D, E, A, R (79));
2053d0407baSopenharmony_ci
2063d0407baSopenharmony_ci#undef K
2073d0407baSopenharmony_ci#undef F
2083d0407baSopenharmony_ci
2093d0407baSopenharmony_ci	ctx->state[0] += A;
2103d0407baSopenharmony_ci	ctx->state[1] += B;
2113d0407baSopenharmony_ci	ctx->state[2] += C;
2123d0407baSopenharmony_ci	ctx->state[3] += D;
2133d0407baSopenharmony_ci	ctx->state[4] += E;
2143d0407baSopenharmony_ci}
2153d0407baSopenharmony_ci
2163d0407baSopenharmony_ci#undef P
2173d0407baSopenharmony_ci#undef R
2183d0407baSopenharmony_ci#undef S
2193d0407baSopenharmony_ci
2203d0407baSopenharmony_ci/*
2213d0407baSopenharmony_ci * SHA-1 process buffer
2223d0407baSopenharmony_ci */
2233d0407baSopenharmony_cistatic
2243d0407baSopenharmony_civoid sha1_update(sha1_context *ctx, const unsigned char *input,
2253d0407baSopenharmony_ci		 unsigned int ilen)
2263d0407baSopenharmony_ci{
2273d0407baSopenharmony_ci	int fill;
2283d0407baSopenharmony_ci	unsigned long left;
2293d0407baSopenharmony_ci
2303d0407baSopenharmony_ci	if (ilen <= 0)
2313d0407baSopenharmony_ci		return;
2323d0407baSopenharmony_ci
2333d0407baSopenharmony_ci	left = ctx->total[0] & 0x3F;
2343d0407baSopenharmony_ci	fill = 64 - left;
2353d0407baSopenharmony_ci
2363d0407baSopenharmony_ci	ctx->total[0] += ilen;
2373d0407baSopenharmony_ci	ctx->total[0] &= 0xFFFFFFFF;
2383d0407baSopenharmony_ci
2393d0407baSopenharmony_ci	if (ctx->total[0] < (unsigned long) ilen)
2403d0407baSopenharmony_ci		ctx->total[1]++;
2413d0407baSopenharmony_ci
2423d0407baSopenharmony_ci	if (left && ilen >= fill) {
2433d0407baSopenharmony_ci		memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
2443d0407baSopenharmony_ci		sha1_process (ctx, ctx->buffer);
2453d0407baSopenharmony_ci		input += fill;
2463d0407baSopenharmony_ci		ilen -= fill;
2473d0407baSopenharmony_ci		left = 0;
2483d0407baSopenharmony_ci	}
2493d0407baSopenharmony_ci
2503d0407baSopenharmony_ci	while (ilen >= 64) {
2513d0407baSopenharmony_ci		sha1_process (ctx, input);
2523d0407baSopenharmony_ci		input += 64;
2533d0407baSopenharmony_ci		ilen -= 64;
2543d0407baSopenharmony_ci	}
2553d0407baSopenharmony_ci
2563d0407baSopenharmony_ci	if (ilen > 0) {
2573d0407baSopenharmony_ci		memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
2583d0407baSopenharmony_ci	}
2593d0407baSopenharmony_ci}
2603d0407baSopenharmony_ci
2613d0407baSopenharmony_cistatic const unsigned char sha1_padding[64] = {
2623d0407baSopenharmony_ci	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2633d0407baSopenharmony_ci	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2643d0407baSopenharmony_ci	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2653d0407baSopenharmony_ci	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
2663d0407baSopenharmony_ci};
2673d0407baSopenharmony_ci
2683d0407baSopenharmony_ci/*
2693d0407baSopenharmony_ci * SHA-1 final digest
2703d0407baSopenharmony_ci */
2713d0407baSopenharmony_cistatic
2723d0407baSopenharmony_civoid sha1_finish (sha1_context * ctx, unsigned char output[20])
2733d0407baSopenharmony_ci{
2743d0407baSopenharmony_ci	unsigned long last, padn;
2753d0407baSopenharmony_ci	unsigned long high, low;
2763d0407baSopenharmony_ci	unsigned char msglen[8];
2773d0407baSopenharmony_ci
2783d0407baSopenharmony_ci	high = (ctx->total[0] >> 29)
2793d0407baSopenharmony_ci		| (ctx->total[1] << 3);
2803d0407baSopenharmony_ci	low = (ctx->total[0] << 3);
2813d0407baSopenharmony_ci
2823d0407baSopenharmony_ci	PUT_UINT32_BE (high, msglen, 0);
2833d0407baSopenharmony_ci	PUT_UINT32_BE (low, msglen, 4);
2843d0407baSopenharmony_ci
2853d0407baSopenharmony_ci	last = ctx->total[0] & 0x3F;
2863d0407baSopenharmony_ci	padn = (last < 56) ? (56 - last) : (120 - last);
2873d0407baSopenharmony_ci
2883d0407baSopenharmony_ci	sha1_update (ctx, (unsigned char *) sha1_padding, padn);
2893d0407baSopenharmony_ci	sha1_update (ctx, msglen, 8);
2903d0407baSopenharmony_ci
2913d0407baSopenharmony_ci	PUT_UINT32_BE (ctx->state[0], output, 0);
2923d0407baSopenharmony_ci	PUT_UINT32_BE (ctx->state[1], output, 4);
2933d0407baSopenharmony_ci	PUT_UINT32_BE (ctx->state[2], output, 8);
2943d0407baSopenharmony_ci	PUT_UINT32_BE (ctx->state[3], output, 12);
2953d0407baSopenharmony_ci	PUT_UINT32_BE (ctx->state[4], output, 16);
2963d0407baSopenharmony_ci}
2973d0407baSopenharmony_ci
2983d0407baSopenharmony_ci/*
2993d0407baSopenharmony_ci * Output = SHA-1( input buffer )
3003d0407baSopenharmony_ci */
3013d0407baSopenharmony_cistatic
3023d0407baSopenharmony_civoid sha1_csum(const unsigned char *input, unsigned int ilen,
3033d0407baSopenharmony_ci	       unsigned char *output)
3043d0407baSopenharmony_ci{
3053d0407baSopenharmony_ci	sha1_context ctx;
3063d0407baSopenharmony_ci
3073d0407baSopenharmony_ci	sha1_starts (&ctx);
3083d0407baSopenharmony_ci	sha1_update (&ctx, input, ilen);
3093d0407baSopenharmony_ci	sha1_finish (&ctx, output);
3103d0407baSopenharmony_ci}
3113d0407baSopenharmony_ci
3123d0407baSopenharmony_citypedef struct {
3133d0407baSopenharmony_ci	uint32_t total[2];
3143d0407baSopenharmony_ci	uint32_t state[8];
3153d0407baSopenharmony_ci	uint8_t buffer[64];
3163d0407baSopenharmony_ci} sha256_context;
3173d0407baSopenharmony_ci
3183d0407baSopenharmony_cistatic
3193d0407baSopenharmony_civoid sha256_starts(sha256_context * ctx)
3203d0407baSopenharmony_ci{
3213d0407baSopenharmony_ci	ctx->total[0] = 0;
3223d0407baSopenharmony_ci	ctx->total[1] = 0;
3233d0407baSopenharmony_ci
3243d0407baSopenharmony_ci	ctx->state[0] = 0x6A09E667;
3253d0407baSopenharmony_ci	ctx->state[1] = 0xBB67AE85;
3263d0407baSopenharmony_ci	ctx->state[2] = 0x3C6EF372;
3273d0407baSopenharmony_ci	ctx->state[3] = 0xA54FF53A;
3283d0407baSopenharmony_ci	ctx->state[4] = 0x510E527F;
3293d0407baSopenharmony_ci	ctx->state[5] = 0x9B05688C;
3303d0407baSopenharmony_ci	ctx->state[6] = 0x1F83D9AB;
3313d0407baSopenharmony_ci	ctx->state[7] = 0x5BE0CD19;
3323d0407baSopenharmony_ci}
3333d0407baSopenharmony_ci
3343d0407baSopenharmony_cistatic void sha256_process(sha256_context *ctx, const uint8_t data[64])
3353d0407baSopenharmony_ci{
3363d0407baSopenharmony_ci	uint32_t temp1, temp2;
3373d0407baSopenharmony_ci	uint32_t W[64];
3383d0407baSopenharmony_ci	uint32_t A, B, C, D, E, F, G, H;
3393d0407baSopenharmony_ci
3403d0407baSopenharmony_ci	GET_UINT32_BE(W[0], data, 0);
3413d0407baSopenharmony_ci	GET_UINT32_BE(W[1], data, 4);
3423d0407baSopenharmony_ci	GET_UINT32_BE(W[2], data, 8);
3433d0407baSopenharmony_ci	GET_UINT32_BE(W[3], data, 12);
3443d0407baSopenharmony_ci	GET_UINT32_BE(W[4], data, 16);
3453d0407baSopenharmony_ci	GET_UINT32_BE(W[5], data, 20);
3463d0407baSopenharmony_ci	GET_UINT32_BE(W[6], data, 24);
3473d0407baSopenharmony_ci	GET_UINT32_BE(W[7], data, 28);
3483d0407baSopenharmony_ci	GET_UINT32_BE(W[8], data, 32);
3493d0407baSopenharmony_ci	GET_UINT32_BE(W[9], data, 36);
3503d0407baSopenharmony_ci	GET_UINT32_BE(W[10], data, 40);
3513d0407baSopenharmony_ci	GET_UINT32_BE(W[11], data, 44);
3523d0407baSopenharmony_ci	GET_UINT32_BE(W[12], data, 48);
3533d0407baSopenharmony_ci	GET_UINT32_BE(W[13], data, 52);
3543d0407baSopenharmony_ci	GET_UINT32_BE(W[14], data, 56);
3553d0407baSopenharmony_ci	GET_UINT32_BE(W[15], data, 60);
3563d0407baSopenharmony_ci
3573d0407baSopenharmony_ci#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
3583d0407baSopenharmony_ci#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
3593d0407baSopenharmony_ci
3603d0407baSopenharmony_ci#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
3613d0407baSopenharmony_ci#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
3623d0407baSopenharmony_ci
3633d0407baSopenharmony_ci#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
3643d0407baSopenharmony_ci#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
3653d0407baSopenharmony_ci
3663d0407baSopenharmony_ci#define F0(x,y,z) ((x & y) | (z & (x | y)))
3673d0407baSopenharmony_ci#define F1(x,y,z) (z ^ (x & (y ^ z)))
3683d0407baSopenharmony_ci
3693d0407baSopenharmony_ci#define R(t)					\
3703d0407baSopenharmony_ci(						\
3713d0407baSopenharmony_ci	W[t] = S1(W[t - 2]) + W[t - 7] +	\
3723d0407baSopenharmony_ci		S0(W[t - 15]) + W[t - 16]	\
3733d0407baSopenharmony_ci)
3743d0407baSopenharmony_ci
3753d0407baSopenharmony_ci#define P(a,b,c,d,e,f,g,h,x,K) {		\
3763d0407baSopenharmony_ci	temp1 = h + S3(e) + F1(e,f,g) + K + x;	\
3773d0407baSopenharmony_ci	temp2 = S2(a) + F0(a,b,c);		\
3783d0407baSopenharmony_ci	d += temp1; h = temp1 + temp2;		\
3793d0407baSopenharmony_ci}
3803d0407baSopenharmony_ci
3813d0407baSopenharmony_ci	A = ctx->state[0];
3823d0407baSopenharmony_ci	B = ctx->state[1];
3833d0407baSopenharmony_ci	C = ctx->state[2];
3843d0407baSopenharmony_ci	D = ctx->state[3];
3853d0407baSopenharmony_ci	E = ctx->state[4];
3863d0407baSopenharmony_ci	F = ctx->state[5];
3873d0407baSopenharmony_ci	G = ctx->state[6];
3883d0407baSopenharmony_ci	H = ctx->state[7];
3893d0407baSopenharmony_ci
3903d0407baSopenharmony_ci	P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
3913d0407baSopenharmony_ci	P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
3923d0407baSopenharmony_ci	P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
3933d0407baSopenharmony_ci	P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
3943d0407baSopenharmony_ci	P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
3953d0407baSopenharmony_ci	P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
3963d0407baSopenharmony_ci	P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
3973d0407baSopenharmony_ci	P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
3983d0407baSopenharmony_ci	P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
3993d0407baSopenharmony_ci	P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
4003d0407baSopenharmony_ci	P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
4013d0407baSopenharmony_ci	P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
4023d0407baSopenharmony_ci	P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
4033d0407baSopenharmony_ci	P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
4043d0407baSopenharmony_ci	P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
4053d0407baSopenharmony_ci	P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
4063d0407baSopenharmony_ci	P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
4073d0407baSopenharmony_ci	P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
4083d0407baSopenharmony_ci	P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
4093d0407baSopenharmony_ci	P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
4103d0407baSopenharmony_ci	P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
4113d0407baSopenharmony_ci	P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
4123d0407baSopenharmony_ci	P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
4133d0407baSopenharmony_ci	P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
4143d0407baSopenharmony_ci	P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
4153d0407baSopenharmony_ci	P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
4163d0407baSopenharmony_ci	P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
4173d0407baSopenharmony_ci	P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
4183d0407baSopenharmony_ci	P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
4193d0407baSopenharmony_ci	P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
4203d0407baSopenharmony_ci	P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
4213d0407baSopenharmony_ci	P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
4223d0407baSopenharmony_ci	P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
4233d0407baSopenharmony_ci	P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
4243d0407baSopenharmony_ci	P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
4253d0407baSopenharmony_ci	P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
4263d0407baSopenharmony_ci	P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
4273d0407baSopenharmony_ci	P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
4283d0407baSopenharmony_ci	P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
4293d0407baSopenharmony_ci	P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
4303d0407baSopenharmony_ci	P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
4313d0407baSopenharmony_ci	P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
4323d0407baSopenharmony_ci	P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
4333d0407baSopenharmony_ci	P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
4343d0407baSopenharmony_ci	P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
4353d0407baSopenharmony_ci	P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
4363d0407baSopenharmony_ci	P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
4373d0407baSopenharmony_ci	P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
4383d0407baSopenharmony_ci	P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
4393d0407baSopenharmony_ci	P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
4403d0407baSopenharmony_ci	P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
4413d0407baSopenharmony_ci	P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
4423d0407baSopenharmony_ci	P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
4433d0407baSopenharmony_ci	P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
4443d0407baSopenharmony_ci	P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
4453d0407baSopenharmony_ci	P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
4463d0407baSopenharmony_ci	P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
4473d0407baSopenharmony_ci	P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
4483d0407baSopenharmony_ci	P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
4493d0407baSopenharmony_ci	P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
4503d0407baSopenharmony_ci	P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
4513d0407baSopenharmony_ci	P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
4523d0407baSopenharmony_ci	P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
4533d0407baSopenharmony_ci	P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
4543d0407baSopenharmony_ci
4553d0407baSopenharmony_ci	ctx->state[0] += A;
4563d0407baSopenharmony_ci	ctx->state[1] += B;
4573d0407baSopenharmony_ci	ctx->state[2] += C;
4583d0407baSopenharmony_ci	ctx->state[3] += D;
4593d0407baSopenharmony_ci	ctx->state[4] += E;
4603d0407baSopenharmony_ci	ctx->state[5] += F;
4613d0407baSopenharmony_ci	ctx->state[6] += G;
4623d0407baSopenharmony_ci	ctx->state[7] += H;
4633d0407baSopenharmony_ci}
4643d0407baSopenharmony_ci
4653d0407baSopenharmony_ci#undef P
4663d0407baSopenharmony_ci#undef R
4673d0407baSopenharmony_ci#undef F1
4683d0407baSopenharmony_ci#undef F0
4693d0407baSopenharmony_ci#undef S3
4703d0407baSopenharmony_ci#undef S2
4713d0407baSopenharmony_ci#undef S1
4723d0407baSopenharmony_ci#undef S0
4733d0407baSopenharmony_ci#undef ROTR
4743d0407baSopenharmony_ci#undef SHR
4753d0407baSopenharmony_ci
4763d0407baSopenharmony_cistatic
4773d0407baSopenharmony_civoid sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
4783d0407baSopenharmony_ci{
4793d0407baSopenharmony_ci	uint32_t left, fill;
4803d0407baSopenharmony_ci
4813d0407baSopenharmony_ci	if (!length)
4823d0407baSopenharmony_ci		return;
4833d0407baSopenharmony_ci
4843d0407baSopenharmony_ci	left = ctx->total[0] & 0x3F;
4853d0407baSopenharmony_ci	fill = 64 - left;
4863d0407baSopenharmony_ci
4873d0407baSopenharmony_ci	ctx->total[0] += length;
4883d0407baSopenharmony_ci	ctx->total[0] &= 0xFFFFFFFF;
4893d0407baSopenharmony_ci
4903d0407baSopenharmony_ci	if (ctx->total[0] < length)
4913d0407baSopenharmony_ci		ctx->total[1]++;
4923d0407baSopenharmony_ci
4933d0407baSopenharmony_ci	if (left && length >= fill) {
4943d0407baSopenharmony_ci		memcpy((void *) (ctx->buffer + left), (void *) input, fill);
4953d0407baSopenharmony_ci		sha256_process(ctx, ctx->buffer);
4963d0407baSopenharmony_ci		length -= fill;
4973d0407baSopenharmony_ci		input += fill;
4983d0407baSopenharmony_ci		left = 0;
4993d0407baSopenharmony_ci	}
5003d0407baSopenharmony_ci
5013d0407baSopenharmony_ci	while (length >= 64) {
5023d0407baSopenharmony_ci		sha256_process(ctx, input);
5033d0407baSopenharmony_ci		length -= 64;
5043d0407baSopenharmony_ci		input += 64;
5053d0407baSopenharmony_ci	}
5063d0407baSopenharmony_ci
5073d0407baSopenharmony_ci	if (length)
5083d0407baSopenharmony_ci		memcpy((void *) (ctx->buffer + left), (void *) input, length);
5093d0407baSopenharmony_ci}
5103d0407baSopenharmony_ci
5113d0407baSopenharmony_cistatic uint8_t sha256_padding[64] = {
5123d0407baSopenharmony_ci	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5133d0407baSopenharmony_ci	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5143d0407baSopenharmony_ci	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5153d0407baSopenharmony_ci	   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
5163d0407baSopenharmony_ci};
5173d0407baSopenharmony_ci
5183d0407baSopenharmony_cistatic
5193d0407baSopenharmony_civoid sha256_finish(sha256_context * ctx, uint8_t digest[32])
5203d0407baSopenharmony_ci{
5213d0407baSopenharmony_ci	uint32_t last, padn;
5223d0407baSopenharmony_ci	uint32_t high, low;
5233d0407baSopenharmony_ci	uint8_t msglen[8];
5243d0407baSopenharmony_ci
5253d0407baSopenharmony_ci	high = ((ctx->total[0] >> 29)
5263d0407baSopenharmony_ci		| (ctx->total[1] << 3));
5273d0407baSopenharmony_ci	low = (ctx->total[0] << 3);
5283d0407baSopenharmony_ci
5293d0407baSopenharmony_ci	PUT_UINT32_BE(high, msglen, 0);
5303d0407baSopenharmony_ci	PUT_UINT32_BE(low, msglen, 4);
5313d0407baSopenharmony_ci
5323d0407baSopenharmony_ci	last = ctx->total[0] & 0x3F;
5333d0407baSopenharmony_ci	padn = (last < 56) ? (56 - last) : (120 - last);
5343d0407baSopenharmony_ci
5353d0407baSopenharmony_ci	sha256_update(ctx, sha256_padding, padn);
5363d0407baSopenharmony_ci	sha256_update(ctx, msglen, 8);
5373d0407baSopenharmony_ci
5383d0407baSopenharmony_ci	PUT_UINT32_BE(ctx->state[0], digest, 0);
5393d0407baSopenharmony_ci	PUT_UINT32_BE(ctx->state[1], digest, 4);
5403d0407baSopenharmony_ci	PUT_UINT32_BE(ctx->state[2], digest, 8);
5413d0407baSopenharmony_ci	PUT_UINT32_BE(ctx->state[3], digest, 12);
5423d0407baSopenharmony_ci	PUT_UINT32_BE(ctx->state[4], digest, 16);
5433d0407baSopenharmony_ci	PUT_UINT32_BE(ctx->state[5], digest, 20);
5443d0407baSopenharmony_ci	PUT_UINT32_BE(ctx->state[6], digest, 24);
5453d0407baSopenharmony_ci	PUT_UINT32_BE(ctx->state[7], digest, 28);
5463d0407baSopenharmony_ci}
5473d0407baSopenharmony_ci
5483d0407baSopenharmony_ci/*
5493d0407baSopenharmony_ci * Output = SHA-256( input buffer ).
5503d0407baSopenharmony_ci */
5513d0407baSopenharmony_cistatic
5523d0407baSopenharmony_civoid sha256_csum(const unsigned char *input, unsigned int ilen,
5533d0407baSopenharmony_ci		 unsigned char *output)
5543d0407baSopenharmony_ci{
5553d0407baSopenharmony_ci	sha256_context ctx;
5563d0407baSopenharmony_ci
5573d0407baSopenharmony_ci	sha256_starts(&ctx);
5583d0407baSopenharmony_ci	sha256_update(&ctx, input, ilen);
5593d0407baSopenharmony_ci	sha256_finish(&ctx, output);
5603d0407baSopenharmony_ci}
5613d0407baSopenharmony_ci
5623d0407baSopenharmony_ci/* #define DEBUG */
5633d0407baSopenharmony_ci
5643d0407baSopenharmony_cistatic bool g_debug =
5653d0407baSopenharmony_ci#ifdef DEBUG
5663d0407baSopenharmony_ci        true;
5673d0407baSopenharmony_ci#else
5683d0407baSopenharmony_ci        false;
5693d0407baSopenharmony_ci#endif /* DEBUG */
5703d0407baSopenharmony_ci
5713d0407baSopenharmony_ci#define LOGE(fmt, args...)                                                     \
5723d0407baSopenharmony_ci  fprintf(stderr, "E/%s(%d): " fmt "\n", __func__, __LINE__, ##args)
5733d0407baSopenharmony_ci#define LOGD(fmt, args...)                                                     \
5743d0407baSopenharmony_ci  do {                                                                         \
5753d0407baSopenharmony_ci    if (g_debug)                                                               \
5763d0407baSopenharmony_ci      fprintf(stderr, "D/%s(%d): " fmt "\n", __func__, __LINE__, ##args);      \
5773d0407baSopenharmony_ci  } while (0)
5783d0407baSopenharmony_ci
5793d0407baSopenharmony_ci/* sync with ./board/rockchip/rk30xx/rkloader.c #define FDT_PATH */
5803d0407baSopenharmony_ci#define FDT_PATH "rk-kernel.dtb"
5813d0407baSopenharmony_ci#define DTD_SUBFIX ".dtb"
5823d0407baSopenharmony_ci
5833d0407baSopenharmony_ci#define DEFAULT_IMAGE_PATH "resource.img"
5843d0407baSopenharmony_ci#define DEFAULT_UNPACK_DIR "out"
5853d0407baSopenharmony_ci#define BLOCK_SIZE 512
5863d0407baSopenharmony_ci
5873d0407baSopenharmony_ci#define RESOURCE_PTN_HDR_SIZE 1
5883d0407baSopenharmony_ci#define INDEX_TBL_ENTR_SIZE 1
5893d0407baSopenharmony_ci
5903d0407baSopenharmony_ci#define RESOURCE_PTN_VERSION 0
5913d0407baSopenharmony_ci#define INDEX_TBL_VERSION 0
5923d0407baSopenharmony_ci
5933d0407baSopenharmony_ci#define RESOURCE_PTN_HDR_MAGIC "RSCE"
5943d0407baSopenharmony_citypedef struct {
5953d0407baSopenharmony_ci	char magic[4]; /* tag, "RSCE" */
5963d0407baSopenharmony_ci	uint16_t resource_ptn_version;
5973d0407baSopenharmony_ci	uint16_t index_tbl_version;
5983d0407baSopenharmony_ci	uint8_t header_size;    /* blocks, size of ptn header. */
5993d0407baSopenharmony_ci	uint8_t tbl_offset;     /* blocks, offset of index table. */
6003d0407baSopenharmony_ci	uint8_t tbl_entry_size; /* blocks, size of index table's entry. */
6013d0407baSopenharmony_ci	uint32_t tbl_entry_num; /* numbers of index table's entry. */
6023d0407baSopenharmony_ci} resource_ptn_header;
6033d0407baSopenharmony_ci
6043d0407baSopenharmony_ci#define INDEX_TBL_ENTR_TAG "ENTR"
6053d0407baSopenharmony_ci#define MAX_INDEX_ENTRY_PATH_LEN	220
6063d0407baSopenharmony_ci#define MAX_HASH_LEN			32
6073d0407baSopenharmony_ci
6083d0407baSopenharmony_citypedef struct {
6093d0407baSopenharmony_ci	char tag[4]; /* tag, "ENTR" */
6103d0407baSopenharmony_ci	char path[MAX_INDEX_ENTRY_PATH_LEN];
6113d0407baSopenharmony_ci	char hash[MAX_HASH_LEN]; /* hash data */
6123d0407baSopenharmony_ci	uint32_t hash_size;	 /* 20 or 32 */
6133d0407baSopenharmony_ci	uint32_t content_offset; /* blocks, offset of resource content. */
6143d0407baSopenharmony_ci	uint32_t content_size;   /* bytes, size of resource content. */
6153d0407baSopenharmony_ci} index_tbl_entry;
6163d0407baSopenharmony_ci
6173d0407baSopenharmony_ci#define OPT_VERBOSE "--verbose"
6183d0407baSopenharmony_ci#define OPT_HELP "--help"
6193d0407baSopenharmony_ci#define OPT_VERSION "--version"
6203d0407baSopenharmony_ci#define OPT_PRINT "--print"
6213d0407baSopenharmony_ci#define OPT_PACK "--pack"
6223d0407baSopenharmony_ci#define OPT_UNPACK "--unpack"
6233d0407baSopenharmony_ci#define OPT_TEST_LOAD "--test_load"
6243d0407baSopenharmony_ci#define OPT_TEST_CHARGE "--test_charge"
6253d0407baSopenharmony_ci#define OPT_IMAGE "--image="
6263d0407baSopenharmony_ci#define OPT_ROOT "--root="
6273d0407baSopenharmony_ci
6283d0407baSopenharmony_ci#define VERSION "2014-5-31 14:43:42"
6293d0407baSopenharmony_ci
6303d0407baSopenharmony_citypedef struct {
6313d0407baSopenharmony_ci	char path[MAX_INDEX_ENTRY_PATH_LEN];
6323d0407baSopenharmony_ci	uint32_t content_offset; /* blocks, offset of resource content. */
6333d0407baSopenharmony_ci	uint32_t content_size;   /* bytes, size of resource content. */
6343d0407baSopenharmony_ci	void *load_addr;
6353d0407baSopenharmony_ci} resource_content;
6363d0407baSopenharmony_ci
6373d0407baSopenharmony_citypedef struct {
6383d0407baSopenharmony_ci	int max_level;
6393d0407baSopenharmony_ci	int num;
6403d0407baSopenharmony_ci	int delay;
6413d0407baSopenharmony_ci	char prefix[MAX_INDEX_ENTRY_PATH_LEN];
6423d0407baSopenharmony_ci} anim_level_conf;
6433d0407baSopenharmony_ci
6443d0407baSopenharmony_ci#define DEF_CHARGE_DESC_PATH "charge_anim_desc.txt"
6453d0407baSopenharmony_ci
6463d0407baSopenharmony_ci#define OPT_CHARGE_ANIM_DELAY "delay="
6473d0407baSopenharmony_ci#define OPT_CHARGE_ANIM_LOOP_CUR "only_current_level="
6483d0407baSopenharmony_ci#define OPT_CHARGE_ANIM_LEVELS "levels="
6493d0407baSopenharmony_ci#define OPT_CHARGE_ANIM_LEVEL_CONF "max_level="
6503d0407baSopenharmony_ci#define OPT_CHARGE_ANIM_LEVEL_NUM "num="
6513d0407baSopenharmony_ci#define OPT_CHARGE_ANIM_LEVEL_PFX "prefix="
6523d0407baSopenharmony_ci
6533d0407baSopenharmony_cistatic char image_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";
6543d0407baSopenharmony_ci
6553d0407baSopenharmony_cistatic int fix_blocks(size_t size)
6563d0407baSopenharmony_ci{
6573d0407baSopenharmony_ci	return (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
6583d0407baSopenharmony_ci}
6593d0407baSopenharmony_ci
6603d0407baSopenharmony_cistatic const char *fix_path(const char *path)
6613d0407baSopenharmony_ci{
6623d0407baSopenharmony_ci	if (!memcmp(path, "./", 2)) {
6633d0407baSopenharmony_ci		return path + 2;
6643d0407baSopenharmony_ci	}
6653d0407baSopenharmony_ci	return path;
6663d0407baSopenharmony_ci}
6673d0407baSopenharmony_ci
6683d0407baSopenharmony_cistatic uint16_t switch_short(uint16_t x)
6693d0407baSopenharmony_ci{
6703d0407baSopenharmony_ci	uint16_t val;
6713d0407baSopenharmony_ci	uint8_t *p = (uint8_t *)(&x);
6723d0407baSopenharmony_ci
6733d0407baSopenharmony_ci	val = (*p++ & 0xff) << 0;
6743d0407baSopenharmony_ci	val |= (*p & 0xff) << 8;
6753d0407baSopenharmony_ci
6763d0407baSopenharmony_ci	return val;
6773d0407baSopenharmony_ci}
6783d0407baSopenharmony_ci
6793d0407baSopenharmony_cistatic uint32_t switch_int(uint32_t x)
6803d0407baSopenharmony_ci{
6813d0407baSopenharmony_ci	uint32_t val;
6823d0407baSopenharmony_ci	uint8_t *p = (uint8_t *)(&x);
6833d0407baSopenharmony_ci
6843d0407baSopenharmony_ci	val = (*p++ & 0xff) << 0;
6853d0407baSopenharmony_ci	val |= (*p++ & 0xff) << 8;
6863d0407baSopenharmony_ci	val |= (*p++ & 0xff) << 16;
6873d0407baSopenharmony_ci	val |= (*p & 0xff) << 24;
6883d0407baSopenharmony_ci
6893d0407baSopenharmony_ci	return val;
6903d0407baSopenharmony_ci}
6913d0407baSopenharmony_ci
6923d0407baSopenharmony_cistatic void fix_header(resource_ptn_header *header)
6933d0407baSopenharmony_ci{
6943d0407baSopenharmony_ci	/* switch for be. */
6953d0407baSopenharmony_ci	header->resource_ptn_version = switch_short(header->resource_ptn_version);
6963d0407baSopenharmony_ci	header->index_tbl_version = switch_short(header->index_tbl_version);
6973d0407baSopenharmony_ci	header->tbl_entry_num = switch_int(header->tbl_entry_num);
6983d0407baSopenharmony_ci}
6993d0407baSopenharmony_ci
7003d0407baSopenharmony_cistatic void fix_entry(index_tbl_entry *entry)
7013d0407baSopenharmony_ci{
7023d0407baSopenharmony_ci	/* switch for be. */
7033d0407baSopenharmony_ci	entry->content_offset = switch_int(entry->content_offset);
7043d0407baSopenharmony_ci	entry->content_size = switch_int(entry->content_size);
7053d0407baSopenharmony_ci}
7063d0407baSopenharmony_ci
7073d0407baSopenharmony_cistatic int inline get_ptn_offset(void)
7083d0407baSopenharmony_ci{
7093d0407baSopenharmony_ci	return 0;
7103d0407baSopenharmony_ci}
7113d0407baSopenharmony_ci
7123d0407baSopenharmony_cistatic bool StorageWriteLba(int offset_block, void *data, int blocks)
7133d0407baSopenharmony_ci{
7143d0407baSopenharmony_ci	bool ret = false;
7153d0407baSopenharmony_ci	FILE *file = fopen(image_path, "rb+");
7163d0407baSopenharmony_ci	if (!file)
7173d0407baSopenharmony_ci		goto end;
7183d0407baSopenharmony_ci	int offset = offset_block * BLOCK_SIZE;
7193d0407baSopenharmony_ci	fseek(file, offset, SEEK_SET);
7203d0407baSopenharmony_ci	if (offset != ftell(file)) {
7213d0407baSopenharmony_ci		LOGE("Failed to seek %s to %d!", image_path, offset);
7223d0407baSopenharmony_ci		goto end;
7233d0407baSopenharmony_ci	}
7243d0407baSopenharmony_ci	if (!fwrite(data, blocks * BLOCK_SIZE, 1, file)) {
7253d0407baSopenharmony_ci		LOGE("Failed to write %s!", image_path);
7263d0407baSopenharmony_ci		goto end;
7273d0407baSopenharmony_ci	}
7283d0407baSopenharmony_ci	ret = true;
7293d0407baSopenharmony_ciend:
7303d0407baSopenharmony_ci	if (file)
7313d0407baSopenharmony_ci		fclose(file);
7323d0407baSopenharmony_ci	return ret;
7333d0407baSopenharmony_ci}
7343d0407baSopenharmony_ci
7353d0407baSopenharmony_cistatic bool StorageReadLba(int offset_block, void *data, int blocks)
7363d0407baSopenharmony_ci{
7373d0407baSopenharmony_ci	bool ret = false;
7383d0407baSopenharmony_ci	FILE *file = fopen(image_path, "rb");
7393d0407baSopenharmony_ci	if (!file)
7403d0407baSopenharmony_ci		goto end;
7413d0407baSopenharmony_ci	int offset = offset_block * BLOCK_SIZE;
7423d0407baSopenharmony_ci	fseek(file, offset, SEEK_SET);
7433d0407baSopenharmony_ci	if (offset != ftell(file)) {
7443d0407baSopenharmony_ci		goto end;
7453d0407baSopenharmony_ci	}
7463d0407baSopenharmony_ci	if (!fread(data, blocks * BLOCK_SIZE, 1, file)) {
7473d0407baSopenharmony_ci		goto end;
7483d0407baSopenharmony_ci	}
7493d0407baSopenharmony_ci	ret = true;
7503d0407baSopenharmony_ciend:
7513d0407baSopenharmony_ci	if (file)
7523d0407baSopenharmony_ci		fclose(file);
7533d0407baSopenharmony_ci	return ret;
7543d0407baSopenharmony_ci}
7553d0407baSopenharmony_ci
7563d0407baSopenharmony_cistatic bool write_data(int offset_block, void *data, size_t len)
7573d0407baSopenharmony_ci{
7583d0407baSopenharmony_ci	bool ret = false;
7593d0407baSopenharmony_ci	if (!data)
7603d0407baSopenharmony_ci		goto end;
7613d0407baSopenharmony_ci	int blocks = len / BLOCK_SIZE;
7623d0407baSopenharmony_ci	if (blocks && !StorageWriteLba(offset_block, data, blocks)) {
7633d0407baSopenharmony_ci		goto end;
7643d0407baSopenharmony_ci	}
7653d0407baSopenharmony_ci	int left = len % BLOCK_SIZE;
7663d0407baSopenharmony_ci	if (left) {
7673d0407baSopenharmony_ci		char buf[BLOCK_SIZE] = "\0";
7683d0407baSopenharmony_ci		memcpy(buf, data + blocks * BLOCK_SIZE, left);
7693d0407baSopenharmony_ci		if (!StorageWriteLba(offset_block + blocks, buf, 1))
7703d0407baSopenharmony_ci			goto end;
7713d0407baSopenharmony_ci	}
7723d0407baSopenharmony_ci	ret = true;
7733d0407baSopenharmony_ciend:
7743d0407baSopenharmony_ci	return ret;
7753d0407baSopenharmony_ci}
7763d0407baSopenharmony_ci
7773d0407baSopenharmony_ci/**********************load test************************/
7783d0407baSopenharmony_cistatic int load_file(const char *file_path, int offset_block, int blocks);
7793d0407baSopenharmony_ci
7803d0407baSopenharmony_cistatic int test_load(int argc, char **argv)
7813d0407baSopenharmony_ci{
7823d0407baSopenharmony_ci	if (argc < 1) {
7833d0407baSopenharmony_ci		LOGE("Nothing to load!");
7843d0407baSopenharmony_ci		return -1;
7853d0407baSopenharmony_ci	}
7863d0407baSopenharmony_ci	const char *file_path;
7873d0407baSopenharmony_ci	int offset_block = 0;
7883d0407baSopenharmony_ci	int blocks = 0;
7893d0407baSopenharmony_ci	if (argc > 0) {
7903d0407baSopenharmony_ci		file_path = (const char *)fix_path(argv[0]);
7913d0407baSopenharmony_ci		argc--, argv++;
7923d0407baSopenharmony_ci	}
7933d0407baSopenharmony_ci	if (argc > 0) {
7943d0407baSopenharmony_ci		offset_block = atoi(argv[0]);
7953d0407baSopenharmony_ci		argc--, argv++;
7963d0407baSopenharmony_ci	}
7973d0407baSopenharmony_ci	if (argc > 0) {
7983d0407baSopenharmony_ci		blocks = atoi(argv[0]);
7993d0407baSopenharmony_ci	}
8003d0407baSopenharmony_ci	return load_file(file_path, offset_block, blocks);
8013d0407baSopenharmony_ci}
8023d0407baSopenharmony_ci
8033d0407baSopenharmony_cistatic void free_content(resource_content *content)
8043d0407baSopenharmony_ci{
8053d0407baSopenharmony_ci	if (content->load_addr) {
8063d0407baSopenharmony_ci		free(content->load_addr);
8073d0407baSopenharmony_ci		content->load_addr = 0;
8083d0407baSopenharmony_ci	}
8093d0407baSopenharmony_ci}
8103d0407baSopenharmony_ci
8113d0407baSopenharmony_cistatic void tests_dump_file(const char *path, void *data, int len)
8123d0407baSopenharmony_ci{
8133d0407baSopenharmony_ci	FILE *file = fopen(path, "wb");
8143d0407baSopenharmony_ci	if (!file)
8153d0407baSopenharmony_ci		return;
8163d0407baSopenharmony_ci	fwrite(data, len, 1, file);
8173d0407baSopenharmony_ci	fclose(file);
8183d0407baSopenharmony_ci}
8193d0407baSopenharmony_ci
8203d0407baSopenharmony_cistatic bool load_content(resource_content *content)
8213d0407baSopenharmony_ci{
8223d0407baSopenharmony_ci	if (content->load_addr)
8233d0407baSopenharmony_ci		return true;
8243d0407baSopenharmony_ci	int blocks = fix_blocks(content->content_size);
8253d0407baSopenharmony_ci	content->load_addr = malloc(blocks * BLOCK_SIZE);
8263d0407baSopenharmony_ci	if (!content->load_addr)
8273d0407baSopenharmony_ci		return false;
8283d0407baSopenharmony_ci	if (!StorageReadLba(get_ptn_offset() + content->content_offset,
8293d0407baSopenharmony_ci	                    content->load_addr, blocks)) {
8303d0407baSopenharmony_ci		free_content(content);
8313d0407baSopenharmony_ci		return false;
8323d0407baSopenharmony_ci	}
8333d0407baSopenharmony_ci
8343d0407baSopenharmony_ci	tests_dump_file(content->path, content->load_addr, content->content_size);
8353d0407baSopenharmony_ci	return true;
8363d0407baSopenharmony_ci}
8373d0407baSopenharmony_ci
8383d0407baSopenharmony_cistatic bool load_content_data(resource_content *content, int offset_block,
8393d0407baSopenharmony_ci                              void *data, int blocks)
8403d0407baSopenharmony_ci{
8413d0407baSopenharmony_ci	if (!StorageReadLba(get_ptn_offset() + content->content_offset + offset_block,
8423d0407baSopenharmony_ci	                    data, blocks)) {
8433d0407baSopenharmony_ci		return false;
8443d0407baSopenharmony_ci	}
8453d0407baSopenharmony_ci	tests_dump_file(content->path, data, blocks * BLOCK_SIZE);
8463d0407baSopenharmony_ci	return true;
8473d0407baSopenharmony_ci}
8483d0407baSopenharmony_ci
8493d0407baSopenharmony_cistatic bool get_entry(const char *file_path, index_tbl_entry *entry)
8503d0407baSopenharmony_ci{
8513d0407baSopenharmony_ci	bool ret = false;
8523d0407baSopenharmony_ci	char buf[BLOCK_SIZE];
8533d0407baSopenharmony_ci	resource_ptn_header header;
8543d0407baSopenharmony_ci	if (!StorageReadLba(get_ptn_offset(), buf, 1)) {
8553d0407baSopenharmony_ci		LOGE("Failed to read header!");
8563d0407baSopenharmony_ci		goto end;
8573d0407baSopenharmony_ci	}
8583d0407baSopenharmony_ci	memcpy(&header, buf, sizeof(header));
8593d0407baSopenharmony_ci
8603d0407baSopenharmony_ci	if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {
8613d0407baSopenharmony_ci		LOGE("Not a resource image(%s)!", image_path);
8623d0407baSopenharmony_ci		goto end;
8633d0407baSopenharmony_ci	}
8643d0407baSopenharmony_ci	/* test on pc, switch for be. */
8653d0407baSopenharmony_ci	fix_header(&header);
8663d0407baSopenharmony_ci
8673d0407baSopenharmony_ci	/* TODO: support header_size & tbl_entry_size */
8683d0407baSopenharmony_ci	if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||
8693d0407baSopenharmony_ci	    header.header_size != RESOURCE_PTN_HDR_SIZE ||
8703d0407baSopenharmony_ci	    header.index_tbl_version != INDEX_TBL_VERSION ||
8713d0407baSopenharmony_ci	    header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {
8723d0407baSopenharmony_ci		LOGE("Not supported in this version!");
8733d0407baSopenharmony_ci		goto end;
8743d0407baSopenharmony_ci	}
8753d0407baSopenharmony_ci
8763d0407baSopenharmony_ci	int i;
8773d0407baSopenharmony_ci	for (i = 0; i < header.tbl_entry_num; i++) {
8783d0407baSopenharmony_ci		/* TODO: support tbl_entry_size */
8793d0407baSopenharmony_ci		if (!StorageReadLba(
8803d0407baSopenharmony_ci		            get_ptn_offset() + header.header_size + i * header.tbl_entry_size,
8813d0407baSopenharmony_ci		            buf, 1)) {
8823d0407baSopenharmony_ci			LOGE("Failed to read index entry:%d!", i);
8833d0407baSopenharmony_ci			goto end;
8843d0407baSopenharmony_ci		}
8853d0407baSopenharmony_ci		memcpy(entry, buf, sizeof(*entry));
8863d0407baSopenharmony_ci
8873d0407baSopenharmony_ci		if (memcmp(entry->tag, INDEX_TBL_ENTR_TAG, sizeof(entry->tag))) {
8883d0407baSopenharmony_ci			LOGE("Something wrong with index entry:%d!", i);
8893d0407baSopenharmony_ci			goto end;
8903d0407baSopenharmony_ci		}
8913d0407baSopenharmony_ci
8923d0407baSopenharmony_ci		if (!strncmp(entry->path, file_path, sizeof(entry->path)))
8933d0407baSopenharmony_ci			break;
8943d0407baSopenharmony_ci	}
8953d0407baSopenharmony_ci	if (i == header.tbl_entry_num) {
8963d0407baSopenharmony_ci		LOGE("Cannot find %s!", file_path);
8973d0407baSopenharmony_ci		goto end;
8983d0407baSopenharmony_ci	}
8993d0407baSopenharmony_ci	/* test on pc, switch for be. */
9003d0407baSopenharmony_ci	fix_entry(entry);
9013d0407baSopenharmony_ci
9023d0407baSopenharmony_ci	printf("Found entry:\n\tpath:%s\n\toffset:%d\tsize:%d\n", entry->path,
9033d0407baSopenharmony_ci	       entry->content_offset, entry->content_size);
9043d0407baSopenharmony_ci
9053d0407baSopenharmony_ci	ret = true;
9063d0407baSopenharmony_ciend:
9073d0407baSopenharmony_ci	return ret;
9083d0407baSopenharmony_ci}
9093d0407baSopenharmony_ci
9103d0407baSopenharmony_cistatic bool get_content(resource_content *content)
9113d0407baSopenharmony_ci{
9123d0407baSopenharmony_ci	bool ret = false;
9133d0407baSopenharmony_ci	index_tbl_entry entry;
9143d0407baSopenharmony_ci	if (!get_entry(content->path, &entry))
9153d0407baSopenharmony_ci		goto end;
9163d0407baSopenharmony_ci	content->content_offset = entry.content_offset;
9173d0407baSopenharmony_ci	content->content_size = entry.content_size;
9183d0407baSopenharmony_ci	ret = true;
9193d0407baSopenharmony_ciend:
9203d0407baSopenharmony_ci	return ret;
9213d0407baSopenharmony_ci}
9223d0407baSopenharmony_ci
9233d0407baSopenharmony_cistatic int load_file(const char *file_path, int offset_block, int blocks)
9243d0407baSopenharmony_ci{
9253d0407baSopenharmony_ci	printf("Try to load:%s", file_path);
9263d0407baSopenharmony_ci	if (blocks) {
9273d0407baSopenharmony_ci		printf(", offset block:%d, blocks:%d\n", offset_block, blocks);
9283d0407baSopenharmony_ci	} else {
9293d0407baSopenharmony_ci		printf("\n");
9303d0407baSopenharmony_ci	}
9313d0407baSopenharmony_ci	bool ret = false;
9323d0407baSopenharmony_ci	resource_content content;
9333d0407baSopenharmony_ci	snprintf(content.path, sizeof(content.path), "%s", file_path);
9343d0407baSopenharmony_ci	content.load_addr = 0;
9353d0407baSopenharmony_ci	if (!get_content(&content)) {
9363d0407baSopenharmony_ci		goto end;
9373d0407baSopenharmony_ci	}
9383d0407baSopenharmony_ci	if (!blocks) {
9393d0407baSopenharmony_ci		if (!load_content(&content)) {
9403d0407baSopenharmony_ci			goto end;
9413d0407baSopenharmony_ci		}
9423d0407baSopenharmony_ci	} else {
9433d0407baSopenharmony_ci		void *data = malloc(blocks * BLOCK_SIZE);
9443d0407baSopenharmony_ci		if (!data)
9453d0407baSopenharmony_ci			goto end;
9463d0407baSopenharmony_ci		if (!load_content_data(&content, offset_block, data, blocks)) {
9473d0407baSopenharmony_ci			goto end;
9483d0407baSopenharmony_ci		}
9493d0407baSopenharmony_ci	}
9503d0407baSopenharmony_ci	ret = true;
9513d0407baSopenharmony_ciend:
9523d0407baSopenharmony_ci	free_content(&content);
9533d0407baSopenharmony_ci	return ret;
9543d0407baSopenharmony_ci}
9553d0407baSopenharmony_ci
9563d0407baSopenharmony_ci/**********************load test end************************/
9573d0407baSopenharmony_ci/**********************anim test************************/
9583d0407baSopenharmony_ci
9593d0407baSopenharmony_cistatic bool parse_level_conf(const char *arg, anim_level_conf *level_conf)
9603d0407baSopenharmony_ci{
9613d0407baSopenharmony_ci	memset(level_conf, 0, sizeof(anim_level_conf));
9623d0407baSopenharmony_ci	char *buf = NULL;
9633d0407baSopenharmony_ci	buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_CONF);
9643d0407baSopenharmony_ci	if (buf) {
9653d0407baSopenharmony_ci		level_conf->max_level = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_CONF));
9663d0407baSopenharmony_ci	} else {
9673d0407baSopenharmony_ci		LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_CONF);
9683d0407baSopenharmony_ci		return false;
9693d0407baSopenharmony_ci	}
9703d0407baSopenharmony_ci	buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_NUM);
9713d0407baSopenharmony_ci	if (buf) {
9723d0407baSopenharmony_ci		level_conf->num = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_NUM));
9733d0407baSopenharmony_ci		if (level_conf->num <= 0) {
9743d0407baSopenharmony_ci			return false;
9753d0407baSopenharmony_ci		}
9763d0407baSopenharmony_ci	} else {
9773d0407baSopenharmony_ci		LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_NUM);
9783d0407baSopenharmony_ci		return false;
9793d0407baSopenharmony_ci	}
9803d0407baSopenharmony_ci	buf = strstr(arg, OPT_CHARGE_ANIM_DELAY);
9813d0407baSopenharmony_ci	if (buf) {
9823d0407baSopenharmony_ci		level_conf->delay = atoi(buf + strlen(OPT_CHARGE_ANIM_DELAY));
9833d0407baSopenharmony_ci	}
9843d0407baSopenharmony_ci	buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_PFX);
9853d0407baSopenharmony_ci	if (buf) {
9863d0407baSopenharmony_ci		snprintf(level_conf->prefix, sizeof(level_conf->prefix), "%s",
9873d0407baSopenharmony_ci		         buf + strlen(OPT_CHARGE_ANIM_LEVEL_PFX));
9883d0407baSopenharmony_ci	} else {
9893d0407baSopenharmony_ci		LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_PFX);
9903d0407baSopenharmony_ci		return false;
9913d0407baSopenharmony_ci	}
9923d0407baSopenharmony_ci
9933d0407baSopenharmony_ci	LOGD("Found conf:\nmax_level:%d, num:%d, delay:%d, prefix:%s",
9943d0407baSopenharmony_ci	     level_conf->max_level, level_conf->num, level_conf->delay,
9953d0407baSopenharmony_ci	     level_conf->prefix);
9963d0407baSopenharmony_ci	return true;
9973d0407baSopenharmony_ci}
9983d0407baSopenharmony_ci
9993d0407baSopenharmony_cistatic int test_charge(int argc, char **argv)
10003d0407baSopenharmony_ci{
10013d0407baSopenharmony_ci	const char *desc;
10023d0407baSopenharmony_ci	if (argc > 0) {
10033d0407baSopenharmony_ci		desc = argv[0];
10043d0407baSopenharmony_ci	} else {
10053d0407baSopenharmony_ci		desc = DEF_CHARGE_DESC_PATH;
10063d0407baSopenharmony_ci	}
10073d0407baSopenharmony_ci
10083d0407baSopenharmony_ci	resource_content content;
10093d0407baSopenharmony_ci	snprintf(content.path, sizeof(content.path), "%s", desc);
10103d0407baSopenharmony_ci	content.load_addr = 0;
10113d0407baSopenharmony_ci	if (!get_content(&content)) {
10123d0407baSopenharmony_ci		goto end;
10133d0407baSopenharmony_ci	}
10143d0407baSopenharmony_ci	if (!load_content(&content)) {
10153d0407baSopenharmony_ci		goto end;
10163d0407baSopenharmony_ci	}
10173d0407baSopenharmony_ci
10183d0407baSopenharmony_ci	char *buf = (char *)content.load_addr;
10193d0407baSopenharmony_ci	char *end = buf + content.content_size - 1;
10203d0407baSopenharmony_ci	*end = '\0';
10213d0407baSopenharmony_ci	LOGD("desc:\n%s", buf);
10223d0407baSopenharmony_ci
10233d0407baSopenharmony_ci	int pos = 0;
10243d0407baSopenharmony_ci	while (1) {
10253d0407baSopenharmony_ci		char *line = (char *)memchr(buf + pos, '\n', strlen(buf + pos));
10263d0407baSopenharmony_ci		if (!line)
10273d0407baSopenharmony_ci			break;
10283d0407baSopenharmony_ci		*line = '\0';
10293d0407baSopenharmony_ci		LOGD("splite:%s", buf + pos);
10303d0407baSopenharmony_ci		pos += (strlen(buf + pos) + 1);
10313d0407baSopenharmony_ci	}
10323d0407baSopenharmony_ci
10333d0407baSopenharmony_ci	int delay = 900;
10343d0407baSopenharmony_ci	int only_current_level = false;
10353d0407baSopenharmony_ci	anim_level_conf *level_confs = NULL;
10363d0407baSopenharmony_ci	int level_conf_pos = 0;
10373d0407baSopenharmony_ci	int level_conf_num = 0;
10383d0407baSopenharmony_ci
10393d0407baSopenharmony_ci	while (true) {
10403d0407baSopenharmony_ci		if (buf >= end)
10413d0407baSopenharmony_ci			break;
10423d0407baSopenharmony_ci		const char *arg = buf;
10433d0407baSopenharmony_ci		buf += (strlen(buf) + 1);
10443d0407baSopenharmony_ci
10453d0407baSopenharmony_ci		LOGD("parse arg:%s", arg);
10463d0407baSopenharmony_ci		if (!memcmp(arg, OPT_CHARGE_ANIM_LEVEL_CONF,
10473d0407baSopenharmony_ci		            strlen(OPT_CHARGE_ANIM_LEVEL_CONF))) {
10483d0407baSopenharmony_ci			if (!level_confs) {
10493d0407baSopenharmony_ci				LOGE("Found level conf before levels!");
10503d0407baSopenharmony_ci				goto end;
10513d0407baSopenharmony_ci			}
10523d0407baSopenharmony_ci			if (level_conf_pos >= level_conf_num) {
10533d0407baSopenharmony_ci				LOGE("Too many level confs!(%d >= %d)", level_conf_pos, level_conf_num);
10543d0407baSopenharmony_ci				goto end;
10553d0407baSopenharmony_ci			}
10563d0407baSopenharmony_ci			if (!parse_level_conf(arg, level_confs + level_conf_pos)) {
10573d0407baSopenharmony_ci				LOGE("Failed to parse level conf:%s", arg);
10583d0407baSopenharmony_ci				goto end;
10593d0407baSopenharmony_ci			}
10603d0407baSopenharmony_ci			level_conf_pos++;
10613d0407baSopenharmony_ci		} else if (!memcmp(arg, OPT_CHARGE_ANIM_DELAY,
10623d0407baSopenharmony_ci		                   strlen(OPT_CHARGE_ANIM_DELAY))) {
10633d0407baSopenharmony_ci			delay = atoi(arg + strlen(OPT_CHARGE_ANIM_DELAY));
10643d0407baSopenharmony_ci			LOGD("Found delay:%d", delay);
10653d0407baSopenharmony_ci		} else if (!memcmp(arg, OPT_CHARGE_ANIM_LOOP_CUR,
10663d0407baSopenharmony_ci		                   strlen(OPT_CHARGE_ANIM_LOOP_CUR))) {
10673d0407baSopenharmony_ci			only_current_level =
10683d0407baSopenharmony_ci			        !memcmp(arg + strlen(OPT_CHARGE_ANIM_LOOP_CUR), "true", 4);
10693d0407baSopenharmony_ci			LOGD("Found only_current_level:%d", only_current_level);
10703d0407baSopenharmony_ci		} else if (!memcmp(arg, OPT_CHARGE_ANIM_LEVELS,
10713d0407baSopenharmony_ci		                   strlen(OPT_CHARGE_ANIM_LEVELS))) {
10723d0407baSopenharmony_ci			if (level_conf_num) {
10733d0407baSopenharmony_ci				goto end;
10743d0407baSopenharmony_ci			}
10753d0407baSopenharmony_ci			level_conf_num = atoi(arg + strlen(OPT_CHARGE_ANIM_LEVELS));
10763d0407baSopenharmony_ci			if (!level_conf_num) {
10773d0407baSopenharmony_ci				goto end;
10783d0407baSopenharmony_ci			}
10793d0407baSopenharmony_ci			level_confs =
10803d0407baSopenharmony_ci			        (anim_level_conf *)malloc(level_conf_num * sizeof(anim_level_conf));
10813d0407baSopenharmony_ci			LOGD("Found levels:%d", level_conf_num);
10823d0407baSopenharmony_ci		} else {
10833d0407baSopenharmony_ci			LOGE("Unknown arg:%s", arg);
10843d0407baSopenharmony_ci			goto end;
10853d0407baSopenharmony_ci		}
10863d0407baSopenharmony_ci	}
10873d0407baSopenharmony_ci
10883d0407baSopenharmony_ci	if (level_conf_pos != level_conf_num || !level_conf_num) {
10893d0407baSopenharmony_ci		LOGE("Something wrong with level confs!");
10903d0407baSopenharmony_ci		goto end;
10913d0407baSopenharmony_ci	}
10923d0407baSopenharmony_ci
10933d0407baSopenharmony_ci	int i = 0, j = 0;
10943d0407baSopenharmony_ci	for (i = 0; i < level_conf_num; i++) {
10953d0407baSopenharmony_ci		if (!level_confs[i].delay) {
10963d0407baSopenharmony_ci			level_confs[i].delay = delay;
10973d0407baSopenharmony_ci		}
10983d0407baSopenharmony_ci		if (!level_confs[i].delay) {
10993d0407baSopenharmony_ci			LOGE("Missing delay in level conf:%d", i);
11003d0407baSopenharmony_ci			goto end;
11013d0407baSopenharmony_ci		}
11023d0407baSopenharmony_ci		for (j = 0; j < i; j++) {
11033d0407baSopenharmony_ci			if (level_confs[j].max_level == level_confs[i].max_level) {
11043d0407baSopenharmony_ci				LOGE("Dup level conf:%d", i);
11053d0407baSopenharmony_ci				goto end;
11063d0407baSopenharmony_ci			}
11073d0407baSopenharmony_ci			if (level_confs[j].max_level > level_confs[i].max_level) {
11083d0407baSopenharmony_ci				anim_level_conf conf = level_confs[i];
11093d0407baSopenharmony_ci				memmove(level_confs + j + 1, level_confs + j,
11103d0407baSopenharmony_ci				        (i - j) * sizeof(anim_level_conf));
11113d0407baSopenharmony_ci				level_confs[j] = conf;
11123d0407baSopenharmony_ci			}
11133d0407baSopenharmony_ci		}
11143d0407baSopenharmony_ci	}
11153d0407baSopenharmony_ci
11163d0407baSopenharmony_ci	printf("Parse anim desc(%s):\n", desc);
11173d0407baSopenharmony_ci	printf("only_current_level=%d\n", only_current_level);
11183d0407baSopenharmony_ci	printf("level conf:\n");
11193d0407baSopenharmony_ci	for (i = 0; i < level_conf_num; i++) {
11203d0407baSopenharmony_ci		printf("\tmax=%d, delay=%d, num=%d, prefix=%s\n", level_confs[i].max_level,
11213d0407baSopenharmony_ci		       level_confs[i].delay, level_confs[i].num, level_confs[i].prefix);
11223d0407baSopenharmony_ci	}
11233d0407baSopenharmony_ci
11243d0407baSopenharmony_ciend:
11253d0407baSopenharmony_ci	free_content(&content);
11263d0407baSopenharmony_ci	return 0;
11273d0407baSopenharmony_ci}
11283d0407baSopenharmony_ci
11293d0407baSopenharmony_ci/**********************anim test end************************/
11303d0407baSopenharmony_ci/**********************append file************************/
11313d0407baSopenharmony_ci
11323d0407baSopenharmony_cistatic const char *PROG = NULL;
11333d0407baSopenharmony_cistatic resource_ptn_header header;
11343d0407baSopenharmony_cistatic bool just_print = false;
11353d0407baSopenharmony_cistatic char root_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";
11363d0407baSopenharmony_ci
11373d0407baSopenharmony_cistatic void version(void)
11383d0407baSopenharmony_ci{
11393d0407baSopenharmony_ci	printf("%s (cjf@rock-chips.com)\t" VERSION "\n", PROG);
11403d0407baSopenharmony_ci}
11413d0407baSopenharmony_ci
11423d0407baSopenharmony_cistatic void usage(void)
11433d0407baSopenharmony_ci{
11443d0407baSopenharmony_ci	printf("Usage: %s [options] [FILES]\n", PROG);
11453d0407baSopenharmony_ci	printf("Tools for Rockchip's resource image.\n");
11463d0407baSopenharmony_ci	version();
11473d0407baSopenharmony_ci	printf("Options:\n");
11483d0407baSopenharmony_ci	printf("\t" OPT_PACK "\t\t\tPack image from given files.\n");
11493d0407baSopenharmony_ci	printf("\t" OPT_UNPACK "\t\tUnpack given image to current dir.\n");
11503d0407baSopenharmony_ci	printf("\t" OPT_IMAGE "path"
11513d0407baSopenharmony_ci	       "\t\tSpecify input/output image path.\n");
11523d0407baSopenharmony_ci	printf("\t" OPT_PRINT "\t\t\tJust print informations.\n");
11533d0407baSopenharmony_ci	printf("\t" OPT_VERBOSE "\t\tDisplay more runtime informations.\n");
11543d0407baSopenharmony_ci	printf("\t" OPT_HELP "\t\t\tDisplay this information.\n");
11553d0407baSopenharmony_ci	printf("\t" OPT_VERSION "\t\tDisplay version information.\n");
11563d0407baSopenharmony_ci	printf("\t" OPT_ROOT "path"
11573d0407baSopenharmony_ci	       "\t\tSpecify resources' root dir.\n");
11583d0407baSopenharmony_ci}
11593d0407baSopenharmony_ci
11603d0407baSopenharmony_cistatic int pack_image(int file_num, const char **files);
11613d0407baSopenharmony_cistatic int unpack_image(const char *unpack_dir);
11623d0407baSopenharmony_ci
11633d0407baSopenharmony_cienum ACTION {
11643d0407baSopenharmony_ci	ACTION_PACK,
11653d0407baSopenharmony_ci	ACTION_UNPACK,
11663d0407baSopenharmony_ci	ACTION_TEST_LOAD,
11673d0407baSopenharmony_ci	ACTION_TEST_CHARGE,
11683d0407baSopenharmony_ci};
11693d0407baSopenharmony_ci
11703d0407baSopenharmony_ciint main(int argc, char **argv)
11713d0407baSopenharmony_ci{
11723d0407baSopenharmony_ci	PROG = fix_path(argv[0]);
11733d0407baSopenharmony_ci
11743d0407baSopenharmony_ci	enum ACTION action = ACTION_PACK;
11753d0407baSopenharmony_ci
11763d0407baSopenharmony_ci	argc--, argv++;
11773d0407baSopenharmony_ci	while (argc > 0 && argv[0][0] == '-') {
11783d0407baSopenharmony_ci		/* it's a opt arg. */
11793d0407baSopenharmony_ci		const char *arg = argv[0];
11803d0407baSopenharmony_ci		argc--, argv++;
11813d0407baSopenharmony_ci		if (!strcmp(OPT_VERBOSE, arg)) {
11823d0407baSopenharmony_ci			g_debug = true;
11833d0407baSopenharmony_ci		} else if (!strcmp(OPT_HELP, arg)) {
11843d0407baSopenharmony_ci			usage();
11853d0407baSopenharmony_ci			return 0;
11863d0407baSopenharmony_ci		} else if (!strcmp(OPT_VERSION, arg)) {
11873d0407baSopenharmony_ci			version();
11883d0407baSopenharmony_ci			return 0;
11893d0407baSopenharmony_ci		} else if (!strcmp(OPT_PRINT, arg)) {
11903d0407baSopenharmony_ci			just_print = true;
11913d0407baSopenharmony_ci		} else if (!strcmp(OPT_PACK, arg)) {
11923d0407baSopenharmony_ci			action = ACTION_PACK;
11933d0407baSopenharmony_ci		} else if (!strcmp(OPT_UNPACK, arg)) {
11943d0407baSopenharmony_ci			action = ACTION_UNPACK;
11953d0407baSopenharmony_ci		} else if (!strcmp(OPT_TEST_LOAD, arg)) {
11963d0407baSopenharmony_ci			action = ACTION_TEST_LOAD;
11973d0407baSopenharmony_ci		} else if (!strcmp(OPT_TEST_CHARGE, arg)) {
11983d0407baSopenharmony_ci			action = ACTION_TEST_CHARGE;
11993d0407baSopenharmony_ci		} else if (!memcmp(OPT_IMAGE, arg, strlen(OPT_IMAGE))) {
12003d0407baSopenharmony_ci			snprintf(image_path, sizeof(image_path), "%s", arg + strlen(OPT_IMAGE));
12013d0407baSopenharmony_ci		} else if (!memcmp(OPT_ROOT, arg, strlen(OPT_ROOT))) {
12023d0407baSopenharmony_ci			snprintf(root_path, sizeof(root_path), "%s", arg + strlen(OPT_ROOT));
12033d0407baSopenharmony_ci		} else {
12043d0407baSopenharmony_ci			LOGE("Unknown opt:%s", arg);
12053d0407baSopenharmony_ci			usage();
12063d0407baSopenharmony_ci			return -1;
12073d0407baSopenharmony_ci		}
12083d0407baSopenharmony_ci	}
12093d0407baSopenharmony_ci
12103d0407baSopenharmony_ci	if (!image_path[0]) {
12113d0407baSopenharmony_ci		snprintf(image_path, sizeof(image_path), "%s", DEFAULT_IMAGE_PATH);
12123d0407baSopenharmony_ci	}
12133d0407baSopenharmony_ci
12143d0407baSopenharmony_ci	switch (action) {
12153d0407baSopenharmony_ci	case ACTION_PACK: {
12163d0407baSopenharmony_ci		int file_num = argc;
12173d0407baSopenharmony_ci		const char **files = (const char **)argv;
12183d0407baSopenharmony_ci		if (!file_num) {
12193d0407baSopenharmony_ci			LOGE("No file to pack!");
12203d0407baSopenharmony_ci			return 0;
12213d0407baSopenharmony_ci		}
12223d0407baSopenharmony_ci		LOGD("try to pack %d files.", file_num);
12233d0407baSopenharmony_ci		return pack_image(file_num, files);
12243d0407baSopenharmony_ci	}
12253d0407baSopenharmony_ci	case ACTION_UNPACK: {
12263d0407baSopenharmony_ci		return unpack_image(argc > 0 ? argv[0] : DEFAULT_UNPACK_DIR);
12273d0407baSopenharmony_ci	}
12283d0407baSopenharmony_ci	case ACTION_TEST_LOAD: {
12293d0407baSopenharmony_ci		return test_load(argc, argv);
12303d0407baSopenharmony_ci	}
12313d0407baSopenharmony_ci	case ACTION_TEST_CHARGE: {
12323d0407baSopenharmony_ci		return test_charge(argc, argv);
12333d0407baSopenharmony_ci	}
12343d0407baSopenharmony_ci	}
12353d0407baSopenharmony_ci	/* not reach here. */
12363d0407baSopenharmony_ci	return -1;
12373d0407baSopenharmony_ci}
12383d0407baSopenharmony_ci
12393d0407baSopenharmony_ci/************unpack code****************/
12403d0407baSopenharmony_cistatic bool mkdirs(char *path)
12413d0407baSopenharmony_ci{
12423d0407baSopenharmony_ci	char *tmp = path;
12433d0407baSopenharmony_ci	char *pos = NULL;
12443d0407baSopenharmony_ci	char buf[MAX_INDEX_ENTRY_PATH_LEN];
12453d0407baSopenharmony_ci	bool ret = true;
12463d0407baSopenharmony_ci	while ((pos = memchr(tmp, '/', strlen(tmp)))) {
12473d0407baSopenharmony_ci		strcpy(buf, path);
12483d0407baSopenharmony_ci		buf[pos - path] = '\0';
12493d0407baSopenharmony_ci		tmp = pos + 1;
12503d0407baSopenharmony_ci		LOGD("mkdir:%s", buf);
12513d0407baSopenharmony_ci		if (!mkdir(buf, 0755)) {
12523d0407baSopenharmony_ci			ret = false;
12533d0407baSopenharmony_ci		}
12543d0407baSopenharmony_ci	}
12553d0407baSopenharmony_ci	if (!ret)
12563d0407baSopenharmony_ci		LOGD("Failed to mkdir(%s)!", path);
12573d0407baSopenharmony_ci	return ret;
12583d0407baSopenharmony_ci}
12593d0407baSopenharmony_ci
12603d0407baSopenharmony_cistatic bool dump_file(FILE *file, const char *unpack_dir,
12613d0407baSopenharmony_ci                      index_tbl_entry entry)
12623d0407baSopenharmony_ci{
12633d0407baSopenharmony_ci	LOGD("try to dump entry:%s", entry.path);
12643d0407baSopenharmony_ci	bool ret = false;
12653d0407baSopenharmony_ci	FILE *out_file = NULL;
12663d0407baSopenharmony_ci	long int pos = 0;
12673d0407baSopenharmony_ci	char path[MAX_INDEX_ENTRY_PATH_LEN * 2 + 1];
12683d0407baSopenharmony_ci	if (just_print) {
12693d0407baSopenharmony_ci		ret = true;
12703d0407baSopenharmony_ci		goto done;
12713d0407baSopenharmony_ci	}
12723d0407baSopenharmony_ci
12733d0407baSopenharmony_ci	pos = ftell(file);
12743d0407baSopenharmony_ci	snprintf(path, sizeof(path), "%s/%s", unpack_dir, entry.path);
12753d0407baSopenharmony_ci	mkdirs(path);
12763d0407baSopenharmony_ci	out_file = fopen(path, "wb");
12773d0407baSopenharmony_ci	if (!out_file) {
12783d0407baSopenharmony_ci		LOGE("Failed to create:%s", path);
12793d0407baSopenharmony_ci		goto end;
12803d0407baSopenharmony_ci	}
12813d0407baSopenharmony_ci	long int offset = entry.content_offset * BLOCK_SIZE;
12823d0407baSopenharmony_ci	fseek(file, offset, SEEK_SET);
12833d0407baSopenharmony_ci	if (offset != ftell(file)) {
12843d0407baSopenharmony_ci		LOGE("Failed to read content:%s", entry.path);
12853d0407baSopenharmony_ci		goto end;
12863d0407baSopenharmony_ci	}
12873d0407baSopenharmony_ci	char buf[BLOCK_SIZE];
12883d0407baSopenharmony_ci	int n;
12893d0407baSopenharmony_ci	int len = entry.content_size;
12903d0407baSopenharmony_ci	while (len > 0) {
12913d0407baSopenharmony_ci		n = len > BLOCK_SIZE ? BLOCK_SIZE : len;
12923d0407baSopenharmony_ci		if (!fread(buf, n, 1, file)) {
12933d0407baSopenharmony_ci			LOGE("Failed to read content:%s", entry.path);
12943d0407baSopenharmony_ci			goto end;
12953d0407baSopenharmony_ci		}
12963d0407baSopenharmony_ci		if (!fwrite(buf, n, 1, out_file)) {
12973d0407baSopenharmony_ci			LOGE("Failed to write:%s", entry.path);
12983d0407baSopenharmony_ci			goto end;
12993d0407baSopenharmony_ci		}
13003d0407baSopenharmony_ci		len -= n;
13013d0407baSopenharmony_ci	}
13023d0407baSopenharmony_cidone:
13033d0407baSopenharmony_ci	ret = true;
13043d0407baSopenharmony_ciend:
13053d0407baSopenharmony_ci	if (out_file)
13063d0407baSopenharmony_ci		fclose(out_file);
13073d0407baSopenharmony_ci	if (pos)
13083d0407baSopenharmony_ci		fseek(file, pos, SEEK_SET);
13093d0407baSopenharmony_ci	return ret;
13103d0407baSopenharmony_ci}
13113d0407baSopenharmony_ci
13123d0407baSopenharmony_cistatic int unpack_image(const char *dir)
13133d0407baSopenharmony_ci{
13143d0407baSopenharmony_ci	FILE *image_file = NULL;
13153d0407baSopenharmony_ci	bool ret = false;
13163d0407baSopenharmony_ci	char unpack_dir[MAX_INDEX_ENTRY_PATH_LEN];
13173d0407baSopenharmony_ci	if (just_print)
13183d0407baSopenharmony_ci		dir = ".";
13193d0407baSopenharmony_ci	snprintf(unpack_dir, sizeof(unpack_dir), "%s", dir);
13203d0407baSopenharmony_ci	if (!strlen(unpack_dir)) {
13213d0407baSopenharmony_ci		goto end;
13223d0407baSopenharmony_ci	} else if (unpack_dir[strlen(unpack_dir) - 1] == '/') {
13233d0407baSopenharmony_ci		unpack_dir[strlen(unpack_dir) - 1] = '\0';
13243d0407baSopenharmony_ci	}
13253d0407baSopenharmony_ci
13263d0407baSopenharmony_ci	mkdir(unpack_dir, 0755);
13273d0407baSopenharmony_ci	image_file = fopen(image_path, "rb");
13283d0407baSopenharmony_ci	char buf[BLOCK_SIZE];
13293d0407baSopenharmony_ci	if (!image_file) {
13303d0407baSopenharmony_ci		LOGE("Failed to open:%s", image_path);
13313d0407baSopenharmony_ci		goto end;
13323d0407baSopenharmony_ci	}
13333d0407baSopenharmony_ci	if (!fread(buf, BLOCK_SIZE, 1, image_file)) {
13343d0407baSopenharmony_ci		LOGE("Failed to read header!");
13353d0407baSopenharmony_ci		goto end;
13363d0407baSopenharmony_ci	}
13373d0407baSopenharmony_ci	memcpy(&header, buf, sizeof(header));
13383d0407baSopenharmony_ci
13393d0407baSopenharmony_ci	if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {
13403d0407baSopenharmony_ci		LOGE("Not a resource image(%s)!", image_path);
13413d0407baSopenharmony_ci		goto end;
13423d0407baSopenharmony_ci	}
13433d0407baSopenharmony_ci	/* switch for be. */
13443d0407baSopenharmony_ci	fix_header(&header);
13453d0407baSopenharmony_ci
13463d0407baSopenharmony_ci	printf("Dump header:\n");
13473d0407baSopenharmony_ci	printf("partition version:%d.%d\n", header.resource_ptn_version,
13483d0407baSopenharmony_ci	       header.index_tbl_version);
13493d0407baSopenharmony_ci	printf("header size:%d\n", header.header_size);
13503d0407baSopenharmony_ci	printf("index tbl:\n\toffset:%d\tentry size:%d\tentry num:%d\n",
13513d0407baSopenharmony_ci	       header.tbl_offset, header.tbl_entry_size, header.tbl_entry_num);
13523d0407baSopenharmony_ci
13533d0407baSopenharmony_ci	/* TODO: support header_size & tbl_entry_size */
13543d0407baSopenharmony_ci	if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||
13553d0407baSopenharmony_ci	    header.header_size != RESOURCE_PTN_HDR_SIZE ||
13563d0407baSopenharmony_ci	    header.index_tbl_version != INDEX_TBL_VERSION ||
13573d0407baSopenharmony_ci	    header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {
13583d0407baSopenharmony_ci		LOGE("Not supported in this version!");
13593d0407baSopenharmony_ci		goto end;
13603d0407baSopenharmony_ci	}
13613d0407baSopenharmony_ci
13623d0407baSopenharmony_ci	printf("Dump Index table:\n");
13633d0407baSopenharmony_ci	index_tbl_entry entry;
13643d0407baSopenharmony_ci	int i;
13653d0407baSopenharmony_ci	for (i = 0; i < header.tbl_entry_num; i++) {
13663d0407baSopenharmony_ci		/* TODO: support tbl_entry_size */
13673d0407baSopenharmony_ci		if (!fread(buf, BLOCK_SIZE, 1, image_file)) {
13683d0407baSopenharmony_ci			LOGE("Failed to read index entry:%d!", i);
13693d0407baSopenharmony_ci			goto end;
13703d0407baSopenharmony_ci		}
13713d0407baSopenharmony_ci		memcpy(&entry, buf, sizeof(entry));
13723d0407baSopenharmony_ci
13733d0407baSopenharmony_ci		if (memcmp(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag))) {
13743d0407baSopenharmony_ci			LOGE("Something wrong with index entry:%d!", i);
13753d0407baSopenharmony_ci			goto end;
13763d0407baSopenharmony_ci		}
13773d0407baSopenharmony_ci		/* switch for be. */
13783d0407baSopenharmony_ci		fix_entry(&entry);
13793d0407baSopenharmony_ci
13803d0407baSopenharmony_ci		printf("entry(%d):\n\tpath:%s\n\toffset:%d\tsize:%d\n", i, entry.path,
13813d0407baSopenharmony_ci		       entry.content_offset, entry.content_size);
13823d0407baSopenharmony_ci		if (!dump_file(image_file, unpack_dir, entry)) {
13833d0407baSopenharmony_ci			goto end;
13843d0407baSopenharmony_ci		}
13853d0407baSopenharmony_ci	}
13863d0407baSopenharmony_ci	printf("Unack %s to %s successed!\n", image_path, unpack_dir);
13873d0407baSopenharmony_ci	ret = true;
13883d0407baSopenharmony_ciend:
13893d0407baSopenharmony_ci	if (image_file)
13903d0407baSopenharmony_ci		fclose(image_file);
13913d0407baSopenharmony_ci	return ret ? 0 : -1;
13923d0407baSopenharmony_ci}
13933d0407baSopenharmony_ci
13943d0407baSopenharmony_ci/************unpack code end****************/
13953d0407baSopenharmony_ci/************pack code****************/
13963d0407baSopenharmony_ci
13973d0407baSopenharmony_cistatic inline size_t get_file_size(const char *path)
13983d0407baSopenharmony_ci{
13993d0407baSopenharmony_ci	LOGD("try to get size(%s)...", path);
14003d0407baSopenharmony_ci	struct stat st;
14013d0407baSopenharmony_ci	if (stat(path, &st) < 0) {
14023d0407baSopenharmony_ci		LOGE("Failed to get size:%s", path);
14033d0407baSopenharmony_ci		return -1;
14043d0407baSopenharmony_ci	}
14053d0407baSopenharmony_ci	LOGD("path:%s, size:%ld", path, st.st_size);
14063d0407baSopenharmony_ci	return st.st_size;
14073d0407baSopenharmony_ci}
14083d0407baSopenharmony_ci
14093d0407baSopenharmony_cistatic int write_file(int offset_block, const char *src_path,
14103d0407baSopenharmony_ci		      char hash[], int hash_size)
14113d0407baSopenharmony_ci{
14123d0407baSopenharmony_ci	LOGD("try to write file(%s) to offset:%d...", src_path, offset_block);
14133d0407baSopenharmony_ci	char *buf = NULL;
14143d0407baSopenharmony_ci	int ret = -1;
14153d0407baSopenharmony_ci	size_t file_size;
14163d0407baSopenharmony_ci	LOGE("#### [zhq] src_path: %s", src_path);
14173d0407baSopenharmony_ci	FILE *src_file = fopen(src_path, "rb");
14183d0407baSopenharmony_ci	if (!src_file) {
14193d0407baSopenharmony_ci		LOGE("Failed to open:%s", src_path);
14203d0407baSopenharmony_ci		goto end;
14213d0407baSopenharmony_ci	}
14223d0407baSopenharmony_ci
14233d0407baSopenharmony_ci	file_size = get_file_size(src_path);
14243d0407baSopenharmony_ci	if (file_size < 0) {
14253d0407baSopenharmony_ci		goto end;
14263d0407baSopenharmony_ci	}
14273d0407baSopenharmony_ci
14283d0407baSopenharmony_ci	buf = calloc(file_size, 1);
14293d0407baSopenharmony_ci	if (!buf)
14303d0407baSopenharmony_ci		goto end;
14313d0407baSopenharmony_ci
14323d0407baSopenharmony_ci	if (!fread(buf, file_size, 1, src_file))
14333d0407baSopenharmony_ci		goto end;
14343d0407baSopenharmony_ci
14353d0407baSopenharmony_ci	if (!write_data(offset_block, buf, file_size))
14363d0407baSopenharmony_ci		goto end;
14373d0407baSopenharmony_ci
14383d0407baSopenharmony_ci	if (hash_size == 20)
14393d0407baSopenharmony_ci		sha1_csum((const unsigned char *)buf, file_size,
14403d0407baSopenharmony_ci			  (unsigned char *)hash);
14413d0407baSopenharmony_ci	else if (hash_size == 32)
14423d0407baSopenharmony_ci		sha256_csum((const unsigned char *)buf, file_size,
14433d0407baSopenharmony_ci			    (unsigned char *)hash);
14443d0407baSopenharmony_ci	else
14453d0407baSopenharmony_ci		goto end;
14463d0407baSopenharmony_ci
14473d0407baSopenharmony_ci	ret = file_size;
14483d0407baSopenharmony_ciend:
14493d0407baSopenharmony_ci	if (src_file)
14503d0407baSopenharmony_ci		fclose(src_file);
14513d0407baSopenharmony_ci	if (buf)
14523d0407baSopenharmony_ci		free(buf);
14533d0407baSopenharmony_ci
14543d0407baSopenharmony_ci	return ret;
14553d0407baSopenharmony_ci}
14563d0407baSopenharmony_ci
14573d0407baSopenharmony_cistatic bool write_header(const int file_num)
14583d0407baSopenharmony_ci{
14593d0407baSopenharmony_ci	LOGD("try to write header...");
14603d0407baSopenharmony_ci	memcpy(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic));
14613d0407baSopenharmony_ci	header.resource_ptn_version = RESOURCE_PTN_VERSION;
14623d0407baSopenharmony_ci	header.index_tbl_version = INDEX_TBL_VERSION;
14633d0407baSopenharmony_ci	header.header_size = RESOURCE_PTN_HDR_SIZE;
14643d0407baSopenharmony_ci	header.tbl_offset = header.header_size;
14653d0407baSopenharmony_ci	header.tbl_entry_size = INDEX_TBL_ENTR_SIZE;
14663d0407baSopenharmony_ci	header.tbl_entry_num = file_num;
14673d0407baSopenharmony_ci
14683d0407baSopenharmony_ci	/* switch for le. */
14693d0407baSopenharmony_ci	resource_ptn_header hdr = header;
14703d0407baSopenharmony_ci	fix_header(&hdr);
14713d0407baSopenharmony_ci	return write_data(0, &hdr, sizeof(hdr));
14723d0407baSopenharmony_ci}
14733d0407baSopenharmony_ci
14743d0407baSopenharmony_cistatic bool write_index_tbl(const int file_num, const char **files)
14753d0407baSopenharmony_ci{
14763d0407baSopenharmony_ci	LOGD("try to write index table...");
14773d0407baSopenharmony_ci	bool ret = false;
14783d0407baSopenharmony_ci	bool foundFdt = false;
14793d0407baSopenharmony_ci	int offset =
14803d0407baSopenharmony_ci	        header.header_size + header.tbl_entry_size * header.tbl_entry_num;
14813d0407baSopenharmony_ci	index_tbl_entry entry;
14823d0407baSopenharmony_ci	char hash[20];	/* sha1 */
14833d0407baSopenharmony_ci	int i;
14843d0407baSopenharmony_ci
14853d0407baSopenharmony_ci	memcpy(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag));
14863d0407baSopenharmony_ci	for (i = 0; i < file_num; i++) {
14873d0407baSopenharmony_ci		size_t file_size = get_file_size(files[i]);
14883d0407baSopenharmony_ci		if (file_size < 0)
14893d0407baSopenharmony_ci			goto end;
14903d0407baSopenharmony_ci		entry.content_size = file_size;
14913d0407baSopenharmony_ci		entry.content_offset = offset;
14923d0407baSopenharmony_ci
14933d0407baSopenharmony_ci		if (write_file(offset, files[i], hash, sizeof(hash)) < 0)
14943d0407baSopenharmony_ci			goto end;
14953d0407baSopenharmony_ci
14963d0407baSopenharmony_ci		memcpy(entry.hash, hash, sizeof(hash));
14973d0407baSopenharmony_ci		entry.hash_size = sizeof(hash);
14983d0407baSopenharmony_ci
14993d0407baSopenharmony_ci		LOGD("try to write index entry(%s)...", files[i]);
15003d0407baSopenharmony_ci
15013d0407baSopenharmony_ci		/* switch for le. */
15023d0407baSopenharmony_ci		fix_entry(&entry);
15033d0407baSopenharmony_ci		memset(entry.path, 0, sizeof(entry.path));
15043d0407baSopenharmony_ci		const char *path = files[i];
15053d0407baSopenharmony_ci		if (root_path[0]) {
15063d0407baSopenharmony_ci			if (!strncmp(path, root_path, strlen(root_path))) {
15073d0407baSopenharmony_ci				path += strlen(root_path);
15083d0407baSopenharmony_ci				if (path[0] == '/')
15093d0407baSopenharmony_ci					path++;
15103d0407baSopenharmony_ci			}
15113d0407baSopenharmony_ci		}
15123d0407baSopenharmony_ci		path = fix_path(path);
15133d0407baSopenharmony_ci		if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {
15143d0407baSopenharmony_ci			if (!foundFdt) {
15153d0407baSopenharmony_ci				/* use default path. */
15163d0407baSopenharmony_ci				LOGD("mod fdt path:%s -> %s...", files[i], FDT_PATH);
15173d0407baSopenharmony_ci				path = FDT_PATH;
15183d0407baSopenharmony_ci				foundFdt = true;
15193d0407baSopenharmony_ci			}
15203d0407baSopenharmony_ci		}
15213d0407baSopenharmony_ci		snprintf(entry.path, sizeof(entry.path), "%s", path);
15223d0407baSopenharmony_ci		offset += fix_blocks(file_size);
15233d0407baSopenharmony_ci		if (!write_data(header.header_size + i * header.tbl_entry_size, &entry,
15243d0407baSopenharmony_ci		                sizeof(entry)))
15253d0407baSopenharmony_ci			goto end;
15263d0407baSopenharmony_ci	}
15273d0407baSopenharmony_ci	ret = true;
15283d0407baSopenharmony_ciend:
15293d0407baSopenharmony_ci	return ret;
15303d0407baSopenharmony_ci}
15313d0407baSopenharmony_ci
15323d0407baSopenharmony_cistatic int pack_image(int file_num, const char **files)
15333d0407baSopenharmony_ci{
15343d0407baSopenharmony_ci	bool ret = false;
15353d0407baSopenharmony_ci	FILE *image_file = fopen(image_path, "wb");
15363d0407baSopenharmony_ci	if (!image_file) {
15373d0407baSopenharmony_ci		LOGE("Failed to create:%s", image_path);
15383d0407baSopenharmony_ci		goto end;
15393d0407baSopenharmony_ci	}
15403d0407baSopenharmony_ci	fclose(image_file);
15413d0407baSopenharmony_ci
15423d0407baSopenharmony_ci	/* prepare files */
15433d0407baSopenharmony_ci	int i = 0;
15443d0407baSopenharmony_ci	int pos = 0;
15453d0407baSopenharmony_ci	const char *tmp;
15463d0407baSopenharmony_ci	for (i = 0; i < file_num; i++) {
15473d0407baSopenharmony_ci		if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {
15483d0407baSopenharmony_ci			/* dtb files for kernel. */
15493d0407baSopenharmony_ci			tmp = files[pos];
15503d0407baSopenharmony_ci			files[pos] = files[i];
15513d0407baSopenharmony_ci			files[i] = tmp;
15523d0407baSopenharmony_ci			pos++;
15533d0407baSopenharmony_ci		} else if (!strcmp(fix_path(image_path), fix_path(files[i]))) {
15543d0407baSopenharmony_ci			/* not to pack image itself! */
15553d0407baSopenharmony_ci			tmp = files[file_num - 1];
15563d0407baSopenharmony_ci			files[file_num - 1] = files[i];
15573d0407baSopenharmony_ci			files[i] = tmp;
15583d0407baSopenharmony_ci			file_num--;
15593d0407baSopenharmony_ci		}
15603d0407baSopenharmony_ci	}
15613d0407baSopenharmony_ci
15623d0407baSopenharmony_ci	if (!write_header(file_num)) {
15633d0407baSopenharmony_ci		LOGE("Failed to write header!");
15643d0407baSopenharmony_ci		goto end;
15653d0407baSopenharmony_ci	}
15663d0407baSopenharmony_ci	if (!write_index_tbl(file_num, files)) {
15673d0407baSopenharmony_ci		LOGE("Failed to write index table!");
15683d0407baSopenharmony_ci		goto end;
15693d0407baSopenharmony_ci	}
15703d0407baSopenharmony_ci	printf("Pack to %s successed!\n", image_path);
15713d0407baSopenharmony_ci	ret = true;
15723d0407baSopenharmony_ciend:
15733d0407baSopenharmony_ci	return ret ? 0 : -1;
15743d0407baSopenharmony_ci}
15753d0407baSopenharmony_ci
15763d0407baSopenharmony_ci/************pack code end****************/
1577