]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/HOMER/AliHLTHOMERReader.cxx
correcting printf-like format length modifier
[u/mrichter/AliRoot.git] / HLT / BASE / HOMER / AliHLTHOMERReader.cxx
CommitLineData
2be16a33 1/************************************************************************
2**
3**
4** This file is property of and copyright by the Technical Computer
5** Science Group, Kirchhoff Institute for Physics, Ruprecht-Karls-
6** University, Heidelberg, Germany, 2001
7** This file has been written by Timm Morten Steinbeck,
8** timm@kip.uni-heidelberg.de
9**
10**
11** See the file license.txt for details regarding usage, modification,
12** distribution and warranty.
13** Important: This file is provided without any warranty, including
14** fitness for any particular purpose.
15**
16**
17** Newer versions of this file's package will be made available from
18** http://web.kip.uni-heidelberg.de/Hardwinf/L3/
19** or the corresponding page of the Heidelberg Alice Level 3 group.
20**
21*************************************************************************/
22
23/*
24***************************************************************************
25**
26** $Author$ - Initial Version by Timm Morten Steinbeck
27**
28** $Id$
29**
30***************************************************************************
31*/
32
9e91e956 33/** @file AliHLTHOMERReader.cxx
2be16a33 34 @author Timm Steinbeck
35 @date Sep 14 2007
36 @brief HLT Online Monitoring Environment including ROOT - Reader
37 @note migrated from PubSub HLT-stable-20070905.141318 (rev 2375) */
38
04a939f7 39// see header file for class documentation
2be16a33 40// or
41// refer to README to build package
42// or
43// visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
44
45#include "AliHLTHOMERReader.h"
6a8e0bb4 46//#include <stdio.h>
5a1c4a5e 47#ifdef __SUNPRO_CC
48#include <string.h>
49#else
6a8e0bb4 50#include <cstring>
5a1c4a5e 51#endif
6a8e0bb4 52#include <cerrno>
2be16a33 53#include <netdb.h>
6a8e0bb4 54//#include <sys/types.h>
55//#include <sys/socket.h>
56//#include <netinet/in.h>
57//#include <netinet/tcp.h>
2be16a33 58#include <unistd.h>
72ae28cd 59#ifndef __CYGWIN__
2be16a33 60#include <rpc/types.h>
72ae28cd 61#endif
2be16a33 62#include <fcntl.h>
63#include <sys/stat.h>
64#include <netinet/in.h>
65#include <arpa/inet.h>
66#ifdef USE_ROOT
67#include <Rtypes.h>
68#endif
69
70
71#define MOD_BIN "MOD BIN\n"
72#define MOD_ASC "MOD ASC\n"
73#define GET_ONE "GET ONE\n"
74#define GET_ALL "GET ALL\n"
75
27011446 76// MAXHOSTNAMELEN not defined on macosx
77// 686-apple-darwin9-gcc-4.0.1
78#ifndef MAXHOSTNAMELEN
79#define MAXHOSTNAMELEN 64
80#endif
81
2be16a33 82#ifdef USE_ROOT
fe1edbae 83ClassImp(AliHLTMonitoringReader);
84ClassImp(AliHLTHOMERReader);
2be16a33 85#endif
86
87
88
89
90
91#ifdef USE_ROOT
fe1edbae 92AliHLTHOMERReader::AliHLTHOMERReader()
746d2a94 93 :
94 fCurrentEventType(~(homer_uint64)0),
95 fCurrentEventID(~(homer_uint64)0),
96 fBlockCnt(0),
97 fMaxBlockCnt(0),
98 fBlocks(NULL),
99 fDataSourceCnt(0),
100 fTCPDataSourceCnt(0),
101 fShmDataSourceCnt(0),
102 fDataSourceMaxCnt(0),
04a939f7 103 fDataSources(NULL),
104 fConnectionStatus(0),
105 fErrorConnection(~(unsigned int)0),
106 fEventRequestAdvanceTime(0)
2be16a33 107 {
1d47dbac 108// Reader implementation of the HOMER interface.
109// The HLT Monitoring Environment including ROOT is
110// a native interface to ship out data from the HLT chain.
111// See pdf document shiped with the package
112// for class documentation and tutorial.
2be16a33 113 Init();
114 }
115#endif
116
117
fe1edbae 118AliHLTHOMERReader::AliHLTHOMERReader( const char* hostname, unsigned short port )
746d2a94 119 :
fe1edbae 120 AliHLTMonitoringReader(),
cfa641b1 121 TObject(),
746d2a94 122 fCurrentEventType(~(homer_uint64)0),
123 fCurrentEventID(~(homer_uint64)0),
124 fBlockCnt(0),
125 fMaxBlockCnt(0),
126 fBlocks(NULL),
127 fDataSourceCnt(0),
128 fTCPDataSourceCnt(0),
129 fShmDataSourceCnt(0),
130 fDataSourceMaxCnt(0),
04a939f7 131 fDataSources(NULL),
132 fConnectionStatus(0),
133 fErrorConnection(~(unsigned int)0),
134 fEventRequestAdvanceTime(0)
2be16a33 135 {
04a939f7 136// see header file for class documentation
137// For reading from a TCP port
2be16a33 138 Init();
139 if ( !AllocDataSources(1) )
140 {
141 fErrorConnection = 0;
142 fConnectionStatus = ENOMEM;
143 return;
144 }
145 fConnectionStatus = AddDataSource( hostname, port, fDataSources[0] );
146 if ( fConnectionStatus )
147 fErrorConnection = 0;
148 else
149 {
150 fDataSourceCnt++;
151 fTCPDataSourceCnt++;
152 fDataSources[0].fNdx = 0;
153 }
154 }
155
09eb5e44 156AliHLTHOMERReader::AliHLTHOMERReader( unsigned int tcpCnt, const char** hostnames, const unsigned short* ports )
746d2a94 157 :
fe1edbae 158 AliHLTMonitoringReader(),
cfa641b1 159 TObject(),
746d2a94 160 fCurrentEventType(~(homer_uint64)0),
161 fCurrentEventID(~(homer_uint64)0),
162 fBlockCnt(0),
163 fMaxBlockCnt(0),
164 fBlocks(NULL),
165 fDataSourceCnt(0),
166 fTCPDataSourceCnt(0),
167 fShmDataSourceCnt(0),
168 fDataSourceMaxCnt(0),
04a939f7 169 fDataSources(NULL),
170 fConnectionStatus(0),
171 fErrorConnection(~(unsigned int)0),
172 fEventRequestAdvanceTime(0)
2be16a33 173 {
04a939f7 174// see header file for class documentation
175// For reading from multiple TCP ports
2be16a33 176 Init();
177 if ( !AllocDataSources(tcpCnt) )
178 {
179 fErrorConnection = 0;
180 fConnectionStatus = ENOMEM;
181 return;
182 }
183 for ( unsigned int n = 0; n < tcpCnt; n++, fDataSourceCnt++, fTCPDataSourceCnt++ )
184 {
185 fConnectionStatus = AddDataSource( hostnames[n], ports[n], fDataSources[n] );
186 if ( fConnectionStatus )
187 {
188 fErrorConnection = n;
189 return;
190 }
191 fDataSources[n].fNdx = n;
192 }
193 }
194
fe1edbae 195AliHLTHOMERReader::AliHLTHOMERReader( key_t shmKey, int shmSize )
746d2a94 196 :
fe1edbae 197 AliHLTMonitoringReader(),
cfa641b1 198 TObject(),
746d2a94 199 fCurrentEventType(~(homer_uint64)0),
200 fCurrentEventID(~(homer_uint64)0),
201 fBlockCnt(0),
202 fMaxBlockCnt(0),
203 fBlocks(NULL),
204 fDataSourceCnt(0),
205 fTCPDataSourceCnt(0),
206 fShmDataSourceCnt(0),
207 fDataSourceMaxCnt(0),
04a939f7 208 fDataSources(NULL),
209 fConnectionStatus(0),
210 fErrorConnection(~(unsigned int)0),
211 fEventRequestAdvanceTime(0)
2be16a33 212 {
04a939f7 213// see header file for class documentation
214// For reading from a System V shared memory segment
2be16a33 215 Init();
216 if ( !AllocDataSources(1) )
217 {
218 fErrorConnection = 0;
219 fConnectionStatus = ENOMEM;
220 return;
221 }
222 fConnectionStatus = AddDataSource( shmKey, shmSize, fDataSources[0] );
223 if ( fConnectionStatus )
224 fErrorConnection = 0;
225 else
226 {
227 fDataSourceCnt++;
228 fShmDataSourceCnt++;
229 fDataSources[0].fNdx = 0;
230 }
231 }
232
09eb5e44 233AliHLTHOMERReader::AliHLTHOMERReader( unsigned int shmCnt, const key_t* shmKeys, const int* shmSizes )
746d2a94 234 :
fe1edbae 235 AliHLTMonitoringReader(),
cfa641b1 236 TObject(),
746d2a94 237 fCurrentEventType(~(homer_uint64)0),
238 fCurrentEventID(~(homer_uint64)0),
239 fBlockCnt(0),
240 fMaxBlockCnt(0),
241 fBlocks(NULL),
242 fDataSourceCnt(0),
243 fTCPDataSourceCnt(0),
244 fShmDataSourceCnt(0),
245 fDataSourceMaxCnt(0),
04a939f7 246 fDataSources(NULL),
247 fConnectionStatus(0),
248 fErrorConnection(~(unsigned int)0),
249 fEventRequestAdvanceTime(0)
2be16a33 250 {
04a939f7 251// see header file for class documentation
252// For reading from multiple System V shared memory segments
2be16a33 253 Init();
254 if ( !AllocDataSources(shmCnt) )
255 {
256 fErrorConnection = 0;
257 fConnectionStatus = ENOMEM;
258 return;
259 }
260 for ( unsigned int n = 0; n < shmCnt; n++, fDataSourceCnt++, fShmDataSourceCnt++ )
261 {
262 fConnectionStatus = AddDataSource( shmKeys[n], shmSizes[n], fDataSources[n] );
263 if ( fConnectionStatus )
264 {
265 fErrorConnection = n;
266 return;
267 }
268 fDataSources[n].fNdx = n;
269 }
270 }
271
09eb5e44 272AliHLTHOMERReader::AliHLTHOMERReader( unsigned int tcpCnt, const char** hostnames, const unsigned short* ports,
273 unsigned int shmCnt, const key_t* shmKeys, const int* shmSizes )
746d2a94 274 :
fe1edbae 275 AliHLTMonitoringReader(),
cfa641b1 276 TObject(),
746d2a94 277 fCurrentEventType(~(homer_uint64)0),
278 fCurrentEventID(~(homer_uint64)0),
279 fBlockCnt(0),
280 fMaxBlockCnt(0),
281 fBlocks(NULL),
282 fDataSourceCnt(0),
283 fTCPDataSourceCnt(0),
284 fShmDataSourceCnt(0),
285 fDataSourceMaxCnt(0),
04a939f7 286 fDataSources(NULL),
287 fConnectionStatus(0),
288 fErrorConnection(~(unsigned int)0),
289 fEventRequestAdvanceTime(0)
2be16a33 290 {
04a939f7 291// see header file for class documentation
292// For reading from multiple TCP ports and multiple System V shared memory segments
2be16a33 293 Init();
294 if ( !AllocDataSources(tcpCnt+shmCnt) )
295 {
296 fErrorConnection = 0;
297 fConnectionStatus = ENOMEM;
298 return;
299 }
300 for ( unsigned int n = 0; n < tcpCnt; n++, fDataSourceCnt++, fTCPDataSourceCnt++ )
301 {
302 fConnectionStatus = AddDataSource( hostnames[n], ports[n], fDataSources[n] );
303 if ( fConnectionStatus )
304 {
305 fErrorConnection = n;
306 return;
307 }
308 fDataSources[n].fNdx = n;
309 }
310 for ( unsigned int n = 0; n < shmCnt; n++, fDataSourceCnt++, fShmDataSourceCnt++ )
311 {
312 fConnectionStatus = AddDataSource( shmKeys[n], shmSizes[n], fDataSources[tcpCnt+n] );
313 if ( fConnectionStatus )
314 {
315 fErrorConnection = tcpCnt+n;
316 return;
317 }
318 fDataSources[n].fNdx = n;
319 }
320 }
8c617325 321
29e6fd20 322AliHLTHOMERReader::AliHLTHOMERReader( const void* pBuffer, int size )
8c617325 323 :
324 AliHLTMonitoringReader(),
cfa641b1 325 TObject(),
8c617325 326 fCurrentEventType(~(homer_uint64)0),
327 fCurrentEventID(~(homer_uint64)0),
328 fBlockCnt(0),
329 fMaxBlockCnt(0),
330 fBlocks(NULL),
331 fDataSourceCnt(0),
332 fTCPDataSourceCnt(0),
333 fShmDataSourceCnt(0),
334 fDataSourceMaxCnt(0),
335 fDataSources(NULL),
336 fConnectionStatus(0),
337 fErrorConnection(~(unsigned int)0),
338 fEventRequestAdvanceTime(0)
339 {
340// see header file for class documentation
341// For reading from a System V shared memory segment
342 Init();
343 if ( !AllocDataSources(1) )
344 {
345 fErrorConnection = 0;
346 fConnectionStatus = ENOMEM;
347 return;
348 }
29e6fd20 349 fConnectionStatus = AddDataSource(const_cast<void*>(pBuffer), size, fDataSources[0] );
8c617325 350 if ( fConnectionStatus )
351 fErrorConnection = 0;
352 else
353 {
354 fDataSourceCnt++;
aa5178e8 355 fShmDataSourceCnt++;
8c617325 356 fDataSources[0].fNdx = 0;
357 }
358 }
359
fe1edbae 360AliHLTHOMERReader::~AliHLTHOMERReader()
2be16a33 361 {
04a939f7 362// see header file for class documentation
2be16a33 363 ReleaseCurrentEvent();
364 FreeDataSources();
242e6536 365
366 if (fDataSources)
367 delete [] fDataSources;
2be16a33 368 }
369
fe1edbae 370int AliHLTHOMERReader::ReadNextEvent()
2be16a33 371 {
04a939f7 372// see header file for class documentation
373// Read in the next available event
2be16a33 374 return ReadNextEvent( false, 0 );
375 }
376
fe1edbae 377int AliHLTHOMERReader::ReadNextEvent( unsigned long timeout )
2be16a33 378 {
04a939f7 379// see header file for class documentation
380// Read in the next available event
2be16a33 381 return ReadNextEvent( true, timeout );
382 }
383
fe1edbae 384unsigned long AliHLTHOMERReader::GetBlockDataLength( unsigned long ndx ) const
2be16a33 385 {
04a939f7 386// see header file for class documentation
387// Return the size (in bytes) of the current event's data
388// block with the given block index (starting at 0).
2be16a33 389 if ( ndx >= fBlockCnt )
390 return 0;
391 return fBlocks[ndx].fLength;
392 }
393
fe1edbae 394const void* AliHLTHOMERReader::GetBlockData( unsigned long ndx ) const
2be16a33 395 {
04a939f7 396// see header file for class documentation
397// Return a pointer to the start of the current event's data
398// block with the given block index (starting at 0).
2be16a33 399 if ( ndx >= fBlockCnt )
400 return NULL;
401 return fBlocks[ndx].fData;
402 }
403
fe1edbae 404const char* AliHLTHOMERReader::GetBlockSendNodeID( unsigned long ndx ) const
2be16a33 405 {
04a939f7 406// see header file for class documentation
407// Return IP address or hostname of node which sent the
408// current event's data block with the given block index
409// (starting at 0).
410// For HOMER this is the ID of the node on which the subscriber
411// that provided this data runs/ran.
2be16a33 412 if ( ndx >= fBlockCnt )
413 return NULL;
414#ifdef DEBUG
415 if ( fBlocks[ndx].fSource >= fDataSourceCnt )
416 {
937cec81 417 fprintf( stderr, "%s:%d: Internal Error: fBlocks[ndx].fSource (%u) >= fDataSourceCnt (%u)\n",
2be16a33 418 __FILE__, __LINE__, fBlocks[ndx].fSource, fDataSourceCnt );
419 return NULL;
420 }
421#endif
422 return fDataSources[ fBlocks[ndx].fSource ].fHostname;
423 //return fBlocks[ndx].fOriginatingNodeID;
424 }
425
fe1edbae 426homer_uint8 AliHLTHOMERReader::GetBlockByteOrder( unsigned long ndx ) const
2be16a33 427 {
04a939f7 428// see header file for class documentation
429// Return byte order of the data stored in the
430// current event's data block with the given block index (starting at 0).
431// 0 is unknown alignment,
432// 1 ist little endian,
433// 2 is big endian. */
2be16a33 434 if ( ndx >= fBlockCnt )
435 return 0;
436 //return ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fType.fID;
437 return *(((homer_uint8*)fBlocks[ndx].fMetaData)+kByteOrderAttribute_8b_Offset);
438 }
04a939f7 439
fe1edbae 440homer_uint8 AliHLTHOMERReader::GetBlockTypeAlignment( unsigned long ndx, homer_uint8 dataType ) const
2be16a33 441 {
04a939f7 442// see header file for class documentation
443// Return the alignment (in bytes) of the given datatype
444// in the data stored in the current event's data block
445// with the given block index (starting at 0).
446// Possible values for the data type are
447// 0: homer_uint64
448// 1: homer_uint32
449// 2: uin16
450// 3: homer_uint8
451// 4: double
452// 5: float
2be16a33 453 if ( ndx >= fBlockCnt )
454 return 0;
455 if ( dataType > (kFloatAlignment_8b_Offset-kAlignment_8b_StartOffset) )
456 return 0;
457 //return ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fType.fID;
458 return *(((homer_uint8*)fBlocks[ndx].fMetaData)+kAlignment_8b_StartOffset+dataType);
459 }
460
fe1edbae 461homer_uint64 AliHLTHOMERReader::GetBlockStatusFlags( unsigned long ndx ) const
2be16a33 462 {
04a939f7 463// see header file for class documentation
2be16a33 464 if ( ndx >= fBlockCnt )
465 return 0;
466 return *(((homer_uint64*)fBlocks[ndx].fMetaData)+kStatusFlags_64b_Offset);
467 }
468
469/* HOMER specific */
470/* Return the type of the data in the current event's data
471 block with the given block index (starting at 0). */
fe1edbae 472homer_uint64 AliHLTHOMERReader::GetBlockDataType( unsigned long ndx ) const
2be16a33 473 {
04a939f7 474// see header file for class documentation
2be16a33 475 if ( ndx >= fBlockCnt )
476 return ~(homer_uint64)0;
477 //return ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fType.fID;
478 return *(((homer_uint64*)fBlocks[ndx].fMetaData)+kType_64b_Offset);
479 }
480
481/* Return the origin of the data in the current event's data
482 block with the given block index (starting at 0). */
fe1edbae 483homer_uint32 AliHLTHOMERReader::GetBlockDataOrigin( unsigned long ndx ) const
2be16a33 484 {
04a939f7 485// see header file for class documentation
2be16a33 486 if ( ndx >= fBlockCnt )
487 return ~(homer_uint32)0;
488 //return (homer_uint32)( ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fSubType1.fID );
489 return (homer_uint32)*(((homer_uint64*)fBlocks[ndx].fMetaData)+kSubType1_64b_Offset);
490 }
491
492/* Return a specification of the data in the current event's data
493 block with the given block index (starting at 0). */
fe1edbae 494homer_uint32 AliHLTHOMERReader::GetBlockDataSpec( unsigned long ndx ) const
2be16a33 495 {
04a939f7 496// see header file for class documentation
2be16a33 497 if ( ndx >= fBlockCnt )
498 return ~(homer_uint32)0;
499 //return (homer_uint32)( ((AliHLTRIBlockDescriptorV1*)fBlocks[ndx].fMetaData)->fSubType2.fID );
500 return (homer_uint32)*(((homer_uint64*)fBlocks[ndx].fMetaData)+kSubType2_64b_Offset);
501 }
502
34bd0bb2 503homer_uint64 AliHLTHOMERReader::GetBlockBirthSeconds( unsigned long ndx ) const
504 {
505// see header file for class documentation
506 if ( ndx >= fBlockCnt )
507 return 0;
508 return *(((homer_uint64*)fBlocks[ndx].fMetaData)+kBirth_s_64b_Offset);
509 }
510
511homer_uint64 AliHLTHOMERReader::GetBlockBirthMicroSeconds( unsigned long ndx ) const
512 {
513// see header file for class documentation
514 if ( ndx >= fBlockCnt )
515 return 0;
516 return *(((homer_uint64*)fBlocks[ndx].fMetaData)+kBirth_us_64b_Offset);
517 }
518
2be16a33 519/* Find the next data block in the current event with the given
520 data type, origin, and specification. Returns the block's
521 index. */
fe1edbae 522unsigned long AliHLTHOMERReader::FindBlockNdx( homer_uint64 type, homer_uint32 origin,
2be16a33 523 homer_uint32 spec, unsigned long startNdx ) const
524 {
04a939f7 525// see header file for class documentation
2be16a33 526 for ( unsigned long n=startNdx; n < fBlockCnt; n++ )
527 {
528 if ( ( type == 0xFFFFFFFFFFFFFFFFULL || *(((homer_uint64*)fBlocks[n].fMetaData)+kType_64b_Offset)==type ) &&
529 ( origin == 0xFFFFFFFF || (homer_uint32)( *(((homer_uint64*)fBlocks[n].fMetaData)+kSubType1_64b_Offset) )==origin ) &&
530 ( spec == 0xFFFFFFFF || (homer_uint32)( *(((homer_uint64*)fBlocks[n].fMetaData)+kSubType2_64b_Offset) )==spec ) )
531 return n;
532 }
533 return ~(unsigned long)0;
534 }
535
536/* Find the next data block in the current event with the given
537 data type, origin, and specification. Returns the block's
538 index. */
fe1edbae 539unsigned long AliHLTHOMERReader::FindBlockNdx( char type[8], char origin[4],
2be16a33 540 homer_uint32 spec, unsigned long startNdx ) const
541 {
04a939f7 542// see header file for class documentation
2be16a33 543 for ( unsigned long n=startNdx; n < fBlockCnt; n++ )
544 {
545 bool found1=true, found2=true;
546 for ( unsigned i = 0; i < 8; i++ )
547 {
548 if ( type[i] != (char)0xFF )
549 {
550 found1=false;
551 break;
552 }
553 }
554 if ( !found1 )
555 {
556 found1 = true;
557 for ( unsigned i = 0; i < 8; i++ )
558 {
559 //printf( "%u: Comparing type '%c' and '%c'\n", i, ((char*)(((homer_uint64*)fBlocks[n].fMetaData)+kType_64b_Offset))[i], type[i] );
560 if ( ((char*)(((homer_uint64*)fBlocks[n].fMetaData)+kType_64b_Offset))[i] != type[i] )
561 {
562 found1=false;
563 break;
564 }
565 }
566 }
567 for ( unsigned i = 0; i < 4; i++ )
568 {
569 if ( origin[i] != (char)0xFF )
570 {
571 found2 = false;
572 break;
573 }
574 }
575 if ( !found2 )
576 {
577 found2 = true;
578 for ( unsigned i = 0; i < 4; i++ )
579 {
580 //printf( "Comparing origin '%c' and '%c'\n", ((char*)(((homer_uint64*)fBlocks[n].fMetaData)+kSubType1_64b_Offset))[i], origin[i] );
581 if ( ((char*)(((homer_uint64*)fBlocks[n].fMetaData)+kSubType1_64b_Offset))[i] != origin[i] )
582 {
583 found2=false;
584 break;
585 }
586 }
587 }
588 //printf( "Comparing spec '0x%08lX' and '0x%08lX'\n", (homer_uint32)( *(((homer_uint64*)fBlocks[n].fMetaData)+kSubType2_64b_Offset) ), spec );
589 if ( found1 && found2 &&
590 ( spec == 0xFFFFFFFF || ((homer_uint32)( *(((homer_uint64*)fBlocks[n].fMetaData)+kSubType2_64b_Offset)) )==spec ) )
591 return n;
592 }
593 return ~(unsigned long)0;
594 }
595
596/* Return the ID of the node that actually produced this data block.
597 This may be different from the node which sent the data to this
598 monitoring object as returned by GetBlockSendNodeID. */
fe1edbae 599const char* AliHLTHOMERReader::GetBlockCreateNodeID( unsigned long ndx ) const
2be16a33 600 {
04a939f7 601// see header file for class documentation
2be16a33 602 if ( ndx >= fBlockCnt )
603 return NULL;
604 return fBlocks[ndx].fOriginatingNodeID;
605 }
606
607
fe1edbae 608void AliHLTHOMERReader::Init()
2be16a33 609 {
04a939f7 610// see header file for class documentation
2be16a33 611 fCurrentEventType = ~(homer_uint64)0;
612 fCurrentEventID = ~(homer_uint64)0;
613 fMaxBlockCnt = fBlockCnt = 0;
614 fBlocks = NULL;
615
616 fDataSourceMaxCnt = fDataSourceCnt = fTCPDataSourceCnt = fShmDataSourceCnt = 0;
617 fDataSources = NULL;
618
619
620 fConnectionStatus = 0;
621 fErrorConnection = ~(unsigned int)0;
622
04a939f7 623 fEventRequestAdvanceTime = 0;
2be16a33 624 }
625
fe1edbae 626bool AliHLTHOMERReader::AllocDataSources( unsigned int sourceCnt )
2be16a33 627 {
04a939f7 628// see header file for class documentation
2be16a33 629 fDataSources = new DataSource[ sourceCnt ];
630 if ( !fDataSources )
631 return false;
6a8e0bb4 632 memset(fDataSources, 0, sizeof(DataSource)*sourceCnt);
2be16a33 633 fDataSourceCnt = 0;
634 fDataSourceMaxCnt = sourceCnt;
635 return true;
636 }
637
fe1edbae 638int AliHLTHOMERReader::AddDataSource( const char* hostname, unsigned short port, DataSource& source )
2be16a33 639 {
04a939f7 640// see header file for class documentation
2be16a33 641 struct hostent* he;
642 he = gethostbyname( hostname );
643 if ( he == NULL )
644 {
645 //fprintf( stderr, "Unable to determine remote host address from '%s'.\n", hostname );
646 return EADDRNOTAVAIL;
647 }
648
649 struct sockaddr_in remoteAddr;
650 remoteAddr.sin_family = AF_INET; // host byte order
651 remoteAddr.sin_port = htons(port); // short, network byte order
652 remoteAddr.sin_addr = *((struct in_addr *)he->h_addr);
653 memset(&(remoteAddr.sin_zero), '\0', 8); // zero the rest of the struct
654
655 // Create socket and connect to target program on remote node
656 source.fTCPConnection = socket( AF_INET, SOCK_STREAM, 0 );
657 if ( source.fTCPConnection == -1 )
658 {
659 return errno;
660 }
661
662 int ret;
663
664 ret = connect( source.fTCPConnection, (struct sockaddr *)&remoteAddr, sizeof(struct sockaddr) );
665 if ( ret == -1 )
666 {
667 ret=errno;
668 close( source.fTCPConnection );
669 return ret;
670 }
671
672 ret = write( source.fTCPConnection, MOD_BIN, strlen(MOD_BIN) );
673 if ( ret != (int)strlen(MOD_BIN) )
674 {
675 ret=errno;
676 close( source.fTCPConnection );
677 return ret;
678 }
679
c9926985 680 unsigned hostnamelen=strlen( hostname );
681 char* tmpchar = new char[ hostnamelen+1 ];
2be16a33 682 if ( !tmpchar )
683 {
684 close( source.fTCPConnection );
685 return ENOMEM;
686 }
c9926985 687 strncpy( tmpchar, hostname, hostnamelen );
688 tmpchar[hostnamelen]=0;
2be16a33 689 source.fHostname = tmpchar;
690
691 source.fType = kTCP;
692 source.fTCPPort = port;
693 source.fData = NULL;
694 source.fDataSize = 0;
695 source.fDataRead = 0;
696 return 0;
697 }
698
fe1edbae 699int AliHLTHOMERReader::AddDataSource( key_t shmKey, int shmSize, DataSource& source )
2be16a33 700 {
04a939f7 701// see header file for class documentation
2be16a33 702 int ret;
703 char* tmpchar = new char[ MAXHOSTNAMELEN+1 ];
704 if ( !tmpchar )
705 {
706 return ENOMEM;
707 }
708 gethostname( tmpchar, MAXHOSTNAMELEN );
709 tmpchar[MAXHOSTNAMELEN]=(char)0;
710 source.fHostname = tmpchar;
711
712 source.fShmID = shmget( shmKey, shmSize, 0660 );
713 if ( source.fShmID == -1 )
714 {
715 ret = errno;
716 delete [] source.fHostname;
717 return ret;
718 }
719
720 source.fShmPtr = (void*)shmat( source.fShmID, NULL, 0 );
721
722 if ( !source.fShmPtr )
723 {
724 ret = errno;
725 shmctl( source.fShmID, IPC_RMID, NULL );
726 delete [] source.fHostname;
727 return ret;
728 }
729
730 source.fType = kShm;
731 source.fShmKey = shmKey;
732 source.fShmSize = shmSize;
733 source.fDataSize = 0;
734 source.fDataRead = 0;
735 return 0;
736 }
737
8c617325 738int AliHLTHOMERReader::AddDataSource( void* pBuffer, int size, DataSource& source )
739 {
740// see header file for class documentation
741// a buffer data source is like a shm source apart from the shm attach and detach
742// procedure. Furthermore, the size indicator at the beginning of the buffer is not
743// cleared right before sources are read but after the reading.
d76bc02a 744 //int ret;
8c617325 745 if ( !pBuffer || size<=0) return EINVAL;
746
747 char* tmpchar = new char[ MAXHOSTNAMELEN+1 ];
748 if ( !tmpchar )
749 {
750 return ENOMEM;
751 }
752 gethostname( tmpchar, MAXHOSTNAMELEN );
753 tmpchar[MAXHOSTNAMELEN]=(char)0;
754 source.fHostname = tmpchar;
755
756 source.fShmID = -1;
757 // the data buffer does not contain a size indicator in the first 4 bytes
758 // like the shm source buffer. Still we want to use the mechanism to invalidate/
759 // trigger by clearing the size indicator. Take the source.fShmSize variable.
760 source.fShmPtr = &source.fShmSize;
761 source.fType = kBuf;
762 source.fShmKey = 0;
763 source.fShmSize = size;
764 source.fData = pBuffer;
765 source.fDataSize = 0;
766 source.fDataRead = 0;
767 return 0;
768 }
769
fe1edbae 770void AliHLTHOMERReader::FreeDataSources()
2be16a33 771 {
04a939f7 772// see header file for class documentation
2be16a33 773 for ( unsigned n=0; n < fDataSourceCnt; n++ )
774 {
775 if ( fDataSources[n].fType == kTCP )
776 FreeTCPDataSource( fDataSources[n] );
8c617325 777 else if ( fDataSources[n].fType == kShm )
2be16a33 778 FreeShmDataSource( fDataSources[n] );
242e6536 779 if ( fDataSources[n].fHostname )
780 delete [] fDataSources[n].fHostname;
2be16a33 781 }
242e6536 782 fDataSourceCnt=0;
2be16a33 783 }
784
fe1edbae 785int AliHLTHOMERReader::FreeShmDataSource( DataSource& source )
2be16a33 786 {
04a939f7 787// see header file for class documentation
2be16a33 788 if ( source.fShmPtr )
6001c5d5 789 shmdt( (char*)source.fShmPtr );
2be16a33 790// if ( source.fShmID != -1 )
791// shmctl( source.fShmID, IPC_RMID, NULL );
2be16a33 792 return 0;
793 }
794
fe1edbae 795int AliHLTHOMERReader::FreeTCPDataSource( DataSource& source )
2be16a33 796 {
04a939f7 797// see header file for class documentation
2be16a33 798 if ( source.fTCPConnection )
799 close( source.fTCPConnection );
2be16a33 800 return 0;
801 }
802
fe1edbae 803int AliHLTHOMERReader::ReadNextEvent( bool useTimeout, unsigned long timeout )
2be16a33 804 {
04a939f7 805// see header file for class documentation
2be16a33 806 if ( fDataSourceCnt<=0 )
807 return ENXIO;
808 // Clean up currently active event.
809 ReleaseCurrentEvent();
29e6fd20 810 int ret=0;
2be16a33 811 // Trigger all configured data sources
cfa641b1 812 for ( unsigned n = 0; n<fDataSourceCnt; n++ ){
813 if ( fDataSources[n].fType == kTCP )
814 ret = TriggerTCPSource( fDataSources[n], useTimeout, timeout );
815 else if ( fDataSources[n].fType == kShm )
816 ret = TriggerShmSource( fDataSources[n], useTimeout, timeout );
817 if ( ret )
2be16a33 818 {
cfa641b1 819 fErrorConnection = n;
820 fConnectionStatus=ret;
821 return fConnectionStatus;
2be16a33 822 }
cfa641b1 823 }
2be16a33 824 // Now read in data from the configured data source
825 ret = ReadDataFromTCPSources( fTCPDataSourceCnt, fDataSources, useTimeout, timeout );
cfa641b1 826
2be16a33 827 if ( ret )
cfa641b1 828 {
2be16a33 829 return ret;
cfa641b1 830 }
2be16a33 831 ret = ReadDataFromShmSources( fShmDataSourceCnt, fDataSources+fTCPDataSourceCnt, useTimeout, timeout );
832 if ( ret )
833 {
834 return ret;
835 }
836// for ( unsigned n = 0; n<fDataSourceCnt; n++ )
837// {
838// if ( fDataSources[n].fType == kTCP )
839// ret = ReadDataFromTCPSource( fDataSources[n], useTimeout, timeout );
840// else
841// ret = ReadDataFromShmSource( fDataSources[n], useTimeout, timeout );
842// if ( ret )
843// {
844// fErrorConnection = n;
845// fConnectionStatus=ret;
846// return fConnectionStatus;
847// }
848// }
849 //Check to see that all sources contributed data for the same event
850 homer_uint64 eventID;
851 homer_uint64 eventType;
29e6fd20 852 if (!fDataSources[0].fData)
853 {
854 fErrorConnection = 0;
855 fConnectionStatus=56;//ENOBUF;
856 return fConnectionStatus;
857 }
2be16a33 858 eventID = GetSourceEventID( fDataSources[0] );
859 eventType = GetSourceEventType( fDataSources[0] );
860 for ( unsigned n = 1; n < fDataSourceCnt; n++ )
861 {
29e6fd20 862 if ( !fDataSources[n].fData || GetSourceEventID( fDataSources[n] ) != eventID || GetSourceEventType( fDataSources[n] ) != eventType )
2be16a33 863 {
864 fErrorConnection = n;
746d2a94 865 fConnectionStatus=56;//EBADRQC;
2be16a33 866 return fConnectionStatus;
867 }
868 }
869 // Find all the different data blocks contained in the data from all
870 // the sources.
871 for ( unsigned n = 0; n < fDataSourceCnt; n++ )
872 {
873 ret = ParseSourceData( fDataSources[n] );
874 if ( ret )
875 {
876 fErrorConnection = n;
746d2a94 877 fConnectionStatus=57;//EBADSLT;
aa5178e8 878 return ret;
2be16a33 879 }
880 }
881 fCurrentEventID = eventID;
882 fCurrentEventType = eventType;
883 return 0;
884 }
885
fe1edbae 886void AliHLTHOMERReader::ReleaseCurrentEvent()
2be16a33 887 {
04a939f7 888// see header file for class documentation
2be16a33 889 // sources.fDataRead = 0;
890 // fMaxBlockCnt
891 fCurrentEventID = ~(homer_uint64)0;
892 fCurrentEventType = ~(homer_uint64)0;
893 for ( unsigned n = 0; n < fDataSourceCnt; n++ )
894 {
895 if ( fDataSources[n].fData )
896 {
897 if ( fDataSources[n].fType == kTCP )
898 delete [] (homer_uint8*)fDataSources[n].fData;
29e6fd20 899 // do not reset the data pointer for kBuf sources since this
900 // can not be set again.
901 if ( fDataSources[n].fType != kBuf )
902 fDataSources[n].fData = NULL;
2be16a33 903 }
904 fDataSources[n].fDataSize = fDataSources[n].fDataRead = 0;
905 }
906 if ( fBlocks )
907 {
908 for ( unsigned n = 0; n < fMaxBlockCnt; n++ )
909 {
910 if ( fBlocks[n].fOriginatingNodeID )
911 delete [] fBlocks[n].fOriginatingNodeID;
912 }
913 delete [] fBlocks;
914 fBlocks=0;
915 fMaxBlockCnt = 0;
916 fBlockCnt=0;
917 }
918 }
919
fe1edbae 920int AliHLTHOMERReader::TriggerTCPSource( DataSource& source, bool useTimeout, unsigned long timeoutUsec )
2be16a33 921 {
04a939f7 922// see header file for class documentation
620aa46c 923 int ret=0;
2be16a33 924 struct timeval oldSndTO, newSndTO;
620aa46c 925 memset(&oldSndTO, 0, sizeof(oldSndTO));
926 memset(&newSndTO, 0, sizeof(newSndTO));
2be16a33 927 if ( useTimeout )
928 {
929 socklen_t optlen=sizeof(oldSndTO);
930 ret = getsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &oldSndTO, &optlen );
931 if ( ret )
932 {
933 return errno;
934 }
935 if ( optlen!=sizeof(oldSndTO) )
936 {
937 return ENXIO;
938 }
3a7c0444 939 newSndTO.tv_sec = timeoutUsec / 1000000;
940 newSndTO.tv_usec = timeoutUsec - (newSndTO.tv_sec*1000000);
2be16a33 941 ret = setsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &newSndTO, sizeof(newSndTO) );
942 if ( ret )
943 {
944 return errno;
945 }
946 }
947 // Send one event request
04a939f7 948 if ( !fEventRequestAdvanceTime )
2be16a33 949 {
950 ret = write( source.fTCPConnection, GET_ONE, strlen(GET_ONE) );
951
952 if ( ret != (int)strlen(GET_ONE) )
953 {
954 ret=errno;
955 setsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &oldSndTO, sizeof(oldSndTO) );
956 return ret;
957 }
958 }
959 else
960 {
961 char tmpCmd[ 128 ];
962
70616995 963 int len = snprintf( tmpCmd, 128, "FIRST ORBIT EVENT 0x%llu\n", (unsigned long long)fEventRequestAdvanceTime );
2be16a33 964 if ( len>128 || len<0 )
965 {
966 ret=EMSGSIZE;
967 setsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &oldSndTO, sizeof(oldSndTO) );
968 return ret;
969 }
970
971 ret = write( source.fTCPConnection, tmpCmd, strlen(tmpCmd) );
972
973 if ( ret != (int)strlen(tmpCmd) )
974 {
975 ret=errno;
976 setsockopt( source.fTCPConnection, SOL_SOCKET, SO_SNDTIMEO, &oldSndTO, sizeof(oldSndTO) );
977 return ret;
978 }
979
980 }
981 return 0;
982 }
983
6a8e0bb4 984int AliHLTHOMERReader::TriggerShmSource( DataSource& source, bool, unsigned long ) const
2be16a33 985 {
04a939f7 986// see header file for class documentation
fe1edbae 987// clear the size indicator in the first 4 bytes of the buffer to request data
988// from the HOMER writer.
2be16a33 989 if ( source.fShmPtr )
990 {
991 *(homer_uint32*)( source.fShmPtr ) = 0;
992 return 0;
993 }
994 else
995 return EFAULT;
996 }
997
fe1edbae 998int AliHLTHOMERReader::ReadDataFromTCPSources( unsigned sourceCnt, DataSource* sources, bool useTimeout, unsigned long timeout )
2be16a33 999 {
3a7c0444 1000// see header file for class documentation
2be16a33 1001 bool toRead = false;
1002 do
1003 {
1004 fd_set conns;
1005 FD_ZERO( &conns );
1006 int highestConn=0;
1007 toRead = false;
1008 unsigned firstConnection=~(unsigned)0;
1009 for ( unsigned long n = 0; n < sourceCnt; n++ )
1010 {
1011 if ( sources[n].fDataSize == 0 // size specifier not yet read
1012 || sources[n].fDataRead < sources[n].fDataSize ) // Data not yet read fully
1013 {
1014 toRead = true;
1015 FD_SET( sources[n].fTCPConnection, &conns );
1016 if ( sources[n].fTCPConnection > highestConn )
1017 highestConn = sources[n].fTCPConnection;
1018 fcntl( sources[n].fTCPConnection, F_SETFL, O_NONBLOCK );
1019 if ( firstConnection == ~(unsigned)0 )
1020 firstConnection = n;
1021 }
1022 else
1023 {
1024 fcntl( sources[n].fTCPConnection, F_SETFL, 0 );
1025 }
1026 }
1027 if ( toRead )
1028 {
1029 struct timeval tv, *ptv;
1030 if ( useTimeout )
1031 {
1032 tv.tv_sec = timeout / 1000000;
1033 tv.tv_usec = timeout - (tv.tv_sec*1000000);
1034 ptv = &tv;
1035 }
1036 else
1037 ptv = NULL;
1038 // wait until something is ready to be read
1039 // either for timeout usecs or until eternity
1040 int ret;
1041 ret = select( highestConn+1, &conns, NULL, NULL, ptv );
1042 if ( ret <=0 )
1043 {
1044 fErrorConnection = firstConnection;
1045 if ( errno )
1046 fConnectionStatus = errno;
1047 else
1048 fConnectionStatus = ETIMEDOUT;
1049 return fConnectionStatus;
1050 }
1051 for ( unsigned n = 0; n < sourceCnt; n++ )
1052 {
1053 if ( FD_ISSET( sources[n].fTCPConnection, &conns ) )
1054 {
1055 if ( sources[n].fDataSize == 0 )
1056 {
1057 ret=read( sources[n].fTCPConnection, &(sources[n].fDataSize), sizeof(homer_uint32) );
1058 if ( ret != sizeof(homer_uint32) )
1059 {
1060 fErrorConnection = n;
1061 if ( errno )
1062 fConnectionStatus = errno;
1063 else
1064 fConnectionStatus = ENOMSG;
1065 return fConnectionStatus;
1066 }
1067 sources[n].fDataSize = ntohl( sources[n].fDataSize );
1068 sources[n].fDataRead = 0;
1069 sources[n].fData = new homer_uint8[ sources[n].fDataSize ];
1070 if ( !sources[n].fData )
1071 {
1072 fErrorConnection = n;
1073 fConnectionStatus = ENOMEM;
1074 return fConnectionStatus;
1075 }
1076 }
1077 else if ( sources[n].fData && sources[n].fDataRead < sources[n].fDataSize)
1078 {
1079 ret=read( sources[n].fTCPConnection, ((homer_uint8*)sources[n].fData)+sources[n].fDataRead, sources[n].fDataSize-sources[n].fDataRead );
1080 if ( ret>0 )
1081 sources[n].fDataRead += ret;
1082 else if ( ret == 0 )
1083 {
1084 fErrorConnection = n;
1085 fConnectionStatus = ECONNRESET;
1086 return fConnectionStatus;
1087 }
1088 else
1089 {
1090 fErrorConnection = n;
1091 fConnectionStatus = errno;
1092 return fConnectionStatus;
1093 }
1094 }
1095 else
1096 {
1097 fErrorConnection = n;
1098 fConnectionStatus = ENXIO;
1099 return fConnectionStatus;
1100 }
1101 }
1102 }
1103 }
1104 }
1105 while ( toRead );
1106 return 0;
1107 }
1108
1109/*
fe1edbae 1110int AliHLTHOMERReader::ReadDataFromTCPSources( DataSource& source, bool useTimeout, unsigned long timeout )
2be16a33 1111 {
1112#warning TODO If useTimeout: Set sockets to nonblocking, select + loop around GET_ONE write
1113 // Send one event request
1114 ret = write( source.fTCPConnection, GET_ONE, strlen(GET_ONE) );
1115 if ( ret != strlen(GET_ONE) )
1116 {
1117 return errno;
1118 }
1119 // wait for and read back size specifier
1120 unsigned sizeNBO;
1121 // The value transmitted is binary, in network byte order
1122 ret = read( source.fTCPConnection, &sizeNBO, sizeof(sizeNBO) );
1123 if ( ret != sizeof(sizeNBO) )
1124 {
1125 return errno;
1126 }
1127 // Convert back to host byte order
1128 source.fDataSize = ntohl( sizeNBO );
1129 source.fData = new homer_uint8[ source.fDataSize ];
1130 unsigned long dataRead=0, toRead;
1131 if ( !source.fData )
1132 {
1133 char buffer[1024];
1134 // Read in data into buffer in order not to block connection
1135 while ( dataRead < source.fDataSize )
1136 {
1137 if ( source.fDataSize-dataRead > 1024 )
1138 toRead = 1024;
1139 else
1140 toRead = source.fDataSize-dataRead;
1141 ret = read( source.fTCPConnection, buffer, toRead );
1142 if ( ret > 0 )
1143 dataRead += ret;
1144 else
1145 return errno;
1146 }
1147 return ENOMEM;
1148 }
1149 while ( dataRead < source.fDataSize )
1150 {
1151 toRead = source.fDataSize-dataRead;
1152 ret = read( source.fTCPConnection, source.fData+dataRead, toRead );
1153 if ( ret > 0 )
1154 dataRead += ret;
1155 else if ( ret == 0 && useTimeout )
1156 {
1157 struct timeval tv;
1158 tv.tv_sec = timeout / 1000000;
1159 tv.tv_usec = timeout - (tv.tv_sec*1000000);
1160 fd_set conns;
1161 FD_ZERO( &conns );
1162 FD_SET( source.fTCPConnection, &conns );
1163 ret = select( source.fTCPConnection+1, &conns, NULL, NULL );
1164 if ( ret <=0 )
1165 return errno;
1166 }
1167 else if ( ret == 0 )
1168 {
1169 if ( errno == EOK )
1170 return ECONNRESET;
1171 else
1172 return errno;
1173 }
1174 else
1175 {
1176 return errno;
1177 }
1178 }
1179 return 0;
1180 }
1181*/
1182
1183/*
fe1edbae 1184int AliHLTHOMERReader::ReadDataFromShmSource( DataSource& source, bool useTimeout, unsigned long timeout )
2be16a33 1185 {
1186
1187 }
1188*/
1189
fe1edbae 1190int AliHLTHOMERReader::ReadDataFromShmSources( unsigned sourceCnt, DataSource* sources, bool useTimeout, unsigned long timeout )
2be16a33 1191 {
04a939f7 1192// see header file for class documentation
2be16a33 1193 struct timeval tv1, tv2;
1194 bool found=false;
1195 bool all=true;
1196 if ( useTimeout )
1197 gettimeofday( &tv1, NULL );
1198 do
1199 {
1200 found = false;
1201 all = true;
1202 for ( unsigned n = 0; n < sourceCnt; n++ )
1203 {
1204 if ( !sources[n].fDataSize )
1205 all = false;
1206 if ( sources[n].fShmPtr && *(homer_uint32*)sources[n].fShmPtr>0 && !sources[n].fDataSize )
1207 {
1208 found = true;
1209 sources[n].fDataSize = *(homer_uint32*)sources[n].fShmPtr;
8c617325 1210 if (sources[n].fType==kBuf)
1211 {
1212 // the data buffer is already set to fData, just need to set fDataSize member
1213 // to invalidate after the first reading. Subsequent calls to ReadNextEvent return 0
1214 TriggerShmSource( sources[n], 0, 0 );
1215 } else
1216 {
1217 sources[n].fData = ((homer_uint8*)sources[n].fShmPtr)+sizeof(homer_uint32);
1218 }
2be16a33 1219 }
1220 }
1221 if ( found && useTimeout )
1222 gettimeofday( &tv1, NULL );
1223 if ( !all && useTimeout )
1224 {
1225 gettimeofday( &tv2, NULL );
1226 unsigned long long tdiff;
1227 tdiff = tv2.tv_sec-tv1.tv_sec;
1228 tdiff *= 1000000;
1229 tdiff += tv2.tv_usec-tv1.tv_usec;
1230 if ( tdiff > timeout )
1231 return ETIMEDOUT;
1232 }
1233 if ( !all )
1234 usleep( 0 );
1235 }
1236 while ( !all );
1237 return 0;
1238 }
1239
09eb5e44 1240int AliHLTHOMERReader::ParseSourceData( const DataSource& source )
2be16a33 1241 {
04a939f7 1242// see header file for class documentation
2be16a33 1243 if ( source.fData )
1244 {
1245 homer_uint8 sourceByteOrder = ((homer_uint8*)source.fData)[ kByteOrderAttribute_8b_Offset ];
aa5178e8 1246 if (sourceByteOrder!=kHOMERLittleEndianByteOrder && sourceByteOrder!=kHOMERBigEndianByteOrder) return EBADMSG;
2be16a33 1247 homer_uint64 blockCnt = Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)source.fData)[ kSubType2_64b_Offset ] );
aa5178e8 1248 // block count is not related to size of the data in the way the
1249 // following condition implies. But we can at least limit the block
1250 // count for the case the data is corrupted
1251 if (blockCnt>source.fDataSize) return EBADMSG;
2be16a33 1252 int ret=ReAllocBlocks( fMaxBlockCnt+blockCnt );
1253 if ( ret )
1254 return ret;
1255 homer_uint64 descrOffset = Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)source.fData)[ kOffset_64b_Offset ] );
1256 for ( homer_uint64 n = 0; n < blockCnt && fBlockCnt < fMaxBlockCnt; n++, fBlockCnt++ )
1257 {
aa5178e8 1258 if (descrOffset+kLength_64b_Offset>=source.fDataSize) return EBADMSG;
2be16a33 1259 homer_uint8* descr = ((homer_uint8*)source.fData)+descrOffset;
1260 unsigned descrLen = Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)descr)[ kLength_64b_Offset ] );
aa5178e8 1261 if (descrOffset+descrLen>=source.fDataSize) return EBADMSG;
31774e81 1262 if (Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)descr)[ kID_64b_Offset ] ) != HOMER_BLOCK_DESCRIPTOR_TYPEID) return 126/*ENOKEY*/;
2be16a33 1263 fBlocks[fBlockCnt].fSource = source.fNdx;
1264 fBlocks[fBlockCnt].fData = ((homer_uint8*)source.fData) + Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)descr)[ kOffset_64b_Offset ] );
1265 fBlocks[fBlockCnt].fLength = Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)descr)[ kSize_64b_Offset ] );
1266 fBlocks[fBlockCnt].fMetaData = (homer_uint64*)descr;
1267 struct in_addr tmpA;
1268 tmpA.s_addr = (homer_uint32)( ((homer_uint64*)descr)[ kProducerNode_64b_Offset ] );
1269 char* addr = inet_ntoa( tmpA );
c9926985 1270 unsigned straddrlen=strlen(addr);
1271 char* tmpchar = new char[ straddrlen+1 ];
2be16a33 1272 if ( !tmpchar )
1273 return ENOMEM;
c9926985 1274 strncpy( tmpchar, addr, straddrlen );
1275 tmpchar[straddrlen]=0;
2be16a33 1276 fBlocks[fBlockCnt].fOriginatingNodeID = tmpchar;
1277 descrOffset += descrLen;
1278 }
1279 return 0;
1280 }
1281 return EFAULT;
1282 }
1283
fe1edbae 1284int AliHLTHOMERReader::ReAllocBlocks( unsigned long newCnt )
2be16a33 1285 {
04a939f7 1286// see header file for class documentation
2be16a33 1287 DataBlock* newBlocks;
1288 newBlocks = new DataBlock[ newCnt ];
1289 if ( !newBlocks )
1290 return ENOMEM;
1291 unsigned long cpCnt = (newCnt > fMaxBlockCnt) ? fMaxBlockCnt : newCnt;
c9926985 1292 if ( fBlocks ) {
2be16a33 1293 memcpy( newBlocks, fBlocks, cpCnt*sizeof(DataBlock) );
c9926985 1294 } else {
1295 fMaxBlockCnt=0;
1296 }
2be16a33 1297 if ( newCnt > fMaxBlockCnt )
1298 memset( newBlocks+fMaxBlockCnt, 0, (newCnt-fMaxBlockCnt)*sizeof(DataBlock) );
1299 if ( fBlocks )
1300 delete [] fBlocks;
1301 fBlocks = newBlocks;
1302 fMaxBlockCnt = newCnt;
1303 return 0;
1304 }
1305
09eb5e44 1306homer_uint64 AliHLTHOMERReader::GetSourceEventID( const DataSource& source )
2be16a33 1307 {
04a939f7 1308// see header file for class documentation
2be16a33 1309 homer_uint8 sourceByteOrder = ((homer_uint8*)source.fData)[ kByteOrderAttribute_8b_Offset ];
1310 return Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)source.fData)[ kSubType1_64b_Offset ] );
1311 }
1312
09eb5e44 1313homer_uint64 AliHLTHOMERReader::GetSourceEventType( const DataSource& source )
2be16a33 1314 {
04a939f7 1315// see header file for class documentation
2be16a33 1316 homer_uint8 sourceByteOrder = ((homer_uint8*)source.fData)[ kByteOrderAttribute_8b_Offset ];
1317 return Swap( kHOMERNativeByteOrder, sourceByteOrder, ((homer_uint64*)source.fData)[ kType_64b_Offset ] );
1318 }
1319
fe1edbae 1320homer_uint64 AliHLTHOMERReader::Swap( homer_uint8 destFormat, homer_uint8 sourceFormat, homer_uint64 source ) const
3a7c0444 1321 {
1322// see header file for class documentation
1323 if ( destFormat == sourceFormat )
1324 return source;
1325 else
1326 return ((source & 0xFFULL) << 56) |
1327 ((source & 0xFF00ULL) << 40) |
1328 ((source & 0xFF0000ULL) << 24) |
1329 ((source & 0xFF000000ULL) << 8) |
1330 ((source & 0xFF00000000ULL) >> 8) |
1331 ((source & 0xFF0000000000ULL) >> 24) |
1332 ((source & 0xFF000000000000ULL) >> 40) |
1333 ((source & 0xFF00000000000000ULL) >> 56);
1334 }
2be16a33 1335
fe1edbae 1336homer_uint32 AliHLTHOMERReader::Swap( homer_uint8 destFormat, homer_uint8 sourceFormat, homer_uint32 source ) const
3a7c0444 1337 {
1338// see header file for class documentation
1339 if ( destFormat == sourceFormat )
1340 return source;
1341 else
1342 return ((source & 0xFFUL) << 24) |
1343 ((source & 0xFF00UL) << 8) |
1344 ((source & 0xFF0000UL) >> 8) |
1345 ((source & 0xFF000000UL) >> 24);
1346 }
fe1edbae 1347
a183f221 1348AliHLTHOMERReader* AliHLTHOMERReaderCreateFromTCPPort(const char* hostname, unsigned short port )
fe1edbae 1349 {
a183f221 1350 // see header file for function documentation
1351 return new AliHLTHOMERReader(hostname, port);
1352 }
1353
1354AliHLTHOMERReader* AliHLTHOMERReaderCreateFromTCPPorts(unsigned int tcpCnt, const char** hostnames, unsigned short* ports)
1355 {
1356 // see header file for function documentation
1357 return new AliHLTHOMERReader(tcpCnt, hostnames, ports);
1358 }
1359
1360AliHLTHOMERReader* AliHLTHOMERReaderCreateFromBuffer(const void* pBuffer, int size)
1361 {
1362 // see header file for function documentation
8c617325 1363 return new AliHLTHOMERReader(pBuffer, size);
fe1edbae 1364 }
1365
1366void AliHLTHOMERReaderDelete(AliHLTHOMERReader* pInstance)
1367 {
a183f221 1368 // see header file for function documentation
fe1edbae 1369 if (pInstance) delete pInstance;
1370 }
1371
2be16a33 1372/*
1373***************************************************************************
1374**
1375** $Author$ - Initial Version by Timm Morten Steinbeck
1376**
1377** $Id$
1378**
1379***************************************************************************
1380*/