1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #include <errno.h>
7*4882a593Smuzhiyun #include <memory.h>
8*4882a593Smuzhiyun #include <stdint.h>
9*4882a593Smuzhiyun #include <stdio.h>
10*4882a593Smuzhiyun #include <stdlib.h>
11*4882a593Smuzhiyun #include <stdbool.h>
12*4882a593Smuzhiyun #include <sys/stat.h>
13*4882a593Smuzhiyun #include <time.h>
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun /**
16*4882a593Smuzhiyun * \brief SHA-1 context structure
17*4882a593Smuzhiyun */
18*4882a593Smuzhiyun typedef struct
19*4882a593Smuzhiyun {
20*4882a593Smuzhiyun unsigned long total[2]; /*!< number of bytes processed */
21*4882a593Smuzhiyun unsigned long state[5]; /*!< intermediate digest state */
22*4882a593Smuzhiyun unsigned char buffer[64]; /*!< data block being processed */
23*4882a593Smuzhiyun }
24*4882a593Smuzhiyun sha1_context;
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun /*
27*4882a593Smuzhiyun * 32-bit integer manipulation macros (big endian)
28*4882a593Smuzhiyun */
29*4882a593Smuzhiyun #ifndef GET_UINT32_BE
30*4882a593Smuzhiyun #define GET_UINT32_BE(n,b,i) { \
31*4882a593Smuzhiyun (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
32*4882a593Smuzhiyun | ( (unsigned long) (b)[(i) + 1] << 16 ) \
33*4882a593Smuzhiyun | ( (unsigned long) (b)[(i) + 2] << 8 ) \
34*4882a593Smuzhiyun | ( (unsigned long) (b)[(i) + 3] ); \
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun #endif
37*4882a593Smuzhiyun #ifndef PUT_UINT32_BE
38*4882a593Smuzhiyun #define PUT_UINT32_BE(n,b,i) { \
39*4882a593Smuzhiyun (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
40*4882a593Smuzhiyun (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
41*4882a593Smuzhiyun (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
42*4882a593Smuzhiyun (b)[(i) + 3] = (unsigned char) ( (n) ); \
43*4882a593Smuzhiyun }
44*4882a593Smuzhiyun #endif
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /*
47*4882a593Smuzhiyun * SHA-1 context setup
48*4882a593Smuzhiyun */
49*4882a593Smuzhiyun static
sha1_starts(sha1_context * ctx)50*4882a593Smuzhiyun void sha1_starts (sha1_context * ctx)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun ctx->total[0] = 0;
53*4882a593Smuzhiyun ctx->total[1] = 0;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun ctx->state[0] = 0x67452301;
56*4882a593Smuzhiyun ctx->state[1] = 0xEFCDAB89;
57*4882a593Smuzhiyun ctx->state[2] = 0x98BADCFE;
58*4882a593Smuzhiyun ctx->state[3] = 0x10325476;
59*4882a593Smuzhiyun ctx->state[4] = 0xC3D2E1F0;
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun
sha1_process(sha1_context * ctx,const unsigned char data[64])62*4882a593Smuzhiyun static void sha1_process(sha1_context *ctx, const unsigned char data[64])
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun unsigned long temp, W[16], A, B, C, D, E;
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun GET_UINT32_BE (W[0], data, 0);
67*4882a593Smuzhiyun GET_UINT32_BE (W[1], data, 4);
68*4882a593Smuzhiyun GET_UINT32_BE (W[2], data, 8);
69*4882a593Smuzhiyun GET_UINT32_BE (W[3], data, 12);
70*4882a593Smuzhiyun GET_UINT32_BE (W[4], data, 16);
71*4882a593Smuzhiyun GET_UINT32_BE (W[5], data, 20);
72*4882a593Smuzhiyun GET_UINT32_BE (W[6], data, 24);
73*4882a593Smuzhiyun GET_UINT32_BE (W[7], data, 28);
74*4882a593Smuzhiyun GET_UINT32_BE (W[8], data, 32);
75*4882a593Smuzhiyun GET_UINT32_BE (W[9], data, 36);
76*4882a593Smuzhiyun GET_UINT32_BE (W[10], data, 40);
77*4882a593Smuzhiyun GET_UINT32_BE (W[11], data, 44);
78*4882a593Smuzhiyun GET_UINT32_BE (W[12], data, 48);
79*4882a593Smuzhiyun GET_UINT32_BE (W[13], data, 52);
80*4882a593Smuzhiyun GET_UINT32_BE (W[14], data, 56);
81*4882a593Smuzhiyun GET_UINT32_BE (W[15], data, 60);
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun #define R(t) ( \
86*4882a593Smuzhiyun temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
87*4882a593Smuzhiyun W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
88*4882a593Smuzhiyun ( W[t & 0x0F] = S(temp,1) ) \
89*4882a593Smuzhiyun )
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun #define P(a,b,c,d,e,x) { \
92*4882a593Smuzhiyun e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun A = ctx->state[0];
96*4882a593Smuzhiyun B = ctx->state[1];
97*4882a593Smuzhiyun C = ctx->state[2];
98*4882a593Smuzhiyun D = ctx->state[3];
99*4882a593Smuzhiyun E = ctx->state[4];
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun #define F(x,y,z) (z ^ (x & (y ^ z)))
102*4882a593Smuzhiyun #define K 0x5A827999
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun P (A, B, C, D, E, W[0]);
105*4882a593Smuzhiyun P (E, A, B, C, D, W[1]);
106*4882a593Smuzhiyun P (D, E, A, B, C, W[2]);
107*4882a593Smuzhiyun P (C, D, E, A, B, W[3]);
108*4882a593Smuzhiyun P (B, C, D, E, A, W[4]);
109*4882a593Smuzhiyun P (A, B, C, D, E, W[5]);
110*4882a593Smuzhiyun P (E, A, B, C, D, W[6]);
111*4882a593Smuzhiyun P (D, E, A, B, C, W[7]);
112*4882a593Smuzhiyun P (C, D, E, A, B, W[8]);
113*4882a593Smuzhiyun P (B, C, D, E, A, W[9]);
114*4882a593Smuzhiyun P (A, B, C, D, E, W[10]);
115*4882a593Smuzhiyun P (E, A, B, C, D, W[11]);
116*4882a593Smuzhiyun P (D, E, A, B, C, W[12]);
117*4882a593Smuzhiyun P (C, D, E, A, B, W[13]);
118*4882a593Smuzhiyun P (B, C, D, E, A, W[14]);
119*4882a593Smuzhiyun P (A, B, C, D, E, W[15]);
120*4882a593Smuzhiyun P (E, A, B, C, D, R (16));
121*4882a593Smuzhiyun P (D, E, A, B, C, R (17));
122*4882a593Smuzhiyun P (C, D, E, A, B, R (18));
123*4882a593Smuzhiyun P (B, C, D, E, A, R (19));
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun #undef K
126*4882a593Smuzhiyun #undef F
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun #define F(x,y,z) (x ^ y ^ z)
129*4882a593Smuzhiyun #define K 0x6ED9EBA1
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun P (A, B, C, D, E, R (20));
132*4882a593Smuzhiyun P (E, A, B, C, D, R (21));
133*4882a593Smuzhiyun P (D, E, A, B, C, R (22));
134*4882a593Smuzhiyun P (C, D, E, A, B, R (23));
135*4882a593Smuzhiyun P (B, C, D, E, A, R (24));
136*4882a593Smuzhiyun P (A, B, C, D, E, R (25));
137*4882a593Smuzhiyun P (E, A, B, C, D, R (26));
138*4882a593Smuzhiyun P (D, E, A, B, C, R (27));
139*4882a593Smuzhiyun P (C, D, E, A, B, R (28));
140*4882a593Smuzhiyun P (B, C, D, E, A, R (29));
141*4882a593Smuzhiyun P (A, B, C, D, E, R (30));
142*4882a593Smuzhiyun P (E, A, B, C, D, R (31));
143*4882a593Smuzhiyun P (D, E, A, B, C, R (32));
144*4882a593Smuzhiyun P (C, D, E, A, B, R (33));
145*4882a593Smuzhiyun P (B, C, D, E, A, R (34));
146*4882a593Smuzhiyun P (A, B, C, D, E, R (35));
147*4882a593Smuzhiyun P (E, A, B, C, D, R (36));
148*4882a593Smuzhiyun P (D, E, A, B, C, R (37));
149*4882a593Smuzhiyun P (C, D, E, A, B, R (38));
150*4882a593Smuzhiyun P (B, C, D, E, A, R (39));
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun #undef K
153*4882a593Smuzhiyun #undef F
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun #define F(x,y,z) ((x & y) | (z & (x | y)))
156*4882a593Smuzhiyun #define K 0x8F1BBCDC
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun P (A, B, C, D, E, R (40));
159*4882a593Smuzhiyun P (E, A, B, C, D, R (41));
160*4882a593Smuzhiyun P (D, E, A, B, C, R (42));
161*4882a593Smuzhiyun P (C, D, E, A, B, R (43));
162*4882a593Smuzhiyun P (B, C, D, E, A, R (44));
163*4882a593Smuzhiyun P (A, B, C, D, E, R (45));
164*4882a593Smuzhiyun P (E, A, B, C, D, R (46));
165*4882a593Smuzhiyun P (D, E, A, B, C, R (47));
166*4882a593Smuzhiyun P (C, D, E, A, B, R (48));
167*4882a593Smuzhiyun P (B, C, D, E, A, R (49));
168*4882a593Smuzhiyun P (A, B, C, D, E, R (50));
169*4882a593Smuzhiyun P (E, A, B, C, D, R (51));
170*4882a593Smuzhiyun P (D, E, A, B, C, R (52));
171*4882a593Smuzhiyun P (C, D, E, A, B, R (53));
172*4882a593Smuzhiyun P (B, C, D, E, A, R (54));
173*4882a593Smuzhiyun P (A, B, C, D, E, R (55));
174*4882a593Smuzhiyun P (E, A, B, C, D, R (56));
175*4882a593Smuzhiyun P (D, E, A, B, C, R (57));
176*4882a593Smuzhiyun P (C, D, E, A, B, R (58));
177*4882a593Smuzhiyun P (B, C, D, E, A, R (59));
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun #undef K
180*4882a593Smuzhiyun #undef F
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun #define F(x,y,z) (x ^ y ^ z)
183*4882a593Smuzhiyun #define K 0xCA62C1D6
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun P (A, B, C, D, E, R (60));
186*4882a593Smuzhiyun P (E, A, B, C, D, R (61));
187*4882a593Smuzhiyun P (D, E, A, B, C, R (62));
188*4882a593Smuzhiyun P (C, D, E, A, B, R (63));
189*4882a593Smuzhiyun P (B, C, D, E, A, R (64));
190*4882a593Smuzhiyun P (A, B, C, D, E, R (65));
191*4882a593Smuzhiyun P (E, A, B, C, D, R (66));
192*4882a593Smuzhiyun P (D, E, A, B, C, R (67));
193*4882a593Smuzhiyun P (C, D, E, A, B, R (68));
194*4882a593Smuzhiyun P (B, C, D, E, A, R (69));
195*4882a593Smuzhiyun P (A, B, C, D, E, R (70));
196*4882a593Smuzhiyun P (E, A, B, C, D, R (71));
197*4882a593Smuzhiyun P (D, E, A, B, C, R (72));
198*4882a593Smuzhiyun P (C, D, E, A, B, R (73));
199*4882a593Smuzhiyun P (B, C, D, E, A, R (74));
200*4882a593Smuzhiyun P (A, B, C, D, E, R (75));
201*4882a593Smuzhiyun P (E, A, B, C, D, R (76));
202*4882a593Smuzhiyun P (D, E, A, B, C, R (77));
203*4882a593Smuzhiyun P (C, D, E, A, B, R (78));
204*4882a593Smuzhiyun P (B, C, D, E, A, R (79));
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun #undef K
207*4882a593Smuzhiyun #undef F
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun ctx->state[0] += A;
210*4882a593Smuzhiyun ctx->state[1] += B;
211*4882a593Smuzhiyun ctx->state[2] += C;
212*4882a593Smuzhiyun ctx->state[3] += D;
213*4882a593Smuzhiyun ctx->state[4] += E;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun #undef P
217*4882a593Smuzhiyun #undef R
218*4882a593Smuzhiyun #undef S
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /*
221*4882a593Smuzhiyun * SHA-1 process buffer
222*4882a593Smuzhiyun */
223*4882a593Smuzhiyun static
sha1_update(sha1_context * ctx,const unsigned char * input,unsigned int ilen)224*4882a593Smuzhiyun void sha1_update(sha1_context *ctx, const unsigned char *input,
225*4882a593Smuzhiyun unsigned int ilen)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun int fill;
228*4882a593Smuzhiyun unsigned long left;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun if (ilen <= 0)
231*4882a593Smuzhiyun return;
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun left = ctx->total[0] & 0x3F;
234*4882a593Smuzhiyun fill = 64 - left;
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun ctx->total[0] += ilen;
237*4882a593Smuzhiyun ctx->total[0] &= 0xFFFFFFFF;
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun if (ctx->total[0] < (unsigned long) ilen)
240*4882a593Smuzhiyun ctx->total[1]++;
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun if (left && ilen >= fill) {
243*4882a593Smuzhiyun memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
244*4882a593Smuzhiyun sha1_process (ctx, ctx->buffer);
245*4882a593Smuzhiyun input += fill;
246*4882a593Smuzhiyun ilen -= fill;
247*4882a593Smuzhiyun left = 0;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun while (ilen >= 64) {
251*4882a593Smuzhiyun sha1_process (ctx, input);
252*4882a593Smuzhiyun input += 64;
253*4882a593Smuzhiyun ilen -= 64;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun if (ilen > 0) {
257*4882a593Smuzhiyun memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun
261*4882a593Smuzhiyun static const unsigned char sha1_padding[64] = {
262*4882a593Smuzhiyun 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
263*4882a593Smuzhiyun 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
264*4882a593Smuzhiyun 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265*4882a593Smuzhiyun 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
266*4882a593Smuzhiyun };
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun /*
269*4882a593Smuzhiyun * SHA-1 final digest
270*4882a593Smuzhiyun */
271*4882a593Smuzhiyun static
sha1_finish(sha1_context * ctx,unsigned char output[20])272*4882a593Smuzhiyun void sha1_finish (sha1_context * ctx, unsigned char output[20])
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun unsigned long last, padn;
275*4882a593Smuzhiyun unsigned long high, low;
276*4882a593Smuzhiyun unsigned char msglen[8];
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun high = (ctx->total[0] >> 29)
279*4882a593Smuzhiyun | (ctx->total[1] << 3);
280*4882a593Smuzhiyun low = (ctx->total[0] << 3);
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun PUT_UINT32_BE (high, msglen, 0);
283*4882a593Smuzhiyun PUT_UINT32_BE (low, msglen, 4);
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun last = ctx->total[0] & 0x3F;
286*4882a593Smuzhiyun padn = (last < 56) ? (56 - last) : (120 - last);
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun sha1_update (ctx, (unsigned char *) sha1_padding, padn);
289*4882a593Smuzhiyun sha1_update (ctx, msglen, 8);
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun PUT_UINT32_BE (ctx->state[0], output, 0);
292*4882a593Smuzhiyun PUT_UINT32_BE (ctx->state[1], output, 4);
293*4882a593Smuzhiyun PUT_UINT32_BE (ctx->state[2], output, 8);
294*4882a593Smuzhiyun PUT_UINT32_BE (ctx->state[3], output, 12);
295*4882a593Smuzhiyun PUT_UINT32_BE (ctx->state[4], output, 16);
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun /*
299*4882a593Smuzhiyun * Output = SHA-1( input buffer )
300*4882a593Smuzhiyun */
301*4882a593Smuzhiyun static
sha1_csum(const unsigned char * input,unsigned int ilen,unsigned char * output)302*4882a593Smuzhiyun void sha1_csum(const unsigned char *input, unsigned int ilen,
303*4882a593Smuzhiyun unsigned char *output)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun sha1_context ctx;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun sha1_starts (&ctx);
308*4882a593Smuzhiyun sha1_update (&ctx, input, ilen);
309*4882a593Smuzhiyun sha1_finish (&ctx, output);
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun typedef struct {
313*4882a593Smuzhiyun uint32_t total[2];
314*4882a593Smuzhiyun uint32_t state[8];
315*4882a593Smuzhiyun uint8_t buffer[64];
316*4882a593Smuzhiyun } sha256_context;
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun static
sha256_starts(sha256_context * ctx)319*4882a593Smuzhiyun void sha256_starts(sha256_context * ctx)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun ctx->total[0] = 0;
322*4882a593Smuzhiyun ctx->total[1] = 0;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun ctx->state[0] = 0x6A09E667;
325*4882a593Smuzhiyun ctx->state[1] = 0xBB67AE85;
326*4882a593Smuzhiyun ctx->state[2] = 0x3C6EF372;
327*4882a593Smuzhiyun ctx->state[3] = 0xA54FF53A;
328*4882a593Smuzhiyun ctx->state[4] = 0x510E527F;
329*4882a593Smuzhiyun ctx->state[5] = 0x9B05688C;
330*4882a593Smuzhiyun ctx->state[6] = 0x1F83D9AB;
331*4882a593Smuzhiyun ctx->state[7] = 0x5BE0CD19;
332*4882a593Smuzhiyun }
333*4882a593Smuzhiyun
sha256_process(sha256_context * ctx,const uint8_t data[64])334*4882a593Smuzhiyun static void sha256_process(sha256_context *ctx, const uint8_t data[64])
335*4882a593Smuzhiyun {
336*4882a593Smuzhiyun uint32_t temp1, temp2;
337*4882a593Smuzhiyun uint32_t W[64];
338*4882a593Smuzhiyun uint32_t A, B, C, D, E, F, G, H;
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun GET_UINT32_BE(W[0], data, 0);
341*4882a593Smuzhiyun GET_UINT32_BE(W[1], data, 4);
342*4882a593Smuzhiyun GET_UINT32_BE(W[2], data, 8);
343*4882a593Smuzhiyun GET_UINT32_BE(W[3], data, 12);
344*4882a593Smuzhiyun GET_UINT32_BE(W[4], data, 16);
345*4882a593Smuzhiyun GET_UINT32_BE(W[5], data, 20);
346*4882a593Smuzhiyun GET_UINT32_BE(W[6], data, 24);
347*4882a593Smuzhiyun GET_UINT32_BE(W[7], data, 28);
348*4882a593Smuzhiyun GET_UINT32_BE(W[8], data, 32);
349*4882a593Smuzhiyun GET_UINT32_BE(W[9], data, 36);
350*4882a593Smuzhiyun GET_UINT32_BE(W[10], data, 40);
351*4882a593Smuzhiyun GET_UINT32_BE(W[11], data, 44);
352*4882a593Smuzhiyun GET_UINT32_BE(W[12], data, 48);
353*4882a593Smuzhiyun GET_UINT32_BE(W[13], data, 52);
354*4882a593Smuzhiyun GET_UINT32_BE(W[14], data, 56);
355*4882a593Smuzhiyun GET_UINT32_BE(W[15], data, 60);
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun #define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
358*4882a593Smuzhiyun #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
361*4882a593Smuzhiyun #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
364*4882a593Smuzhiyun #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun #define F0(x,y,z) ((x & y) | (z & (x | y)))
367*4882a593Smuzhiyun #define F1(x,y,z) (z ^ (x & (y ^ z)))
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun #define R(t) \
370*4882a593Smuzhiyun ( \
371*4882a593Smuzhiyun W[t] = S1(W[t - 2]) + W[t - 7] + \
372*4882a593Smuzhiyun S0(W[t - 15]) + W[t - 16] \
373*4882a593Smuzhiyun )
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun #define P(a,b,c,d,e,f,g,h,x,K) { \
376*4882a593Smuzhiyun temp1 = h + S3(e) + F1(e,f,g) + K + x; \
377*4882a593Smuzhiyun temp2 = S2(a) + F0(a,b,c); \
378*4882a593Smuzhiyun d += temp1; h = temp1 + temp2; \
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun A = ctx->state[0];
382*4882a593Smuzhiyun B = ctx->state[1];
383*4882a593Smuzhiyun C = ctx->state[2];
384*4882a593Smuzhiyun D = ctx->state[3];
385*4882a593Smuzhiyun E = ctx->state[4];
386*4882a593Smuzhiyun F = ctx->state[5];
387*4882a593Smuzhiyun G = ctx->state[6];
388*4882a593Smuzhiyun H = ctx->state[7];
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
391*4882a593Smuzhiyun P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
392*4882a593Smuzhiyun P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
393*4882a593Smuzhiyun P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
394*4882a593Smuzhiyun P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
395*4882a593Smuzhiyun P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
396*4882a593Smuzhiyun P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
397*4882a593Smuzhiyun P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
398*4882a593Smuzhiyun P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
399*4882a593Smuzhiyun P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
400*4882a593Smuzhiyun P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
401*4882a593Smuzhiyun P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
402*4882a593Smuzhiyun P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
403*4882a593Smuzhiyun P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
404*4882a593Smuzhiyun P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
405*4882a593Smuzhiyun P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
406*4882a593Smuzhiyun P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
407*4882a593Smuzhiyun P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
408*4882a593Smuzhiyun P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
409*4882a593Smuzhiyun P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
410*4882a593Smuzhiyun P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
411*4882a593Smuzhiyun P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
412*4882a593Smuzhiyun P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
413*4882a593Smuzhiyun P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
414*4882a593Smuzhiyun P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
415*4882a593Smuzhiyun P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
416*4882a593Smuzhiyun P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
417*4882a593Smuzhiyun P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
418*4882a593Smuzhiyun P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
419*4882a593Smuzhiyun P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
420*4882a593Smuzhiyun P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
421*4882a593Smuzhiyun P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
422*4882a593Smuzhiyun P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
423*4882a593Smuzhiyun P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
424*4882a593Smuzhiyun P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
425*4882a593Smuzhiyun P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
426*4882a593Smuzhiyun P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
427*4882a593Smuzhiyun P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
428*4882a593Smuzhiyun P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
429*4882a593Smuzhiyun P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
430*4882a593Smuzhiyun P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
431*4882a593Smuzhiyun P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
432*4882a593Smuzhiyun P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
433*4882a593Smuzhiyun P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
434*4882a593Smuzhiyun P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
435*4882a593Smuzhiyun P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
436*4882a593Smuzhiyun P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
437*4882a593Smuzhiyun P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
438*4882a593Smuzhiyun P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
439*4882a593Smuzhiyun P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
440*4882a593Smuzhiyun P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
441*4882a593Smuzhiyun P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
442*4882a593Smuzhiyun P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
443*4882a593Smuzhiyun P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
444*4882a593Smuzhiyun P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
445*4882a593Smuzhiyun P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
446*4882a593Smuzhiyun P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
447*4882a593Smuzhiyun P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
448*4882a593Smuzhiyun P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
449*4882a593Smuzhiyun P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
450*4882a593Smuzhiyun P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
451*4882a593Smuzhiyun P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
452*4882a593Smuzhiyun P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
453*4882a593Smuzhiyun P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun ctx->state[0] += A;
456*4882a593Smuzhiyun ctx->state[1] += B;
457*4882a593Smuzhiyun ctx->state[2] += C;
458*4882a593Smuzhiyun ctx->state[3] += D;
459*4882a593Smuzhiyun ctx->state[4] += E;
460*4882a593Smuzhiyun ctx->state[5] += F;
461*4882a593Smuzhiyun ctx->state[6] += G;
462*4882a593Smuzhiyun ctx->state[7] += H;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun #undef P
466*4882a593Smuzhiyun #undef R
467*4882a593Smuzhiyun #undef F1
468*4882a593Smuzhiyun #undef F0
469*4882a593Smuzhiyun #undef S3
470*4882a593Smuzhiyun #undef S2
471*4882a593Smuzhiyun #undef S1
472*4882a593Smuzhiyun #undef S0
473*4882a593Smuzhiyun #undef ROTR
474*4882a593Smuzhiyun #undef SHR
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun static
sha256_update(sha256_context * ctx,const uint8_t * input,uint32_t length)477*4882a593Smuzhiyun void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
478*4882a593Smuzhiyun {
479*4882a593Smuzhiyun uint32_t left, fill;
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun if (!length)
482*4882a593Smuzhiyun return;
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun left = ctx->total[0] & 0x3F;
485*4882a593Smuzhiyun fill = 64 - left;
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun ctx->total[0] += length;
488*4882a593Smuzhiyun ctx->total[0] &= 0xFFFFFFFF;
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun if (ctx->total[0] < length)
491*4882a593Smuzhiyun ctx->total[1]++;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun if (left && length >= fill) {
494*4882a593Smuzhiyun memcpy((void *) (ctx->buffer + left), (void *) input, fill);
495*4882a593Smuzhiyun sha256_process(ctx, ctx->buffer);
496*4882a593Smuzhiyun length -= fill;
497*4882a593Smuzhiyun input += fill;
498*4882a593Smuzhiyun left = 0;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun while (length >= 64) {
502*4882a593Smuzhiyun sha256_process(ctx, input);
503*4882a593Smuzhiyun length -= 64;
504*4882a593Smuzhiyun input += 64;
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun if (length)
508*4882a593Smuzhiyun memcpy((void *) (ctx->buffer + left), (void *) input, length);
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun static uint8_t sha256_padding[64] = {
512*4882a593Smuzhiyun 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
513*4882a593Smuzhiyun 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
514*4882a593Smuzhiyun 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
515*4882a593Smuzhiyun 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
516*4882a593Smuzhiyun };
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun static
sha256_finish(sha256_context * ctx,uint8_t digest[32])519*4882a593Smuzhiyun void sha256_finish(sha256_context * ctx, uint8_t digest[32])
520*4882a593Smuzhiyun {
521*4882a593Smuzhiyun uint32_t last, padn;
522*4882a593Smuzhiyun uint32_t high, low;
523*4882a593Smuzhiyun uint8_t msglen[8];
524*4882a593Smuzhiyun
525*4882a593Smuzhiyun high = ((ctx->total[0] >> 29)
526*4882a593Smuzhiyun | (ctx->total[1] << 3));
527*4882a593Smuzhiyun low = (ctx->total[0] << 3);
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun PUT_UINT32_BE(high, msglen, 0);
530*4882a593Smuzhiyun PUT_UINT32_BE(low, msglen, 4);
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun last = ctx->total[0] & 0x3F;
533*4882a593Smuzhiyun padn = (last < 56) ? (56 - last) : (120 - last);
534*4882a593Smuzhiyun
535*4882a593Smuzhiyun sha256_update(ctx, sha256_padding, padn);
536*4882a593Smuzhiyun sha256_update(ctx, msglen, 8);
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun PUT_UINT32_BE(ctx->state[0], digest, 0);
539*4882a593Smuzhiyun PUT_UINT32_BE(ctx->state[1], digest, 4);
540*4882a593Smuzhiyun PUT_UINT32_BE(ctx->state[2], digest, 8);
541*4882a593Smuzhiyun PUT_UINT32_BE(ctx->state[3], digest, 12);
542*4882a593Smuzhiyun PUT_UINT32_BE(ctx->state[4], digest, 16);
543*4882a593Smuzhiyun PUT_UINT32_BE(ctx->state[5], digest, 20);
544*4882a593Smuzhiyun PUT_UINT32_BE(ctx->state[6], digest, 24);
545*4882a593Smuzhiyun PUT_UINT32_BE(ctx->state[7], digest, 28);
546*4882a593Smuzhiyun }
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun /*
549*4882a593Smuzhiyun * Output = SHA-256( input buffer ).
550*4882a593Smuzhiyun */
551*4882a593Smuzhiyun static
sha256_csum(const unsigned char * input,unsigned int ilen,unsigned char * output)552*4882a593Smuzhiyun void sha256_csum(const unsigned char *input, unsigned int ilen,
553*4882a593Smuzhiyun unsigned char *output)
554*4882a593Smuzhiyun {
555*4882a593Smuzhiyun sha256_context ctx;
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun sha256_starts(&ctx);
558*4882a593Smuzhiyun sha256_update(&ctx, input, ilen);
559*4882a593Smuzhiyun sha256_finish(&ctx, output);
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun /* #define DEBUG */
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun static bool g_debug =
565*4882a593Smuzhiyun #ifdef DEBUG
566*4882a593Smuzhiyun true;
567*4882a593Smuzhiyun #else
568*4882a593Smuzhiyun false;
569*4882a593Smuzhiyun #endif /* DEBUG */
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun #define LOGE(fmt, args...) \
572*4882a593Smuzhiyun fprintf(stderr, "E/%s(%d): " fmt "\n", __func__, __LINE__, ##args)
573*4882a593Smuzhiyun #define LOGD(fmt, args...) \
574*4882a593Smuzhiyun do { \
575*4882a593Smuzhiyun if (g_debug) \
576*4882a593Smuzhiyun fprintf(stderr, "D/%s(%d): " fmt "\n", __func__, __LINE__, ##args); \
577*4882a593Smuzhiyun } while (0)
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun /* sync with ./board/rockchip/rk30xx/rkloader.c #define FDT_PATH */
580*4882a593Smuzhiyun #define FDT_PATH "rk-kernel.dtb"
581*4882a593Smuzhiyun #define DTD_SUBFIX ".dtb"
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun #define DEFAULT_IMAGE_PATH "resource.img"
584*4882a593Smuzhiyun #define DEFAULT_UNPACK_DIR "out"
585*4882a593Smuzhiyun #define BLOCK_SIZE 512
586*4882a593Smuzhiyun
587*4882a593Smuzhiyun #define RESOURCE_PTN_HDR_SIZE 1
588*4882a593Smuzhiyun #define INDEX_TBL_ENTR_SIZE 1
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun #define RESOURCE_PTN_VERSION 0
591*4882a593Smuzhiyun #define INDEX_TBL_VERSION 0
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun #define RESOURCE_PTN_HDR_MAGIC "RSCE"
594*4882a593Smuzhiyun typedef struct {
595*4882a593Smuzhiyun char magic[4]; /* tag, "RSCE" */
596*4882a593Smuzhiyun uint16_t resource_ptn_version;
597*4882a593Smuzhiyun uint16_t index_tbl_version;
598*4882a593Smuzhiyun uint8_t header_size; /* blocks, size of ptn header. */
599*4882a593Smuzhiyun uint8_t tbl_offset; /* blocks, offset of index table. */
600*4882a593Smuzhiyun uint8_t tbl_entry_size; /* blocks, size of index table's entry. */
601*4882a593Smuzhiyun uint32_t tbl_entry_num; /* numbers of index table's entry. */
602*4882a593Smuzhiyun } resource_ptn_header;
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun #define INDEX_TBL_ENTR_TAG "ENTR"
605*4882a593Smuzhiyun #define MAX_INDEX_ENTRY_PATH_LEN 220
606*4882a593Smuzhiyun #define MAX_HASH_LEN 32
607*4882a593Smuzhiyun
608*4882a593Smuzhiyun typedef struct {
609*4882a593Smuzhiyun char tag[4]; /* tag, "ENTR" */
610*4882a593Smuzhiyun char path[MAX_INDEX_ENTRY_PATH_LEN];
611*4882a593Smuzhiyun char hash[MAX_HASH_LEN]; /* hash data */
612*4882a593Smuzhiyun uint32_t hash_size; /* 20 or 32 */
613*4882a593Smuzhiyun uint32_t content_offset; /* blocks, offset of resource content. */
614*4882a593Smuzhiyun uint32_t content_size; /* bytes, size of resource content. */
615*4882a593Smuzhiyun } index_tbl_entry;
616*4882a593Smuzhiyun
617*4882a593Smuzhiyun #define OPT_VERBOSE "--verbose"
618*4882a593Smuzhiyun #define OPT_HELP "--help"
619*4882a593Smuzhiyun #define OPT_VERSION "--version"
620*4882a593Smuzhiyun #define OPT_PRINT "--print"
621*4882a593Smuzhiyun #define OPT_PACK "--pack"
622*4882a593Smuzhiyun #define OPT_UNPACK "--unpack"
623*4882a593Smuzhiyun #define OPT_TEST_LOAD "--test_load"
624*4882a593Smuzhiyun #define OPT_TEST_CHARGE "--test_charge"
625*4882a593Smuzhiyun #define OPT_IMAGE "--image="
626*4882a593Smuzhiyun #define OPT_ROOT "--root="
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun #define VERSION "2014-5-31 14:43:42"
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun typedef struct {
631*4882a593Smuzhiyun char path[MAX_INDEX_ENTRY_PATH_LEN];
632*4882a593Smuzhiyun uint32_t content_offset; /* blocks, offset of resource content. */
633*4882a593Smuzhiyun uint32_t content_size; /* bytes, size of resource content. */
634*4882a593Smuzhiyun void *load_addr;
635*4882a593Smuzhiyun } resource_content;
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun typedef struct {
638*4882a593Smuzhiyun int max_level;
639*4882a593Smuzhiyun int num;
640*4882a593Smuzhiyun int delay;
641*4882a593Smuzhiyun char prefix[MAX_INDEX_ENTRY_PATH_LEN];
642*4882a593Smuzhiyun } anim_level_conf;
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun #define DEF_CHARGE_DESC_PATH "charge_anim_desc.txt"
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun #define OPT_CHARGE_ANIM_DELAY "delay="
647*4882a593Smuzhiyun #define OPT_CHARGE_ANIM_LOOP_CUR "only_current_level="
648*4882a593Smuzhiyun #define OPT_CHARGE_ANIM_LEVELS "levels="
649*4882a593Smuzhiyun #define OPT_CHARGE_ANIM_LEVEL_CONF "max_level="
650*4882a593Smuzhiyun #define OPT_CHARGE_ANIM_LEVEL_NUM "num="
651*4882a593Smuzhiyun #define OPT_CHARGE_ANIM_LEVEL_PFX "prefix="
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun static char image_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";
654*4882a593Smuzhiyun
fix_blocks(size_t size)655*4882a593Smuzhiyun static int fix_blocks(size_t size)
656*4882a593Smuzhiyun {
657*4882a593Smuzhiyun return (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun
fix_path(const char * path)660*4882a593Smuzhiyun static const char *fix_path(const char *path)
661*4882a593Smuzhiyun {
662*4882a593Smuzhiyun if (!memcmp(path, "./", 2)) {
663*4882a593Smuzhiyun return path + 2;
664*4882a593Smuzhiyun }
665*4882a593Smuzhiyun return path;
666*4882a593Smuzhiyun }
667*4882a593Smuzhiyun
switch_short(uint16_t x)668*4882a593Smuzhiyun static uint16_t switch_short(uint16_t x)
669*4882a593Smuzhiyun {
670*4882a593Smuzhiyun uint16_t val;
671*4882a593Smuzhiyun uint8_t *p = (uint8_t *)(&x);
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun val = (*p++ & 0xff) << 0;
674*4882a593Smuzhiyun val |= (*p & 0xff) << 8;
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun return val;
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun
switch_int(uint32_t x)679*4882a593Smuzhiyun static uint32_t switch_int(uint32_t x)
680*4882a593Smuzhiyun {
681*4882a593Smuzhiyun uint32_t val;
682*4882a593Smuzhiyun uint8_t *p = (uint8_t *)(&x);
683*4882a593Smuzhiyun
684*4882a593Smuzhiyun val = (*p++ & 0xff) << 0;
685*4882a593Smuzhiyun val |= (*p++ & 0xff) << 8;
686*4882a593Smuzhiyun val |= (*p++ & 0xff) << 16;
687*4882a593Smuzhiyun val |= (*p & 0xff) << 24;
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun return val;
690*4882a593Smuzhiyun }
691*4882a593Smuzhiyun
fix_header(resource_ptn_header * header)692*4882a593Smuzhiyun static void fix_header(resource_ptn_header *header)
693*4882a593Smuzhiyun {
694*4882a593Smuzhiyun /* switch for be. */
695*4882a593Smuzhiyun header->resource_ptn_version = switch_short(header->resource_ptn_version);
696*4882a593Smuzhiyun header->index_tbl_version = switch_short(header->index_tbl_version);
697*4882a593Smuzhiyun header->tbl_entry_num = switch_int(header->tbl_entry_num);
698*4882a593Smuzhiyun }
699*4882a593Smuzhiyun
fix_entry(index_tbl_entry * entry)700*4882a593Smuzhiyun static void fix_entry(index_tbl_entry *entry)
701*4882a593Smuzhiyun {
702*4882a593Smuzhiyun /* switch for be. */
703*4882a593Smuzhiyun entry->content_offset = switch_int(entry->content_offset);
704*4882a593Smuzhiyun entry->content_size = switch_int(entry->content_size);
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun
get_ptn_offset(void)707*4882a593Smuzhiyun static int inline get_ptn_offset(void)
708*4882a593Smuzhiyun {
709*4882a593Smuzhiyun return 0;
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun
StorageWriteLba(int offset_block,void * data,int blocks)712*4882a593Smuzhiyun static bool StorageWriteLba(int offset_block, void *data, int blocks)
713*4882a593Smuzhiyun {
714*4882a593Smuzhiyun bool ret = false;
715*4882a593Smuzhiyun FILE *file = fopen(image_path, "rb+");
716*4882a593Smuzhiyun if (!file)
717*4882a593Smuzhiyun goto end;
718*4882a593Smuzhiyun int offset = offset_block * BLOCK_SIZE;
719*4882a593Smuzhiyun fseek(file, offset, SEEK_SET);
720*4882a593Smuzhiyun if (offset != ftell(file)) {
721*4882a593Smuzhiyun LOGE("Failed to seek %s to %d!", image_path, offset);
722*4882a593Smuzhiyun goto end;
723*4882a593Smuzhiyun }
724*4882a593Smuzhiyun if (!fwrite(data, blocks * BLOCK_SIZE, 1, file)) {
725*4882a593Smuzhiyun LOGE("Failed to write %s!", image_path);
726*4882a593Smuzhiyun goto end;
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun ret = true;
729*4882a593Smuzhiyun end:
730*4882a593Smuzhiyun if (file)
731*4882a593Smuzhiyun fclose(file);
732*4882a593Smuzhiyun return ret;
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun
StorageReadLba(int offset_block,void * data,int blocks)735*4882a593Smuzhiyun static bool StorageReadLba(int offset_block, void *data, int blocks)
736*4882a593Smuzhiyun {
737*4882a593Smuzhiyun bool ret = false;
738*4882a593Smuzhiyun FILE *file = fopen(image_path, "rb");
739*4882a593Smuzhiyun if (!file)
740*4882a593Smuzhiyun goto end;
741*4882a593Smuzhiyun int offset = offset_block * BLOCK_SIZE;
742*4882a593Smuzhiyun fseek(file, offset, SEEK_SET);
743*4882a593Smuzhiyun if (offset != ftell(file)) {
744*4882a593Smuzhiyun goto end;
745*4882a593Smuzhiyun }
746*4882a593Smuzhiyun if (!fread(data, blocks * BLOCK_SIZE, 1, file)) {
747*4882a593Smuzhiyun goto end;
748*4882a593Smuzhiyun }
749*4882a593Smuzhiyun ret = true;
750*4882a593Smuzhiyun end:
751*4882a593Smuzhiyun if (file)
752*4882a593Smuzhiyun fclose(file);
753*4882a593Smuzhiyun return ret;
754*4882a593Smuzhiyun }
755*4882a593Smuzhiyun
write_data(int offset_block,void * data,size_t len)756*4882a593Smuzhiyun static bool write_data(int offset_block, void *data, size_t len)
757*4882a593Smuzhiyun {
758*4882a593Smuzhiyun bool ret = false;
759*4882a593Smuzhiyun if (!data)
760*4882a593Smuzhiyun goto end;
761*4882a593Smuzhiyun int blocks = len / BLOCK_SIZE;
762*4882a593Smuzhiyun if (blocks && !StorageWriteLba(offset_block, data, blocks)) {
763*4882a593Smuzhiyun goto end;
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun int left = len % BLOCK_SIZE;
766*4882a593Smuzhiyun if (left) {
767*4882a593Smuzhiyun char buf[BLOCK_SIZE] = "\0";
768*4882a593Smuzhiyun memcpy(buf, data + blocks * BLOCK_SIZE, left);
769*4882a593Smuzhiyun if (!StorageWriteLba(offset_block + blocks, buf, 1))
770*4882a593Smuzhiyun goto end;
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun ret = true;
773*4882a593Smuzhiyun end:
774*4882a593Smuzhiyun return ret;
775*4882a593Smuzhiyun }
776*4882a593Smuzhiyun
777*4882a593Smuzhiyun /**********************load test************************/
778*4882a593Smuzhiyun static int load_file(const char *file_path, int offset_block, int blocks);
779*4882a593Smuzhiyun
test_load(int argc,char ** argv)780*4882a593Smuzhiyun static int test_load(int argc, char **argv)
781*4882a593Smuzhiyun {
782*4882a593Smuzhiyun if (argc < 1) {
783*4882a593Smuzhiyun LOGE("Nothing to load!");
784*4882a593Smuzhiyun return -1;
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun const char *file_path;
787*4882a593Smuzhiyun int offset_block = 0;
788*4882a593Smuzhiyun int blocks = 0;
789*4882a593Smuzhiyun if (argc > 0) {
790*4882a593Smuzhiyun file_path = (const char *)fix_path(argv[0]);
791*4882a593Smuzhiyun argc--, argv++;
792*4882a593Smuzhiyun }
793*4882a593Smuzhiyun if (argc > 0) {
794*4882a593Smuzhiyun offset_block = atoi(argv[0]);
795*4882a593Smuzhiyun argc--, argv++;
796*4882a593Smuzhiyun }
797*4882a593Smuzhiyun if (argc > 0) {
798*4882a593Smuzhiyun blocks = atoi(argv[0]);
799*4882a593Smuzhiyun }
800*4882a593Smuzhiyun return load_file(file_path, offset_block, blocks);
801*4882a593Smuzhiyun }
802*4882a593Smuzhiyun
free_content(resource_content * content)803*4882a593Smuzhiyun static void free_content(resource_content *content)
804*4882a593Smuzhiyun {
805*4882a593Smuzhiyun if (content->load_addr) {
806*4882a593Smuzhiyun free(content->load_addr);
807*4882a593Smuzhiyun content->load_addr = 0;
808*4882a593Smuzhiyun }
809*4882a593Smuzhiyun }
810*4882a593Smuzhiyun
tests_dump_file(const char * path,void * data,int len)811*4882a593Smuzhiyun static void tests_dump_file(const char *path, void *data, int len)
812*4882a593Smuzhiyun {
813*4882a593Smuzhiyun FILE *file = fopen(path, "wb");
814*4882a593Smuzhiyun if (!file)
815*4882a593Smuzhiyun return;
816*4882a593Smuzhiyun fwrite(data, len, 1, file);
817*4882a593Smuzhiyun fclose(file);
818*4882a593Smuzhiyun }
819*4882a593Smuzhiyun
load_content(resource_content * content)820*4882a593Smuzhiyun static bool load_content(resource_content *content)
821*4882a593Smuzhiyun {
822*4882a593Smuzhiyun if (content->load_addr)
823*4882a593Smuzhiyun return true;
824*4882a593Smuzhiyun int blocks = fix_blocks(content->content_size);
825*4882a593Smuzhiyun content->load_addr = malloc(blocks * BLOCK_SIZE);
826*4882a593Smuzhiyun if (!content->load_addr)
827*4882a593Smuzhiyun return false;
828*4882a593Smuzhiyun if (!StorageReadLba(get_ptn_offset() + content->content_offset,
829*4882a593Smuzhiyun content->load_addr, blocks)) {
830*4882a593Smuzhiyun free_content(content);
831*4882a593Smuzhiyun return false;
832*4882a593Smuzhiyun }
833*4882a593Smuzhiyun
834*4882a593Smuzhiyun tests_dump_file(content->path, content->load_addr, content->content_size);
835*4882a593Smuzhiyun return true;
836*4882a593Smuzhiyun }
837*4882a593Smuzhiyun
load_content_data(resource_content * content,int offset_block,void * data,int blocks)838*4882a593Smuzhiyun static bool load_content_data(resource_content *content, int offset_block,
839*4882a593Smuzhiyun void *data, int blocks)
840*4882a593Smuzhiyun {
841*4882a593Smuzhiyun if (!StorageReadLba(get_ptn_offset() + content->content_offset + offset_block,
842*4882a593Smuzhiyun data, blocks)) {
843*4882a593Smuzhiyun return false;
844*4882a593Smuzhiyun }
845*4882a593Smuzhiyun tests_dump_file(content->path, data, blocks * BLOCK_SIZE);
846*4882a593Smuzhiyun return true;
847*4882a593Smuzhiyun }
848*4882a593Smuzhiyun
get_entry(const char * file_path,index_tbl_entry * entry)849*4882a593Smuzhiyun static bool get_entry(const char *file_path, index_tbl_entry *entry)
850*4882a593Smuzhiyun {
851*4882a593Smuzhiyun bool ret = false;
852*4882a593Smuzhiyun char buf[BLOCK_SIZE];
853*4882a593Smuzhiyun resource_ptn_header header;
854*4882a593Smuzhiyun if (!StorageReadLba(get_ptn_offset(), buf, 1)) {
855*4882a593Smuzhiyun LOGE("Failed to read header!");
856*4882a593Smuzhiyun goto end;
857*4882a593Smuzhiyun }
858*4882a593Smuzhiyun memcpy(&header, buf, sizeof(header));
859*4882a593Smuzhiyun
860*4882a593Smuzhiyun if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {
861*4882a593Smuzhiyun LOGE("Not a resource image(%s)!", image_path);
862*4882a593Smuzhiyun goto end;
863*4882a593Smuzhiyun }
864*4882a593Smuzhiyun /* test on pc, switch for be. */
865*4882a593Smuzhiyun fix_header(&header);
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun /* TODO: support header_size & tbl_entry_size */
868*4882a593Smuzhiyun if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||
869*4882a593Smuzhiyun header.header_size != RESOURCE_PTN_HDR_SIZE ||
870*4882a593Smuzhiyun header.index_tbl_version != INDEX_TBL_VERSION ||
871*4882a593Smuzhiyun header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {
872*4882a593Smuzhiyun LOGE("Not supported in this version!");
873*4882a593Smuzhiyun goto end;
874*4882a593Smuzhiyun }
875*4882a593Smuzhiyun
876*4882a593Smuzhiyun int i;
877*4882a593Smuzhiyun for (i = 0; i < header.tbl_entry_num; i++) {
878*4882a593Smuzhiyun /* TODO: support tbl_entry_size */
879*4882a593Smuzhiyun if (!StorageReadLba(
880*4882a593Smuzhiyun get_ptn_offset() + header.header_size + i * header.tbl_entry_size,
881*4882a593Smuzhiyun buf, 1)) {
882*4882a593Smuzhiyun LOGE("Failed to read index entry:%d!", i);
883*4882a593Smuzhiyun goto end;
884*4882a593Smuzhiyun }
885*4882a593Smuzhiyun memcpy(entry, buf, sizeof(*entry));
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun if (memcmp(entry->tag, INDEX_TBL_ENTR_TAG, sizeof(entry->tag))) {
888*4882a593Smuzhiyun LOGE("Something wrong with index entry:%d!", i);
889*4882a593Smuzhiyun goto end;
890*4882a593Smuzhiyun }
891*4882a593Smuzhiyun
892*4882a593Smuzhiyun if (!strncmp(entry->path, file_path, sizeof(entry->path)))
893*4882a593Smuzhiyun break;
894*4882a593Smuzhiyun }
895*4882a593Smuzhiyun if (i == header.tbl_entry_num) {
896*4882a593Smuzhiyun LOGE("Cannot find %s!", file_path);
897*4882a593Smuzhiyun goto end;
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun /* test on pc, switch for be. */
900*4882a593Smuzhiyun fix_entry(entry);
901*4882a593Smuzhiyun
902*4882a593Smuzhiyun printf("Found entry:\n\tpath:%s\n\toffset:%d\tsize:%d\n", entry->path,
903*4882a593Smuzhiyun entry->content_offset, entry->content_size);
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun ret = true;
906*4882a593Smuzhiyun end:
907*4882a593Smuzhiyun return ret;
908*4882a593Smuzhiyun }
909*4882a593Smuzhiyun
get_content(resource_content * content)910*4882a593Smuzhiyun static bool get_content(resource_content *content)
911*4882a593Smuzhiyun {
912*4882a593Smuzhiyun bool ret = false;
913*4882a593Smuzhiyun index_tbl_entry entry;
914*4882a593Smuzhiyun if (!get_entry(content->path, &entry))
915*4882a593Smuzhiyun goto end;
916*4882a593Smuzhiyun content->content_offset = entry.content_offset;
917*4882a593Smuzhiyun content->content_size = entry.content_size;
918*4882a593Smuzhiyun ret = true;
919*4882a593Smuzhiyun end:
920*4882a593Smuzhiyun return ret;
921*4882a593Smuzhiyun }
922*4882a593Smuzhiyun
load_file(const char * file_path,int offset_block,int blocks)923*4882a593Smuzhiyun static int load_file(const char *file_path, int offset_block, int blocks)
924*4882a593Smuzhiyun {
925*4882a593Smuzhiyun printf("Try to load:%s", file_path);
926*4882a593Smuzhiyun if (blocks) {
927*4882a593Smuzhiyun printf(", offset block:%d, blocks:%d\n", offset_block, blocks);
928*4882a593Smuzhiyun } else {
929*4882a593Smuzhiyun printf("\n");
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun bool ret = false;
932*4882a593Smuzhiyun resource_content content;
933*4882a593Smuzhiyun snprintf(content.path, sizeof(content.path), "%s", file_path);
934*4882a593Smuzhiyun content.load_addr = 0;
935*4882a593Smuzhiyun if (!get_content(&content)) {
936*4882a593Smuzhiyun goto end;
937*4882a593Smuzhiyun }
938*4882a593Smuzhiyun if (!blocks) {
939*4882a593Smuzhiyun if (!load_content(&content)) {
940*4882a593Smuzhiyun goto end;
941*4882a593Smuzhiyun }
942*4882a593Smuzhiyun } else {
943*4882a593Smuzhiyun void *data = malloc(blocks * BLOCK_SIZE);
944*4882a593Smuzhiyun if (!data)
945*4882a593Smuzhiyun goto end;
946*4882a593Smuzhiyun if (!load_content_data(&content, offset_block, data, blocks)) {
947*4882a593Smuzhiyun goto end;
948*4882a593Smuzhiyun }
949*4882a593Smuzhiyun }
950*4882a593Smuzhiyun ret = true;
951*4882a593Smuzhiyun end:
952*4882a593Smuzhiyun free_content(&content);
953*4882a593Smuzhiyun return ret;
954*4882a593Smuzhiyun }
955*4882a593Smuzhiyun
956*4882a593Smuzhiyun /**********************load test end************************/
957*4882a593Smuzhiyun /**********************anim test************************/
958*4882a593Smuzhiyun
parse_level_conf(const char * arg,anim_level_conf * level_conf)959*4882a593Smuzhiyun static bool parse_level_conf(const char *arg, anim_level_conf *level_conf)
960*4882a593Smuzhiyun {
961*4882a593Smuzhiyun memset(level_conf, 0, sizeof(anim_level_conf));
962*4882a593Smuzhiyun char *buf = NULL;
963*4882a593Smuzhiyun buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_CONF);
964*4882a593Smuzhiyun if (buf) {
965*4882a593Smuzhiyun level_conf->max_level = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_CONF));
966*4882a593Smuzhiyun } else {
967*4882a593Smuzhiyun LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_CONF);
968*4882a593Smuzhiyun return false;
969*4882a593Smuzhiyun }
970*4882a593Smuzhiyun buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_NUM);
971*4882a593Smuzhiyun if (buf) {
972*4882a593Smuzhiyun level_conf->num = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_NUM));
973*4882a593Smuzhiyun if (level_conf->num <= 0) {
974*4882a593Smuzhiyun return false;
975*4882a593Smuzhiyun }
976*4882a593Smuzhiyun } else {
977*4882a593Smuzhiyun LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_NUM);
978*4882a593Smuzhiyun return false;
979*4882a593Smuzhiyun }
980*4882a593Smuzhiyun buf = strstr(arg, OPT_CHARGE_ANIM_DELAY);
981*4882a593Smuzhiyun if (buf) {
982*4882a593Smuzhiyun level_conf->delay = atoi(buf + strlen(OPT_CHARGE_ANIM_DELAY));
983*4882a593Smuzhiyun }
984*4882a593Smuzhiyun buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_PFX);
985*4882a593Smuzhiyun if (buf) {
986*4882a593Smuzhiyun snprintf(level_conf->prefix, sizeof(level_conf->prefix), "%s",
987*4882a593Smuzhiyun buf + strlen(OPT_CHARGE_ANIM_LEVEL_PFX));
988*4882a593Smuzhiyun } else {
989*4882a593Smuzhiyun LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_PFX);
990*4882a593Smuzhiyun return false;
991*4882a593Smuzhiyun }
992*4882a593Smuzhiyun
993*4882a593Smuzhiyun LOGD("Found conf:\nmax_level:%d, num:%d, delay:%d, prefix:%s",
994*4882a593Smuzhiyun level_conf->max_level, level_conf->num, level_conf->delay,
995*4882a593Smuzhiyun level_conf->prefix);
996*4882a593Smuzhiyun return true;
997*4882a593Smuzhiyun }
998*4882a593Smuzhiyun
test_charge(int argc,char ** argv)999*4882a593Smuzhiyun static int test_charge(int argc, char **argv)
1000*4882a593Smuzhiyun {
1001*4882a593Smuzhiyun const char *desc;
1002*4882a593Smuzhiyun if (argc > 0) {
1003*4882a593Smuzhiyun desc = argv[0];
1004*4882a593Smuzhiyun } else {
1005*4882a593Smuzhiyun desc = DEF_CHARGE_DESC_PATH;
1006*4882a593Smuzhiyun }
1007*4882a593Smuzhiyun
1008*4882a593Smuzhiyun resource_content content;
1009*4882a593Smuzhiyun snprintf(content.path, sizeof(content.path), "%s", desc);
1010*4882a593Smuzhiyun content.load_addr = 0;
1011*4882a593Smuzhiyun if (!get_content(&content)) {
1012*4882a593Smuzhiyun goto end;
1013*4882a593Smuzhiyun }
1014*4882a593Smuzhiyun if (!load_content(&content)) {
1015*4882a593Smuzhiyun goto end;
1016*4882a593Smuzhiyun }
1017*4882a593Smuzhiyun
1018*4882a593Smuzhiyun char *buf = (char *)content.load_addr;
1019*4882a593Smuzhiyun char *end = buf + content.content_size - 1;
1020*4882a593Smuzhiyun *end = '\0';
1021*4882a593Smuzhiyun LOGD("desc:\n%s", buf);
1022*4882a593Smuzhiyun
1023*4882a593Smuzhiyun int pos = 0;
1024*4882a593Smuzhiyun while (1) {
1025*4882a593Smuzhiyun char *line = (char *)memchr(buf + pos, '\n', strlen(buf + pos));
1026*4882a593Smuzhiyun if (!line)
1027*4882a593Smuzhiyun break;
1028*4882a593Smuzhiyun *line = '\0';
1029*4882a593Smuzhiyun LOGD("splite:%s", buf + pos);
1030*4882a593Smuzhiyun pos += (strlen(buf + pos) + 1);
1031*4882a593Smuzhiyun }
1032*4882a593Smuzhiyun
1033*4882a593Smuzhiyun int delay = 900;
1034*4882a593Smuzhiyun int only_current_level = false;
1035*4882a593Smuzhiyun anim_level_conf *level_confs = NULL;
1036*4882a593Smuzhiyun int level_conf_pos = 0;
1037*4882a593Smuzhiyun int level_conf_num = 0;
1038*4882a593Smuzhiyun
1039*4882a593Smuzhiyun while (true) {
1040*4882a593Smuzhiyun if (buf >= end)
1041*4882a593Smuzhiyun break;
1042*4882a593Smuzhiyun const char *arg = buf;
1043*4882a593Smuzhiyun buf += (strlen(buf) + 1);
1044*4882a593Smuzhiyun
1045*4882a593Smuzhiyun LOGD("parse arg:%s", arg);
1046*4882a593Smuzhiyun if (!memcmp(arg, OPT_CHARGE_ANIM_LEVEL_CONF,
1047*4882a593Smuzhiyun strlen(OPT_CHARGE_ANIM_LEVEL_CONF))) {
1048*4882a593Smuzhiyun if (!level_confs) {
1049*4882a593Smuzhiyun LOGE("Found level conf before levels!");
1050*4882a593Smuzhiyun goto end;
1051*4882a593Smuzhiyun }
1052*4882a593Smuzhiyun if (level_conf_pos >= level_conf_num) {
1053*4882a593Smuzhiyun LOGE("Too many level confs!(%d >= %d)", level_conf_pos, level_conf_num);
1054*4882a593Smuzhiyun goto end;
1055*4882a593Smuzhiyun }
1056*4882a593Smuzhiyun if (!parse_level_conf(arg, level_confs + level_conf_pos)) {
1057*4882a593Smuzhiyun LOGE("Failed to parse level conf:%s", arg);
1058*4882a593Smuzhiyun goto end;
1059*4882a593Smuzhiyun }
1060*4882a593Smuzhiyun level_conf_pos++;
1061*4882a593Smuzhiyun } else if (!memcmp(arg, OPT_CHARGE_ANIM_DELAY,
1062*4882a593Smuzhiyun strlen(OPT_CHARGE_ANIM_DELAY))) {
1063*4882a593Smuzhiyun delay = atoi(arg + strlen(OPT_CHARGE_ANIM_DELAY));
1064*4882a593Smuzhiyun LOGD("Found delay:%d", delay);
1065*4882a593Smuzhiyun } else if (!memcmp(arg, OPT_CHARGE_ANIM_LOOP_CUR,
1066*4882a593Smuzhiyun strlen(OPT_CHARGE_ANIM_LOOP_CUR))) {
1067*4882a593Smuzhiyun only_current_level =
1068*4882a593Smuzhiyun !memcmp(arg + strlen(OPT_CHARGE_ANIM_LOOP_CUR), "true", 4);
1069*4882a593Smuzhiyun LOGD("Found only_current_level:%d", only_current_level);
1070*4882a593Smuzhiyun } else if (!memcmp(arg, OPT_CHARGE_ANIM_LEVELS,
1071*4882a593Smuzhiyun strlen(OPT_CHARGE_ANIM_LEVELS))) {
1072*4882a593Smuzhiyun if (level_conf_num) {
1073*4882a593Smuzhiyun goto end;
1074*4882a593Smuzhiyun }
1075*4882a593Smuzhiyun level_conf_num = atoi(arg + strlen(OPT_CHARGE_ANIM_LEVELS));
1076*4882a593Smuzhiyun if (!level_conf_num) {
1077*4882a593Smuzhiyun goto end;
1078*4882a593Smuzhiyun }
1079*4882a593Smuzhiyun level_confs =
1080*4882a593Smuzhiyun (anim_level_conf *)malloc(level_conf_num * sizeof(anim_level_conf));
1081*4882a593Smuzhiyun LOGD("Found levels:%d", level_conf_num);
1082*4882a593Smuzhiyun } else {
1083*4882a593Smuzhiyun LOGE("Unknown arg:%s", arg);
1084*4882a593Smuzhiyun goto end;
1085*4882a593Smuzhiyun }
1086*4882a593Smuzhiyun }
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun if (level_conf_pos != level_conf_num || !level_conf_num) {
1089*4882a593Smuzhiyun LOGE("Something wrong with level confs!");
1090*4882a593Smuzhiyun goto end;
1091*4882a593Smuzhiyun }
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun int i = 0, j = 0;
1094*4882a593Smuzhiyun for (i = 0; i < level_conf_num; i++) {
1095*4882a593Smuzhiyun if (!level_confs[i].delay) {
1096*4882a593Smuzhiyun level_confs[i].delay = delay;
1097*4882a593Smuzhiyun }
1098*4882a593Smuzhiyun if (!level_confs[i].delay) {
1099*4882a593Smuzhiyun LOGE("Missing delay in level conf:%d", i);
1100*4882a593Smuzhiyun goto end;
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun for (j = 0; j < i; j++) {
1103*4882a593Smuzhiyun if (level_confs[j].max_level == level_confs[i].max_level) {
1104*4882a593Smuzhiyun LOGE("Dup level conf:%d", i);
1105*4882a593Smuzhiyun goto end;
1106*4882a593Smuzhiyun }
1107*4882a593Smuzhiyun if (level_confs[j].max_level > level_confs[i].max_level) {
1108*4882a593Smuzhiyun anim_level_conf conf = level_confs[i];
1109*4882a593Smuzhiyun memmove(level_confs + j + 1, level_confs + j,
1110*4882a593Smuzhiyun (i - j) * sizeof(anim_level_conf));
1111*4882a593Smuzhiyun level_confs[j] = conf;
1112*4882a593Smuzhiyun }
1113*4882a593Smuzhiyun }
1114*4882a593Smuzhiyun }
1115*4882a593Smuzhiyun
1116*4882a593Smuzhiyun printf("Parse anim desc(%s):\n", desc);
1117*4882a593Smuzhiyun printf("only_current_level=%d\n", only_current_level);
1118*4882a593Smuzhiyun printf("level conf:\n");
1119*4882a593Smuzhiyun for (i = 0; i < level_conf_num; i++) {
1120*4882a593Smuzhiyun printf("\tmax=%d, delay=%d, num=%d, prefix=%s\n", level_confs[i].max_level,
1121*4882a593Smuzhiyun level_confs[i].delay, level_confs[i].num, level_confs[i].prefix);
1122*4882a593Smuzhiyun }
1123*4882a593Smuzhiyun
1124*4882a593Smuzhiyun end:
1125*4882a593Smuzhiyun free_content(&content);
1126*4882a593Smuzhiyun return 0;
1127*4882a593Smuzhiyun }
1128*4882a593Smuzhiyun
1129*4882a593Smuzhiyun /**********************anim test end************************/
1130*4882a593Smuzhiyun /**********************append file************************/
1131*4882a593Smuzhiyun
1132*4882a593Smuzhiyun static const char *PROG = NULL;
1133*4882a593Smuzhiyun static resource_ptn_header header;
1134*4882a593Smuzhiyun static bool just_print = false;
1135*4882a593Smuzhiyun static char root_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";
1136*4882a593Smuzhiyun
version(void)1137*4882a593Smuzhiyun static void version(void)
1138*4882a593Smuzhiyun {
1139*4882a593Smuzhiyun printf("%s (cjf@rock-chips.com)\t" VERSION "\n", PROG);
1140*4882a593Smuzhiyun }
1141*4882a593Smuzhiyun
usage(void)1142*4882a593Smuzhiyun static void usage(void)
1143*4882a593Smuzhiyun {
1144*4882a593Smuzhiyun printf("Usage: %s [options] [FILES]\n", PROG);
1145*4882a593Smuzhiyun printf("Tools for Rockchip's resource image.\n");
1146*4882a593Smuzhiyun version();
1147*4882a593Smuzhiyun printf("Options:\n");
1148*4882a593Smuzhiyun printf("\t" OPT_PACK "\t\t\tPack image from given files.\n");
1149*4882a593Smuzhiyun printf("\t" OPT_UNPACK "\t\tUnpack given image to current dir.\n");
1150*4882a593Smuzhiyun printf("\t" OPT_IMAGE "path"
1151*4882a593Smuzhiyun "\t\tSpecify input/output image path.\n");
1152*4882a593Smuzhiyun printf("\t" OPT_PRINT "\t\t\tJust print informations.\n");
1153*4882a593Smuzhiyun printf("\t" OPT_VERBOSE "\t\tDisplay more runtime informations.\n");
1154*4882a593Smuzhiyun printf("\t" OPT_HELP "\t\t\tDisplay this information.\n");
1155*4882a593Smuzhiyun printf("\t" OPT_VERSION "\t\tDisplay version information.\n");
1156*4882a593Smuzhiyun printf("\t" OPT_ROOT "path"
1157*4882a593Smuzhiyun "\t\tSpecify resources' root dir.\n");
1158*4882a593Smuzhiyun }
1159*4882a593Smuzhiyun
1160*4882a593Smuzhiyun static int pack_image(int file_num, const char **files);
1161*4882a593Smuzhiyun static int unpack_image(const char *unpack_dir);
1162*4882a593Smuzhiyun
1163*4882a593Smuzhiyun enum ACTION {
1164*4882a593Smuzhiyun ACTION_PACK,
1165*4882a593Smuzhiyun ACTION_UNPACK,
1166*4882a593Smuzhiyun ACTION_TEST_LOAD,
1167*4882a593Smuzhiyun ACTION_TEST_CHARGE,
1168*4882a593Smuzhiyun };
1169*4882a593Smuzhiyun
main(int argc,char ** argv)1170*4882a593Smuzhiyun int main(int argc, char **argv)
1171*4882a593Smuzhiyun {
1172*4882a593Smuzhiyun PROG = fix_path(argv[0]);
1173*4882a593Smuzhiyun
1174*4882a593Smuzhiyun enum ACTION action = ACTION_PACK;
1175*4882a593Smuzhiyun
1176*4882a593Smuzhiyun argc--, argv++;
1177*4882a593Smuzhiyun while (argc > 0 && argv[0][0] == '-') {
1178*4882a593Smuzhiyun /* it's a opt arg. */
1179*4882a593Smuzhiyun const char *arg = argv[0];
1180*4882a593Smuzhiyun argc--, argv++;
1181*4882a593Smuzhiyun if (!strcmp(OPT_VERBOSE, arg)) {
1182*4882a593Smuzhiyun g_debug = true;
1183*4882a593Smuzhiyun } else if (!strcmp(OPT_HELP, arg)) {
1184*4882a593Smuzhiyun usage();
1185*4882a593Smuzhiyun return 0;
1186*4882a593Smuzhiyun } else if (!strcmp(OPT_VERSION, arg)) {
1187*4882a593Smuzhiyun version();
1188*4882a593Smuzhiyun return 0;
1189*4882a593Smuzhiyun } else if (!strcmp(OPT_PRINT, arg)) {
1190*4882a593Smuzhiyun just_print = true;
1191*4882a593Smuzhiyun } else if (!strcmp(OPT_PACK, arg)) {
1192*4882a593Smuzhiyun action = ACTION_PACK;
1193*4882a593Smuzhiyun } else if (!strcmp(OPT_UNPACK, arg)) {
1194*4882a593Smuzhiyun action = ACTION_UNPACK;
1195*4882a593Smuzhiyun } else if (!strcmp(OPT_TEST_LOAD, arg)) {
1196*4882a593Smuzhiyun action = ACTION_TEST_LOAD;
1197*4882a593Smuzhiyun } else if (!strcmp(OPT_TEST_CHARGE, arg)) {
1198*4882a593Smuzhiyun action = ACTION_TEST_CHARGE;
1199*4882a593Smuzhiyun } else if (!memcmp(OPT_IMAGE, arg, strlen(OPT_IMAGE))) {
1200*4882a593Smuzhiyun snprintf(image_path, sizeof(image_path), "%s", arg + strlen(OPT_IMAGE));
1201*4882a593Smuzhiyun } else if (!memcmp(OPT_ROOT, arg, strlen(OPT_ROOT))) {
1202*4882a593Smuzhiyun snprintf(root_path, sizeof(root_path), "%s", arg + strlen(OPT_ROOT));
1203*4882a593Smuzhiyun } else {
1204*4882a593Smuzhiyun LOGE("Unknown opt:%s", arg);
1205*4882a593Smuzhiyun usage();
1206*4882a593Smuzhiyun return -1;
1207*4882a593Smuzhiyun }
1208*4882a593Smuzhiyun }
1209*4882a593Smuzhiyun
1210*4882a593Smuzhiyun if (!image_path[0]) {
1211*4882a593Smuzhiyun snprintf(image_path, sizeof(image_path), "%s", DEFAULT_IMAGE_PATH);
1212*4882a593Smuzhiyun }
1213*4882a593Smuzhiyun
1214*4882a593Smuzhiyun switch (action) {
1215*4882a593Smuzhiyun case ACTION_PACK: {
1216*4882a593Smuzhiyun int file_num = argc;
1217*4882a593Smuzhiyun const char **files = (const char **)argv;
1218*4882a593Smuzhiyun if (!file_num) {
1219*4882a593Smuzhiyun LOGE("No file to pack!");
1220*4882a593Smuzhiyun return 0;
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun LOGD("try to pack %d files.", file_num);
1223*4882a593Smuzhiyun return pack_image(file_num, files);
1224*4882a593Smuzhiyun }
1225*4882a593Smuzhiyun case ACTION_UNPACK: {
1226*4882a593Smuzhiyun return unpack_image(argc > 0 ? argv[0] : DEFAULT_UNPACK_DIR);
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun case ACTION_TEST_LOAD: {
1229*4882a593Smuzhiyun return test_load(argc, argv);
1230*4882a593Smuzhiyun }
1231*4882a593Smuzhiyun case ACTION_TEST_CHARGE: {
1232*4882a593Smuzhiyun return test_charge(argc, argv);
1233*4882a593Smuzhiyun }
1234*4882a593Smuzhiyun }
1235*4882a593Smuzhiyun /* not reach here. */
1236*4882a593Smuzhiyun return -1;
1237*4882a593Smuzhiyun }
1238*4882a593Smuzhiyun
1239*4882a593Smuzhiyun /************unpack code****************/
mkdirs(char * path)1240*4882a593Smuzhiyun static bool mkdirs(char *path)
1241*4882a593Smuzhiyun {
1242*4882a593Smuzhiyun char *tmp = path;
1243*4882a593Smuzhiyun char *pos = NULL;
1244*4882a593Smuzhiyun char buf[MAX_INDEX_ENTRY_PATH_LEN];
1245*4882a593Smuzhiyun bool ret = true;
1246*4882a593Smuzhiyun while ((pos = memchr(tmp, '/', strlen(tmp)))) {
1247*4882a593Smuzhiyun strcpy(buf, path);
1248*4882a593Smuzhiyun buf[pos - path] = '\0';
1249*4882a593Smuzhiyun tmp = pos + 1;
1250*4882a593Smuzhiyun LOGD("mkdir:%s", buf);
1251*4882a593Smuzhiyun if (!mkdir(buf, 0755)) {
1252*4882a593Smuzhiyun ret = false;
1253*4882a593Smuzhiyun }
1254*4882a593Smuzhiyun }
1255*4882a593Smuzhiyun if (!ret)
1256*4882a593Smuzhiyun LOGD("Failed to mkdir(%s)!", path);
1257*4882a593Smuzhiyun return ret;
1258*4882a593Smuzhiyun }
1259*4882a593Smuzhiyun
dump_file(FILE * file,const char * unpack_dir,index_tbl_entry entry)1260*4882a593Smuzhiyun static bool dump_file(FILE *file, const char *unpack_dir,
1261*4882a593Smuzhiyun index_tbl_entry entry)
1262*4882a593Smuzhiyun {
1263*4882a593Smuzhiyun LOGD("try to dump entry:%s", entry.path);
1264*4882a593Smuzhiyun bool ret = false;
1265*4882a593Smuzhiyun FILE *out_file = NULL;
1266*4882a593Smuzhiyun long int pos = 0;
1267*4882a593Smuzhiyun char path[MAX_INDEX_ENTRY_PATH_LEN * 2 + 1];
1268*4882a593Smuzhiyun if (just_print) {
1269*4882a593Smuzhiyun ret = true;
1270*4882a593Smuzhiyun goto done;
1271*4882a593Smuzhiyun }
1272*4882a593Smuzhiyun
1273*4882a593Smuzhiyun pos = ftell(file);
1274*4882a593Smuzhiyun snprintf(path, sizeof(path), "%s/%s", unpack_dir, entry.path);
1275*4882a593Smuzhiyun mkdirs(path);
1276*4882a593Smuzhiyun out_file = fopen(path, "wb");
1277*4882a593Smuzhiyun if (!out_file) {
1278*4882a593Smuzhiyun LOGE("Failed to create:%s", path);
1279*4882a593Smuzhiyun goto end;
1280*4882a593Smuzhiyun }
1281*4882a593Smuzhiyun long int offset = entry.content_offset * BLOCK_SIZE;
1282*4882a593Smuzhiyun fseek(file, offset, SEEK_SET);
1283*4882a593Smuzhiyun if (offset != ftell(file)) {
1284*4882a593Smuzhiyun LOGE("Failed to read content:%s", entry.path);
1285*4882a593Smuzhiyun goto end;
1286*4882a593Smuzhiyun }
1287*4882a593Smuzhiyun char buf[BLOCK_SIZE];
1288*4882a593Smuzhiyun int n;
1289*4882a593Smuzhiyun int len = entry.content_size;
1290*4882a593Smuzhiyun while (len > 0) {
1291*4882a593Smuzhiyun n = len > BLOCK_SIZE ? BLOCK_SIZE : len;
1292*4882a593Smuzhiyun if (!fread(buf, n, 1, file)) {
1293*4882a593Smuzhiyun LOGE("Failed to read content:%s", entry.path);
1294*4882a593Smuzhiyun goto end;
1295*4882a593Smuzhiyun }
1296*4882a593Smuzhiyun if (!fwrite(buf, n, 1, out_file)) {
1297*4882a593Smuzhiyun LOGE("Failed to write:%s", entry.path);
1298*4882a593Smuzhiyun goto end;
1299*4882a593Smuzhiyun }
1300*4882a593Smuzhiyun len -= n;
1301*4882a593Smuzhiyun }
1302*4882a593Smuzhiyun done:
1303*4882a593Smuzhiyun ret = true;
1304*4882a593Smuzhiyun end:
1305*4882a593Smuzhiyun if (out_file)
1306*4882a593Smuzhiyun fclose(out_file);
1307*4882a593Smuzhiyun if (pos)
1308*4882a593Smuzhiyun fseek(file, pos, SEEK_SET);
1309*4882a593Smuzhiyun return ret;
1310*4882a593Smuzhiyun }
1311*4882a593Smuzhiyun
unpack_image(const char * dir)1312*4882a593Smuzhiyun static int unpack_image(const char *dir)
1313*4882a593Smuzhiyun {
1314*4882a593Smuzhiyun FILE *image_file = NULL;
1315*4882a593Smuzhiyun bool ret = false;
1316*4882a593Smuzhiyun char unpack_dir[MAX_INDEX_ENTRY_PATH_LEN];
1317*4882a593Smuzhiyun if (just_print)
1318*4882a593Smuzhiyun dir = ".";
1319*4882a593Smuzhiyun snprintf(unpack_dir, sizeof(unpack_dir), "%s", dir);
1320*4882a593Smuzhiyun if (!strlen(unpack_dir)) {
1321*4882a593Smuzhiyun goto end;
1322*4882a593Smuzhiyun } else if (unpack_dir[strlen(unpack_dir) - 1] == '/') {
1323*4882a593Smuzhiyun unpack_dir[strlen(unpack_dir) - 1] = '\0';
1324*4882a593Smuzhiyun }
1325*4882a593Smuzhiyun
1326*4882a593Smuzhiyun mkdir(unpack_dir, 0755);
1327*4882a593Smuzhiyun image_file = fopen(image_path, "rb");
1328*4882a593Smuzhiyun char buf[BLOCK_SIZE];
1329*4882a593Smuzhiyun if (!image_file) {
1330*4882a593Smuzhiyun LOGE("Failed to open:%s", image_path);
1331*4882a593Smuzhiyun goto end;
1332*4882a593Smuzhiyun }
1333*4882a593Smuzhiyun if (!fread(buf, BLOCK_SIZE, 1, image_file)) {
1334*4882a593Smuzhiyun LOGE("Failed to read header!");
1335*4882a593Smuzhiyun goto end;
1336*4882a593Smuzhiyun }
1337*4882a593Smuzhiyun memcpy(&header, buf, sizeof(header));
1338*4882a593Smuzhiyun
1339*4882a593Smuzhiyun if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {
1340*4882a593Smuzhiyun LOGE("Not a resource image(%s)!", image_path);
1341*4882a593Smuzhiyun goto end;
1342*4882a593Smuzhiyun }
1343*4882a593Smuzhiyun /* switch for be. */
1344*4882a593Smuzhiyun fix_header(&header);
1345*4882a593Smuzhiyun
1346*4882a593Smuzhiyun printf("Dump header:\n");
1347*4882a593Smuzhiyun printf("partition version:%d.%d\n", header.resource_ptn_version,
1348*4882a593Smuzhiyun header.index_tbl_version);
1349*4882a593Smuzhiyun printf("header size:%d\n", header.header_size);
1350*4882a593Smuzhiyun printf("index tbl:\n\toffset:%d\tentry size:%d\tentry num:%d\n",
1351*4882a593Smuzhiyun header.tbl_offset, header.tbl_entry_size, header.tbl_entry_num);
1352*4882a593Smuzhiyun
1353*4882a593Smuzhiyun /* TODO: support header_size & tbl_entry_size */
1354*4882a593Smuzhiyun if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||
1355*4882a593Smuzhiyun header.header_size != RESOURCE_PTN_HDR_SIZE ||
1356*4882a593Smuzhiyun header.index_tbl_version != INDEX_TBL_VERSION ||
1357*4882a593Smuzhiyun header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {
1358*4882a593Smuzhiyun LOGE("Not supported in this version!");
1359*4882a593Smuzhiyun goto end;
1360*4882a593Smuzhiyun }
1361*4882a593Smuzhiyun
1362*4882a593Smuzhiyun printf("Dump Index table:\n");
1363*4882a593Smuzhiyun index_tbl_entry entry;
1364*4882a593Smuzhiyun int i;
1365*4882a593Smuzhiyun for (i = 0; i < header.tbl_entry_num; i++) {
1366*4882a593Smuzhiyun /* TODO: support tbl_entry_size */
1367*4882a593Smuzhiyun if (!fread(buf, BLOCK_SIZE, 1, image_file)) {
1368*4882a593Smuzhiyun LOGE("Failed to read index entry:%d!", i);
1369*4882a593Smuzhiyun goto end;
1370*4882a593Smuzhiyun }
1371*4882a593Smuzhiyun memcpy(&entry, buf, sizeof(entry));
1372*4882a593Smuzhiyun
1373*4882a593Smuzhiyun if (memcmp(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag))) {
1374*4882a593Smuzhiyun LOGE("Something wrong with index entry:%d!", i);
1375*4882a593Smuzhiyun goto end;
1376*4882a593Smuzhiyun }
1377*4882a593Smuzhiyun /* switch for be. */
1378*4882a593Smuzhiyun fix_entry(&entry);
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun printf("entry(%d):\n\tpath:%s\n\toffset:%d\tsize:%d\n", i, entry.path,
1381*4882a593Smuzhiyun entry.content_offset, entry.content_size);
1382*4882a593Smuzhiyun if (!dump_file(image_file, unpack_dir, entry)) {
1383*4882a593Smuzhiyun goto end;
1384*4882a593Smuzhiyun }
1385*4882a593Smuzhiyun }
1386*4882a593Smuzhiyun printf("Unack %s to %s successed!\n", image_path, unpack_dir);
1387*4882a593Smuzhiyun ret = true;
1388*4882a593Smuzhiyun end:
1389*4882a593Smuzhiyun if (image_file)
1390*4882a593Smuzhiyun fclose(image_file);
1391*4882a593Smuzhiyun return ret ? 0 : -1;
1392*4882a593Smuzhiyun }
1393*4882a593Smuzhiyun
1394*4882a593Smuzhiyun /************unpack code end****************/
1395*4882a593Smuzhiyun /************pack code****************/
1396*4882a593Smuzhiyun
get_file_size(const char * path)1397*4882a593Smuzhiyun static inline size_t get_file_size(const char *path)
1398*4882a593Smuzhiyun {
1399*4882a593Smuzhiyun LOGD("try to get size(%s)...", path);
1400*4882a593Smuzhiyun struct stat st;
1401*4882a593Smuzhiyun if (stat(path, &st) < 0) {
1402*4882a593Smuzhiyun LOGE("Failed to get size:%s", path);
1403*4882a593Smuzhiyun return -1;
1404*4882a593Smuzhiyun }
1405*4882a593Smuzhiyun LOGD("path:%s, size:%ld", path, st.st_size);
1406*4882a593Smuzhiyun return st.st_size;
1407*4882a593Smuzhiyun }
1408*4882a593Smuzhiyun
write_file(int offset_block,const char * src_path,char hash[],int hash_size)1409*4882a593Smuzhiyun static int write_file(int offset_block, const char *src_path,
1410*4882a593Smuzhiyun char hash[], int hash_size)
1411*4882a593Smuzhiyun {
1412*4882a593Smuzhiyun LOGD("try to write file(%s) to offset:%d...", src_path, offset_block);
1413*4882a593Smuzhiyun char *buf = NULL;
1414*4882a593Smuzhiyun int ret = -1;
1415*4882a593Smuzhiyun size_t file_size;
1416*4882a593Smuzhiyun FILE *src_file = fopen(src_path, "rb");
1417*4882a593Smuzhiyun if (!src_file) {
1418*4882a593Smuzhiyun LOGE("Failed to open:%s", src_path);
1419*4882a593Smuzhiyun goto end;
1420*4882a593Smuzhiyun }
1421*4882a593Smuzhiyun
1422*4882a593Smuzhiyun file_size = get_file_size(src_path);
1423*4882a593Smuzhiyun if (file_size < 0) {
1424*4882a593Smuzhiyun goto end;
1425*4882a593Smuzhiyun }
1426*4882a593Smuzhiyun
1427*4882a593Smuzhiyun buf = calloc(file_size, 1);
1428*4882a593Smuzhiyun if (!buf)
1429*4882a593Smuzhiyun goto end;
1430*4882a593Smuzhiyun
1431*4882a593Smuzhiyun if (!fread(buf, file_size, 1, src_file))
1432*4882a593Smuzhiyun goto end;
1433*4882a593Smuzhiyun
1434*4882a593Smuzhiyun if (!write_data(offset_block, buf, file_size))
1435*4882a593Smuzhiyun goto end;
1436*4882a593Smuzhiyun
1437*4882a593Smuzhiyun if (hash_size == 20)
1438*4882a593Smuzhiyun sha1_csum((const unsigned char *)buf, file_size,
1439*4882a593Smuzhiyun (unsigned char *)hash);
1440*4882a593Smuzhiyun else if (hash_size == 32)
1441*4882a593Smuzhiyun sha256_csum((const unsigned char *)buf, file_size,
1442*4882a593Smuzhiyun (unsigned char *)hash);
1443*4882a593Smuzhiyun else
1444*4882a593Smuzhiyun goto end;
1445*4882a593Smuzhiyun
1446*4882a593Smuzhiyun ret = file_size;
1447*4882a593Smuzhiyun end:
1448*4882a593Smuzhiyun if (src_file)
1449*4882a593Smuzhiyun fclose(src_file);
1450*4882a593Smuzhiyun if (buf)
1451*4882a593Smuzhiyun free(buf);
1452*4882a593Smuzhiyun
1453*4882a593Smuzhiyun return ret;
1454*4882a593Smuzhiyun }
1455*4882a593Smuzhiyun
write_header(const int file_num)1456*4882a593Smuzhiyun static bool write_header(const int file_num)
1457*4882a593Smuzhiyun {
1458*4882a593Smuzhiyun LOGD("try to write header...");
1459*4882a593Smuzhiyun memcpy(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic));
1460*4882a593Smuzhiyun header.resource_ptn_version = RESOURCE_PTN_VERSION;
1461*4882a593Smuzhiyun header.index_tbl_version = INDEX_TBL_VERSION;
1462*4882a593Smuzhiyun header.header_size = RESOURCE_PTN_HDR_SIZE;
1463*4882a593Smuzhiyun header.tbl_offset = header.header_size;
1464*4882a593Smuzhiyun header.tbl_entry_size = INDEX_TBL_ENTR_SIZE;
1465*4882a593Smuzhiyun header.tbl_entry_num = file_num;
1466*4882a593Smuzhiyun
1467*4882a593Smuzhiyun /* switch for le. */
1468*4882a593Smuzhiyun resource_ptn_header hdr = header;
1469*4882a593Smuzhiyun fix_header(&hdr);
1470*4882a593Smuzhiyun return write_data(0, &hdr, sizeof(hdr));
1471*4882a593Smuzhiyun }
1472*4882a593Smuzhiyun
write_index_tbl(const int file_num,const char ** files)1473*4882a593Smuzhiyun static bool write_index_tbl(const int file_num, const char **files)
1474*4882a593Smuzhiyun {
1475*4882a593Smuzhiyun LOGD("try to write index table...");
1476*4882a593Smuzhiyun bool ret = false;
1477*4882a593Smuzhiyun bool foundFdt = false;
1478*4882a593Smuzhiyun int offset =
1479*4882a593Smuzhiyun header.header_size + header.tbl_entry_size * header.tbl_entry_num;
1480*4882a593Smuzhiyun index_tbl_entry entry;
1481*4882a593Smuzhiyun char hash[20]; /* sha1 */
1482*4882a593Smuzhiyun int i;
1483*4882a593Smuzhiyun
1484*4882a593Smuzhiyun memcpy(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag));
1485*4882a593Smuzhiyun for (i = 0; i < file_num; i++) {
1486*4882a593Smuzhiyun size_t file_size = get_file_size(files[i]);
1487*4882a593Smuzhiyun if (file_size < 0)
1488*4882a593Smuzhiyun goto end;
1489*4882a593Smuzhiyun entry.content_size = file_size;
1490*4882a593Smuzhiyun entry.content_offset = offset;
1491*4882a593Smuzhiyun
1492*4882a593Smuzhiyun if (write_file(offset, files[i], hash, sizeof(hash)) < 0)
1493*4882a593Smuzhiyun goto end;
1494*4882a593Smuzhiyun
1495*4882a593Smuzhiyun memcpy(entry.hash, hash, sizeof(hash));
1496*4882a593Smuzhiyun entry.hash_size = sizeof(hash);
1497*4882a593Smuzhiyun
1498*4882a593Smuzhiyun LOGD("try to write index entry(%s)...", files[i]);
1499*4882a593Smuzhiyun
1500*4882a593Smuzhiyun /* switch for le. */
1501*4882a593Smuzhiyun fix_entry(&entry);
1502*4882a593Smuzhiyun memset(entry.path, 0, sizeof(entry.path));
1503*4882a593Smuzhiyun const char *path = files[i];
1504*4882a593Smuzhiyun if (root_path[0]) {
1505*4882a593Smuzhiyun if (!strncmp(path, root_path, strlen(root_path))) {
1506*4882a593Smuzhiyun path += strlen(root_path);
1507*4882a593Smuzhiyun if (path[0] == '/')
1508*4882a593Smuzhiyun path++;
1509*4882a593Smuzhiyun }
1510*4882a593Smuzhiyun }
1511*4882a593Smuzhiyun path = fix_path(path);
1512*4882a593Smuzhiyun if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {
1513*4882a593Smuzhiyun if (!foundFdt) {
1514*4882a593Smuzhiyun /* use default path. */
1515*4882a593Smuzhiyun LOGD("mod fdt path:%s -> %s...", files[i], FDT_PATH);
1516*4882a593Smuzhiyun path = FDT_PATH;
1517*4882a593Smuzhiyun foundFdt = true;
1518*4882a593Smuzhiyun }
1519*4882a593Smuzhiyun }
1520*4882a593Smuzhiyun snprintf(entry.path, sizeof(entry.path), "%s", path);
1521*4882a593Smuzhiyun offset += fix_blocks(file_size);
1522*4882a593Smuzhiyun if (!write_data(header.header_size + i * header.tbl_entry_size, &entry,
1523*4882a593Smuzhiyun sizeof(entry)))
1524*4882a593Smuzhiyun goto end;
1525*4882a593Smuzhiyun }
1526*4882a593Smuzhiyun ret = true;
1527*4882a593Smuzhiyun end:
1528*4882a593Smuzhiyun return ret;
1529*4882a593Smuzhiyun }
1530*4882a593Smuzhiyun
pack_image(int file_num,const char ** files)1531*4882a593Smuzhiyun static int pack_image(int file_num, const char **files)
1532*4882a593Smuzhiyun {
1533*4882a593Smuzhiyun bool ret = false;
1534*4882a593Smuzhiyun FILE *image_file = fopen(image_path, "wb");
1535*4882a593Smuzhiyun if (!image_file) {
1536*4882a593Smuzhiyun LOGE("Failed to create:%s", image_path);
1537*4882a593Smuzhiyun goto end;
1538*4882a593Smuzhiyun }
1539*4882a593Smuzhiyun fclose(image_file);
1540*4882a593Smuzhiyun
1541*4882a593Smuzhiyun /* prepare files */
1542*4882a593Smuzhiyun int i = 0;
1543*4882a593Smuzhiyun int pos = 0;
1544*4882a593Smuzhiyun const char *tmp;
1545*4882a593Smuzhiyun for (i = 0; i < file_num; i++) {
1546*4882a593Smuzhiyun if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {
1547*4882a593Smuzhiyun /* dtb files for kernel. */
1548*4882a593Smuzhiyun tmp = files[pos];
1549*4882a593Smuzhiyun files[pos] = files[i];
1550*4882a593Smuzhiyun files[i] = tmp;
1551*4882a593Smuzhiyun pos++;
1552*4882a593Smuzhiyun } else if (!strcmp(fix_path(image_path), fix_path(files[i]))) {
1553*4882a593Smuzhiyun /* not to pack image itself! */
1554*4882a593Smuzhiyun tmp = files[file_num - 1];
1555*4882a593Smuzhiyun files[file_num - 1] = files[i];
1556*4882a593Smuzhiyun files[i] = tmp;
1557*4882a593Smuzhiyun file_num--;
1558*4882a593Smuzhiyun }
1559*4882a593Smuzhiyun }
1560*4882a593Smuzhiyun
1561*4882a593Smuzhiyun if (!write_header(file_num)) {
1562*4882a593Smuzhiyun LOGE("Failed to write header!");
1563*4882a593Smuzhiyun goto end;
1564*4882a593Smuzhiyun }
1565*4882a593Smuzhiyun if (!write_index_tbl(file_num, files)) {
1566*4882a593Smuzhiyun LOGE("Failed to write index table!");
1567*4882a593Smuzhiyun goto end;
1568*4882a593Smuzhiyun }
1569*4882a593Smuzhiyun printf("Pack to %s successed!\n", image_path);
1570*4882a593Smuzhiyun ret = true;
1571*4882a593Smuzhiyun end:
1572*4882a593Smuzhiyun return ret ? 0 : -1;
1573*4882a593Smuzhiyun }
1574*4882a593Smuzhiyun
1575*4882a593Smuzhiyun /************pack code end****************/
1576