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