123ba6841SJoseph Chen // SPDX-License-Identifier: GPL-2.0+
223ba6841SJoseph Chen /*
323ba6841SJoseph Chen * (C) Copyright 2008-2015 Fuzhou Rockchip Electronics Co., Ltd
423ba6841SJoseph Chen */
523ba6841SJoseph Chen
623ba6841SJoseph Chen #include <errno.h>
723ba6841SJoseph Chen #include <memory.h>
823ba6841SJoseph Chen #include <stdint.h>
923ba6841SJoseph Chen #include <stdio.h>
1023ba6841SJoseph Chen #include <stdlib.h>
1123ba6841SJoseph Chen #include <stdbool.h>
1223ba6841SJoseph Chen #include <sys/stat.h>
1323ba6841SJoseph Chen #include <time.h>
14*467d16dbSJoseph Chen
15*467d16dbSJoseph Chen /**
16*467d16dbSJoseph Chen * \brief SHA-1 context structure
17*467d16dbSJoseph Chen */
18*467d16dbSJoseph Chen typedef struct
19*467d16dbSJoseph Chen {
20*467d16dbSJoseph Chen unsigned long total[2]; /*!< number of bytes processed */
21*467d16dbSJoseph Chen unsigned long state[5]; /*!< intermediate digest state */
22*467d16dbSJoseph Chen unsigned char buffer[64]; /*!< data block being processed */
23*467d16dbSJoseph Chen }
24*467d16dbSJoseph Chen sha1_context;
25*467d16dbSJoseph Chen
26*467d16dbSJoseph Chen /*
27*467d16dbSJoseph Chen * 32-bit integer manipulation macros (big endian)
28*467d16dbSJoseph Chen */
29*467d16dbSJoseph Chen #ifndef GET_UINT32_BE
30*467d16dbSJoseph Chen #define GET_UINT32_BE(n,b,i) { \
31*467d16dbSJoseph Chen (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
32*467d16dbSJoseph Chen | ( (unsigned long) (b)[(i) + 1] << 16 ) \
33*467d16dbSJoseph Chen | ( (unsigned long) (b)[(i) + 2] << 8 ) \
34*467d16dbSJoseph Chen | ( (unsigned long) (b)[(i) + 3] ); \
35*467d16dbSJoseph Chen }
36*467d16dbSJoseph Chen #endif
37*467d16dbSJoseph Chen #ifndef PUT_UINT32_BE
38*467d16dbSJoseph Chen #define PUT_UINT32_BE(n,b,i) { \
39*467d16dbSJoseph Chen (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
40*467d16dbSJoseph Chen (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
41*467d16dbSJoseph Chen (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
42*467d16dbSJoseph Chen (b)[(i) + 3] = (unsigned char) ( (n) ); \
43*467d16dbSJoseph Chen }
44*467d16dbSJoseph Chen #endif
45*467d16dbSJoseph Chen
46*467d16dbSJoseph Chen /*
47*467d16dbSJoseph Chen * SHA-1 context setup
48*467d16dbSJoseph Chen */
49*467d16dbSJoseph Chen static
sha1_starts(sha1_context * ctx)50*467d16dbSJoseph Chen void sha1_starts (sha1_context * ctx)
51*467d16dbSJoseph Chen {
52*467d16dbSJoseph Chen ctx->total[0] = 0;
53*467d16dbSJoseph Chen ctx->total[1] = 0;
54*467d16dbSJoseph Chen
55*467d16dbSJoseph Chen ctx->state[0] = 0x67452301;
56*467d16dbSJoseph Chen ctx->state[1] = 0xEFCDAB89;
57*467d16dbSJoseph Chen ctx->state[2] = 0x98BADCFE;
58*467d16dbSJoseph Chen ctx->state[3] = 0x10325476;
59*467d16dbSJoseph Chen ctx->state[4] = 0xC3D2E1F0;
60*467d16dbSJoseph Chen }
61*467d16dbSJoseph Chen
sha1_process(sha1_context * ctx,const unsigned char data[64])62*467d16dbSJoseph Chen static void sha1_process(sha1_context *ctx, const unsigned char data[64])
63*467d16dbSJoseph Chen {
64*467d16dbSJoseph Chen unsigned long temp, W[16], A, B, C, D, E;
65*467d16dbSJoseph Chen
66*467d16dbSJoseph Chen GET_UINT32_BE (W[0], data, 0);
67*467d16dbSJoseph Chen GET_UINT32_BE (W[1], data, 4);
68*467d16dbSJoseph Chen GET_UINT32_BE (W[2], data, 8);
69*467d16dbSJoseph Chen GET_UINT32_BE (W[3], data, 12);
70*467d16dbSJoseph Chen GET_UINT32_BE (W[4], data, 16);
71*467d16dbSJoseph Chen GET_UINT32_BE (W[5], data, 20);
72*467d16dbSJoseph Chen GET_UINT32_BE (W[6], data, 24);
73*467d16dbSJoseph Chen GET_UINT32_BE (W[7], data, 28);
74*467d16dbSJoseph Chen GET_UINT32_BE (W[8], data, 32);
75*467d16dbSJoseph Chen GET_UINT32_BE (W[9], data, 36);
76*467d16dbSJoseph Chen GET_UINT32_BE (W[10], data, 40);
77*467d16dbSJoseph Chen GET_UINT32_BE (W[11], data, 44);
78*467d16dbSJoseph Chen GET_UINT32_BE (W[12], data, 48);
79*467d16dbSJoseph Chen GET_UINT32_BE (W[13], data, 52);
80*467d16dbSJoseph Chen GET_UINT32_BE (W[14], data, 56);
81*467d16dbSJoseph Chen GET_UINT32_BE (W[15], data, 60);
82*467d16dbSJoseph Chen
83*467d16dbSJoseph Chen #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
84*467d16dbSJoseph Chen
85*467d16dbSJoseph Chen #define R(t) ( \
86*467d16dbSJoseph Chen temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
87*467d16dbSJoseph Chen W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
88*467d16dbSJoseph Chen ( W[t & 0x0F] = S(temp,1) ) \
89*467d16dbSJoseph Chen )
90*467d16dbSJoseph Chen
91*467d16dbSJoseph Chen #define P(a,b,c,d,e,x) { \
92*467d16dbSJoseph Chen e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
93*467d16dbSJoseph Chen }
94*467d16dbSJoseph Chen
95*467d16dbSJoseph Chen A = ctx->state[0];
96*467d16dbSJoseph Chen B = ctx->state[1];
97*467d16dbSJoseph Chen C = ctx->state[2];
98*467d16dbSJoseph Chen D = ctx->state[3];
99*467d16dbSJoseph Chen E = ctx->state[4];
100*467d16dbSJoseph Chen
101*467d16dbSJoseph Chen #define F(x,y,z) (z ^ (x & (y ^ z)))
102*467d16dbSJoseph Chen #define K 0x5A827999
103*467d16dbSJoseph Chen
104*467d16dbSJoseph Chen P (A, B, C, D, E, W[0]);
105*467d16dbSJoseph Chen P (E, A, B, C, D, W[1]);
106*467d16dbSJoseph Chen P (D, E, A, B, C, W[2]);
107*467d16dbSJoseph Chen P (C, D, E, A, B, W[3]);
108*467d16dbSJoseph Chen P (B, C, D, E, A, W[4]);
109*467d16dbSJoseph Chen P (A, B, C, D, E, W[5]);
110*467d16dbSJoseph Chen P (E, A, B, C, D, W[6]);
111*467d16dbSJoseph Chen P (D, E, A, B, C, W[7]);
112*467d16dbSJoseph Chen P (C, D, E, A, B, W[8]);
113*467d16dbSJoseph Chen P (B, C, D, E, A, W[9]);
114*467d16dbSJoseph Chen P (A, B, C, D, E, W[10]);
115*467d16dbSJoseph Chen P (E, A, B, C, D, W[11]);
116*467d16dbSJoseph Chen P (D, E, A, B, C, W[12]);
117*467d16dbSJoseph Chen P (C, D, E, A, B, W[13]);
118*467d16dbSJoseph Chen P (B, C, D, E, A, W[14]);
119*467d16dbSJoseph Chen P (A, B, C, D, E, W[15]);
120*467d16dbSJoseph Chen P (E, A, B, C, D, R (16));
121*467d16dbSJoseph Chen P (D, E, A, B, C, R (17));
122*467d16dbSJoseph Chen P (C, D, E, A, B, R (18));
123*467d16dbSJoseph Chen P (B, C, D, E, A, R (19));
124*467d16dbSJoseph Chen
125*467d16dbSJoseph Chen #undef K
126*467d16dbSJoseph Chen #undef F
127*467d16dbSJoseph Chen
128*467d16dbSJoseph Chen #define F(x,y,z) (x ^ y ^ z)
129*467d16dbSJoseph Chen #define K 0x6ED9EBA1
130*467d16dbSJoseph Chen
131*467d16dbSJoseph Chen P (A, B, C, D, E, R (20));
132*467d16dbSJoseph Chen P (E, A, B, C, D, R (21));
133*467d16dbSJoseph Chen P (D, E, A, B, C, R (22));
134*467d16dbSJoseph Chen P (C, D, E, A, B, R (23));
135*467d16dbSJoseph Chen P (B, C, D, E, A, R (24));
136*467d16dbSJoseph Chen P (A, B, C, D, E, R (25));
137*467d16dbSJoseph Chen P (E, A, B, C, D, R (26));
138*467d16dbSJoseph Chen P (D, E, A, B, C, R (27));
139*467d16dbSJoseph Chen P (C, D, E, A, B, R (28));
140*467d16dbSJoseph Chen P (B, C, D, E, A, R (29));
141*467d16dbSJoseph Chen P (A, B, C, D, E, R (30));
142*467d16dbSJoseph Chen P (E, A, B, C, D, R (31));
143*467d16dbSJoseph Chen P (D, E, A, B, C, R (32));
144*467d16dbSJoseph Chen P (C, D, E, A, B, R (33));
145*467d16dbSJoseph Chen P (B, C, D, E, A, R (34));
146*467d16dbSJoseph Chen P (A, B, C, D, E, R (35));
147*467d16dbSJoseph Chen P (E, A, B, C, D, R (36));
148*467d16dbSJoseph Chen P (D, E, A, B, C, R (37));
149*467d16dbSJoseph Chen P (C, D, E, A, B, R (38));
150*467d16dbSJoseph Chen P (B, C, D, E, A, R (39));
151*467d16dbSJoseph Chen
152*467d16dbSJoseph Chen #undef K
153*467d16dbSJoseph Chen #undef F
154*467d16dbSJoseph Chen
155*467d16dbSJoseph Chen #define F(x,y,z) ((x & y) | (z & (x | y)))
156*467d16dbSJoseph Chen #define K 0x8F1BBCDC
157*467d16dbSJoseph Chen
158*467d16dbSJoseph Chen P (A, B, C, D, E, R (40));
159*467d16dbSJoseph Chen P (E, A, B, C, D, R (41));
160*467d16dbSJoseph Chen P (D, E, A, B, C, R (42));
161*467d16dbSJoseph Chen P (C, D, E, A, B, R (43));
162*467d16dbSJoseph Chen P (B, C, D, E, A, R (44));
163*467d16dbSJoseph Chen P (A, B, C, D, E, R (45));
164*467d16dbSJoseph Chen P (E, A, B, C, D, R (46));
165*467d16dbSJoseph Chen P (D, E, A, B, C, R (47));
166*467d16dbSJoseph Chen P (C, D, E, A, B, R (48));
167*467d16dbSJoseph Chen P (B, C, D, E, A, R (49));
168*467d16dbSJoseph Chen P (A, B, C, D, E, R (50));
169*467d16dbSJoseph Chen P (E, A, B, C, D, R (51));
170*467d16dbSJoseph Chen P (D, E, A, B, C, R (52));
171*467d16dbSJoseph Chen P (C, D, E, A, B, R (53));
172*467d16dbSJoseph Chen P (B, C, D, E, A, R (54));
173*467d16dbSJoseph Chen P (A, B, C, D, E, R (55));
174*467d16dbSJoseph Chen P (E, A, B, C, D, R (56));
175*467d16dbSJoseph Chen P (D, E, A, B, C, R (57));
176*467d16dbSJoseph Chen P (C, D, E, A, B, R (58));
177*467d16dbSJoseph Chen P (B, C, D, E, A, R (59));
178*467d16dbSJoseph Chen
179*467d16dbSJoseph Chen #undef K
180*467d16dbSJoseph Chen #undef F
181*467d16dbSJoseph Chen
182*467d16dbSJoseph Chen #define F(x,y,z) (x ^ y ^ z)
183*467d16dbSJoseph Chen #define K 0xCA62C1D6
184*467d16dbSJoseph Chen
185*467d16dbSJoseph Chen P (A, B, C, D, E, R (60));
186*467d16dbSJoseph Chen P (E, A, B, C, D, R (61));
187*467d16dbSJoseph Chen P (D, E, A, B, C, R (62));
188*467d16dbSJoseph Chen P (C, D, E, A, B, R (63));
189*467d16dbSJoseph Chen P (B, C, D, E, A, R (64));
190*467d16dbSJoseph Chen P (A, B, C, D, E, R (65));
191*467d16dbSJoseph Chen P (E, A, B, C, D, R (66));
192*467d16dbSJoseph Chen P (D, E, A, B, C, R (67));
193*467d16dbSJoseph Chen P (C, D, E, A, B, R (68));
194*467d16dbSJoseph Chen P (B, C, D, E, A, R (69));
195*467d16dbSJoseph Chen P (A, B, C, D, E, R (70));
196*467d16dbSJoseph Chen P (E, A, B, C, D, R (71));
197*467d16dbSJoseph Chen P (D, E, A, B, C, R (72));
198*467d16dbSJoseph Chen P (C, D, E, A, B, R (73));
199*467d16dbSJoseph Chen P (B, C, D, E, A, R (74));
200*467d16dbSJoseph Chen P (A, B, C, D, E, R (75));
201*467d16dbSJoseph Chen P (E, A, B, C, D, R (76));
202*467d16dbSJoseph Chen P (D, E, A, B, C, R (77));
203*467d16dbSJoseph Chen P (C, D, E, A, B, R (78));
204*467d16dbSJoseph Chen P (B, C, D, E, A, R (79));
205*467d16dbSJoseph Chen
206*467d16dbSJoseph Chen #undef K
207*467d16dbSJoseph Chen #undef F
208*467d16dbSJoseph Chen
209*467d16dbSJoseph Chen ctx->state[0] += A;
210*467d16dbSJoseph Chen ctx->state[1] += B;
211*467d16dbSJoseph Chen ctx->state[2] += C;
212*467d16dbSJoseph Chen ctx->state[3] += D;
213*467d16dbSJoseph Chen ctx->state[4] += E;
214*467d16dbSJoseph Chen }
215*467d16dbSJoseph Chen
216*467d16dbSJoseph Chen #undef P
217*467d16dbSJoseph Chen #undef R
218*467d16dbSJoseph Chen #undef S
219*467d16dbSJoseph Chen
220*467d16dbSJoseph Chen /*
221*467d16dbSJoseph Chen * SHA-1 process buffer
222*467d16dbSJoseph Chen */
223*467d16dbSJoseph Chen static
sha1_update(sha1_context * ctx,const unsigned char * input,unsigned int ilen)224*467d16dbSJoseph Chen void sha1_update(sha1_context *ctx, const unsigned char *input,
225*467d16dbSJoseph Chen unsigned int ilen)
226*467d16dbSJoseph Chen {
227*467d16dbSJoseph Chen int fill;
228*467d16dbSJoseph Chen unsigned long left;
229*467d16dbSJoseph Chen
230*467d16dbSJoseph Chen if (ilen <= 0)
231*467d16dbSJoseph Chen return;
232*467d16dbSJoseph Chen
233*467d16dbSJoseph Chen left = ctx->total[0] & 0x3F;
234*467d16dbSJoseph Chen fill = 64 - left;
235*467d16dbSJoseph Chen
236*467d16dbSJoseph Chen ctx->total[0] += ilen;
237*467d16dbSJoseph Chen ctx->total[0] &= 0xFFFFFFFF;
238*467d16dbSJoseph Chen
239*467d16dbSJoseph Chen if (ctx->total[0] < (unsigned long) ilen)
240*467d16dbSJoseph Chen ctx->total[1]++;
241*467d16dbSJoseph Chen
242*467d16dbSJoseph Chen if (left && ilen >= fill) {
243*467d16dbSJoseph Chen memcpy ((void *) (ctx->buffer + left), (void *) input, fill);
244*467d16dbSJoseph Chen sha1_process (ctx, ctx->buffer);
245*467d16dbSJoseph Chen input += fill;
246*467d16dbSJoseph Chen ilen -= fill;
247*467d16dbSJoseph Chen left = 0;
248*467d16dbSJoseph Chen }
249*467d16dbSJoseph Chen
250*467d16dbSJoseph Chen while (ilen >= 64) {
251*467d16dbSJoseph Chen sha1_process (ctx, input);
252*467d16dbSJoseph Chen input += 64;
253*467d16dbSJoseph Chen ilen -= 64;
254*467d16dbSJoseph Chen }
255*467d16dbSJoseph Chen
256*467d16dbSJoseph Chen if (ilen > 0) {
257*467d16dbSJoseph Chen memcpy ((void *) (ctx->buffer + left), (void *) input, ilen);
258*467d16dbSJoseph Chen }
259*467d16dbSJoseph Chen }
260*467d16dbSJoseph Chen
261*467d16dbSJoseph Chen static const unsigned char sha1_padding[64] = {
262*467d16dbSJoseph Chen 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
263*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
264*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
266*467d16dbSJoseph Chen };
267*467d16dbSJoseph Chen
268*467d16dbSJoseph Chen /*
269*467d16dbSJoseph Chen * SHA-1 final digest
270*467d16dbSJoseph Chen */
271*467d16dbSJoseph Chen static
sha1_finish(sha1_context * ctx,unsigned char output[20])272*467d16dbSJoseph Chen void sha1_finish (sha1_context * ctx, unsigned char output[20])
273*467d16dbSJoseph Chen {
274*467d16dbSJoseph Chen unsigned long last, padn;
275*467d16dbSJoseph Chen unsigned long high, low;
276*467d16dbSJoseph Chen unsigned char msglen[8];
277*467d16dbSJoseph Chen
278*467d16dbSJoseph Chen high = (ctx->total[0] >> 29)
279*467d16dbSJoseph Chen | (ctx->total[1] << 3);
280*467d16dbSJoseph Chen low = (ctx->total[0] << 3);
281*467d16dbSJoseph Chen
282*467d16dbSJoseph Chen PUT_UINT32_BE (high, msglen, 0);
283*467d16dbSJoseph Chen PUT_UINT32_BE (low, msglen, 4);
284*467d16dbSJoseph Chen
285*467d16dbSJoseph Chen last = ctx->total[0] & 0x3F;
286*467d16dbSJoseph Chen padn = (last < 56) ? (56 - last) : (120 - last);
287*467d16dbSJoseph Chen
288*467d16dbSJoseph Chen sha1_update (ctx, (unsigned char *) sha1_padding, padn);
289*467d16dbSJoseph Chen sha1_update (ctx, msglen, 8);
290*467d16dbSJoseph Chen
291*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[0], output, 0);
292*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[1], output, 4);
293*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[2], output, 8);
294*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[3], output, 12);
295*467d16dbSJoseph Chen PUT_UINT32_BE (ctx->state[4], output, 16);
296*467d16dbSJoseph Chen }
297*467d16dbSJoseph Chen
298*467d16dbSJoseph Chen /*
299*467d16dbSJoseph Chen * Output = SHA-1( input buffer )
300*467d16dbSJoseph Chen */
301*467d16dbSJoseph Chen static
sha1_csum(const unsigned char * input,unsigned int ilen,unsigned char * output)302*467d16dbSJoseph Chen void sha1_csum(const unsigned char *input, unsigned int ilen,
303*467d16dbSJoseph Chen unsigned char *output)
304*467d16dbSJoseph Chen {
305*467d16dbSJoseph Chen sha1_context ctx;
306*467d16dbSJoseph Chen
307*467d16dbSJoseph Chen sha1_starts (&ctx);
308*467d16dbSJoseph Chen sha1_update (&ctx, input, ilen);
309*467d16dbSJoseph Chen sha1_finish (&ctx, output);
310*467d16dbSJoseph Chen }
311*467d16dbSJoseph Chen
312*467d16dbSJoseph Chen typedef struct {
313*467d16dbSJoseph Chen uint32_t total[2];
314*467d16dbSJoseph Chen uint32_t state[8];
315*467d16dbSJoseph Chen uint8_t buffer[64];
316*467d16dbSJoseph Chen } sha256_context;
317*467d16dbSJoseph Chen
318*467d16dbSJoseph Chen static
sha256_starts(sha256_context * ctx)319*467d16dbSJoseph Chen void sha256_starts(sha256_context * ctx)
320*467d16dbSJoseph Chen {
321*467d16dbSJoseph Chen ctx->total[0] = 0;
322*467d16dbSJoseph Chen ctx->total[1] = 0;
323*467d16dbSJoseph Chen
324*467d16dbSJoseph Chen ctx->state[0] = 0x6A09E667;
325*467d16dbSJoseph Chen ctx->state[1] = 0xBB67AE85;
326*467d16dbSJoseph Chen ctx->state[2] = 0x3C6EF372;
327*467d16dbSJoseph Chen ctx->state[3] = 0xA54FF53A;
328*467d16dbSJoseph Chen ctx->state[4] = 0x510E527F;
329*467d16dbSJoseph Chen ctx->state[5] = 0x9B05688C;
330*467d16dbSJoseph Chen ctx->state[6] = 0x1F83D9AB;
331*467d16dbSJoseph Chen ctx->state[7] = 0x5BE0CD19;
332*467d16dbSJoseph Chen }
333*467d16dbSJoseph Chen
sha256_process(sha256_context * ctx,const uint8_t data[64])334*467d16dbSJoseph Chen static void sha256_process(sha256_context *ctx, const uint8_t data[64])
335*467d16dbSJoseph Chen {
336*467d16dbSJoseph Chen uint32_t temp1, temp2;
337*467d16dbSJoseph Chen uint32_t W[64];
338*467d16dbSJoseph Chen uint32_t A, B, C, D, E, F, G, H;
339*467d16dbSJoseph Chen
340*467d16dbSJoseph Chen GET_UINT32_BE(W[0], data, 0);
341*467d16dbSJoseph Chen GET_UINT32_BE(W[1], data, 4);
342*467d16dbSJoseph Chen GET_UINT32_BE(W[2], data, 8);
343*467d16dbSJoseph Chen GET_UINT32_BE(W[3], data, 12);
344*467d16dbSJoseph Chen GET_UINT32_BE(W[4], data, 16);
345*467d16dbSJoseph Chen GET_UINT32_BE(W[5], data, 20);
346*467d16dbSJoseph Chen GET_UINT32_BE(W[6], data, 24);
347*467d16dbSJoseph Chen GET_UINT32_BE(W[7], data, 28);
348*467d16dbSJoseph Chen GET_UINT32_BE(W[8], data, 32);
349*467d16dbSJoseph Chen GET_UINT32_BE(W[9], data, 36);
350*467d16dbSJoseph Chen GET_UINT32_BE(W[10], data, 40);
351*467d16dbSJoseph Chen GET_UINT32_BE(W[11], data, 44);
352*467d16dbSJoseph Chen GET_UINT32_BE(W[12], data, 48);
353*467d16dbSJoseph Chen GET_UINT32_BE(W[13], data, 52);
354*467d16dbSJoseph Chen GET_UINT32_BE(W[14], data, 56);
355*467d16dbSJoseph Chen GET_UINT32_BE(W[15], data, 60);
356*467d16dbSJoseph Chen
357*467d16dbSJoseph Chen #define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
358*467d16dbSJoseph Chen #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
359*467d16dbSJoseph Chen
360*467d16dbSJoseph Chen #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
361*467d16dbSJoseph Chen #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
362*467d16dbSJoseph Chen
363*467d16dbSJoseph Chen #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
364*467d16dbSJoseph Chen #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
365*467d16dbSJoseph Chen
366*467d16dbSJoseph Chen #define F0(x,y,z) ((x & y) | (z & (x | y)))
367*467d16dbSJoseph Chen #define F1(x,y,z) (z ^ (x & (y ^ z)))
368*467d16dbSJoseph Chen
369*467d16dbSJoseph Chen #define R(t) \
370*467d16dbSJoseph Chen ( \
371*467d16dbSJoseph Chen W[t] = S1(W[t - 2]) + W[t - 7] + \
372*467d16dbSJoseph Chen S0(W[t - 15]) + W[t - 16] \
373*467d16dbSJoseph Chen )
374*467d16dbSJoseph Chen
375*467d16dbSJoseph Chen #define P(a,b,c,d,e,f,g,h,x,K) { \
376*467d16dbSJoseph Chen temp1 = h + S3(e) + F1(e,f,g) + K + x; \
377*467d16dbSJoseph Chen temp2 = S2(a) + F0(a,b,c); \
378*467d16dbSJoseph Chen d += temp1; h = temp1 + temp2; \
379*467d16dbSJoseph Chen }
380*467d16dbSJoseph Chen
381*467d16dbSJoseph Chen A = ctx->state[0];
382*467d16dbSJoseph Chen B = ctx->state[1];
383*467d16dbSJoseph Chen C = ctx->state[2];
384*467d16dbSJoseph Chen D = ctx->state[3];
385*467d16dbSJoseph Chen E = ctx->state[4];
386*467d16dbSJoseph Chen F = ctx->state[5];
387*467d16dbSJoseph Chen G = ctx->state[6];
388*467d16dbSJoseph Chen H = ctx->state[7];
389*467d16dbSJoseph Chen
390*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, W[0], 0x428A2F98);
391*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, W[1], 0x71374491);
392*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, W[2], 0xB5C0FBCF);
393*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, W[3], 0xE9B5DBA5);
394*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, W[4], 0x3956C25B);
395*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, W[5], 0x59F111F1);
396*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, W[6], 0x923F82A4);
397*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, W[7], 0xAB1C5ED5);
398*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, W[8], 0xD807AA98);
399*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, W[9], 0x12835B01);
400*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, W[10], 0x243185BE);
401*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
402*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
403*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
404*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
405*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
406*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
407*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
408*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
409*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
410*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
411*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
412*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
413*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
414*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(24), 0x983E5152);
415*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
416*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
417*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
418*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
419*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
420*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
421*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(31), 0x14292967);
422*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
423*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
424*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
425*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(35), 0x53380D13);
426*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(36), 0x650A7354);
427*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
428*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
429*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(39), 0x92722C85);
430*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
431*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
432*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
433*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
434*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(44), 0xD192E819);
435*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(45), 0xD6990624);
436*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
437*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(47), 0x106AA070);
438*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
439*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
440*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(50), 0x2748774C);
441*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
442*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
443*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
444*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
445*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
446*467d16dbSJoseph Chen P(A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
447*467d16dbSJoseph Chen P(H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
448*467d16dbSJoseph Chen P(G, H, A, B, C, D, E, F, R(58), 0x84C87814);
449*467d16dbSJoseph Chen P(F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
450*467d16dbSJoseph Chen P(E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
451*467d16dbSJoseph Chen P(D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
452*467d16dbSJoseph Chen P(C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
453*467d16dbSJoseph Chen P(B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
454*467d16dbSJoseph Chen
455*467d16dbSJoseph Chen ctx->state[0] += A;
456*467d16dbSJoseph Chen ctx->state[1] += B;
457*467d16dbSJoseph Chen ctx->state[2] += C;
458*467d16dbSJoseph Chen ctx->state[3] += D;
459*467d16dbSJoseph Chen ctx->state[4] += E;
460*467d16dbSJoseph Chen ctx->state[5] += F;
461*467d16dbSJoseph Chen ctx->state[6] += G;
462*467d16dbSJoseph Chen ctx->state[7] += H;
463*467d16dbSJoseph Chen }
464*467d16dbSJoseph Chen
465*467d16dbSJoseph Chen #undef P
466*467d16dbSJoseph Chen #undef R
467*467d16dbSJoseph Chen #undef F1
468*467d16dbSJoseph Chen #undef F0
469*467d16dbSJoseph Chen #undef S3
470*467d16dbSJoseph Chen #undef S2
471*467d16dbSJoseph Chen #undef S1
472*467d16dbSJoseph Chen #undef S0
473*467d16dbSJoseph Chen #undef ROTR
474*467d16dbSJoseph Chen #undef SHR
475*467d16dbSJoseph Chen
476*467d16dbSJoseph Chen static
sha256_update(sha256_context * ctx,const uint8_t * input,uint32_t length)477*467d16dbSJoseph Chen void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length)
478*467d16dbSJoseph Chen {
479*467d16dbSJoseph Chen uint32_t left, fill;
480*467d16dbSJoseph Chen
481*467d16dbSJoseph Chen if (!length)
482*467d16dbSJoseph Chen return;
483*467d16dbSJoseph Chen
484*467d16dbSJoseph Chen left = ctx->total[0] & 0x3F;
485*467d16dbSJoseph Chen fill = 64 - left;
486*467d16dbSJoseph Chen
487*467d16dbSJoseph Chen ctx->total[0] += length;
488*467d16dbSJoseph Chen ctx->total[0] &= 0xFFFFFFFF;
489*467d16dbSJoseph Chen
490*467d16dbSJoseph Chen if (ctx->total[0] < length)
491*467d16dbSJoseph Chen ctx->total[1]++;
492*467d16dbSJoseph Chen
493*467d16dbSJoseph Chen if (left && length >= fill) {
494*467d16dbSJoseph Chen memcpy((void *) (ctx->buffer + left), (void *) input, fill);
495*467d16dbSJoseph Chen sha256_process(ctx, ctx->buffer);
496*467d16dbSJoseph Chen length -= fill;
497*467d16dbSJoseph Chen input += fill;
498*467d16dbSJoseph Chen left = 0;
499*467d16dbSJoseph Chen }
500*467d16dbSJoseph Chen
501*467d16dbSJoseph Chen while (length >= 64) {
502*467d16dbSJoseph Chen sha256_process(ctx, input);
503*467d16dbSJoseph Chen length -= 64;
504*467d16dbSJoseph Chen input += 64;
505*467d16dbSJoseph Chen }
506*467d16dbSJoseph Chen
507*467d16dbSJoseph Chen if (length)
508*467d16dbSJoseph Chen memcpy((void *) (ctx->buffer + left), (void *) input, length);
509*467d16dbSJoseph Chen }
510*467d16dbSJoseph Chen
511*467d16dbSJoseph Chen static uint8_t sha256_padding[64] = {
512*467d16dbSJoseph Chen 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
513*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
514*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
515*467d16dbSJoseph Chen 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
516*467d16dbSJoseph Chen };
517*467d16dbSJoseph Chen
518*467d16dbSJoseph Chen static
sha256_finish(sha256_context * ctx,uint8_t digest[32])519*467d16dbSJoseph Chen void sha256_finish(sha256_context * ctx, uint8_t digest[32])
520*467d16dbSJoseph Chen {
521*467d16dbSJoseph Chen uint32_t last, padn;
522*467d16dbSJoseph Chen uint32_t high, low;
523*467d16dbSJoseph Chen uint8_t msglen[8];
524*467d16dbSJoseph Chen
525*467d16dbSJoseph Chen high = ((ctx->total[0] >> 29)
526*467d16dbSJoseph Chen | (ctx->total[1] << 3));
527*467d16dbSJoseph Chen low = (ctx->total[0] << 3);
528*467d16dbSJoseph Chen
529*467d16dbSJoseph Chen PUT_UINT32_BE(high, msglen, 0);
530*467d16dbSJoseph Chen PUT_UINT32_BE(low, msglen, 4);
531*467d16dbSJoseph Chen
532*467d16dbSJoseph Chen last = ctx->total[0] & 0x3F;
533*467d16dbSJoseph Chen padn = (last < 56) ? (56 - last) : (120 - last);
534*467d16dbSJoseph Chen
535*467d16dbSJoseph Chen sha256_update(ctx, sha256_padding, padn);
536*467d16dbSJoseph Chen sha256_update(ctx, msglen, 8);
537*467d16dbSJoseph Chen
538*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[0], digest, 0);
539*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[1], digest, 4);
540*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[2], digest, 8);
541*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[3], digest, 12);
542*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[4], digest, 16);
543*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[5], digest, 20);
544*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[6], digest, 24);
545*467d16dbSJoseph Chen PUT_UINT32_BE(ctx->state[7], digest, 28);
546*467d16dbSJoseph Chen }
547*467d16dbSJoseph Chen
548*467d16dbSJoseph Chen /*
549*467d16dbSJoseph Chen * Output = SHA-256( input buffer ).
550*467d16dbSJoseph Chen */
551*467d16dbSJoseph Chen static
sha256_csum(const unsigned char * input,unsigned int ilen,unsigned char * output)552*467d16dbSJoseph Chen void sha256_csum(const unsigned char *input, unsigned int ilen,
553*467d16dbSJoseph Chen unsigned char *output)
554*467d16dbSJoseph Chen {
555*467d16dbSJoseph Chen sha256_context ctx;
556*467d16dbSJoseph Chen
557*467d16dbSJoseph Chen sha256_starts(&ctx);
558*467d16dbSJoseph Chen sha256_update(&ctx, input, ilen);
559*467d16dbSJoseph Chen sha256_finish(&ctx, output);
560*467d16dbSJoseph Chen }
56123ba6841SJoseph Chen
56223ba6841SJoseph Chen /* #define DEBUG */
56323ba6841SJoseph Chen
56423ba6841SJoseph Chen static bool g_debug =
56523ba6841SJoseph Chen #ifdef DEBUG
56623ba6841SJoseph Chen true;
56723ba6841SJoseph Chen #else
56823ba6841SJoseph Chen false;
56923ba6841SJoseph Chen #endif /* DEBUG */
57023ba6841SJoseph Chen
57123ba6841SJoseph Chen #define LOGE(fmt, args...) \
57223ba6841SJoseph Chen fprintf(stderr, "E/%s(%d): " fmt "\n", __func__, __LINE__, ##args)
57323ba6841SJoseph Chen #define LOGD(fmt, args...) \
57423ba6841SJoseph Chen do { \
57523ba6841SJoseph Chen if (g_debug) \
57623ba6841SJoseph Chen fprintf(stderr, "D/%s(%d): " fmt "\n", __func__, __LINE__, ##args); \
57723ba6841SJoseph Chen } while (0)
57823ba6841SJoseph Chen
57923ba6841SJoseph Chen /* sync with ./board/rockchip/rk30xx/rkloader.c #define FDT_PATH */
58023ba6841SJoseph Chen #define FDT_PATH "rk-kernel.dtb"
58123ba6841SJoseph Chen #define DTD_SUBFIX ".dtb"
58223ba6841SJoseph Chen
58323ba6841SJoseph Chen #define DEFAULT_IMAGE_PATH "resource.img"
58423ba6841SJoseph Chen #define DEFAULT_UNPACK_DIR "out"
58523ba6841SJoseph Chen #define BLOCK_SIZE 512
58623ba6841SJoseph Chen
58723ba6841SJoseph Chen #define RESOURCE_PTN_HDR_SIZE 1
58823ba6841SJoseph Chen #define INDEX_TBL_ENTR_SIZE 1
58923ba6841SJoseph Chen
59023ba6841SJoseph Chen #define RESOURCE_PTN_VERSION 0
59123ba6841SJoseph Chen #define INDEX_TBL_VERSION 0
59223ba6841SJoseph Chen
59323ba6841SJoseph Chen #define RESOURCE_PTN_HDR_MAGIC "RSCE"
59423ba6841SJoseph Chen typedef struct {
59523ba6841SJoseph Chen char magic[4]; /* tag, "RSCE" */
59623ba6841SJoseph Chen uint16_t resource_ptn_version;
59723ba6841SJoseph Chen uint16_t index_tbl_version;
59823ba6841SJoseph Chen uint8_t header_size; /* blocks, size of ptn header. */
59923ba6841SJoseph Chen uint8_t tbl_offset; /* blocks, offset of index table. */
60023ba6841SJoseph Chen uint8_t tbl_entry_size; /* blocks, size of index table's entry. */
60123ba6841SJoseph Chen uint32_t tbl_entry_num; /* numbers of index table's entry. */
60223ba6841SJoseph Chen } resource_ptn_header;
60323ba6841SJoseph Chen
60423ba6841SJoseph Chen #define INDEX_TBL_ENTR_TAG "ENTR"
6055e817a0eSJoseph Chen #define MAX_INDEX_ENTRY_PATH_LEN 220
6065e817a0eSJoseph Chen #define MAX_HASH_LEN 32
6075e817a0eSJoseph Chen
60823ba6841SJoseph Chen typedef struct {
60923ba6841SJoseph Chen char tag[4]; /* tag, "ENTR" */
61023ba6841SJoseph Chen char path[MAX_INDEX_ENTRY_PATH_LEN];
6115e817a0eSJoseph Chen char hash[MAX_HASH_LEN]; /* hash data */
6125e817a0eSJoseph Chen uint32_t hash_size; /* 20 or 32 */
61323ba6841SJoseph Chen uint32_t content_offset; /* blocks, offset of resource content. */
61423ba6841SJoseph Chen uint32_t content_size; /* bytes, size of resource content. */
61523ba6841SJoseph Chen } index_tbl_entry;
61623ba6841SJoseph Chen
61723ba6841SJoseph Chen #define OPT_VERBOSE "--verbose"
61823ba6841SJoseph Chen #define OPT_HELP "--help"
61923ba6841SJoseph Chen #define OPT_VERSION "--version"
62023ba6841SJoseph Chen #define OPT_PRINT "--print"
62123ba6841SJoseph Chen #define OPT_PACK "--pack"
62223ba6841SJoseph Chen #define OPT_UNPACK "--unpack"
62323ba6841SJoseph Chen #define OPT_TEST_LOAD "--test_load"
62423ba6841SJoseph Chen #define OPT_TEST_CHARGE "--test_charge"
62523ba6841SJoseph Chen #define OPT_IMAGE "--image="
62623ba6841SJoseph Chen #define OPT_ROOT "--root="
62723ba6841SJoseph Chen
62823ba6841SJoseph Chen #define VERSION "2014-5-31 14:43:42"
62923ba6841SJoseph Chen
63023ba6841SJoseph Chen typedef struct {
63123ba6841SJoseph Chen char path[MAX_INDEX_ENTRY_PATH_LEN];
63223ba6841SJoseph Chen uint32_t content_offset; /* blocks, offset of resource content. */
63323ba6841SJoseph Chen uint32_t content_size; /* bytes, size of resource content. */
63423ba6841SJoseph Chen void *load_addr;
63523ba6841SJoseph Chen } resource_content;
63623ba6841SJoseph Chen
63723ba6841SJoseph Chen typedef struct {
63823ba6841SJoseph Chen int max_level;
63923ba6841SJoseph Chen int num;
64023ba6841SJoseph Chen int delay;
64123ba6841SJoseph Chen char prefix[MAX_INDEX_ENTRY_PATH_LEN];
64223ba6841SJoseph Chen } anim_level_conf;
64323ba6841SJoseph Chen
64423ba6841SJoseph Chen #define DEF_CHARGE_DESC_PATH "charge_anim_desc.txt"
64523ba6841SJoseph Chen
64623ba6841SJoseph Chen #define OPT_CHARGE_ANIM_DELAY "delay="
64723ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LOOP_CUR "only_current_level="
64823ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LEVELS "levels="
64923ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LEVEL_CONF "max_level="
65023ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LEVEL_NUM "num="
65123ba6841SJoseph Chen #define OPT_CHARGE_ANIM_LEVEL_PFX "prefix="
65223ba6841SJoseph Chen
65323ba6841SJoseph Chen static char image_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";
65423ba6841SJoseph Chen
fix_blocks(size_t size)65523ba6841SJoseph Chen static int fix_blocks(size_t size)
65623ba6841SJoseph Chen {
65723ba6841SJoseph Chen return (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
65823ba6841SJoseph Chen }
65923ba6841SJoseph Chen
fix_path(const char * path)66023ba6841SJoseph Chen static const char *fix_path(const char *path)
66123ba6841SJoseph Chen {
66223ba6841SJoseph Chen if (!memcmp(path, "./", 2)) {
66323ba6841SJoseph Chen return path + 2;
66423ba6841SJoseph Chen }
66523ba6841SJoseph Chen return path;
66623ba6841SJoseph Chen }
66723ba6841SJoseph Chen
switch_short(uint16_t x)66823ba6841SJoseph Chen static uint16_t switch_short(uint16_t x)
66923ba6841SJoseph Chen {
67023ba6841SJoseph Chen uint16_t val;
67123ba6841SJoseph Chen uint8_t *p = (uint8_t *)(&x);
67223ba6841SJoseph Chen
67323ba6841SJoseph Chen val = (*p++ & 0xff) << 0;
67423ba6841SJoseph Chen val |= (*p & 0xff) << 8;
67523ba6841SJoseph Chen
67623ba6841SJoseph Chen return val;
67723ba6841SJoseph Chen }
67823ba6841SJoseph Chen
switch_int(uint32_t x)67923ba6841SJoseph Chen static uint32_t switch_int(uint32_t x)
68023ba6841SJoseph Chen {
68123ba6841SJoseph Chen uint32_t val;
68223ba6841SJoseph Chen uint8_t *p = (uint8_t *)(&x);
68323ba6841SJoseph Chen
68423ba6841SJoseph Chen val = (*p++ & 0xff) << 0;
68523ba6841SJoseph Chen val |= (*p++ & 0xff) << 8;
68623ba6841SJoseph Chen val |= (*p++ & 0xff) << 16;
68723ba6841SJoseph Chen val |= (*p & 0xff) << 24;
68823ba6841SJoseph Chen
68923ba6841SJoseph Chen return val;
69023ba6841SJoseph Chen }
69123ba6841SJoseph Chen
fix_header(resource_ptn_header * header)69223ba6841SJoseph Chen static void fix_header(resource_ptn_header *header)
69323ba6841SJoseph Chen {
69423ba6841SJoseph Chen /* switch for be. */
69523ba6841SJoseph Chen header->resource_ptn_version = switch_short(header->resource_ptn_version);
69623ba6841SJoseph Chen header->index_tbl_version = switch_short(header->index_tbl_version);
69723ba6841SJoseph Chen header->tbl_entry_num = switch_int(header->tbl_entry_num);
69823ba6841SJoseph Chen }
69923ba6841SJoseph Chen
fix_entry(index_tbl_entry * entry)70023ba6841SJoseph Chen static void fix_entry(index_tbl_entry *entry)
70123ba6841SJoseph Chen {
70223ba6841SJoseph Chen /* switch for be. */
70323ba6841SJoseph Chen entry->content_offset = switch_int(entry->content_offset);
70423ba6841SJoseph Chen entry->content_size = switch_int(entry->content_size);
70523ba6841SJoseph Chen }
70623ba6841SJoseph Chen
get_ptn_offset(void)70723ba6841SJoseph Chen static int inline get_ptn_offset(void)
70823ba6841SJoseph Chen {
70923ba6841SJoseph Chen return 0;
71023ba6841SJoseph Chen }
71123ba6841SJoseph Chen
StorageWriteLba(int offset_block,void * data,int blocks)71223ba6841SJoseph Chen static bool StorageWriteLba(int offset_block, void *data, int blocks)
71323ba6841SJoseph Chen {
71423ba6841SJoseph Chen bool ret = false;
71523ba6841SJoseph Chen FILE *file = fopen(image_path, "rb+");
71623ba6841SJoseph Chen if (!file)
71723ba6841SJoseph Chen goto end;
71823ba6841SJoseph Chen int offset = offset_block * BLOCK_SIZE;
71923ba6841SJoseph Chen fseek(file, offset, SEEK_SET);
72023ba6841SJoseph Chen if (offset != ftell(file)) {
72123ba6841SJoseph Chen LOGE("Failed to seek %s to %d!", image_path, offset);
72223ba6841SJoseph Chen goto end;
72323ba6841SJoseph Chen }
72423ba6841SJoseph Chen if (!fwrite(data, blocks * BLOCK_SIZE, 1, file)) {
72523ba6841SJoseph Chen LOGE("Failed to write %s!", image_path);
72623ba6841SJoseph Chen goto end;
72723ba6841SJoseph Chen }
72823ba6841SJoseph Chen ret = true;
72923ba6841SJoseph Chen end:
73023ba6841SJoseph Chen if (file)
73123ba6841SJoseph Chen fclose(file);
73223ba6841SJoseph Chen return ret;
73323ba6841SJoseph Chen }
73423ba6841SJoseph Chen
StorageReadLba(int offset_block,void * data,int blocks)73523ba6841SJoseph Chen static bool StorageReadLba(int offset_block, void *data, int blocks)
73623ba6841SJoseph Chen {
73723ba6841SJoseph Chen bool ret = false;
73823ba6841SJoseph Chen FILE *file = fopen(image_path, "rb");
73923ba6841SJoseph Chen if (!file)
74023ba6841SJoseph Chen goto end;
74123ba6841SJoseph Chen int offset = offset_block * BLOCK_SIZE;
74223ba6841SJoseph Chen fseek(file, offset, SEEK_SET);
74323ba6841SJoseph Chen if (offset != ftell(file)) {
74423ba6841SJoseph Chen goto end;
74523ba6841SJoseph Chen }
74623ba6841SJoseph Chen if (!fread(data, blocks * BLOCK_SIZE, 1, file)) {
74723ba6841SJoseph Chen goto end;
74823ba6841SJoseph Chen }
74923ba6841SJoseph Chen ret = true;
75023ba6841SJoseph Chen end:
75123ba6841SJoseph Chen if (file)
75223ba6841SJoseph Chen fclose(file);
75323ba6841SJoseph Chen return ret;
75423ba6841SJoseph Chen }
75523ba6841SJoseph Chen
write_data(int offset_block,void * data,size_t len)75623ba6841SJoseph Chen static bool write_data(int offset_block, void *data, size_t len)
75723ba6841SJoseph Chen {
75823ba6841SJoseph Chen bool ret = false;
75923ba6841SJoseph Chen if (!data)
76023ba6841SJoseph Chen goto end;
76123ba6841SJoseph Chen int blocks = len / BLOCK_SIZE;
76223ba6841SJoseph Chen if (blocks && !StorageWriteLba(offset_block, data, blocks)) {
76323ba6841SJoseph Chen goto end;
76423ba6841SJoseph Chen }
76523ba6841SJoseph Chen int left = len % BLOCK_SIZE;
76623ba6841SJoseph Chen if (left) {
76723ba6841SJoseph Chen char buf[BLOCK_SIZE] = "\0";
76823ba6841SJoseph Chen memcpy(buf, data + blocks * BLOCK_SIZE, left);
76923ba6841SJoseph Chen if (!StorageWriteLba(offset_block + blocks, buf, 1))
77023ba6841SJoseph Chen goto end;
77123ba6841SJoseph Chen }
77223ba6841SJoseph Chen ret = true;
77323ba6841SJoseph Chen end:
77423ba6841SJoseph Chen return ret;
77523ba6841SJoseph Chen }
77623ba6841SJoseph Chen
77723ba6841SJoseph Chen /**********************load test************************/
77823ba6841SJoseph Chen static int load_file(const char *file_path, int offset_block, int blocks);
77923ba6841SJoseph Chen
test_load(int argc,char ** argv)78023ba6841SJoseph Chen static int test_load(int argc, char **argv)
78123ba6841SJoseph Chen {
78223ba6841SJoseph Chen if (argc < 1) {
78323ba6841SJoseph Chen LOGE("Nothing to load!");
78423ba6841SJoseph Chen return -1;
78523ba6841SJoseph Chen }
78623ba6841SJoseph Chen const char *file_path;
78723ba6841SJoseph Chen int offset_block = 0;
78823ba6841SJoseph Chen int blocks = 0;
78923ba6841SJoseph Chen if (argc > 0) {
79023ba6841SJoseph Chen file_path = (const char *)fix_path(argv[0]);
79123ba6841SJoseph Chen argc--, argv++;
79223ba6841SJoseph Chen }
79323ba6841SJoseph Chen if (argc > 0) {
79423ba6841SJoseph Chen offset_block = atoi(argv[0]);
79523ba6841SJoseph Chen argc--, argv++;
79623ba6841SJoseph Chen }
79723ba6841SJoseph Chen if (argc > 0) {
79823ba6841SJoseph Chen blocks = atoi(argv[0]);
79923ba6841SJoseph Chen }
80023ba6841SJoseph Chen return load_file(file_path, offset_block, blocks);
80123ba6841SJoseph Chen }
80223ba6841SJoseph Chen
free_content(resource_content * content)80323ba6841SJoseph Chen static void free_content(resource_content *content)
80423ba6841SJoseph Chen {
80523ba6841SJoseph Chen if (content->load_addr) {
80623ba6841SJoseph Chen free(content->load_addr);
80723ba6841SJoseph Chen content->load_addr = 0;
80823ba6841SJoseph Chen }
80923ba6841SJoseph Chen }
81023ba6841SJoseph Chen
tests_dump_file(const char * path,void * data,int len)81123ba6841SJoseph Chen static void tests_dump_file(const char *path, void *data, int len)
81223ba6841SJoseph Chen {
81323ba6841SJoseph Chen FILE *file = fopen(path, "wb");
81423ba6841SJoseph Chen if (!file)
81523ba6841SJoseph Chen return;
81623ba6841SJoseph Chen fwrite(data, len, 1, file);
81723ba6841SJoseph Chen fclose(file);
81823ba6841SJoseph Chen }
81923ba6841SJoseph Chen
load_content(resource_content * content)82023ba6841SJoseph Chen static bool load_content(resource_content *content)
82123ba6841SJoseph Chen {
82223ba6841SJoseph Chen if (content->load_addr)
82323ba6841SJoseph Chen return true;
82423ba6841SJoseph Chen int blocks = fix_blocks(content->content_size);
82523ba6841SJoseph Chen content->load_addr = malloc(blocks * BLOCK_SIZE);
82623ba6841SJoseph Chen if (!content->load_addr)
82723ba6841SJoseph Chen return false;
82823ba6841SJoseph Chen if (!StorageReadLba(get_ptn_offset() + content->content_offset,
82923ba6841SJoseph Chen content->load_addr, blocks)) {
83023ba6841SJoseph Chen free_content(content);
83123ba6841SJoseph Chen return false;
83223ba6841SJoseph Chen }
83323ba6841SJoseph Chen
83423ba6841SJoseph Chen tests_dump_file(content->path, content->load_addr, content->content_size);
83523ba6841SJoseph Chen return true;
83623ba6841SJoseph Chen }
83723ba6841SJoseph Chen
load_content_data(resource_content * content,int offset_block,void * data,int blocks)83823ba6841SJoseph Chen static bool load_content_data(resource_content *content, int offset_block,
83923ba6841SJoseph Chen void *data, int blocks)
84023ba6841SJoseph Chen {
84123ba6841SJoseph Chen if (!StorageReadLba(get_ptn_offset() + content->content_offset + offset_block,
84223ba6841SJoseph Chen data, blocks)) {
84323ba6841SJoseph Chen return false;
84423ba6841SJoseph Chen }
84523ba6841SJoseph Chen tests_dump_file(content->path, data, blocks * BLOCK_SIZE);
84623ba6841SJoseph Chen return true;
84723ba6841SJoseph Chen }
84823ba6841SJoseph Chen
get_entry(const char * file_path,index_tbl_entry * entry)84923ba6841SJoseph Chen static bool get_entry(const char *file_path, index_tbl_entry *entry)
85023ba6841SJoseph Chen {
85123ba6841SJoseph Chen bool ret = false;
85223ba6841SJoseph Chen char buf[BLOCK_SIZE];
85323ba6841SJoseph Chen resource_ptn_header header;
85423ba6841SJoseph Chen if (!StorageReadLba(get_ptn_offset(), buf, 1)) {
85523ba6841SJoseph Chen LOGE("Failed to read header!");
85623ba6841SJoseph Chen goto end;
85723ba6841SJoseph Chen }
85823ba6841SJoseph Chen memcpy(&header, buf, sizeof(header));
85923ba6841SJoseph Chen
86023ba6841SJoseph Chen if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {
86123ba6841SJoseph Chen LOGE("Not a resource image(%s)!", image_path);
86223ba6841SJoseph Chen goto end;
86323ba6841SJoseph Chen }
86423ba6841SJoseph Chen /* test on pc, switch for be. */
86523ba6841SJoseph Chen fix_header(&header);
86623ba6841SJoseph Chen
86723ba6841SJoseph Chen /* TODO: support header_size & tbl_entry_size */
86823ba6841SJoseph Chen if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||
86923ba6841SJoseph Chen header.header_size != RESOURCE_PTN_HDR_SIZE ||
87023ba6841SJoseph Chen header.index_tbl_version != INDEX_TBL_VERSION ||
87123ba6841SJoseph Chen header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {
87223ba6841SJoseph Chen LOGE("Not supported in this version!");
87323ba6841SJoseph Chen goto end;
87423ba6841SJoseph Chen }
87523ba6841SJoseph Chen
87623ba6841SJoseph Chen int i;
87723ba6841SJoseph Chen for (i = 0; i < header.tbl_entry_num; i++) {
87823ba6841SJoseph Chen /* TODO: support tbl_entry_size */
87923ba6841SJoseph Chen if (!StorageReadLba(
88023ba6841SJoseph Chen get_ptn_offset() + header.header_size + i * header.tbl_entry_size,
88123ba6841SJoseph Chen buf, 1)) {
88223ba6841SJoseph Chen LOGE("Failed to read index entry:%d!", i);
88323ba6841SJoseph Chen goto end;
88423ba6841SJoseph Chen }
88523ba6841SJoseph Chen memcpy(entry, buf, sizeof(*entry));
88623ba6841SJoseph Chen
88723ba6841SJoseph Chen if (memcmp(entry->tag, INDEX_TBL_ENTR_TAG, sizeof(entry->tag))) {
88823ba6841SJoseph Chen LOGE("Something wrong with index entry:%d!", i);
88923ba6841SJoseph Chen goto end;
89023ba6841SJoseph Chen }
89123ba6841SJoseph Chen
89223ba6841SJoseph Chen if (!strncmp(entry->path, file_path, sizeof(entry->path)))
89323ba6841SJoseph Chen break;
89423ba6841SJoseph Chen }
89523ba6841SJoseph Chen if (i == header.tbl_entry_num) {
89623ba6841SJoseph Chen LOGE("Cannot find %s!", file_path);
89723ba6841SJoseph Chen goto end;
89823ba6841SJoseph Chen }
89923ba6841SJoseph Chen /* test on pc, switch for be. */
90023ba6841SJoseph Chen fix_entry(entry);
90123ba6841SJoseph Chen
90223ba6841SJoseph Chen printf("Found entry:\n\tpath:%s\n\toffset:%d\tsize:%d\n", entry->path,
90323ba6841SJoseph Chen entry->content_offset, entry->content_size);
90423ba6841SJoseph Chen
90523ba6841SJoseph Chen ret = true;
90623ba6841SJoseph Chen end:
90723ba6841SJoseph Chen return ret;
90823ba6841SJoseph Chen }
90923ba6841SJoseph Chen
get_content(resource_content * content)91023ba6841SJoseph Chen static bool get_content(resource_content *content)
91123ba6841SJoseph Chen {
91223ba6841SJoseph Chen bool ret = false;
91323ba6841SJoseph Chen index_tbl_entry entry;
91423ba6841SJoseph Chen if (!get_entry(content->path, &entry))
91523ba6841SJoseph Chen goto end;
91623ba6841SJoseph Chen content->content_offset = entry.content_offset;
91723ba6841SJoseph Chen content->content_size = entry.content_size;
91823ba6841SJoseph Chen ret = true;
91923ba6841SJoseph Chen end:
92023ba6841SJoseph Chen return ret;
92123ba6841SJoseph Chen }
92223ba6841SJoseph Chen
load_file(const char * file_path,int offset_block,int blocks)92323ba6841SJoseph Chen static int load_file(const char *file_path, int offset_block, int blocks)
92423ba6841SJoseph Chen {
92523ba6841SJoseph Chen printf("Try to load:%s", file_path);
92623ba6841SJoseph Chen if (blocks) {
92723ba6841SJoseph Chen printf(", offset block:%d, blocks:%d\n", offset_block, blocks);
92823ba6841SJoseph Chen } else {
92923ba6841SJoseph Chen printf("\n");
93023ba6841SJoseph Chen }
93123ba6841SJoseph Chen bool ret = false;
93223ba6841SJoseph Chen resource_content content;
93323ba6841SJoseph Chen snprintf(content.path, sizeof(content.path), "%s", file_path);
93423ba6841SJoseph Chen content.load_addr = 0;
93523ba6841SJoseph Chen if (!get_content(&content)) {
93623ba6841SJoseph Chen goto end;
93723ba6841SJoseph Chen }
93823ba6841SJoseph Chen if (!blocks) {
93923ba6841SJoseph Chen if (!load_content(&content)) {
94023ba6841SJoseph Chen goto end;
94123ba6841SJoseph Chen }
94223ba6841SJoseph Chen } else {
94323ba6841SJoseph Chen void *data = malloc(blocks * BLOCK_SIZE);
94423ba6841SJoseph Chen if (!data)
94523ba6841SJoseph Chen goto end;
94623ba6841SJoseph Chen if (!load_content_data(&content, offset_block, data, blocks)) {
94723ba6841SJoseph Chen goto end;
94823ba6841SJoseph Chen }
94923ba6841SJoseph Chen }
95023ba6841SJoseph Chen ret = true;
95123ba6841SJoseph Chen end:
95223ba6841SJoseph Chen free_content(&content);
95323ba6841SJoseph Chen return ret;
95423ba6841SJoseph Chen }
95523ba6841SJoseph Chen
95623ba6841SJoseph Chen /**********************load test end************************/
95723ba6841SJoseph Chen /**********************anim test************************/
95823ba6841SJoseph Chen
parse_level_conf(const char * arg,anim_level_conf * level_conf)95923ba6841SJoseph Chen static bool parse_level_conf(const char *arg, anim_level_conf *level_conf)
96023ba6841SJoseph Chen {
96123ba6841SJoseph Chen memset(level_conf, 0, sizeof(anim_level_conf));
96223ba6841SJoseph Chen char *buf = NULL;
96323ba6841SJoseph Chen buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_CONF);
96423ba6841SJoseph Chen if (buf) {
96523ba6841SJoseph Chen level_conf->max_level = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_CONF));
96623ba6841SJoseph Chen } else {
96723ba6841SJoseph Chen LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_CONF);
96823ba6841SJoseph Chen return false;
96923ba6841SJoseph Chen }
97023ba6841SJoseph Chen buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_NUM);
97123ba6841SJoseph Chen if (buf) {
97223ba6841SJoseph Chen level_conf->num = atoi(buf + strlen(OPT_CHARGE_ANIM_LEVEL_NUM));
97323ba6841SJoseph Chen if (level_conf->num <= 0) {
97423ba6841SJoseph Chen return false;
97523ba6841SJoseph Chen }
97623ba6841SJoseph Chen } else {
97723ba6841SJoseph Chen LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_NUM);
97823ba6841SJoseph Chen return false;
97923ba6841SJoseph Chen }
98023ba6841SJoseph Chen buf = strstr(arg, OPT_CHARGE_ANIM_DELAY);
98123ba6841SJoseph Chen if (buf) {
98223ba6841SJoseph Chen level_conf->delay = atoi(buf + strlen(OPT_CHARGE_ANIM_DELAY));
98323ba6841SJoseph Chen }
98423ba6841SJoseph Chen buf = strstr(arg, OPT_CHARGE_ANIM_LEVEL_PFX);
98523ba6841SJoseph Chen if (buf) {
98623ba6841SJoseph Chen snprintf(level_conf->prefix, sizeof(level_conf->prefix), "%s",
98723ba6841SJoseph Chen buf + strlen(OPT_CHARGE_ANIM_LEVEL_PFX));
98823ba6841SJoseph Chen } else {
98923ba6841SJoseph Chen LOGE("Not found:%s", OPT_CHARGE_ANIM_LEVEL_PFX);
99023ba6841SJoseph Chen return false;
99123ba6841SJoseph Chen }
99223ba6841SJoseph Chen
99323ba6841SJoseph Chen LOGD("Found conf:\nmax_level:%d, num:%d, delay:%d, prefix:%s",
99423ba6841SJoseph Chen level_conf->max_level, level_conf->num, level_conf->delay,
99523ba6841SJoseph Chen level_conf->prefix);
99623ba6841SJoseph Chen return true;
99723ba6841SJoseph Chen }
99823ba6841SJoseph Chen
test_charge(int argc,char ** argv)99923ba6841SJoseph Chen static int test_charge(int argc, char **argv)
100023ba6841SJoseph Chen {
100123ba6841SJoseph Chen const char *desc;
100223ba6841SJoseph Chen if (argc > 0) {
100323ba6841SJoseph Chen desc = argv[0];
100423ba6841SJoseph Chen } else {
100523ba6841SJoseph Chen desc = DEF_CHARGE_DESC_PATH;
100623ba6841SJoseph Chen }
100723ba6841SJoseph Chen
100823ba6841SJoseph Chen resource_content content;
100923ba6841SJoseph Chen snprintf(content.path, sizeof(content.path), "%s", desc);
101023ba6841SJoseph Chen content.load_addr = 0;
101123ba6841SJoseph Chen if (!get_content(&content)) {
101223ba6841SJoseph Chen goto end;
101323ba6841SJoseph Chen }
101423ba6841SJoseph Chen if (!load_content(&content)) {
101523ba6841SJoseph Chen goto end;
101623ba6841SJoseph Chen }
101723ba6841SJoseph Chen
101823ba6841SJoseph Chen char *buf = (char *)content.load_addr;
101923ba6841SJoseph Chen char *end = buf + content.content_size - 1;
102023ba6841SJoseph Chen *end = '\0';
102123ba6841SJoseph Chen LOGD("desc:\n%s", buf);
102223ba6841SJoseph Chen
102323ba6841SJoseph Chen int pos = 0;
102423ba6841SJoseph Chen while (1) {
102523ba6841SJoseph Chen char *line = (char *)memchr(buf + pos, '\n', strlen(buf + pos));
102623ba6841SJoseph Chen if (!line)
102723ba6841SJoseph Chen break;
102823ba6841SJoseph Chen *line = '\0';
102923ba6841SJoseph Chen LOGD("splite:%s", buf + pos);
103023ba6841SJoseph Chen pos += (strlen(buf + pos) + 1);
103123ba6841SJoseph Chen }
103223ba6841SJoseph Chen
103323ba6841SJoseph Chen int delay = 900;
103423ba6841SJoseph Chen int only_current_level = false;
103523ba6841SJoseph Chen anim_level_conf *level_confs = NULL;
103623ba6841SJoseph Chen int level_conf_pos = 0;
103723ba6841SJoseph Chen int level_conf_num = 0;
103823ba6841SJoseph Chen
103923ba6841SJoseph Chen while (true) {
104023ba6841SJoseph Chen if (buf >= end)
104123ba6841SJoseph Chen break;
104223ba6841SJoseph Chen const char *arg = buf;
104323ba6841SJoseph Chen buf += (strlen(buf) + 1);
104423ba6841SJoseph Chen
104523ba6841SJoseph Chen LOGD("parse arg:%s", arg);
104623ba6841SJoseph Chen if (!memcmp(arg, OPT_CHARGE_ANIM_LEVEL_CONF,
104723ba6841SJoseph Chen strlen(OPT_CHARGE_ANIM_LEVEL_CONF))) {
104823ba6841SJoseph Chen if (!level_confs) {
104923ba6841SJoseph Chen LOGE("Found level conf before levels!");
105023ba6841SJoseph Chen goto end;
105123ba6841SJoseph Chen }
105223ba6841SJoseph Chen if (level_conf_pos >= level_conf_num) {
105323ba6841SJoseph Chen LOGE("Too many level confs!(%d >= %d)", level_conf_pos, level_conf_num);
105423ba6841SJoseph Chen goto end;
105523ba6841SJoseph Chen }
105623ba6841SJoseph Chen if (!parse_level_conf(arg, level_confs + level_conf_pos)) {
105723ba6841SJoseph Chen LOGE("Failed to parse level conf:%s", arg);
105823ba6841SJoseph Chen goto end;
105923ba6841SJoseph Chen }
106023ba6841SJoseph Chen level_conf_pos++;
106123ba6841SJoseph Chen } else if (!memcmp(arg, OPT_CHARGE_ANIM_DELAY,
106223ba6841SJoseph Chen strlen(OPT_CHARGE_ANIM_DELAY))) {
106323ba6841SJoseph Chen delay = atoi(arg + strlen(OPT_CHARGE_ANIM_DELAY));
106423ba6841SJoseph Chen LOGD("Found delay:%d", delay);
106523ba6841SJoseph Chen } else if (!memcmp(arg, OPT_CHARGE_ANIM_LOOP_CUR,
106623ba6841SJoseph Chen strlen(OPT_CHARGE_ANIM_LOOP_CUR))) {
106723ba6841SJoseph Chen only_current_level =
106823ba6841SJoseph Chen !memcmp(arg + strlen(OPT_CHARGE_ANIM_LOOP_CUR), "true", 4);
106923ba6841SJoseph Chen LOGD("Found only_current_level:%d", only_current_level);
107023ba6841SJoseph Chen } else if (!memcmp(arg, OPT_CHARGE_ANIM_LEVELS,
107123ba6841SJoseph Chen strlen(OPT_CHARGE_ANIM_LEVELS))) {
107223ba6841SJoseph Chen if (level_conf_num) {
107323ba6841SJoseph Chen goto end;
107423ba6841SJoseph Chen }
107523ba6841SJoseph Chen level_conf_num = atoi(arg + strlen(OPT_CHARGE_ANIM_LEVELS));
107623ba6841SJoseph Chen if (!level_conf_num) {
107723ba6841SJoseph Chen goto end;
107823ba6841SJoseph Chen }
107923ba6841SJoseph Chen level_confs =
108023ba6841SJoseph Chen (anim_level_conf *)malloc(level_conf_num * sizeof(anim_level_conf));
108123ba6841SJoseph Chen LOGD("Found levels:%d", level_conf_num);
108223ba6841SJoseph Chen } else {
108323ba6841SJoseph Chen LOGE("Unknown arg:%s", arg);
108423ba6841SJoseph Chen goto end;
108523ba6841SJoseph Chen }
108623ba6841SJoseph Chen }
108723ba6841SJoseph Chen
108823ba6841SJoseph Chen if (level_conf_pos != level_conf_num || !level_conf_num) {
108923ba6841SJoseph Chen LOGE("Something wrong with level confs!");
109023ba6841SJoseph Chen goto end;
109123ba6841SJoseph Chen }
109223ba6841SJoseph Chen
109323ba6841SJoseph Chen int i = 0, j = 0;
109423ba6841SJoseph Chen for (i = 0; i < level_conf_num; i++) {
109523ba6841SJoseph Chen if (!level_confs[i].delay) {
109623ba6841SJoseph Chen level_confs[i].delay = delay;
109723ba6841SJoseph Chen }
109823ba6841SJoseph Chen if (!level_confs[i].delay) {
109923ba6841SJoseph Chen LOGE("Missing delay in level conf:%d", i);
110023ba6841SJoseph Chen goto end;
110123ba6841SJoseph Chen }
110223ba6841SJoseph Chen for (j = 0; j < i; j++) {
110323ba6841SJoseph Chen if (level_confs[j].max_level == level_confs[i].max_level) {
110423ba6841SJoseph Chen LOGE("Dup level conf:%d", i);
110523ba6841SJoseph Chen goto end;
110623ba6841SJoseph Chen }
110723ba6841SJoseph Chen if (level_confs[j].max_level > level_confs[i].max_level) {
110823ba6841SJoseph Chen anim_level_conf conf = level_confs[i];
110923ba6841SJoseph Chen memmove(level_confs + j + 1, level_confs + j,
111023ba6841SJoseph Chen (i - j) * sizeof(anim_level_conf));
111123ba6841SJoseph Chen level_confs[j] = conf;
111223ba6841SJoseph Chen }
111323ba6841SJoseph Chen }
111423ba6841SJoseph Chen }
111523ba6841SJoseph Chen
111623ba6841SJoseph Chen printf("Parse anim desc(%s):\n", desc);
111723ba6841SJoseph Chen printf("only_current_level=%d\n", only_current_level);
111823ba6841SJoseph Chen printf("level conf:\n");
111923ba6841SJoseph Chen for (i = 0; i < level_conf_num; i++) {
112023ba6841SJoseph Chen printf("\tmax=%d, delay=%d, num=%d, prefix=%s\n", level_confs[i].max_level,
112123ba6841SJoseph Chen level_confs[i].delay, level_confs[i].num, level_confs[i].prefix);
112223ba6841SJoseph Chen }
112323ba6841SJoseph Chen
112423ba6841SJoseph Chen end:
112523ba6841SJoseph Chen free_content(&content);
112623ba6841SJoseph Chen return 0;
112723ba6841SJoseph Chen }
112823ba6841SJoseph Chen
112923ba6841SJoseph Chen /**********************anim test end************************/
113023ba6841SJoseph Chen /**********************append file************************/
113123ba6841SJoseph Chen
113223ba6841SJoseph Chen static const char *PROG = NULL;
113323ba6841SJoseph Chen static resource_ptn_header header;
113423ba6841SJoseph Chen static bool just_print = false;
113523ba6841SJoseph Chen static char root_path[MAX_INDEX_ENTRY_PATH_LEN] = "\0";
113623ba6841SJoseph Chen
version(void)113723ba6841SJoseph Chen static void version(void)
113823ba6841SJoseph Chen {
113923ba6841SJoseph Chen printf("%s (cjf@rock-chips.com)\t" VERSION "\n", PROG);
114023ba6841SJoseph Chen }
114123ba6841SJoseph Chen
usage(void)114223ba6841SJoseph Chen static void usage(void)
114323ba6841SJoseph Chen {
114423ba6841SJoseph Chen printf("Usage: %s [options] [FILES]\n", PROG);
114523ba6841SJoseph Chen printf("Tools for Rockchip's resource image.\n");
114623ba6841SJoseph Chen version();
114723ba6841SJoseph Chen printf("Options:\n");
114823ba6841SJoseph Chen printf("\t" OPT_PACK "\t\t\tPack image from given files.\n");
114923ba6841SJoseph Chen printf("\t" OPT_UNPACK "\t\tUnpack given image to current dir.\n");
115023ba6841SJoseph Chen printf("\t" OPT_IMAGE "path"
115123ba6841SJoseph Chen "\t\tSpecify input/output image path.\n");
115223ba6841SJoseph Chen printf("\t" OPT_PRINT "\t\t\tJust print informations.\n");
115323ba6841SJoseph Chen printf("\t" OPT_VERBOSE "\t\tDisplay more runtime informations.\n");
115423ba6841SJoseph Chen printf("\t" OPT_HELP "\t\t\tDisplay this information.\n");
115523ba6841SJoseph Chen printf("\t" OPT_VERSION "\t\tDisplay version information.\n");
115623ba6841SJoseph Chen printf("\t" OPT_ROOT "path"
115723ba6841SJoseph Chen "\t\tSpecify resources' root dir.\n");
115823ba6841SJoseph Chen }
115923ba6841SJoseph Chen
116023ba6841SJoseph Chen static int pack_image(int file_num, const char **files);
116123ba6841SJoseph Chen static int unpack_image(const char *unpack_dir);
116223ba6841SJoseph Chen
116323ba6841SJoseph Chen enum ACTION {
116423ba6841SJoseph Chen ACTION_PACK,
116523ba6841SJoseph Chen ACTION_UNPACK,
116623ba6841SJoseph Chen ACTION_TEST_LOAD,
116723ba6841SJoseph Chen ACTION_TEST_CHARGE,
116823ba6841SJoseph Chen };
116923ba6841SJoseph Chen
main(int argc,char ** argv)117023ba6841SJoseph Chen int main(int argc, char **argv)
117123ba6841SJoseph Chen {
117223ba6841SJoseph Chen PROG = fix_path(argv[0]);
117323ba6841SJoseph Chen
117423ba6841SJoseph Chen enum ACTION action = ACTION_PACK;
117523ba6841SJoseph Chen
117623ba6841SJoseph Chen argc--, argv++;
117723ba6841SJoseph Chen while (argc > 0 && argv[0][0] == '-') {
117823ba6841SJoseph Chen /* it's a opt arg. */
117923ba6841SJoseph Chen const char *arg = argv[0];
118023ba6841SJoseph Chen argc--, argv++;
118123ba6841SJoseph Chen if (!strcmp(OPT_VERBOSE, arg)) {
118223ba6841SJoseph Chen g_debug = true;
118323ba6841SJoseph Chen } else if (!strcmp(OPT_HELP, arg)) {
118423ba6841SJoseph Chen usage();
118523ba6841SJoseph Chen return 0;
118623ba6841SJoseph Chen } else if (!strcmp(OPT_VERSION, arg)) {
118723ba6841SJoseph Chen version();
118823ba6841SJoseph Chen return 0;
118923ba6841SJoseph Chen } else if (!strcmp(OPT_PRINT, arg)) {
119023ba6841SJoseph Chen just_print = true;
119123ba6841SJoseph Chen } else if (!strcmp(OPT_PACK, arg)) {
119223ba6841SJoseph Chen action = ACTION_PACK;
119323ba6841SJoseph Chen } else if (!strcmp(OPT_UNPACK, arg)) {
119423ba6841SJoseph Chen action = ACTION_UNPACK;
119523ba6841SJoseph Chen } else if (!strcmp(OPT_TEST_LOAD, arg)) {
119623ba6841SJoseph Chen action = ACTION_TEST_LOAD;
119723ba6841SJoseph Chen } else if (!strcmp(OPT_TEST_CHARGE, arg)) {
119823ba6841SJoseph Chen action = ACTION_TEST_CHARGE;
119923ba6841SJoseph Chen } else if (!memcmp(OPT_IMAGE, arg, strlen(OPT_IMAGE))) {
120023ba6841SJoseph Chen snprintf(image_path, sizeof(image_path), "%s", arg + strlen(OPT_IMAGE));
120123ba6841SJoseph Chen } else if (!memcmp(OPT_ROOT, arg, strlen(OPT_ROOT))) {
120223ba6841SJoseph Chen snprintf(root_path, sizeof(root_path), "%s", arg + strlen(OPT_ROOT));
120323ba6841SJoseph Chen } else {
120423ba6841SJoseph Chen LOGE("Unknown opt:%s", arg);
120523ba6841SJoseph Chen usage();
120623ba6841SJoseph Chen return -1;
120723ba6841SJoseph Chen }
120823ba6841SJoseph Chen }
120923ba6841SJoseph Chen
121023ba6841SJoseph Chen if (!image_path[0]) {
121123ba6841SJoseph Chen snprintf(image_path, sizeof(image_path), "%s", DEFAULT_IMAGE_PATH);
121223ba6841SJoseph Chen }
121323ba6841SJoseph Chen
121423ba6841SJoseph Chen switch (action) {
121523ba6841SJoseph Chen case ACTION_PACK: {
121623ba6841SJoseph Chen int file_num = argc;
121723ba6841SJoseph Chen const char **files = (const char **)argv;
121823ba6841SJoseph Chen if (!file_num) {
121923ba6841SJoseph Chen LOGE("No file to pack!");
122023ba6841SJoseph Chen return 0;
122123ba6841SJoseph Chen }
122223ba6841SJoseph Chen LOGD("try to pack %d files.", file_num);
122323ba6841SJoseph Chen return pack_image(file_num, files);
122423ba6841SJoseph Chen }
122523ba6841SJoseph Chen case ACTION_UNPACK: {
122623ba6841SJoseph Chen return unpack_image(argc > 0 ? argv[0] : DEFAULT_UNPACK_DIR);
122723ba6841SJoseph Chen }
122823ba6841SJoseph Chen case ACTION_TEST_LOAD: {
122923ba6841SJoseph Chen return test_load(argc, argv);
123023ba6841SJoseph Chen }
123123ba6841SJoseph Chen case ACTION_TEST_CHARGE: {
123223ba6841SJoseph Chen return test_charge(argc, argv);
123323ba6841SJoseph Chen }
123423ba6841SJoseph Chen }
123523ba6841SJoseph Chen /* not reach here. */
123623ba6841SJoseph Chen return -1;
123723ba6841SJoseph Chen }
123823ba6841SJoseph Chen
123923ba6841SJoseph Chen /************unpack code****************/
mkdirs(char * path)124023ba6841SJoseph Chen static bool mkdirs(char *path)
124123ba6841SJoseph Chen {
124223ba6841SJoseph Chen char *tmp = path;
124323ba6841SJoseph Chen char *pos = NULL;
124423ba6841SJoseph Chen char buf[MAX_INDEX_ENTRY_PATH_LEN];
124523ba6841SJoseph Chen bool ret = true;
124623ba6841SJoseph Chen while ((pos = memchr(tmp, '/', strlen(tmp)))) {
124723ba6841SJoseph Chen strcpy(buf, path);
124823ba6841SJoseph Chen buf[pos - path] = '\0';
124923ba6841SJoseph Chen tmp = pos + 1;
125023ba6841SJoseph Chen LOGD("mkdir:%s", buf);
125123ba6841SJoseph Chen if (!mkdir(buf, 0755)) {
125223ba6841SJoseph Chen ret = false;
125323ba6841SJoseph Chen }
125423ba6841SJoseph Chen }
125523ba6841SJoseph Chen if (!ret)
125623ba6841SJoseph Chen LOGD("Failed to mkdir(%s)!", path);
125723ba6841SJoseph Chen return ret;
125823ba6841SJoseph Chen }
125923ba6841SJoseph Chen
dump_file(FILE * file,const char * unpack_dir,index_tbl_entry entry)126023ba6841SJoseph Chen static bool dump_file(FILE *file, const char *unpack_dir,
126123ba6841SJoseph Chen index_tbl_entry entry)
126223ba6841SJoseph Chen {
126323ba6841SJoseph Chen LOGD("try to dump entry:%s", entry.path);
126423ba6841SJoseph Chen bool ret = false;
126523ba6841SJoseph Chen FILE *out_file = NULL;
126623ba6841SJoseph Chen long int pos = 0;
126723ba6841SJoseph Chen char path[MAX_INDEX_ENTRY_PATH_LEN * 2 + 1];
126823ba6841SJoseph Chen if (just_print) {
126923ba6841SJoseph Chen ret = true;
127023ba6841SJoseph Chen goto done;
127123ba6841SJoseph Chen }
127223ba6841SJoseph Chen
127323ba6841SJoseph Chen pos = ftell(file);
127423ba6841SJoseph Chen snprintf(path, sizeof(path), "%s/%s", unpack_dir, entry.path);
127523ba6841SJoseph Chen mkdirs(path);
127623ba6841SJoseph Chen out_file = fopen(path, "wb");
127723ba6841SJoseph Chen if (!out_file) {
127823ba6841SJoseph Chen LOGE("Failed to create:%s", path);
127923ba6841SJoseph Chen goto end;
128023ba6841SJoseph Chen }
128123ba6841SJoseph Chen long int offset = entry.content_offset * BLOCK_SIZE;
128223ba6841SJoseph Chen fseek(file, offset, SEEK_SET);
128323ba6841SJoseph Chen if (offset != ftell(file)) {
128423ba6841SJoseph Chen LOGE("Failed to read content:%s", entry.path);
128523ba6841SJoseph Chen goto end;
128623ba6841SJoseph Chen }
128723ba6841SJoseph Chen char buf[BLOCK_SIZE];
128823ba6841SJoseph Chen int n;
128923ba6841SJoseph Chen int len = entry.content_size;
129023ba6841SJoseph Chen while (len > 0) {
129123ba6841SJoseph Chen n = len > BLOCK_SIZE ? BLOCK_SIZE : len;
129223ba6841SJoseph Chen if (!fread(buf, n, 1, file)) {
129323ba6841SJoseph Chen LOGE("Failed to read content:%s", entry.path);
129423ba6841SJoseph Chen goto end;
129523ba6841SJoseph Chen }
129623ba6841SJoseph Chen if (!fwrite(buf, n, 1, out_file)) {
129723ba6841SJoseph Chen LOGE("Failed to write:%s", entry.path);
129823ba6841SJoseph Chen goto end;
129923ba6841SJoseph Chen }
130023ba6841SJoseph Chen len -= n;
130123ba6841SJoseph Chen }
130223ba6841SJoseph Chen done:
130323ba6841SJoseph Chen ret = true;
130423ba6841SJoseph Chen end:
130523ba6841SJoseph Chen if (out_file)
130623ba6841SJoseph Chen fclose(out_file);
130723ba6841SJoseph Chen if (pos)
130823ba6841SJoseph Chen fseek(file, pos, SEEK_SET);
130923ba6841SJoseph Chen return ret;
131023ba6841SJoseph Chen }
131123ba6841SJoseph Chen
unpack_image(const char * dir)131223ba6841SJoseph Chen static int unpack_image(const char *dir)
131323ba6841SJoseph Chen {
131423ba6841SJoseph Chen FILE *image_file = NULL;
131523ba6841SJoseph Chen bool ret = false;
131623ba6841SJoseph Chen char unpack_dir[MAX_INDEX_ENTRY_PATH_LEN];
131723ba6841SJoseph Chen if (just_print)
131823ba6841SJoseph Chen dir = ".";
131923ba6841SJoseph Chen snprintf(unpack_dir, sizeof(unpack_dir), "%s", dir);
132023ba6841SJoseph Chen if (!strlen(unpack_dir)) {
132123ba6841SJoseph Chen goto end;
132223ba6841SJoseph Chen } else if (unpack_dir[strlen(unpack_dir) - 1] == '/') {
132323ba6841SJoseph Chen unpack_dir[strlen(unpack_dir) - 1] = '\0';
132423ba6841SJoseph Chen }
132523ba6841SJoseph Chen
132623ba6841SJoseph Chen mkdir(unpack_dir, 0755);
132723ba6841SJoseph Chen image_file = fopen(image_path, "rb");
132823ba6841SJoseph Chen char buf[BLOCK_SIZE];
132923ba6841SJoseph Chen if (!image_file) {
133023ba6841SJoseph Chen LOGE("Failed to open:%s", image_path);
133123ba6841SJoseph Chen goto end;
133223ba6841SJoseph Chen }
133323ba6841SJoseph Chen if (!fread(buf, BLOCK_SIZE, 1, image_file)) {
133423ba6841SJoseph Chen LOGE("Failed to read header!");
133523ba6841SJoseph Chen goto end;
133623ba6841SJoseph Chen }
133723ba6841SJoseph Chen memcpy(&header, buf, sizeof(header));
133823ba6841SJoseph Chen
133923ba6841SJoseph Chen if (memcmp(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic))) {
134023ba6841SJoseph Chen LOGE("Not a resource image(%s)!", image_path);
134123ba6841SJoseph Chen goto end;
134223ba6841SJoseph Chen }
134323ba6841SJoseph Chen /* switch for be. */
134423ba6841SJoseph Chen fix_header(&header);
134523ba6841SJoseph Chen
134623ba6841SJoseph Chen printf("Dump header:\n");
134723ba6841SJoseph Chen printf("partition version:%d.%d\n", header.resource_ptn_version,
134823ba6841SJoseph Chen header.index_tbl_version);
134923ba6841SJoseph Chen printf("header size:%d\n", header.header_size);
135023ba6841SJoseph Chen printf("index tbl:\n\toffset:%d\tentry size:%d\tentry num:%d\n",
135123ba6841SJoseph Chen header.tbl_offset, header.tbl_entry_size, header.tbl_entry_num);
135223ba6841SJoseph Chen
135323ba6841SJoseph Chen /* TODO: support header_size & tbl_entry_size */
135423ba6841SJoseph Chen if (header.resource_ptn_version != RESOURCE_PTN_VERSION ||
135523ba6841SJoseph Chen header.header_size != RESOURCE_PTN_HDR_SIZE ||
135623ba6841SJoseph Chen header.index_tbl_version != INDEX_TBL_VERSION ||
135723ba6841SJoseph Chen header.tbl_entry_size != INDEX_TBL_ENTR_SIZE) {
135823ba6841SJoseph Chen LOGE("Not supported in this version!");
135923ba6841SJoseph Chen goto end;
136023ba6841SJoseph Chen }
136123ba6841SJoseph Chen
136223ba6841SJoseph Chen printf("Dump Index table:\n");
136323ba6841SJoseph Chen index_tbl_entry entry;
136423ba6841SJoseph Chen int i;
136523ba6841SJoseph Chen for (i = 0; i < header.tbl_entry_num; i++) {
136623ba6841SJoseph Chen /* TODO: support tbl_entry_size */
136723ba6841SJoseph Chen if (!fread(buf, BLOCK_SIZE, 1, image_file)) {
136823ba6841SJoseph Chen LOGE("Failed to read index entry:%d!", i);
136923ba6841SJoseph Chen goto end;
137023ba6841SJoseph Chen }
137123ba6841SJoseph Chen memcpy(&entry, buf, sizeof(entry));
137223ba6841SJoseph Chen
137323ba6841SJoseph Chen if (memcmp(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag))) {
137423ba6841SJoseph Chen LOGE("Something wrong with index entry:%d!", i);
137523ba6841SJoseph Chen goto end;
137623ba6841SJoseph Chen }
137723ba6841SJoseph Chen /* switch for be. */
137823ba6841SJoseph Chen fix_entry(&entry);
137923ba6841SJoseph Chen
138023ba6841SJoseph Chen printf("entry(%d):\n\tpath:%s\n\toffset:%d\tsize:%d\n", i, entry.path,
138123ba6841SJoseph Chen entry.content_offset, entry.content_size);
138223ba6841SJoseph Chen if (!dump_file(image_file, unpack_dir, entry)) {
138323ba6841SJoseph Chen goto end;
138423ba6841SJoseph Chen }
138523ba6841SJoseph Chen }
138623ba6841SJoseph Chen printf("Unack %s to %s successed!\n", image_path, unpack_dir);
138723ba6841SJoseph Chen ret = true;
138823ba6841SJoseph Chen end:
138923ba6841SJoseph Chen if (image_file)
139023ba6841SJoseph Chen fclose(image_file);
139123ba6841SJoseph Chen return ret ? 0 : -1;
139223ba6841SJoseph Chen }
139323ba6841SJoseph Chen
139423ba6841SJoseph Chen /************unpack code end****************/
139523ba6841SJoseph Chen /************pack code****************/
139623ba6841SJoseph Chen
get_file_size(const char * path)139723ba6841SJoseph Chen static inline size_t get_file_size(const char *path)
139823ba6841SJoseph Chen {
139923ba6841SJoseph Chen LOGD("try to get size(%s)...", path);
140023ba6841SJoseph Chen struct stat st;
140123ba6841SJoseph Chen if (stat(path, &st) < 0) {
140223ba6841SJoseph Chen LOGE("Failed to get size:%s", path);
140323ba6841SJoseph Chen return -1;
140423ba6841SJoseph Chen }
140523ba6841SJoseph Chen LOGD("path:%s, size:%ld", path, st.st_size);
140623ba6841SJoseph Chen return st.st_size;
140723ba6841SJoseph Chen }
140823ba6841SJoseph Chen
write_file(int offset_block,const char * src_path,char hash[],int hash_size)14095e817a0eSJoseph Chen static int write_file(int offset_block, const char *src_path,
14105e817a0eSJoseph Chen char hash[], int hash_size)
141123ba6841SJoseph Chen {
141223ba6841SJoseph Chen LOGD("try to write file(%s) to offset:%d...", src_path, offset_block);
14135e817a0eSJoseph Chen char *buf = NULL;
141423ba6841SJoseph Chen int ret = -1;
141523ba6841SJoseph Chen size_t file_size;
141623ba6841SJoseph Chen FILE *src_file = fopen(src_path, "rb");
141723ba6841SJoseph Chen if (!src_file) {
141823ba6841SJoseph Chen LOGE("Failed to open:%s", src_path);
141923ba6841SJoseph Chen goto end;
142023ba6841SJoseph Chen }
142123ba6841SJoseph Chen
142223ba6841SJoseph Chen file_size = get_file_size(src_path);
142323ba6841SJoseph Chen if (file_size < 0) {
142423ba6841SJoseph Chen goto end;
142523ba6841SJoseph Chen }
142623ba6841SJoseph Chen
14275e817a0eSJoseph Chen buf = calloc(file_size, 1);
14285e817a0eSJoseph Chen if (!buf)
142923ba6841SJoseph Chen goto end;
14305e817a0eSJoseph Chen
14315e817a0eSJoseph Chen if (!fread(buf, file_size, 1, src_file))
143223ba6841SJoseph Chen goto end;
14335e817a0eSJoseph Chen
14345e817a0eSJoseph Chen if (!write_data(offset_block, buf, file_size))
14355e817a0eSJoseph Chen goto end;
14365e817a0eSJoseph Chen
14375e817a0eSJoseph Chen if (hash_size == 20)
14385e817a0eSJoseph Chen sha1_csum((const unsigned char *)buf, file_size,
14395e817a0eSJoseph Chen (unsigned char *)hash);
14405e817a0eSJoseph Chen else if (hash_size == 32)
14415e817a0eSJoseph Chen sha256_csum((const unsigned char *)buf, file_size,
14425e817a0eSJoseph Chen (unsigned char *)hash);
14435e817a0eSJoseph Chen else
14445e817a0eSJoseph Chen goto end;
14455e817a0eSJoseph Chen
14465e817a0eSJoseph Chen ret = file_size;
144723ba6841SJoseph Chen end:
144823ba6841SJoseph Chen if (src_file)
144923ba6841SJoseph Chen fclose(src_file);
14505e817a0eSJoseph Chen if (buf)
14515e817a0eSJoseph Chen free(buf);
14525e817a0eSJoseph Chen
145323ba6841SJoseph Chen return ret;
145423ba6841SJoseph Chen }
145523ba6841SJoseph Chen
write_header(const int file_num)145623ba6841SJoseph Chen static bool write_header(const int file_num)
145723ba6841SJoseph Chen {
145823ba6841SJoseph Chen LOGD("try to write header...");
145923ba6841SJoseph Chen memcpy(header.magic, RESOURCE_PTN_HDR_MAGIC, sizeof(header.magic));
146023ba6841SJoseph Chen header.resource_ptn_version = RESOURCE_PTN_VERSION;
146123ba6841SJoseph Chen header.index_tbl_version = INDEX_TBL_VERSION;
146223ba6841SJoseph Chen header.header_size = RESOURCE_PTN_HDR_SIZE;
146323ba6841SJoseph Chen header.tbl_offset = header.header_size;
146423ba6841SJoseph Chen header.tbl_entry_size = INDEX_TBL_ENTR_SIZE;
146523ba6841SJoseph Chen header.tbl_entry_num = file_num;
146623ba6841SJoseph Chen
146723ba6841SJoseph Chen /* switch for le. */
146823ba6841SJoseph Chen resource_ptn_header hdr = header;
146923ba6841SJoseph Chen fix_header(&hdr);
147023ba6841SJoseph Chen return write_data(0, &hdr, sizeof(hdr));
147123ba6841SJoseph Chen }
147223ba6841SJoseph Chen
write_index_tbl(const int file_num,const char ** files)147323ba6841SJoseph Chen static bool write_index_tbl(const int file_num, const char **files)
147423ba6841SJoseph Chen {
147523ba6841SJoseph Chen LOGD("try to write index table...");
147623ba6841SJoseph Chen bool ret = false;
147723ba6841SJoseph Chen bool foundFdt = false;
147823ba6841SJoseph Chen int offset =
147923ba6841SJoseph Chen header.header_size + header.tbl_entry_size * header.tbl_entry_num;
148023ba6841SJoseph Chen index_tbl_entry entry;
14815e817a0eSJoseph Chen char hash[20]; /* sha1 */
148223ba6841SJoseph Chen int i;
14835e817a0eSJoseph Chen
14845e817a0eSJoseph Chen memcpy(entry.tag, INDEX_TBL_ENTR_TAG, sizeof(entry.tag));
148523ba6841SJoseph Chen for (i = 0; i < file_num; i++) {
148623ba6841SJoseph Chen size_t file_size = get_file_size(files[i]);
148723ba6841SJoseph Chen if (file_size < 0)
148823ba6841SJoseph Chen goto end;
148923ba6841SJoseph Chen entry.content_size = file_size;
149023ba6841SJoseph Chen entry.content_offset = offset;
149123ba6841SJoseph Chen
14925e817a0eSJoseph Chen if (write_file(offset, files[i], hash, sizeof(hash)) < 0)
149323ba6841SJoseph Chen goto end;
149423ba6841SJoseph Chen
14955e817a0eSJoseph Chen memcpy(entry.hash, hash, sizeof(hash));
14965e817a0eSJoseph Chen entry.hash_size = sizeof(hash);
14975e817a0eSJoseph Chen
149823ba6841SJoseph Chen LOGD("try to write index entry(%s)...", files[i]);
149923ba6841SJoseph Chen
150023ba6841SJoseph Chen /* switch for le. */
150123ba6841SJoseph Chen fix_entry(&entry);
150223ba6841SJoseph Chen memset(entry.path, 0, sizeof(entry.path));
150323ba6841SJoseph Chen const char *path = files[i];
150423ba6841SJoseph Chen if (root_path[0]) {
150523ba6841SJoseph Chen if (!strncmp(path, root_path, strlen(root_path))) {
150623ba6841SJoseph Chen path += strlen(root_path);
150723ba6841SJoseph Chen if (path[0] == '/')
150823ba6841SJoseph Chen path++;
150923ba6841SJoseph Chen }
151023ba6841SJoseph Chen }
151123ba6841SJoseph Chen path = fix_path(path);
151223ba6841SJoseph Chen if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {
151323ba6841SJoseph Chen if (!foundFdt) {
151423ba6841SJoseph Chen /* use default path. */
151523ba6841SJoseph Chen LOGD("mod fdt path:%s -> %s...", files[i], FDT_PATH);
151623ba6841SJoseph Chen path = FDT_PATH;
151723ba6841SJoseph Chen foundFdt = true;
151823ba6841SJoseph Chen }
151923ba6841SJoseph Chen }
152023ba6841SJoseph Chen snprintf(entry.path, sizeof(entry.path), "%s", path);
152123ba6841SJoseph Chen offset += fix_blocks(file_size);
152223ba6841SJoseph Chen if (!write_data(header.header_size + i * header.tbl_entry_size, &entry,
152323ba6841SJoseph Chen sizeof(entry)))
152423ba6841SJoseph Chen goto end;
152523ba6841SJoseph Chen }
152623ba6841SJoseph Chen ret = true;
152723ba6841SJoseph Chen end:
152823ba6841SJoseph Chen return ret;
152923ba6841SJoseph Chen }
153023ba6841SJoseph Chen
pack_image(int file_num,const char ** files)153123ba6841SJoseph Chen static int pack_image(int file_num, const char **files)
153223ba6841SJoseph Chen {
153323ba6841SJoseph Chen bool ret = false;
153423ba6841SJoseph Chen FILE *image_file = fopen(image_path, "wb");
153523ba6841SJoseph Chen if (!image_file) {
153623ba6841SJoseph Chen LOGE("Failed to create:%s", image_path);
153723ba6841SJoseph Chen goto end;
153823ba6841SJoseph Chen }
153923ba6841SJoseph Chen fclose(image_file);
154023ba6841SJoseph Chen
154123ba6841SJoseph Chen /* prepare files */
154223ba6841SJoseph Chen int i = 0;
154323ba6841SJoseph Chen int pos = 0;
154423ba6841SJoseph Chen const char *tmp;
154523ba6841SJoseph Chen for (i = 0; i < file_num; i++) {
154623ba6841SJoseph Chen if (!strcmp(files[i] + strlen(files[i]) - strlen(DTD_SUBFIX), DTD_SUBFIX)) {
154723ba6841SJoseph Chen /* dtb files for kernel. */
154823ba6841SJoseph Chen tmp = files[pos];
154923ba6841SJoseph Chen files[pos] = files[i];
155023ba6841SJoseph Chen files[i] = tmp;
155123ba6841SJoseph Chen pos++;
155223ba6841SJoseph Chen } else if (!strcmp(fix_path(image_path), fix_path(files[i]))) {
155323ba6841SJoseph Chen /* not to pack image itself! */
155423ba6841SJoseph Chen tmp = files[file_num - 1];
155523ba6841SJoseph Chen files[file_num - 1] = files[i];
155623ba6841SJoseph Chen files[i] = tmp;
155723ba6841SJoseph Chen file_num--;
155823ba6841SJoseph Chen }
155923ba6841SJoseph Chen }
156023ba6841SJoseph Chen
156123ba6841SJoseph Chen if (!write_header(file_num)) {
156223ba6841SJoseph Chen LOGE("Failed to write header!");
156323ba6841SJoseph Chen goto end;
156423ba6841SJoseph Chen }
156523ba6841SJoseph Chen if (!write_index_tbl(file_num, files)) {
156623ba6841SJoseph Chen LOGE("Failed to write index table!");
156723ba6841SJoseph Chen goto end;
156823ba6841SJoseph Chen }
156923ba6841SJoseph Chen printf("Pack to %s successed!\n", image_path);
157023ba6841SJoseph Chen ret = true;
157123ba6841SJoseph Chen end:
157223ba6841SJoseph Chen return ret ? 0 : -1;
157323ba6841SJoseph Chen }
157423ba6841SJoseph Chen
157523ba6841SJoseph Chen /************pack code end****************/
1576