EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
packetRoutines.C
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file packetRoutines.C
1 /*
2 ** packetRoutines.C
3 **
4 ** Author: $Author: pinkenbu $
5 ** Date: $Date: 2004/10/19 19:21:05 $
6 **
7 ** $Log: packetRoutines.C,v $
8 ** Revision 1.4 2004/10/19 19:21:05 pinkenbu
9 ** fix insure warnings
10 **
11 ** Revision 1.3 2004/07/15 13:06:07 phoncs
12 ** DLW: add extendPacketDataBlock call to extendUnstructDataBlock
13 **
14 ** Revision 1.8 2001/03/12 17:13:00 kelly
15 ** committed packetRoutines bugfix
16 **
17 ** Revision 1.7 1998/12/16 15:40:52 markacs
18 ** (stephen markacs) changes to rawFormat code to stop using bool,true,false
19 **
20 ** Revision 1.6 1998/12/11 22:02:06 markacs
21 ** (stephen markacs) adding log into cvs tags
22 **
23 */
24 /*
25 ** Contains routines which manipulate packets in a fixed-length contiguous
26 ** array in memory. Uses generic routines in Cpacket to extract fields
27 ** from the packet headersand uses routines in dataBlock to maintain the
28 ** relevant fields in the data block descriptor.
29 */
30 
31 #ifndef VXWORKS
32 #include "malloc.h"
33 #include <stdlib.h>
34 #endif
35 
36 #include "phenixOnline.h"
37 #include "packetPublic.h"
38 #include "Cpacket.h"
39 #include "dataBlock.h"
40 #include "packetRoutines.h"
41 
42 /*
43 ** makeEmptyPacket
44 **
45 ** Routine to make a new packet header in a buffer pointed to by "newPacketPtr".
46 ** The header is created with "empty" data, debug and error blocks.
47 **
48 ** A pointer to the PHDWORD immediately following the "packet" (the header) is returned
49 */
50 
51 PTR_ret makeEmptyPacket (PACKET_ptr packet_ptr, UINT maxPacketLen, UINT packetId)
52 {
53  UINT packetLength = makePacketHdr (packet_ptr, maxPacketLen);
54  if (packetLength == valueFailure) return ptrFailure;
55 
56  /*
57  ** Now set user-specified fields
58  */
59  setPacketId(packet_ptr, packetId);
60 
61  /*
62  ** Success
63  */
64  return findPacketEnd(packet_ptr)+1;
65 }
66 
67 /*
68 ** setPacketUnstructured
69 */
71  UINT inHitFormat)
72 {
73  /*
74  ** Check for valid input
75  */
76  if (inWordSize > 4 ) return logicFailure;
77 
78  /*
79  ** Set the packet structure field
80  */
81  setPacketStructure(packet_ptr, Unstructured);
82 
83  /*
84  ** Make the data descriptor.
85  */
86 
87  makeUnstructPacketDataDescr (packet_ptr, inWordSize, inHitFormat);
88 
89  return logicSuccess;
90 }
91 
92 /*
93 ** Make an unstructured empty packet. a pointer to the PHDWORD following the empty
94 ** packet is returned
95 */
96 PTR_ret makeUnstructPacket (PACKET_ptr packet_ptr, UINT maxPacketLength,
97  UINT packetId, UINT inWordSize, UINT inHitFormat)
98 {
99  VALUE_ret packetLength;
100  LOGIC_ret logicalResult;
101 
102  packetLength = makePacketHdr (packet_ptr, maxPacketLength);
103  if (packetLength == valueFailure) return ptrFailure;
104 
105  /*
106  ** Now set user-specified fields
107  */
108  setPacketId(packet_ptr, packetId);
109  setPacketStructure(packet_ptr, Unstructured);
110 
111  logicalResult = makeUnstructPacketDataDescr(packet_ptr, inWordSize, inHitFormat);
112  if (!logicalResult) return ptrFailure;
113  else return findPacketEnd(packet_ptr)+1;
114 }
115 
116 /*
117 ** Store a new error entry in the packet. Return the length of the
118 ** resulting error block
119 */
120 LOGIC_ret appendPacketError (PACKET_ptr packet_ptr, UINT maxPacketLength,
121  ERRORENTRYV1_ptr errorEntry_ptr)
122 {
123  PHDWORD newLength;
124  PHDWORD* newError_ptr = findPacketErrorStart(packet_ptr) +
125  getPacketErrorLength(packet_ptr);
126 
127  /*
128  ** Extend the length of the error block (and the packet)
129  */
130  newLength = extendPacketErrorBlock(packet_ptr, maxPacketLength,
132  if (newLength == valueFailure) return logicFailure;
133 
134  /*
135  ** Now copy in the error entry
136  */
137  dwordCopy(newError_ptr, (PHDWORD*) errorEntry_ptr, errorEntryV1Length);
138  return logicSuccess;
139 }
140 
141 /*
142 ** Reserve space for numDwords in the packet debug block. Return a pointer to the
143 ** start of the debug block. The assumption is that the user will completely
144 ** fill the requested space.
145 */
146 PTR_ret reservePacketDebugData (PACKET_ptr packet_ptr, UINT maxPacketLength,
147  UINT numDwords)
148 {
149  PHDWORD newLength;
150 
151  /*
152  ** We can only do this when there's no error block
153  */
154  if (getPacketErrorLength(packet_ptr) > 0) {
156  }
157 
158  /*
159  ** Extend the length of the debug block.
160  */
161  newLength = extendPacketDebugBlock(packet_ptr, maxPacketLength, numDwords);
162  if (newLength == valueFailure) return ptrFailure;
163  else return findPacketDebugStart(packet_ptr);
164 }
165 
166 /*
167 ** Initiate a write operation into a pristine unstructured packet.
168 **
169 ** The packet must be initially empty. It is extended to allow space
170 ** fir maxNumWords of unstructured data. A pointer to the start of
171 ** the packet is returned.
172 */
173 PTR_ret startUnstructDataWrite (PACKET_ptr packet_ptr, UINT maxPacketLength,
174  PHDWORD maxNumWords)
175 {
176  PHDWORD* write_ptr;
177  PHDWORD dataBlockLength;
178 
179  /*
180  **
181  ** in the packet. Also make sure there's no debug or error blocks yet because
182  ** we assume that these will be written after the data
183  */
184  if (!emptyPacket(packet_ptr)) {
186  return ptrFailure;
187  }
188 
189  /*
190  ** Check for unstructured packet.
191  */
192  if (getPacketStructure(packet_ptr) != Unstructured) {
194  return ptrFailure;
195  }
196 
197  /*
198  ** Try to extend the unstructured data block
199  */
200  dataBlockLength = extendUnstructPacketDataBlock(packet_ptr, maxNumWords);
201  if (dataBlockLength == valueFailure) return ptrFailure;
202 
203  /*
204  ** Now update the packet length
205  */
206  extendPacketDataBlock(packet_ptr, maxPacketLength, dataBlockLength);
207 
208  write_ptr = findPacketDataStart (packet_ptr);
209 
210  /*
211  ** Now return to the user the pointer to where data is to be written
212  */
213  return write_ptr;
214 }
215 
216 /*
217 ** Finish writing unstructured block
218 */
219 PTR_ret finishUnstructDataWrite (PACKET_ptr packet_ptr, UINT maxPacketLength,
220  PHDWORD actualWords)
221 {
222  PHDWORD deltaWords;
223  PHDWORD newLength;
224  PHDWORD maxNumWords = getUnstructPacketDataLengthWords(packet_ptr);
225 
226 
227  /*
228  ** Check to make sure that user hasn't written beyond the pre-set maximum
229  */
230  if (actualWords > maxNumWords) {
231  /*
232  ** This is a serious error, data will be corrupted
233  */
234  return ptrFailure;
235  }
236 
237  /*
238  ** Now update the length
239  */
240  deltaWords = maxNumWords - actualWords;
241  newLength = extendUnstructPacketDataBlock(packet_ptr, -((int) deltaWords) );
242  if (newLength == valueFailure) return ptrFailure;
243 
244  return findPacketEnd(packet_ptr)+1;
245 }
246 
247 /*
248 ** storePacketHits
249 **
250 ** General routine to store data in a packet. Works for unstructured and (hopefully)
251 ** all structured packets. Currently only implementationis for unstructured packets.
252 **
253 ** For unstructured data, numHits = number of words of size "wordSize"
254 ** data_arr should point to the input data.
255 ** address_arr is ignored.
256 **
257 */
258 VALUE_ret storePacketHits (PACKET_ptr packet_ptr, UINT maxPacketLen,
259  UINT* address_arr, BYTE* data_arr,
260  UINT numHits, UINT maxNumHits)
261 {
262  /*
263  ** Check to make sure packet has valid header and is empty
264  */
265  if (!validPacketHdr(packet_ptr))
266  {
268  return valueFailure;
269  }
270  if (!emptyPacket(packet_ptr))
271  {
273  return valueFailure;
274  }
275 
276  /*
277  ** Handle different structure types
278  */
279  switch (getPacketStructure(packet_ptr)) {
280  case Unstructured: {
281  PHDWORD newLength, result;
282 
283  /*
284  ** Get the size of the data block.
285  */
286  newLength = extendUnstructPacketDataBlock(packet_ptr, numHits);
287 
288  result = extendPacketDataBlock(packet_ptr, maxPacketLen, newLength);
289  if (result == valueFailure) return valueFailure;
290  else {
291  BYTE *data_ptr;
292  PHDWORD numBytes = numHits*getUnstructPacketWordSize(packet_ptr);
293 
294  /*
295  ** Now copy the data in.
296  */
297  data_ptr = (BYTE*) findPacketDataStart(packet_ptr);
298  byteCopy (data_ptr, data_arr, numBytes);
299  data_ptr += numBytes;
300  byteClear (data_ptr, getUnstructPacketDataPadding(packet_ptr));
301 
302  return getPacketLength(packet_ptr);
303  }
304  break;
305  }
306  default:
308  return valueFailure;
309  }
310 
311  /*
312  ** Success
313  */
314  return getPacketLength(packet_ptr);
315 }
316 
317 /*
318 ** fetchPacketHits
319 */
320 VALUE_ret fetchPacketHits (PACKET_ptr packet_ptr, UINT** address_arr, BYTE** hits_arr, UINT* hitLength)
321 {
322  /*
323  ** Make sure we got a pointer to a real packet
324  */
325  if (!validPacketHdr (packet_ptr))
326  return valueFailure;
327 
328  /*
329  ** Handle different structure types
330  */
331  switch (getPacketStructure (packet_ptr)) {
332  case Unstructured:
333  {
334  PHDWORD numWords = getUnstructPacketDataLengthWords(packet_ptr);
335  UINT wordSize = getUnstructPacketWordSize(packet_ptr);
336  PHDWORD* unformBlock_ptr = findPacketDataStart (packet_ptr);
337  PHDWORD numBytes = numWords*wordSize;
338 
339  /*
340  ** Allocate space for data array
341  */
342  BYTE* hits_ptr = (BYTE *) malloc (numBytes);
343  byteCopy (hits_ptr, (BYTE *) unformBlock_ptr, numBytes);
344 
345  /*
346  ** Alllocate space for one address (0)
347  */
348  *address_arr = (UINT*) malloc (sizeof(UINT));
349  **address_arr = 0;
350 
351  *hits_arr = hits_ptr;
352  *hitLength = wordSize;
353  return numWords;
354  }
355 }
356 
357  /*
358  ** Success
359  */
360 
361  return 0;
362 }
363 
364 
365 
366 
367 
368 
369 
370 
371 
372 
373 
374 
375 
376 
377 
378 
379