Field | Type | Size | Notes |
---|---|---|---|
Marker | [8]byte |
8 | Can be either Phyton\x00\x00 or AlmaCode . |
Header Size | uint32 |
4 | Size of whole Header struct. Fields may be omitted if they exceed the size. |
Date Time | uint32 |
4 | Release time in FirmwareDateTime encoding. |
Buffer Size | uint32 |
4 | TBD |
Serial Number | [16]byte |
16 | Firmware coded for a specific device S/N. Usually all zeros. |
Version Low | uint8 |
1 | |
Version High | uint8 |
1 | |
Version | - | - | Derived from Version Low and Version High.fmt.Sprintf("%d.%02d", VersionHigh, VersionLow) |
File Count | uint32 |
4 | TBD. Only used if Marker == AlmaCode |
Firmware Header Size | uint32 |
4 | TBD |
Compressed | bool |
1 | Set to 1 on files with compressed FirmwareBlock. |
Reserved | uint8 |
1 | Set to 0 . |
CRC32 | uint32 |
4 | Contains the CRC of Data. |
Data | []byte |
len(buf) - Buffer Size | In case of Marker == Phyton\x00\x00 , []FirmwareBlock follows until EOF.Refer to source code to decode AlmaCode format. |
package radiacode
import "time"
func DateTimeToTime(dt uint32) time.Time {
high := uint16(dt >> 16)
low := uint16(dt)
year := ((high >> 9) & 127) + 1980
month := (high >> 5) & 15
day := high & 31
hours := (low >> 11) & 31
minutes := (low >> 5) & 63
seconds := (low & 31) * 2
return time.Date(int(year), time.Month(month), int(day), int(hours), int(minutes), int(seconds), 0, time.UTC)
}
Field | Type | XOR Key | Size | Notes |
---|---|---|---|---|
Header Size | uint32 |
- | 4 | Denotes the size of the header. Should be 12, but some weird cases exist in firmware to pad it, 0 value, or 0xFFFF?. |
Size | uint32 |
0xCE27A932 | 4 | |
Addr | uint32 |
0xB2D5A864 | 4 | Denotes the location of Data in Flash. |
Size Aligned | - | - | - | Derived from Size, 8 byte alignment. See Size Aligned derivation |
Key Data | [512]byte |
- | 512 | Encryption keys |
Data | []byte |
- | Size Aligned |
After each FirmwareBlock a new one follows, or EOF. So far each new one addresses the next memory block sequentially, without gaps.
Note that if ASFileHeader has Compressed field set, the Data will be smaller than the actual region.
package radiacode
func AlignSize(size uint32) uint32 {
if (size % 8) != 0 {
size = (size & uint32(0xFFFFFFF8)) + 8
}
return size
}
See Encryption notes