-
Notifications
You must be signed in to change notification settings - Fork 1
/
uarp_payload.py
56 lines (50 loc) · 1.65 KB
/
uarp_payload.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import io
import struct
from dataclasses import dataclass, field
@dataclass
class UarpPayload(object):
# The tag representing this payload, i.e. 'FOTA'.
tag: bytes
# i.e. 100 in '100.7916.1052884864.1'.
major_version: int
# i.e. 7916 in '100.7916.1052884864.1'.
minor_version: int
# i.e. 1052884864 in '100.7916.1052884864.1'.
release_version: int
# i.e. 1 in '100.7916.1052884864.1'.
build_version: int
# Metadata size.
metadata_length: int
# Observed to be zero.
metadata_offset: int
# Payloads length
payloads_length: int
# Payloads offset
payloads_offset: int
# Metadata held by the firmware.
# Note that, in some firmware, it may be empty.
metadata: bytes = field(repr=False)
# The data represented by this payload.
payload: bytes = field(repr=False)
def __init__(self, metadata: bytes, data: io.BufferedReader):
# Parse metadata.
(
metadata_tag_size,
self.tag,
self.major_version,
self.minor_version,
self.release_version,
self.build_version,
self.metadata_offset,
self.metadata_length,
self.payloads_offset,
self.payloads_length,
) = struct.unpack_from(">I4sIIIIIIII", metadata)
# Obtain our metadata and payload.
data.seek(self.metadata_offset)
self.payload = data.read(self.metadata_length)
data.seek(self.payloads_offset)
self.payload = data.read(self.payloads_length)
def get_tag(self) -> str:
"""Returns a string with the given tag name."""
return self.tag.decode("utf-8")