]>
cvs.zerfleddert.de Git - hmcfgusb/blob - firmware.c
650f035e29bbcf3717e14a2e5a909d983e65fe84
   1 /* generic firmware-functions for HomeMatic 
   3  * Copyright (c) 2014 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        512 
  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
++)