80f44f133e8ffa2f2411a47d1902c1c157bf278c
[openwrt/staging/mkresin.git] / tools / firmware-utils / src / encode_crc.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* **************************************************************************
3
4 This program creates a CRC checksum and encodes the file that is named
5 in the command line.
6
7 Compile with: gcc encode_crc.c -Wall -o encode_crc
8
9 Author: Michael Margraf (michael.margraf@freecom.com)
10 Copyright: Freecom Technology GmbH, Berlin, 2004
11 www.freecom.com
12
13 ************************************************************************* */
14
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/stat.h>
20
21 // *******************************************************************
22 // CCITT polynom G(x)=x^16+x^12+x^5+1
23 #define POLYNOM 0x1021
24
25 // CRC algorithm with MSB first
26 int make_crc16(int crc, char new)
27 {
28 int i;
29 crc = crc ^ (((int)new) << 8);
30
31 for(i=0; i<8; i++) { // work on 8 bits in "new"
32 crc <<= 1; // MSBs first
33 if(crc & 0x10000) crc ^= POLYNOM;
34 }
35 return crc & 0xFFFF;
36 }
37
38 // *******************************************************************
39 // Reads the file "filename" into memory and returns pointer to the buffer.
40 static char *readfile(char *filename, int *size)
41 {
42 FILE *fp;
43 char *buffer;
44 struct stat info;
45
46 if (stat(filename,&info)!=0)
47 return NULL;
48
49 if ((fp=fopen(filename,"r"))==NULL)
50 return NULL;
51
52 buffer=NULL;
53 for (;;)
54 {
55 if ((buffer=(char *)malloc(info.st_size+1))==NULL)
56 break;
57
58 if (fread(buffer,1,info.st_size,fp)!=info.st_size)
59 {
60 free(buffer);
61 buffer=NULL;
62 break;
63 }
64
65 buffer[info.st_size]='\0';
66 if(size) *size = info.st_size;
67
68 break;
69 }
70
71 (void)fclose(fp);
72
73 return buffer;
74 }
75
76
77 // *******************************************************************
78 int main(int argc, char** argv)
79 {
80 if(argc < 3) {
81 printf("ERROR: Argument missing!\n\n");
82 return 1;
83 }
84
85 int count; // size of file in bytes
86 char *p, *master = readfile(argv[1], &count);
87 if(!master) {
88 printf("ERROR: File not found!\n");
89 return 1;
90 }
91
92 int crc = 0xFFFF, z;
93
94 p = master;
95 for(z=0; z<count; z++)
96 crc = make_crc16(crc, *(p++)); // calculate CRC
97 short crc16 = (short)crc;
98
99 /*
100 if(argc > 2) { // with flag for device recognition ?
101 p = argv[2];
102 for(z=strlen(p); z>0; z--) {
103 crc ^= (int)(*p);
104 *(p++) = (char)crc; // encode device flag
105 }
106 }
107 */
108
109 p = master;
110 for(z=0; z<count; z++) {
111 crc ^= (int)(*p);
112 *(p++) = (char)crc; // encode file
113 }
114
115
116 // write encoded file...
117 FILE *fp = fopen(argv[2], "w");
118 if(!fp) {
119 printf("ERROR: File not writeable!\n");
120 return 1;
121 }
122
123 if(argc > 3) { // add flag for device recognition ?
124 fwrite(argv[3], strlen(argv[3]), sizeof(char), fp);
125 }
126 else {
127 // Device is an FSG, so byte swap (IXP4xx is big endian)
128 crc16 = ((crc16 >> 8) & 0xFF) | ((crc16 << 8) & 0xFF00);
129 }
130
131 fwrite(&crc16, 1, sizeof(short), fp); // first write CRC
132
133 fwrite(master, count, sizeof(char), fp); // write content
134 fclose(fp);
135
136 free(master);
137 return 0;
138 }