KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
msg_sys.c
1 /*
2  * KM3NeT CLB v2 Firmware
3  * ----------------------
4  *
5  * Copyright 2013 National Institute for Subatomic Physics Nikhef
6  *
7  * All Rights Reserved.
8  *
9  *
10  * File : msg_sys.c
11  * Created : 17 jul. 2013
12  * Author : Vincent van Beveren
13  */
14 
15 #include <stdbool.h>
16 #include <string.h>
17 #include <stdio.h>
18 
19 #include "cfg_soc.h"
20 
21 #include "net/msg.h"
22 #include "util/log.h"
23 #include "util/databuffer.h"
24 #include "kernel/sys.h"
25 #include "kernel/loghist.h"
26 
27 #include "kernel/update.h"
28 #include "kernel/contun.h"
29 #include "runtime.h"
30 #include "subsys/sub_sys.h"
31 
32 // #define SIMULATE_UPDATE
33 
34 // LOG_DEF(MsgSys);
35 
36 /**
37  * Reads an address.
38  */
39 bool _msgPing(MsgId * msgId, DataBuffer * cmd)
40 {
41  // if (!msgRxBufCheck(cmd)) return false; // check if buffer still valid
42  cmd->cur = cmd->start;
43  msgTxReply(msgId, cmd);
44  return true;
45 }
46 
47 bool _msgDateRev(MsgId * msgId, DataBuffer * cmd)
48 {
49  if (!msgRxBufCheck(cmd)) return false; // check if buffer still valid
50 
51 
52  uint8_t buf[9];
53 
54  DataBuffer reply = DB_BUF_INIT(buf, sizeof(buf));
55 
56  dbWriteU32(&reply, sysHwDateRev());
57  dbWriteU32(&reply, sysSwDateRev());
58  dbWriteU8(&reply, sysImageType());
59 
60  return msgTxReply(msgId, &reply);
61 }
62 
63 void resetBackoff() __attribute__((weak));
64 
65 bool _msgEvtTarget(MsgId * msgId, DataBuffer * buf)
66 {
67 
68 
69 
70  if (dbFree(buf) == 6) {
71  SockAddr addr;
72  dbReadU32(buf, &addr.ip);
73  dbReadU16(buf, &addr.port);
74 
75  if (addr.ip == 0 && addr.port == 0) {
76  msgSetEvtTarget(NULL);
77  } else {
78  msgSetEvtTarget(&addr);
79  }
80  } else if (dbLength(buf) == 0) {
81  msgSetEvtTarget(&(msgId->addr));
82  } else return false;
83 
84 
85 
86 
87  if (resetBackoff) resetBackoff();
88  return msgTxReply(msgId, NULL);
89 }
90 
91 
92 bool _msgSysUpdateStart(MsgId * msgId, DataBuffer * cmd)
93 {
94  uint16_t imgIdx;
95  uint16_t chunkCnt;
96  // Disable the event-target.
97  msgSetEvtTarget(NULL);
98  dbReadU16(cmd, &imgIdx);
99  dbReadU16(cmd, &chunkCnt);
100  if (!msgRxBufCheck(cmd)) {
101  return false; // check if buffer still valid
102  }
103 #ifndef SIMULATE_UPDATE
104  if (!updStart(imgIdx, chunkCnt))
105  {
106  return msgTxCurError(msgId);
107  }
108 #endif
109 
110  // okay, in update mode
111  return msgTxReply(msgId, NULL);
112 }
113 
114 
115 bool _msgReset(MsgId * msgId, DataBuffer * cmd)
116 {
117  return false;
118 }
119 
120 /* Event version */
121 bool _msgSysUpdateEnd(MsgId * msgId, DataBuffer * cmd)
122 {
123  if (!msgRxBufCheck(cmd)) return false; // check if buffer still valid
124 #ifndef SIMULATE_UPDATE
125  if (!updEnd(0, 0)) {
126  updCancel();
127  return msgTxCurError(msgId);
128  }
129 #endif
130  return msgTxReply(msgId, NULL);
131 }
132 
133 /* Synchronous versio */
134 bool _msgSysUpdateRecv(MsgId * msgId, DataBuffer * cmd)
135 {
136  uint16_t chunk;
137  if (dbReadU16(cmd, &chunk))
138  {
139  if (dbFree(cmd) == UPD_CHUNK_SIZE) {
140 #ifndef SIMULATE_UPDATE
141  if (!updWrite(chunk, cmd->cur)) {
142  return msgTxCurError(msgId);
143  }
144 #endif
145  return msgTxReply(msgId, NULL);
146  }
147  }
148  return false;
149 }
150 
151 
152 /* Synchronous versio */
153 bool _msgSysUpdateVerify(MsgId * msgId, DataBuffer * cmd)
154 {
155  uint16_t chunk;
156  uint8_t imgNo;
157  dbReadU8(cmd, &imgNo);
158  dbReadU16(cmd, &chunk);
159 
160  if (cmd->error == DB_ERR_NONE)
161  {
162  if (dbFree(cmd) == UPD_CHUNK_SIZE)
163  {
164 #ifndef SIMULATE_UPDATE
165  bool result;
166  if (!updVerify(imgNo, chunk, cmd->cur, &result)) {
167  return msgTxCurError(msgId);
168  }
169 #endif
170  uint8_t outData;
171  DataBuffer outBuf = DB_BUF_INIT(&outData, 1);
172  dbWriteBool(&outBuf, result);
173 
174  return msgTxReply(msgId, &outBuf);
175  }
176  }
177  return false;
178 }
179 
180 
181 bool _msgBoot(MsgId * msgId, DataBuffer * cmd)
182 {
183  uint8_t imgNo;
184  dbReadU8(cmd, &imgNo);
185  if (!msgRxBufCheck(cmd)) return false; // check if buffer still valid
186 
187  if (imgNo >= FLASH_MAX_IMAGES) return false;
188 
190  return msgTxReply(msgId, NULL);
191 }
192 
193 void goldenStop() __attribute__((weak));
194 
195 bool _msgGoldenStop(MsgId * msgId, DataBuffer * cmd)
196 {
197  if (!msgRxBufCheck(cmd)) return false;
198  if (goldenStop) {
199  goldenStop();
200  return msgTxReply(msgId, NULL);;
201  }
202  return false;
203 }
204 
205 
206 bool _msgCoreDumpClr(MsgId * msgId, DataBuffer * cmd)
207 {
208  if (!msgRxBufCheck(cmd)) return false;
209 
210 
211 #ifdef DEBUG
212  coreDumpClear();
213 #endif
214 
215  return msgTxReplyAck(msgId);
216 }
217 
218 bool _msgGoldenUnlock(MsgId * msgId, DataBuffer * cmd)
219 {
220  if (!msgRxBufCheck(cmd)) return false;
221  if (!updUnlock()) {
222  return msgTxCurError(msgId);
223  }
224  return msgTxReply(msgId, NULL);
225 }
226 
227 
228 
229 void _evtSysUpdateRecv(MsgId * msgId, DataBuffer * cmd)
230 {
231  uint16_t chunk;
232  if (dbReadU16(cmd, &chunk))
233  {
234  if (dbFree(cmd) == UPD_CHUNK_SIZE) {
235 #ifndef SIMULATE_UPDATE
236  updWrite(chunk, cmd->cur);
237 #endif
238  }
239  }
240 }
241 
242 /*
243  * Returns the last log lines, from the given index position. Provide 0 if unknown.
244  *
245  * Input:
246  * LAST_ID UINT32 Last received log line number ID
247  * Output:
248  * LOG_LINES STR* A number of log-lines until an empty string is returned
249  * LAST_ID UINT32 Last log line ID returned
250  */
251 bool _msgLogGet(MsgId * msgId, DataBuffer * cmd)
252 {
253  const int REQ_POSTFIX_SIZE = sizeof(uint32_t) + DB_STR_OVERHEAD;
254 
255  uint32_t lastId;
256 
257  dbReadU32(cmd, &lastId);
258  uint32_t newId = 0;
259  if (!msgRxBufCheck(cmd)) return false;
260 
261  uint8_t logMem[512];
262  DataBuffer rpl = DB_BUF_INIT(logMem, sizeof(logMem));
263 
264  char * logLine = NULL;
265 
266  //
267  newId = lhGetLineById(lastId, &logLine);
268  while (logLine != NULL)
269  {
270  // check if it still fits in the buffer
271  if (strlen(logLine) + DB_STR_OVERHEAD + REQ_POSTFIX_SIZE > dbFree(&rpl)) break;
272 
273  dbWriteString(&rpl, logLine, 0);
274 
275  lastId = newId;
276  newId = lhGetLineById(lastId, &logLine);
277  }
278 
279  // empty string to signal end of log data
280  dbWriteString(&rpl, "", 0);
281  dbWriteU32(&rpl, lastId);
282 
283  //
284  return msgTxReply(msgId, &rpl);
285 }
286 
287 static char _pLogBuf[128];
288 
289 bool _msgPLogGet(MsgId * msgId, DataBuffer * cmd)
290 {
291  if (dbFree(cmd) == 4)
292  {
293  int32_t len;
294  dbReadI32(cmd, &len);
295  if (len < 0) return false;
296  if (!lhFlashItStart(len)) return msgTxCurError(msgId);
297  }
298 
299  if (!msgRxBufCheck(cmd)) return false;
300 
301  uint8_t logMem[512];
302  DataBuffer rpl = DB_BUF_INIT(logMem, sizeof(logMem));
303 
304  // check if there are any pending lines. If s, write them.
305  if (strlen(_pLogBuf) > 0) dbWriteString(&rpl, _pLogBuf, 128);
306  // clear buffer, just in case lhFlashItNext() return false.
307  _pLogBuf[0] = '\0';
308 
309  while (lhFlashItNext(_pLogBuf, 128))
310  {
311  int len = strlen(_pLogBuf);
312  // check if the next line fits, if not break
313  if (len + DB_STR_OVERHEAD > dbFree(&rpl)) break;
314  dbWriteString(&rpl, _pLogBuf, 128);
315  _pLogBuf[0] = '\0'; // mark as send
316  }
317 
318  // if log buffer is empty, and there is space, write end marker.
319  if (strlen(_pLogBuf) == 0 && DB_STR_OVERHEAD <= dbFree(&rpl))
320  {
321  dbWriteString(&rpl, "", 1);
322  }
323 
324  return msgTxReply(msgId, &rpl);
325 }
326 
327 
328 bool _msgImgGet(MsgId * msgId, DataBuffer * cmd)
329 {
330  if (!msgRxBufCheck(cmd)) return false;
331 
332  uint8_t msgBuf[1 + FLASH_MAX_IMAGES * 9];
333 
334  DataBuffer rpl = DB_BUF_INIT(msgBuf, sizeof(msgBuf));
335 
336  dbWriteU8(&rpl, FLASH_MAX_IMAGES);
337 
338  for (int i = 0; i < FLASH_MAX_IMAGES; ++i)
339  {
340  UpdImgInfo imgInfo;
341  if (!updImgInfo(i, &imgInfo))
342  return msgTxCurError(msgId);
343  dbWriteU32(&rpl, imgInfo.fwRev);
344  dbWriteU32(&rpl, imgInfo.swRev);
345  dbWriteI8(&rpl, imgInfo.imgType);
346  }
347 
348  return msgTxReply(msgId, &rpl);
349 }
350 
351 bool _msgConTunInit(MsgId * msgId, DataBuffer * cmd)
352 {
353  if (dbFree(cmd) == 6) {
354  SockAddr addr;
355  dbReadU32(cmd, &addr.ip);
356  dbReadU16(cmd, &addr.port);
357 
358  if (addr.ip == 0 && addr.port == 0) {
359  conTunInit(&(msgId->addr));
360  } else {
361  conTunInit(&addr);
362  }
363  } else if (dbFree(cmd) == 0) {
364  conTunDeinit();
365  } else return false;
366 
367  return msgTxReplyAck(msgId);
368 }
369 
370 #define CON_TUN_MAX_RX 16
371 
372 bool _msgConTunSend(MsgId * msgId, DataBuffer * cmd)
373 {
374 
375  char ptp[CON_TUN_MAX_RX];
376  char secLm[CON_TUN_MAX_RX];
377 
378  dbReadString(cmd, ptp, CON_TUN_MAX_RX);
379  dbReadString(cmd, secLm, CON_TUN_MAX_RX);
380 
381  conTunSend(ptp, secLm);
382 
383  return msgTxReplyAck(msgId);
384 }
385 
386 #define RT_CONFIG_VERSION 1
387 
388 bool _msgRtConfig(MsgId * msgId, DataBuffer * cmd)
389 {
390 
391  if (dbFree(cmd) == 2)
392  {
393  uint8_t ver;
394  dbReadU8(cmd, &ver);
395  if (ver != RT_CONFIG_VERSION)
396  return msgTxError(msgId, ERROR(E_INVARGUMENT, E_INVARGUMENT_DESCR));
397 
398  int8_t img;
399  dbReadI8(cmd, &img);
400 
401  if (!msgRxBufCheck(cmd)) return false;
402 
403  rtSetImage(img);
404  if (errHas()) return msgTxCurError(msgId);
405  } else if (!msgRxBufCheck(cmd)) return false;
406 
407  uint8_t msgBuf[2];
408  DataBuffer rpl = DB_BUF_INIT(msgBuf, sizeof(msgBuf));
409  dbWriteU8(&rpl, RT_CONFIG_VERSION);
410  dbWriteI8(&rpl, rtImage());
411  return msgTxReply(msgId, &rpl);
412 }
413 
414 
415 
bool updVerify(uint32_t imgNo, uint32_t chunkNo, uint8_t *chunk, bool *result)
Verify a chunk.
Definition: update.c:143
bool errHas()
Returns whether there is an error pending.
Definition: err.c:52
bool updWrite(uint32_t chunkNo, uint8_t *chunk)
Write a update chunk.
Definition: update.c:102
Defines the configuration of the LM32 SOC for the CLBv2.
void coreDumpClear()
Clears core dump information.
Definition: sys.c:156
int rtImage()
Returns the image loaded for runtime.
Definition: runtime.c:59
bool dbReadU8(DataBuffer *buf, uint8_t *byte)
Reads an unsigned byte.
Definition: databuffer.c:153
bool updUnlock()
Unlocks the golden image for writing.
Definition: update.c:225
uint32_t sysHwDateRev()
Returns the Hardware date revision.
Definition: sys.c:386
Provides access to the runtime image booting.
bool dbReadString(DataBuffer *buf, char *s, int size)
Reads a string from the stream.
Definition: databuffer.c:103
bool _msgPing(MsgId *id, DataBuffer *buf)
Reads an address.
Definition: msg_sys.c:39
bool updImgInfo(uint32_t imgNo, UpdImgInfo *imgInfo)
Retrieve image information for the specified location.
Definition: update.c:193
System start up and management.
bool lhFlashItNext(char *bufPtr, int bufSize)
Get the next element.
Definition: loghist.c:250
static bool dbWriteBool(DataBuffer *buf, bool boolean)
Writes a boolean.
Definition: databuffer.h:249
bool dbReadU16(DataBuffer *buf, uint16_t *u)
Reads a unsigned short (16 bits unsigned) integer.
Definition: databuffer.c:186
uint16_t port
Port number.
Definition: net.h:34
bool dbWriteI8(DataBuffer *buf, int8_t byte)
Writes a byte.
Definition: databuffer.c:129
int8_t imgType
Image type.
Definition: update.h:145
#define DB_ERR_NONE
Indicates no error.
Definition: databuffer.h:34
uint8_t * start
Start Pointer.
Definition: databuffer.h:47
bool updEnd(uint32_t *chunkLostList, uint32_t *chunksCount)
Ends the update.
Definition: update.c:163
uint32_t lhGetLineById(uint32_t lastId, char **logLinePtr)
Returns the last log-line based on log-line ID.
Definition: loghist.c:214
static bool msgTxCurError(MsgId *id)
Invoke to reply the current global error.
Definition: msg.h:378
uint32_t ip
IP address.
Definition: net.h:33
Defines a DataBuffer structure.
Definition: databuffer.h:45
#define E_INVARGUMENT
Generic error: invalid argument.
Definition: errorcode.h:112
static uint32_t dbFree(DataBuffer *buf)
Returns the number of bytes still free in the buffer.
Definition: databuffer.h:95
static uint32_t dbLength(DataBuffer *buf)
Returns the lenght of the current buffer.
Definition: databuffer.h:83
Handles MCF packed messages from the higher protocol layer.
int error
Last error.
Definition: databuffer.h:50
void msgSetEvtTarget(SockAddr *sockAddr)
Set the target for all events, or pass NULL to unset.
Definition: msg.c:251
bool updStart(int imageIdx, uint32_t chunkCount)
Starts an image update.
Definition: update.c:81
void conTunSend(char *ptp, char *secLm32)
Send characters to PTP core and second LM32.
Definition: contun.c:109
Combination of IP address and port.
Definition: net.h:31
void sysArmReset(ResetType rTyp, int imgNo)
Resets the CLB.
Definition: sub_sys.c:370
bool msgTxReply(MsgId *id, DataBuffer *buf)
Invoke to send a reply.
Definition: msg.c:286
Force, reset at any point, select image, 0 - golden.
Definition: sub_sys.h:33
DataBuffer reads and writes data into a buffer in the same format as defined in the data Java DataOut...
void updCancel()
Aborts the update.
Definition: update.c:178
uint32_t swRev
Software revision.
Definition: update.h:144
Stores logging history.
bool msgTxError(MsgId *id, int errCode, const char *errMsg, const char *name)
Invoke to send an error response.
Definition: msg.c:293
uint32_t fwRev
Firmware revision.
Definition: update.h:143
bool msgRxBufCheck(DataBuffer *buf)
Checks the received buffer, and logs an error if there is something wrong.
Definition: msg.c:141
This modules provides console tunneling, for both PTP core and 2nd LM32.
bool dbWriteU8(DataBuffer *buf, uint8_t byte)
Writes a unsigned byte.
Definition: databuffer.c:146
bool dbReadI8(DataBuffer *buf, int8_t *byte)
Reads an byte.
Definition: databuffer.c:136
bool lhFlashItStart(int count)
Start the iteration through the flash entries.
Definition: loghist.c:230
bool dbReadU32(DataBuffer *buf, uint32_t *u)
Reads an 32 bits unsigned integer.
Definition: databuffer.c:219
bool conTunInit(SockAddr *addr)
Initializes the console tunnel.
Definition: contun.c:81
static void conTunDeinit()
Deinitializes the console tunnel.
Definition: contun.h:39
SockAddr addr
the address of the sender
Definition: msg.h:275
If defined, events will not require an acknowledge.
Definition: msg.h:274
bool dbWriteString(DataBuffer *buf, const char *s, int max)
Writes a String as &#39;sort of&#39; UTF-8 encoding, as defined in the Java DataOuput and DataInput writeUTF ...
Definition: databuffer.c:74
uint32_t sysSwDateRev()
Returns the Software date revision.
Definition: sys.c:391
bool dbReadI32(DataBuffer *buf, int32_t *i)
Reads an 32 bits signed integer.
Definition: databuffer.c:262
#define ERROR(CODE,...)
Expands an error code to an error code with a description (if ERROR_W_DESCR is declared).
bool rtSetImage(int imgNo)
Sets the runtime boot image number.
Definition: runtime.c:66
#define UPD_CHUNK_SIZE
chunk size for updates, in bytes
Definition: update.h:32
Implements a generic logger facility.
#define DB_STR_OVERHEAD
Overhead for a String.
Definition: databuffer.h:40
#define DB_BUF_INIT(PTR, LEN)
Simple buffer initialization.
Definition: databuffer.h:63
System subsystem.
uint8_t * cur
Current Pointer.
Definition: databuffer.h:49
static bool msgTxReplyAck(MsgId *id)
Replies a simple ACK with no content.
Definition: msg.h:323
static uint8_t sysImageType()
Number identifying the image type.
Definition: sys.h:69
bool dbWriteU32(DataBuffer *buf, uint32_t u)
Writes an 32 bits unsigned integer.
Definition: databuffer.c:200
Facilitates the update process.