KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mcf.h
Go to the documentation of this file.
1 /*
2  * KM3NeT CLB v2 Firmware
3  *
4  * Copyright 2013 KM3NeT Collaboration
5  *
6  * All Rights Reserved.
7  *
8  * mcf.h
9  *
10  * Created on: 31 mei 2013
11  * Author: Vincent van Beveren
12  */
13 
14 
15 #ifndef MCF_H_
16 #define MCF_H_
17 
18 #include "util/databuffer.h"
19 
20 /**
21  * @file
22  *
23  * @ingroup network
24  *
25  * Message Container Format formatter / parser.
26  *
27  * Reading a MCF message can be done as follows:
28  *
29  * @code
30  * void decodeMCF(uint8_t * ptr, int bufLen)
31  * {
32  * MFCState decoderState;
33  * MFCMessage * msg = &decoderState.msg;
34  * mfcInit(&decoderState, ptr, bufLen);
35  * while (mfcDecodeNext(&decoderState))
36  * {
37  * printf("Current Message %u of %u\n", decoderState.msgCur, decoderState.msgCount);
38  * printf("- Type: %u.%u\n", MFC_TYP2GROUP(msg->typ), MFC_TYP2SUB(msg->typ));
39  * printf("- Time : %lu, Length: %u\n", msg->timestamp, msg->cntLength);
40  * printf("- Class: %u, Identifer: %u\u", msg->clazz, msg->identifier);
41  * // obtain msg->cntPtr for the actual content.
42  * }
43  *
44  * }
45  * @endcode
46  *
47  * Write one can also be done. The next example writes a MCF message with two commands, the
48  * first contains 'hello' and the second contains 'world'.
49  *
50  * @code
51  * #define HELLO_GROUP 0x1
52  * #define HELLO_HELLO MFC_2TYPE(HELLO_GROUP, 0x1)
53  * #define HELLO_WORLD MFC_2TYPE(HELLO_GROUP, 0x2)
54  *
55  * static int msgId;
56  *
57  * void encodeMsgStr(MFCState * state, uint16_t typ, char * cnt, int cntLen)
58  * {
59  * MFCMessage * msg = encoderState->msg;
60  * mfcEncodeNext(state);
61  * msg->class = MFC_CLASS_CMD;
62  * msg->typ = typ;
63  * msg->identifier = msgId++;
64  * msg->timestamp = timeGetDeayMillis();
65  * memcopy(msg->cntPtr, cnt, cntLen);
66  * msg->cntLen = cntLen;
67  * }
68  *
69  * void encodeMCF(uint8_t * ptr, int bufLen)
70  * {
71  * MFCState encoderState;
72  * mfcInit(&encoderState, ptr, bufLen);
73  * encodeMsgStr(&encoderState, HELLO_HELLO, "hello", 5);
74  * encodeMsgStr(&encoderState, HELLO_WORLD, "world", 5);
75  * mfcEncodeFinish(&encoderState);
76  * }
77  * @endcode
78  */
79 
80 #define MCF_CLASS_ERROR 0x00
81 #define MCF_CLASS_CMD 0x01
82 #define MCF_CLASS_REPLY 0x02
83 #define MCF_CLASS_EVENT 0x03
84 
85 #define MCF_TYPE_GROUP_SHIFT 6
86 #define MCF_TYPE_GROUP_MASK 0x0FC0
87 #define MCF_TYPE_NUM_SHIFT 0
88 #define MCF_TYPE_NUM_MASK 0x003F
89 
90 #define MCF_MK_TYPE(GROUP, NUM) \
91  ( ( ( GROUP ) << MCF_TYPE_GROUP_SHIFT & MCF_TYPE_GROUP_MASK ) | \
92  ( ( NUM ) << MCF_TYPE_NUM_SHIFT & MCF_TYPE_NUM_MASK ) )
93 
94 typedef struct
95 {
96  uint8_t identifier;
97  uint8_t clazz;
98  uint16_t typ;
99  uint32_t timestamp;
100  uint8_t * cntPtr;
101  uint16_t cntLength;
102 } MCFMessage;
103 
104 typedef struct
105 {
106  DataBuffer buf;
107  uint32_t tsOffset;
108  uint8_t msgCount;
109  uint8_t msgCur;
110  MCFMessage msg;
111 } MCFState;
112 
113 /**
114  * Dependency function. Should return milliseconds since midnight, UTF
115  * @return
116  */
117 uint32_t _mcfTimeStamp();
118 
119 /**
120  * Initializes the decoding or encoding of a Message Container Formatted message.
121  *
122  * @param state A pointer to a MCFState object. All values will be overwritten.
123  * @param bufPtr A pointer to a buffer to read from or write into.
124  * @param bufLen The length of the buffer.
125  */
126 void mcfInitState(MCFState * state, uint8_t * bufPtr, uint32_t bufLen);
127 
128 /**
129  * Decodes the next message. After initializing the MCF structure, you should first call this
130  * function before reading the message content.
131  *
132  * @param state The decoder state.
133  *
134  * @retval true There is a next message to be decoded
135  * false There are no more messages to be decoded, or interpretation failure.
136  */
137 bool mcfDecodeNext(MCFState * state);
138 
139 /**
140  * Creates a new encoding entry. After initializing the MCF structure, you should first call this
141  * function before writing the message content.
142  *
143  * @param state The decoder state.
144  * @retval true The next entry was created, you can fill it in.
145  * false The next entry could not be created or the previous could not be finalized.
146  * Either the time span is too large or it is out of space.
147  */
148 bool mcfEncodeNext(MCFState * state);
149 
150 /**
151  * Returns the number of bytes available for content in the current message.
152  *
153  * @return The number of bytes available for content in the next message.
154  */
155 uint32_t mcfEncodeFree();
156 
157 /**
158  * Encodes the content of a databuffer into the container.
159  *
160  * @param state The encoder state
161  * @param db The databuffer
162  * @retval true DataBuffer copied as content
163  * false DataBuffer not copied, probably not enough space. See err module.
164  */
165 bool mcfEncodeBuffer(MCFState * state, DataBuffer * db);
166 
167 /**
168  * Returns the number of bytes available for content in the NEXT message. Use this to decide
169  * whether or not you wish to do a mcfEncodeNext() or mcfEncodeFinish() and start a new message.
170  *
171  * @return The number of bytes available for content in the next message.
172  */
173 uint32_t mcfEncodeFreeNext();
174 
175 /**
176  * Call this after encoding to complete the MCF packet.
177  *
178  * @param state The decoder state.
179  * @return The complete length of the MCF message.
180  */
181 uint32_t mcfEncodeFinish(MCFState * state);
182 
183 #endif /* MCF_H_ */
uint32_t mcfEncodeFinish(MCFState *state)
Call this after encoding to complete the MCF packet.
Definition: mcf.c:180
uint32_t _mcfTimeStamp()
Dependency function.
Definition: network.c:90
uint32_t mcfEncodeFree()
Returns the number of bytes available for content in the current message.
bool mcfEncodeBuffer(MCFState *state, DataBuffer *db)
Encodes the content of a databuffer into the container.
Definition: mcf.c:157
bool mcfEncodeNext(MCFState *state)
Creates a new encoding entry.
Definition: mcf.c:170
Defines a DataBuffer structure.
Definition: databuffer.h:45
uint32_t mcfEncodeFreeNext()
Returns the number of bytes available for content in the NEXT message.
DataBuffer reads and writes data into a buffer in the same format as defined in the data Java DataOut...
Definition: mcf.h:94
void mcfInitState(MCFState *state, uint8_t *bufPtr, uint32_t bufLen)
Initializes the decoding or encoding of a Message Container Formatted message.
Definition: mcf.c:63
Definition: mcf.h:104
bool mcfDecodeNext(MCFState *state)
Decodes the next message.
Definition: mcf.c:82