Firmware SDK
twr_info.c
1 #include <twr_info.h>
2 #include <twr_log.h>
3 
4 #ifndef VERSION_MAJOR
5 #define VERSION_MAJOR 0
6 #endif
7 
8 #ifndef VERSION_MINOR
9 #define VERSION_MINOR 0
10 #endif
11 
12 #ifndef VERSION_PATCH
13 #define VERSION_PATCH 0
14 #endif
15 
16 static uint32_t signature
17  __attribute__((section(".pib_signature")));
18 
19 static uint8_t version
20  __attribute__((section(".pib_version")));
21 
22 static uint16_t size
23  __attribute__((section(".pib_size")));
24 
25 static uint32_t serial_number
26  __attribute__((section(".pib_serial_number")));
27 
28 static uint16_t hw_revision
29  __attribute__((section(".pib_hw_revision")));
30 
31 static uint32_t hw_variant
32  __attribute__((section(".pib_hw_variant")));
33 
34 static char vendor_name[32]
35  __attribute__((section(".pib_vendor_name")));
36 
37 static char product_name[32]
38  __attribute__((section(".pib_product_name")));
39 
40 static int16_t rf_offset
41  __attribute__((section(".pib_rf_offset")));
42 
43 static uint32_t crc
44  __attribute__((section(".pib_crc")));
45 
46 static bool pib_valid;
47 
48 static void
49 calc_crc(uint32_t *crc, const uint8_t *buf, size_t len)
50 {
51  for (size_t i = 0; i < len; i++)
52  {
53  *crc ^= buf[i];
54 
55  for (int j = 0; j < 8; j++)
56  {
57  *crc = (*crc >> 1) ^ (0xedb88320 & ~((*crc & 1) - 1));
58  }
59  }
60 
61  *crc = ~*crc;
62 }
63 
64 void twr_info_init(void)
65 {
66  twr_info_pib_t res = twr_info_pib_check();
67 
68  char *type = "";
69 
70  switch (res)
71  {
72  case TWR_INFO_PIB_VALID:
73  return;
74  case TWR_INFO_PIB_ERR_SIGNATURE:
75  type = "signature";
76  break;
77  case TWR_INFO_PIB_ERR_VERSION:
78  type = "version";
79  break;
80  case TWR_INFO_PIB_ERR_SIZE:
81  type = "size";
82  break;
83  case TWR_INFO_PIB_ERR_CRC:
84  type = "crc";
85  break;
86  default:
87  break;
88  }
89 
90  if(type[0] == '\0')
91  {
92  return;
93  }
94 
95  twr_log_error("APP: Integrity check for PIB failed %s", type);
96 }
97 
98 twr_info_pib_t
99 twr_info_pib_check(void)
100 {
101  pib_valid = false;
102 
103  if (signature != 0xbabecafe)
104  return TWR_INFO_PIB_ERR_SIGNATURE;
105 
106  if (version != 1)
107  return TWR_INFO_PIB_ERR_VERSION;
108 
109  if (size != 88 + 4 + 4)
110  return TWR_INFO_PIB_ERR_SIZE;
111 
112  uint32_t crc_ = 0xffffffff;
113 
114  calc_crc(&crc_, (const uint8_t *)&signature, sizeof(signature));
115  calc_crc(&crc_, (const uint8_t *)&version, sizeof(version));
116  calc_crc(&crc_, (const uint8_t *)&size, sizeof(size));
117  calc_crc(&crc_, (const uint8_t *)&serial_number, sizeof(serial_number));
118  calc_crc(&crc_, (const uint8_t *)&hw_revision, sizeof(hw_revision));
119  calc_crc(&crc_, (const uint8_t *)&hw_variant, sizeof(hw_variant));
120  calc_crc(&crc_, (const uint8_t *)&vendor_name, sizeof(vendor_name));
121  calc_crc(&crc_, (const uint8_t *)&product_name, sizeof(product_name));
122  calc_crc(&crc_, (const uint8_t *)&rf_offset, sizeof(rf_offset));
123 
124  // twr_log_debug("crc 0x%08x", crc_);
125  if (crc != crc_)
126  {
127  return TWR_INFO_PIB_ERR_CRC;
128  }
129 
130  pib_valid = true;
131 
132  return TWR_INFO_PIB_VALID;
133 }
134 
135 uint32_t
136 twr_info_serial_number(void)
137 {
138  return pib_valid ? serial_number : 0;
139 }
140 
141 uint16_t
142 twr_info_hw_revision(void)
143 {
144  return pib_valid ? hw_revision : 0;
145 }
146 
147 uint32_t
148 twr_info_hw_variant(void)
149 {
150  return pib_valid ? hw_variant : 0;
151 }
152 
153 uint32_t
154 twr_info_fw_version(void)
155 {
156  if (pib_valid)
157  {
158  return VERSION_MAJOR << 24 | VERSION_MINOR << 16 | VERSION_PATCH << 8;
159  }
160  else
161  {
162  return 0;
163  }
164 }
165 
166 const char *
167 twr_info_vendor_name(void)
168 {
169  if (pib_valid)
170  {
171  return vendor_name;
172  }
173  else
174  {
175  return "";
176  }
177 }
178 
179 const char *
180 twr_info_product_name(void)
181 {
182  if (pib_valid)
183  {
184  return product_name;
185  }
186  else
187  {
188  return "";
189  }
190 }
void void void void void twr_log_error(const char *format,...) __attribute__((format(printf
Log ERROR message (annotated in log as <E>)