DispatcherCmd.cpp
Go to the documentation of this file.
1 #include "EventDispatcher_CommandSet/DispatcherCmd.h"
2 
3 #pragma GCC diagnostic ignored "-Woverflow"
4 
5 #include <sys/types.h>
6 #include <stdint.h>
7 #include <unistd.h>
8 #include <string.h>
9 
10 // These macros allow for the correct setting and extracting of bit fields
11 // from the given size word.
12 //#if __BYTE_ORDER == __LITTLE_ENDIAN
13 //#define SWAB32(word) (word)
14 //#define SWAB64(word) (word)
15 //#elif __BYTE_ORDER == __BIG_ENDIAN
16 #define SWAB32(word) ( (((word) & 0xFF000000) >> 24) | (((word) & 0x00FF0000) >> 8) | (((word) & 0x0000FF00) << 8 | (((word) & 0x000000FF) << 24)) )
17 #define SWAB64(word) ( SWAB32( (uint32_t)((word)>>32) ) | (uint64_t)SWAB32( (uint32_t)(word) )<<32 )
18 //#endif
19 
20 
21 DispatcherCMD::DispatcherCMD(uint8_t* input_buffer){
22  Acknowledge_flag = false;
23  external_buff = NULL;
24 
25  deserializeCmd(input_buffer);
26 
28  buff = buff_base;
29 
30 }
31 
32 DispatcherCMD::DispatcherCMD(void* output_buff, bool ack){
33  // Initialize
34  Init(output_buff);
35  Acknowledge_flag = ack;
36 }
37 
38 DispatcherCMD::DispatcherCMD(DispatcherCommands cmd, void* output_buff, bool ack){
39  // Initialize
40  Init(output_buff);
41  Acknowledge_flag = ack;
42  // Setup the command with default values
43  setCommandDefault(cmd);
44  // Serialize the command to the buffer
45  serializeCmd();
46 }
47 
48 DispatcherCMD::DispatcherCMD(DispatcherCommands cmd, int32_t value, void* output_buff, bool ack){
49  // Initialize
50  Init(output_buff);
51  Acknowledge_flag = ack;
52 
53  // Setup the command
54  aCommand.cmd = cmd;
55  aCommand.data.push_back(value);
56 
57  // Serialize the command to the buffer
58  serializeCmd();
59 }
60 
61 DispatcherCMD::DispatcherCMD(DispatcherCommands cmd, int32_t value1, int32_t value2, void* output_buff, bool ack){
62  // Initialize
63  Init(output_buff);
64 
65  Acknowledge_flag = ack;
66 
67  // Setup the command
68  aCommand.cmd = cmd;
69  aCommand.data.push_back(value1);
70  aCommand.data.push_back(value2);
71 
72  // Serialize the command to the buffer
73  serializeCmd();
74 }
75 
76 DispatcherCMD::DispatcherCMD(DispatcherCommands cmd, std::vector<int32_t> values, void* output_buff, bool ack){
77  // Initialize
78  Init(output_buff);
79 
80  Acknowledge_flag = ack;
81 
82  // Setup the command
83  aCommand.cmd = cmd;
85 
86  // Serialize the command to the buffer
87  serializeCmd();
88 }
89 
90 
92 }
93 
95  aCommand.cmd = cmd;
96  aCommand.data.clear();
97  aCommand.data.push_back(value);
98 
99  serializeCmd();
100  return;
101 }
102 
104  aCommand.cmd = cmd;
105  aCommand.data.clear();
106  aCommand.data = values;
107 
108  serializeCmd();
109  return;
110 }
111 
113  // Zero the internal buffer
114  memset(internal_buff, 0, 256);
115 
116  // Reset the insertion point of the
117  // the internal buffer
118  buff = buff_base;
119  *buff8 =0;
120  buff8++;
121 
123  aCommand.data.clear();
124 }
125 
127  ssize_t cmdsize;
128 
129  // Calculate the length of the command
130  cmdsize = buff8 - buff8_base + 1;
131 
132  // Copy the serialized command out to the external buffer
133  memcpy(external_buff, internal_buff, cmdsize);
134 
135  return cmdsize;
136 }
137 
138 void DispatcherCMD::Init(void* output_buffer){
139  Acknowledge_flag = false;
140 
141  external_buff = output_buffer;
142 
143  // Zero the internal buffer
144  memset(internal_buff, 0, 256);
145 
146  // We initially serialize to the internal
147  // buffer
149 
150  // Set the buffer insertion point
151  // to the start of the buffer
152  buff = buff_base;
153 
154  // Write a leading zero byte count
155  *buff8 = 0;
156 
157  // Advance one byte so we are
158  // ready for command insertion
159  buff8++;
160 
162  aCommand.data.clear();
163 }
164 
165 uint8_t* DispatcherCMD::InsertByteCountMagic(uint8_t* insert_buffer){
166 
167  // Copy the insertion pointer so we don't modify the original
168  uint8_t* local_buffp = insert_buffer;
169 
170  // Insert (write) the 64Bit magic number "0xBBADBEEF 0xBEEFBBAD"
171  *local_buffp = (uint8_t)DSPCMD_BYTECOUNTMAGIC_B0; ++local_buffp;
172  *local_buffp = (uint8_t)DSPCMD_BYTECOUNTMAGIC_B1; ++local_buffp;
173  *local_buffp = (uint8_t)DSPCMD_BYTECOUNTMAGIC_B2; ++local_buffp;
174  *local_buffp = (uint8_t)DSPCMD_BYTECOUNTMAGIC_B3; ++local_buffp;
175  *local_buffp = (uint8_t)DSPCMD_BYTECOUNTMAGIC_B4; ++local_buffp;
176  *local_buffp = (uint8_t)DSPCMD_BYTECOUNTMAGIC_B5; ++local_buffp;
177  *local_buffp = (uint8_t)DSPCMD_BYTECOUNTMAGIC_B6; ++local_buffp;
178  *local_buffp = (uint8_t)DSPCMD_BYTECOUNTMAGIC_B7; ++local_buffp;
179  return local_buffp;
180 }
181 
182 bool DispatcherCMD::deserializeCmd(void* input_buffer){
183  bool valid = true;
184  uint8_t size = 0;
185 
186  // First take off the byte count
187  size = ((uint8_t*)input_buffer)[0];
188 
189 #ifdef USE_MAGIC_NO
190  // Then take off the magic numbers
191  uint32_t* magic = (uint32_t*) (&(((uint8_t*)input_buffer)[1]));
192 
193  if( !(DSPCMD_BYTECOUNTMAGIC1 == magic[0] )){
194  valid = false;
195  }
196 
197  if( !(DSPCMD_BYTECOUNTMAGIC2 == magic[1] )){
198  valid = false;
199  }
200 
201  // Check the magic numbers
202  // if the check fails then set valid = false
203 #endif
204 
205  // Copy the buffer
206  if(valid){
207  memcpy(internal_buff, input_buffer, size);
208  }else{
209  return false; // Invalid buffer
210  }
211 
212  // Figure out where the end of the buffer is
213  uint8_t* endbuff = internal_buff + size;
214 
215  // At this point we have a local copy of the data
216  // we set a pointer to the start of it
218  size = buff8[0];
219  ++buff8;
220 
221 #ifdef USE_MAGIC_NO
222  magicNumberWord[0] = buff32[0];
223  magicNumberWord[1] = buff32[1];
224  ++buff32; // Advance over the first magic word
225  ++buff32; // Advance over the second magic word
226 #endif
227  // Then take the command character
228  aCommand.cmd = static_cast<DispatcherCommands>(buff8[0]);
229  ++buff8;
230 
231  // Unpack the data words into a the data vector untill we
232  // get to the end of the buffer
233  while( endbuff > buff8){
234  aCommand.data.push_back(SWAB32(buff32[0]));
235  ++buff32;
236  }
237 
238  // The last byte in the buffer should be the end mark, check that it is
239  if(DSPCMD_END != endbuff[0]){
240  valid = false;
241  }
242 
243  return valid;
244 }
245 
247  // Zero the leading byte count
248  *buff8_base = 0;
249 
250 #ifdef USE_MAGIC_NO
252 #endif
253 
254  // If we need to embed an acknowledgement flag
255  // put that in next
256  if(Acknowledge_flag){
257  *buff8 = (uint8_t)DSPCMD_ACK;
258  buff8++;
259  }
260 
261  // Write the command into the buffer
262  *buff8 = (uint8_t)aCommand.cmd;
263  buff8++;
264 
265  // Write the data values into the buffer
266  for(uint i=0; i<aCommand.data.size();++i ){
267  *buff32 = SWAB32(aCommand.data[i]);
268  buff32++;
269  }
270 
271  // Write the end value
272  *buff8 = (uint8_t)DSPCMD_END;
273  buff8++;
274 
275  // Rewrite the leading byte count
276  // first calculate the command size in bytes and check that it is
277  // able to fit into 1 byte (i.e. a value less than 255)
278  uint8_t cmdsize = (buff8 - buff8_base -1);
279  uint32_t bsize = (buff8 - buff8_base -1);
280  if(bsize < 255){
281  *buff8_base = cmdsize;
282  }else{
283  // If the size is over 1 byte we put in the overflow value
284  *buff8_base = 255;
285  }
286 
287  // Back up the insertion point one byte
288  // incase we want to insert more commands
289  buff8--;
290 
291  return;
292 }
293 
295  // Setup the command with default parameters
296  aCommand.cmd = cmd;
297 
298  switch(cmd){
299  // This block of commands have no parameter
300  case DSPCMD_IDENT:
301  case DSPCMD_DATA_VERSION:
304  case DSPCMD_NEXT_EVENT:
306  break;
307  // This block of commands take one parameter
309  aCommand.data.push_back(-1);
310  break;
312  aCommand.data.push_back(DEFAULT_MAX_EVENTS);
313  break;
318  // This block of commands take two parameters
319  case DSPCMD_SET_PRESCALE:
322  break;
323  default:
324  break;
325  }//endswitch
326  return;
327 }
328 
329 
330 
static uint8_t * InsertByteCountMagic(uint8_t *insertion_pointer)
bool deserializeCmd(void *input_buffer)
bool Acknowledge_flag
A command.
DispatcherCommands cmd
Definition: DispatcherCmd.h:61
uint8_t * buff8_base
uint32_t magicNumberWord[2]
std::vector< int32_t > data
Definition: DispatcherCmd.h:62
void Init(void *output_buff)
string cmd
Definition: run_hadd.py:52
const XML_Char int const XML_Char * value
Definition: expat.h:331
uint8_t * buff8
uint8_t internal_buff[256]
Pointer to the external output buffer.
void addCommand(DispatcherCommands cmd, int32_t value)
void setCommandDefault(DispatcherCommands cmd)
uint32_t * buff32
DispatcherCMD(void *output_buff, bool ack=false)
#define SWAB32(word)
void * external_buff
unsigned int uint