]>
cvs.zerfleddert.de Git - hmcfgusb/blob - firmware.c
1 /* generic firmware-functions for HomeMatic
3 * Copyright (c) 2014-16 Michael Gernoth <michael@gernoth.net>
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
31 #include <sys/types.h>
39 /* This might be wrong, but it works for current fw */
40 #define MAX_BLOCK_LENGTH 2048
42 struct firmware
* firmware_read_firmware(char *filename
, int debug
)
52 fw
= malloc(sizeof(struct firmware
));
58 memset(fw
, 0, sizeof(struct firmware
));
60 if (stat(filename
, &stat_buf
) == -1) {
61 fprintf(stderr
, "Can't stat %s: %s\n", filename
, strerror(errno
));
65 fd
= open(filename
, O_RDONLY
);
67 fprintf(stderr
, "Can't open %s: %s", filename
, strerror(errno
));
71 printf("Reading firmware from %s...\n", filename
);
73 memset(buf
, 0, sizeof(buf
));
81 printf("can't get length information!\n");
85 for (i
= 0; i
< r
; i
++) {
86 if (!validate_nibble(buf
[i
])) {
87 fprintf(stderr
, "Firmware file not valid!\n");
92 len
= (ascii_to_nibble(buf
[0]) & 0xf)<< 4;
93 len
|= ascii_to_nibble(buf
[1]) & 0xf;
95 len
|= (ascii_to_nibble(buf
[2]) & 0xf)<< 4;
96 len
|= ascii_to_nibble(buf
[3]) & 0xf;
98 if (len
> MAX_BLOCK_LENGTH
) {
99 fprintf(stderr
, "Invalid block-length %u > %u for block %d!\n", len
, MAX_BLOCK_LENGTH
, fw
->fw_blocks
+1);
103 fw
->fw
= realloc(fw
->fw
, sizeof(uint8_t*) * (fw
->fw_blocks
+ 1));
104 if (fw
->fw
== NULL
) {
105 perror("Can't reallocate fw->fw-blocklist");
109 fw
->fw
[fw
->fw_blocks
] = malloc(len
+ 4);
110 if (fw
->fw
[fw
->fw_blocks
] == NULL
) {
111 perror("Can't allocate memory for fw->fw-block");
115 fw
->fw
[fw
->fw_blocks
][0] = (fw
->fw_blocks
>> 8) & 0xff;
116 fw
->fw
[fw
->fw_blocks
][1] = fw
->fw_blocks
& 0xff;
117 fw
->fw
[fw
->fw_blocks
][2] = (len
>> 8) & 0xff;
118 fw
->fw
[fw
->fw_blocks
][3] = len
& 0xff;
120 r
= read(fd
, buf
, len
* 2);
124 } else if (r
< len
* 2) {
125 fprintf(stderr
, "short read, aborting (%d < %d)\n", r
, len
* 2);
129 for (i
= 0; i
< r
; i
+=2) {
130 if ((!validate_nibble(buf
[i
])) ||
131 (!validate_nibble(buf
[i
+1]))) {
132 fprintf(stderr
, "Firmware file not valid!\n");
136 fw
->fw
[fw
->fw_blocks
][(i
/2) + 4] = (ascii_to_nibble(buf
[i
]) & 0xf)<< 4;
137 fw
->fw
[fw
->fw_blocks
][(i
/2) + 4] |= ascii_to_nibble(buf
[i
+1]) & 0xf;
142 printf("Firmware block %d with length %u read.\n", fw
->fw_blocks
, len
);
145 if (fw
->fw_blocks
== 0) {
146 fprintf(stderr
, "Firmware file not valid!\n");
150 printf("Firmware with %d blocks successfully read.\n", fw
->fw_blocks
);
155 void firmware_free(struct firmware
*fw
)
159 for (i
= 0; i
< fw
->fw_blocks
; i
++)