Index: trunk/AddOn/TAcq/acqparam_exemple.d
===================================================================
--- trunk/AddOn/TAcq/acqparam_exemple.d	(revision 3756)
+++ trunk/AddOn/TAcq/acqparam_exemple.d	(revision 3757)
@@ -40,4 +40,13 @@
 #  @reducpaqsz ReducedSize Offset 
 reducpaqsz 1024 0 
+#### cartes de controle pour le mode transfert sur Ethernet
+#  Liste des machines cibles pour les envois de paquets 
+#  @ethrtargets Target1 [ Target2 ... ] 
+ethrtargets machine1 machine2 ...
+#  Activation du mode transfert direct DMA -> Ethernet , sans decoupage/verification en paquet a la source
+#  @pci2ethdirect
+#  Sur la machine destination, nombre total de liens (connexions) ethernet = NbTotalFibre
+#  @ethrnlink 4
+ethrnlink 4
 #  Pour desactiver l'ecriture des fichiers FITS
 #  @nosavesigfits
Index: trunk/AddOn/TAcq/bracqvers.h
===================================================================
--- trunk/AddOn/TAcq/bracqvers.h	(revision 3756)
+++ trunk/AddOn/TAcq/bracqvers.h	(revision 3757)
@@ -5,6 +5,6 @@
    Software version     LAL - 2008-2010 
 */
-#define BAOR_ACQ_VER 6.6
-#define BAOR_ACQ_VER_STR "BaoAcq_v6r6_Nov09 "
+#define BAOR_ACQ_VER 7.1
+#define BAOR_ACQ_VER_STR "BaoAcq_v7r1_Avr10 "
 
 #endif
Index: trunk/AddOn/TAcq/brparam.cc
===================================================================
--- trunk/AddOn/TAcq/brparam.cc	(revision 3756)
+++ trunk/AddOn/TAcq/brparam.cc	(revision 3757)
@@ -4,4 +4,8 @@
 #include "strutilxx.h"
 #include "bracqvers.h"
+
+#ifndef BRSPORTID
+#define BRSPORTID 6912
+#endif
 
 /* --Methode-- */
@@ -129,4 +133,8 @@
   reducoffset=0;
 
+  tcpportid=BRSPORTID;
+  pci2eth_fgdirect=false;
+  ethr_nlink = 0;
+
   skysource="";
 
@@ -181,4 +189,8 @@
   redpqsize=p.redpqsize;
   reducoffset=p.reducoffset;
+
+  pci2eth_fgdirect=p.pci2eth_fgdirect;
+  eths_targets=p.eths_targets;
+  ethr_nlink=p.ethr_nlink;
 
   skysource=p.skysource;
@@ -215,4 +227,14 @@
     reducoffset=(uint_4)conf.IParam("reducpaqsz",1,0);
   }
+  // Mot cle pour le mode envoi-reception sur ethernet 
+  tcpportid=conf.IParam("tcpportid",0,BRSPORTID);
+  if (conf.HasKey("pci2ethdirect"))  pci2eth_fgdirect = true;   // Transfer direct DMA -> Ethernet
+  if (conf.HasKey("ethrtargets")) {    // Machines destinations des paquets 
+    for(int it=0; it<conf.NbParam("ethrtargets"); it++) 
+      eths_targets.push_back(conf.SParam("ethrtargets",it));
+  }
+  ethr_nlink=conf.IParam("ethrnlink",0,0);   // Nombre de sources de paquets en reception ethernet 
+
+
   if (conf.HasKey("monitor")) {
     fgdoProc=true;
@@ -222,5 +244,4 @@
   }
   nopciLossRate=conf.DParam("nopcilossrate",0,0.);
-
   fg_hard_ctrlc=conf.HasKey("hard_ctrlc");
   if (conf.HasKey("nosavesigfits"))  savesigfits=false;
@@ -322,4 +343,10 @@
     os << " PaquetSize Reduction, ReducedSize=" << redpqsize << " Offset=" << reducoffset << endl;
   }
+  if (eths_targets.size()>0)   {
+    cout << " DMA->Ethernet NbTargets=" << eths_targets.size() << ((pci2eth_fgdirect)?" (DirectTransferMode) " : " " ) << " :" << endl;
+    for(size_t it=0; it<eths_targets.size(); it++) cout << eths_targets[it] << " , ";
+    cout << endl;
+  }
+  cout << " EthernetRead NbSources (=NbLinks)= " << ethr_nlink << endl;
   if (fgdoProc>0) 
     os << " Monitoring  NMeanProc=" << nmeanProc << " StepProc=" << stepProc << " NMaxProc=" << nmaxProc << endl;
Index: trunk/AddOn/TAcq/brparam.h
===================================================================
--- trunk/AddOn/TAcq/brparam.h	(revision 3756)
+++ trunk/AddOn/TAcq/brparam.h	(revision 3757)
@@ -97,4 +97,6 @@
   // Taille des paquets apres reduction eventuelle (donc ds memory manager)
   inline uint_4 MMgrPaquetSize() { return (fgreducpsize)?redpqsize:PaqSize; }
+  // Nombre de paquets dans chaque bloc de MMgr 
+  inline uint_4 MMgrNbPaquet() { return nPaqZone; }
   // Operation de conversion/mise en ordre des donnees a la reception 
   inline BRDataFmtConv GetDataConvFg() { return swapall; };
@@ -105,8 +107,16 @@
   inline uint_4 BlocPerFile() { return NBlocPerFile; }
   // Nombre maximum de blocs MMgr traites 
-  inline uint_4 MaxNbBlocs() { return NbFiles*NBlocPerFile; }
+  inline uint_8 MaxNbBlocs() { return (uint_8)NbFiles*(uint_8)NBlocPerFile; }
+  // Nombre maximum paquets traites 
+  inline uint_8 MaxNbPaquets() { return MaxNbBlocs()*(uint_8)nPaqZone; }
 
   // Taille des paquets recus sur PCIExpress 
   inline uint_4 PatternSize() { return ((PaqSize-(BRHDRSIZE+BRTRLSIZE))/4); }
+
+  // Liste des machines cibles pour transfert sur ethernet
+  inline void SetEthTargets(vector<string>& targs) { eths_targets=targs; return; }
+  inline vector<string>& GetEthTargets() { return eths_targets; }
+  // Nombre de liens ethernet comme source de donnees (paquets) 
+  inline int NbEthLinks() { return ethr_nlink; }
 
   // Identification source ciel 
@@ -147,4 +157,12 @@
   uint_4 redpqsize; 
   uint_4 reducoffset; 
+
+  // ---- Variables specifiques em mode transfert DMA vers Ethernet 
+  int tcpportid; 
+  // Cote Send DMA -> Ethernet 
+  bool pci2eth_fgdirect;   // true -> direct transfer DMA to Ethernet  
+  vector< string > eths_targets;   // Liste des machines cibles pour les transferts DMA -> ethernet 
+  // Cote reception 
+  int ethr_nlink;    // Nombre total de source d'envoi (= nb total de fibre de fibre) 
 
   // Identification source observee dans le ciel
@@ -209,4 +227,6 @@
   // Taille des paquets apres reduction eventuelle (donc ds memory manager)
   inline uint_4 MMgrPaquetSize() { return param_->MMgrPaquetSize(); }
+  // Nombre de paquets dans chaque bloc de MMgr 
+  inline uint_4 MMgrNbPaquet() { return param_->MMgrNbPaquet(); }
   // Operation de conversion/mise en ordre des donnees a la reception 
   inline BRDataFmtConv GetDataConvFg() { return param_->GetDataConvFg(); };
@@ -217,5 +237,7 @@
   inline uint_4 BlocPerFile() { return param_->BlocPerFile(); }
   // Nombre maximum de blocs MMgr traites 
-  inline uint_4 MaxNbBlocs() { return param_->MaxNbBlocs(); }
+  inline uint_8 MaxNbBlocs() { return param_->MaxNbBlocs(); }
+  // Nombre maximum paquets traites 
+  inline uint_8 MaxNbPaquets() { return param_->MaxNbPaquets(); }
 
   // Identification source ciel 
Index: trunk/AddOn/TAcq/makefile
===================================================================
--- trunk/AddOn/TAcq/makefile	(revision 3756)
+++ trunk/AddOn/TAcq/makefile	(revision 3757)
@@ -21,10 +21,10 @@
 	echo '---mfacq made'
 
-$(EXE)mfacq : $(OBJ)mfacq.o $(OBJ)brparam.o $(OBJ)racqumem.o $(OBJ)racqurw.o $(OBJ)racquproc.o \
-               $(OBJ)brpaqu.o $(OBJ)pciewrap.o $(OBJ)minifits.o
-	$(CXXLINK) -o $(EXE)mfacq $(OBJ)mfacq.o $(OBJ)brparam.o $(OBJ)racqumem.o $(OBJ)racqurw.o \
-	      $(OBJ)racquproc.o $(OBJ)brpaqu.o $(OBJ)pciewrap.o $(OBJ)minifits.o $(SOPHYAALLSLBLIST)
-
-$(OBJ)mfacq.o : mfacq.cc brparam.h racquproc.h racqurw.h racqumem.h brpaqu.h
+$(EXE)mfacq : $(OBJ)mfacq.o $(OBJ)brparam.o $(OBJ)racqumem.o $(OBJ)racqurw.o  $(OBJ)racqueth.o \
+	$(OBJ)racquproc.o $(OBJ)brpaqu.o $(OBJ)pciewrap.o $(OBJ)minifits.o $(OBJ)swrapsock.o
+	$(CXXLINK) -o $(EXE)mfacq $(OBJ)mfacq.o $(OBJ)brparam.o $(OBJ)racqumem.o $(OBJ)racqurw.o $(OBJ)racqueth.o \
+	      $(OBJ)racquproc.o $(OBJ)brpaqu.o $(OBJ)pciewrap.o $(OBJ)minifits.o $(OBJ)swrapsock.o $(SOPHYAALLSLBLIST)
+
+$(OBJ)mfacq.o : mfacq.cc brparam.h racquproc.h racqurw.h racqueth.h racqumem.h brpaqu.h
 	$(CXXCOMPILE) -c -DNOPCIECARD -o $(OBJ)mfacq.o mfacq.cc 
 
@@ -50,4 +50,7 @@
 	$(CXXCOMPILE) -c -o $(OBJ)racqurw.o racqurw.cc 
 
+$(OBJ)racqueth.o : racqueth.cc racqueth.h racqurw.h racqumem.h brpaqu.h
+	$(CXXCOMPILE) -c -o $(OBJ)racqueth.o racqueth.cc 
+
 $(OBJ)racquproc.o : racquproc.cc racquproc.h racqurw.h racqumem.h brpaqu.h
 	$(CXXCOMPILE) -c -o $(OBJ)racquproc.o racquproc.cc 
Index: trunk/AddOn/TAcq/mfacq.cc
===================================================================
--- trunk/AddOn/TAcq/mfacq.cc	(revision 3756)
+++ trunk/AddOn/TAcq/mfacq.cc	(revision 3757)
@@ -9,4 +9,6 @@
 static RAcqMemZoneMgr* pMmgr=NULL;
 static  PCIEMultiReader* pPcierThr=NULL;
+static  PCIEToEthernet* pPcie2Eth=NULL;
+static  EthernetReader* pEthRdr=NULL;
 
 void Stop(int s)
@@ -15,6 +17,7 @@
   else printf("............. MAIN ... receive signal %d \n",s);
   if (pMmgr != NULL) pMmgr->Stop();
+  if (pPcie2Eth !=NULL) pPcie2Eth->Stop();
   if (pPcierThr !=NULL) pPcierThr->Stop();
-
+  if (pEthRdr !=NULL) pEthRdr->Stop();
 }
 
@@ -40,10 +43,25 @@
 
 
-  if ((narg < 2)||(strcmp(arg[1],"-h"))==0) {
+  if ((narg > 1)&&(strcmp(arg[1],"-h"))==0) {
     Usage(false);
     return 1;
   }
-  
-  string pardcfile=arg[1];
+  if (narg < 3) {
+    Usage(true);
+    return 3;
+  }
+  
+  const char* desact[3] = {"PCIE_To_Ethernet", "Ethernet_To_Disk", "PCIE_DMA_To_Disk"};
+  string action=arg[1];
+  int act = 0;
+  if ((action != "-pci2eth")&&(action != "-pci2disk")&&(action != "-eth2disk")) {
+    cout << " mfacq/Error , Bad action argument : " << action << endl;
+    return 2;
+  }
+  if (action == "-pci2eth")  act=0;
+  else if (action == "-eth2disk") act=1;
+  else if (action == "-pci2disk")  act=2;
+
+  string pardcfile=arg[2];
 #ifndef NOPCIECARD  
   string basedir="/Raid";
@@ -51,19 +69,36 @@
   string basedir="./";
 #endif 
-  if (narg>2)  basedir=arg[2];
+  vector<string> oargs;
+  if (narg>3)  {
+    basedir=arg[2];
+    for(int jj=2; jj<narg; jj++)  oargs.push_back(arg[jj]);
+  }
   try {
     // Creation/initialisation parametres Acq
     BRAcqConfig acpar;
-    acpar.ReadParamFile(arg[1]);
+    acpar.ReadParamFile(pardcfile);
     acpar.GetConfig().SetBaseDirectory(basedir); 
+    if ((act==0)&&(oargs.size()>0))
+      acpar.GetParams().SetEthTargets(oargs);
     // Creation des repertoires 
-    if (acpar.CreateOutputDirectories()!=0)  return 9;
+    if (act > 0) 
+      if (acpar.CreateOutputDirectories()!=0)  return 9;
     acpar.Print(cout);
-    struct sigaction act;  
+    struct sigaction siact;  
     if (!acpar.GetParams().fg_hard_ctrlc) {
-      act.sa_handler=Stop;
-      sigaction(SIGINT,&act,NULL);        
+      siact.sa_handler=Stop;
+      sigaction(SIGINT,&siact,NULL);        
     }
-    rc = MultiFibreAcq();    
+    switch (act) {
+    case 0:
+      rc = PCIEToEthernetTransfer();
+      break;
+    case 1:
+      rc = EthernetToMemoryAcq();
+      break;
+    case 2:
+      rc = MultiFibreAcq();
+      break;
+    }    
   }
   catch (MiniFITSException& exc) {
@@ -97,12 +132,12 @@
 void Usage(bool fgshort) 
 {
-  if (fgshort) {
-    cout << " Usage: mfacq DataCardFile [BaseDirectory] \n" << endl;
-    cout << "   Parameters in DataCard : \n"
-	 << "       fibres outpathname skysource paqsize dmasizekb nbfiles \n" 
-	 << "       nblocperfile acqmode memmgr monitor reducpaqsz "<< endl;
-    cout << "   BaseDirectory (default= /Raid ) " << endl;
-    return;
-  }
+  cout << " Usage: mfacq Action DataCardFile [BaseDirectory / TargetMachines] \n" << endl;
+  if (fgshort) return;
+  cout << "   Action = -pci2disk , -pci2mem -eth2disk \n " 
+       << "   Parameters in DataCard : \n"
+       << "       fibres outpathname skysource paqsize dmasizekb nbfiles \n" 
+       << "       nblocperfile acqmode memmgr monitor reducpaqsz "<< endl;
+  cout << "   BaseDirectory (default= /Raid ) " << endl;
+  cout << "   TargetMachines : List of target machines for PCIe2Ethernet " << endl;
   return;
 }
@@ -114,5 +149,6 @@
   Timer tm("mfacq/MultiFibre");
   cout << " ---------- mfacq/ MultiFibreAcq()  ------------- " << endl;
-  PCIEWrapperInterface* pciwp[4]={NULL,NULL,NULL,NULL};
+  PCIEWrapperInterface* pciwp[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+				   NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
     
   BRAcqConfig bpar;
@@ -144,8 +180,16 @@
   TestPCIWrapperNODMA pciw3(bpar.RecvPaquetSize(), acpar.nopciLossRate);
   TestPCIWrapperNODMA pciw4(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw5(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw6(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw7(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw8(bpar.RecvPaquetSize(), acpar.nopciLossRate);
   pciwp[0] = &pciw1;
   pciwp[1] = &pciw2;
   pciwp[2] = &pciw3;
-  pciwp[3] = &pciw4;  
+  pciwp[3] = &pciw4;
+  pciwp[4] = &pciw5;
+  pciwp[5] = &pciw6;  
+  pciwp[6] = &pciw7;
+  pciwp[7] = &pciw8;  
 #endif 
 
@@ -197,2 +241,135 @@
 
 }
+
+/* --Nouvelle-Fonction-- */
+int PCIEToEthernetTransfer()
+{
+  Timer tm("mfacq/PCIEToEthernetTransfer");
+  cout << " ---------- mfacq/ PCIEToEthernetTransfer()  ------------- " << endl;
+  PCIEWrapperInterface* pciwp[16]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
+				   NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+
+  pMmgr=NULL;    
+  BRAcqConfig bpar;
+  BRParList& acpar=bpar.GetParams();
+  
+  cout << " mfacq[1]/Info: PCIEToEthernet for" << acpar.NbFibers << " fibers , nZones=" 
+       << acpar.nZones << " NbPaquet/Zone=" << acpar.nPaqZone 
+       << " MmgrPaqSize=" << acpar.MMgrPaquetSize() << endl;
+  
+#ifndef NOPCIECARD  
+  for (int i=0 ;i <acpar.NFibers() ;i++) {
+    UINT32 card=(acpar.FiberNum[i]-1)/2+1;
+    UINT32 cardfiber=(acpar.FiberNum[i]-1)%2;
+    cout <<"mfacq[2] CreatePCIEWrapperV6- indice " << i <<  "INIT card " << card 
+	 << " fibre " << cardfiber << endl;
+    pciwp[i] =  CreatePCIEWrapperV6(card,acpar.PatternSize(),acpar.DMASizeBytes(),acpar.activate_pattern,cardfiber);
+  }
+#else 
+  TestPCIWrapperNODMA pciw1(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw2(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw3(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw4(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw5(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw6(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw7(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  TestPCIWrapperNODMA pciw8(bpar.RecvPaquetSize(), acpar.nopciLossRate);
+  pciwp[0] = &pciw1;
+  pciwp[1] = &pciw2;
+  pciwp[2] = &pciw3;
+  pciwp[3] = &pciw4;
+  pciwp[4] = &pciw5;
+  pciwp[5] = &pciw6;  
+  pciwp[6] = &pciw7;
+  pciwp[7] = &pciw8;  
+#endif 
+
+  vector<PCIEWrapperInterface*> vec_pciw;
+  for  (int i=0 ;i<bpar.NFibers();i++)  vec_pciw.push_back( pciwp[i]);
+  cout <<"mfacq[2] Creating PCIEToEthernet  thread object " << endl;
+  PCIEToEthernet pci2eth(vec_pciw, bpar.GetParams().GetEthTargets(), bpar.GetParams());
+  //  usleep(200);  attente au cas ou ...
+  pPcie2Eth=&pci2eth;
+  tm.Split("Threads created");  
+  cout << "mfacq[3] - starting one threads: PCIEToEthernet... " << endl;
+  pci2eth.start();
+  
+  // On attend avant de declencher la terminaison des threads
+  usleep(200000);
+  
+  cout << "mfacq[5] -  Waiting for threads to finish ... " << endl;  
+  pci2eth.join();
+  cout << "mfacq[6] ---------- threads finished ---------------- " << endl;
+  tm.Split("Threads Finished");  
+ 
+#ifndef NOPCIECARD
+  for (int i=0 ;i <acpar.NbFibers ;i++) {
+    UINT32 card=(acpar.FiberNum[i]-1)/2+1;
+    UINT32 cardfiber=(acpar.FiberNum[i]-1)%2;
+    DeletePCIEWrapperV6(card,cardfiber);
+  }
+#endif    
+return 0;
+}
+
+/* --Nouvelle-Fonction-- */
+int EthernetToMemoryAcq() 
+{
+  Timer tm("mfacq/EthernetToMemoryAcq");
+  cout << " ---------- mfacq/ EthernetToMemoryAcq()  ------------- " << endl;
+    
+  BRAcqConfig bpar;
+  BRParList& acpar=bpar.GetParams();
+  
+  cout << " mfacq[1]/Info: Creating RAcqMemZoneMgr for" << acpar.NbEthLinks() << " Eth-links , nZones=" 
+       << acpar.nZones << " NbPaquet/Zone=" << acpar.nPaqZone 
+       << " MmgrPaqSize=" << acpar.MMgrPaquetSize() << endl;
+  RAcqMemZoneMgr mmgr(acpar.nZones, acpar.NbEthLinks(), acpar.nPaqZone, acpar.MMgrPaquetSize());
+  pMmgr=&mmgr;  
+  if (acpar.fgdoProc && (acpar.stepProc>0)) {
+    // Dans ce cas, toutes les zones doivent passer ds le thread de monitoring 
+    // pour etre au moins marque comme traite - seul 1/acpar.stepProc sont effectivement traite 
+    mmgr.SetFinalizedMask(((uint_4)MemZS_Saved) | ((uint_4)MemZS_Proc));
+    cout << " mfacq[1.b]/Info: Mmgr.SetFinalizedMask( MemZS_Saved | MemZS_Proc )" << endl;
+  }
+  
+
+  cout <<"mfacq[2] Creating MultiDataSaver and  MonitorProc thread objects ... " << endl;
+  MultiDataSaver DsThr(mmgr);   //   Utilise les parametres globaux BRAcqConfig
+  string ppath=bpar.OutputDirectory();
+  MonitorProc PrThr(mmgr);
+  cout << "mfacq[3] Creating   EthernetReader thread object     " << endl;
+  EthernetReader ethrdr(mmgr, bpar.GetParams(), bpar.GetParams().tcpportid, false);
+  //  usleep(200);  attente au cas ou ...
+  pEthRdr=&ethrdr;
+  tm.Split("Threads created");  
+  if (acpar.fgdoProc>0) 
+    cout << "mfacq[4] - starting three threads: EthernetReader, MultiDataSaver, MonitorProc ... " << endl;
+  else 
+    cout << "mfacq[4] - starting two threads: EthernetReader, MultiDataSaver  ... " << endl;
+
+  ethrdr.start();
+  DsThr.start();
+  if (acpar.fgdoProc>0) { // On ne demarre que si au moins NMaxProc>0
+    PrThr.start();
+  }
+  
+  // On attend avant de declencher la terminaison des threads
+  usleep(200000);
+  
+  cout << "mfacq[5] -  Waiting for threads to finish ... " << endl;  
+  ethrdr.join();
+  DsThr.join();
+  mmgr.Stop();
+  if (acpar.fgdoProc) { // On n'attend la fin que si le thread a ete demarre (NMaxProc>0)
+    PrThr.join();
+  }
+  pMmgr=NULL;  
+  cout << "mfacq[6] ---------- threads finished ---------------- " << endl;
+  tm.Split("Threads Finished");  
+ 
+  mmgr.Print(cout);
+
+return 0;
+
+}
Index: trunk/AddOn/TAcq/mfacq.h
===================================================================
--- trunk/AddOn/TAcq/mfacq.h	(revision 3756)
+++ trunk/AddOn/TAcq/mfacq.h	(revision 3757)
@@ -12,4 +12,5 @@
 #include "racqumem.h"
 #include "racqurw.h" 
+#include "racqueth.h" 
 #ifndef NOPCIECARD
 #include "racquwbin.h"
@@ -40,4 +41,6 @@
 
 
+int PCIEToEthernetTransfer();
+int EthernetToMemoryAcq();
 int MultiFibreAcq();
 
Index: trunk/AddOn/TAcq/racqueth.cc
===================================================================
--- trunk/AddOn/TAcq/racqueth.cc	(revision 3757)
+++ trunk/AddOn/TAcq/racqueth.cc	(revision 3757)
@@ -0,0 +1,497 @@
+//----------------------------------------------------------------
+// ---- classes de threads pour lecture (transfert DMA) 
+//      et ecriture disque pour acquisition   BAORadio       -----
+// LAL -      R. Ansari - Juin/Juillet 2008 
+//----------------------------------------------------------------
+
+#include "racqueth.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fstream>
+#include <signal.h>
+#include "pexceptions.h"
+#include "ctimer.h"
+#include "timestamp.h"
+
+#include "pciewrap.h"
+#include "brpaqu.h"
+
+#include "resusage.h" // Pour mesure temps elapsed/CPU ...
+#include <sys/time.h>  // pour gettimeofday
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////
+//----------------------------------------------------------------------------------------------------------
+// Classe thread de lecture PCI-Express et recopie sur interface reseau (Ethernet) 
+//----------------------------------------------------------------------------------------------------------
+
+
+/* --Methode-- */
+PCIEToEthernet::PCIEToEthernet(vector<PCIEWrapperInterface*> vec_pciw, vector<string>& destname, BRParList const& par, int portid)
+  :   par_(par), vec_pciw_ (vec_pciw), destname_(destname), tcpportid_(portid)
+{
+  nmaxpaq_ = par_.MaxNbPaquets();	
+  swapall_ = par_.GetDataConvFg();  	// select data swap/format conversion for BRPaquet
+  stop_ = false;
+  packSize_ = par_.RecvPaquetSize();
+  packSizeInMgr_=par_.MMgrPaquetSize();
+  sizeFr_=par_.DMASizeBytes();
+  if (vec_pciw.size() > MAXNBFIB) 
+    throw ParmError("PCIEToEthernet:ERROR/  vec_pciw.size() > MAXNBFIB ");
+  nbDma_= vec_pciw.size();
+
+  char msg[BRTCPMSGLEN];
+  for(size_t i=0; i<vec_pciw_.size(); i++) {
+    vector<ClientSocket> vskt;
+    for(size_t j=0; j<vskt.size(); j++) {
+      ClientSocket sok(destname_[j], tcpportid_);
+      for(int ii=0; ii<BRTCPMSGLEN; ii++) msg[ii]='\0';
+      sprintf(msg,"BAORadio-PCIEToEthernet %d %d",0,i);
+      sok.Send(msg,BRTCPMSGLEN);
+      sok.Receive(msg,BRTCPMSGLEN);
+      if (strncmp(msg,"BAORadio-EthernetReader-OK",26)!=0) 
+	throw SocketException("PCIEToEthernet:ERROR/  Connection to EthernetReader not established ");
+      cout << " PCIEToEthernet: Ethernet connection established for DMA/fiber" << i << " with " << destname_[j] << endl;
+      vskt.push_back(sok);    
+    }
+    vvec_skt_.push_back(vskt);    
+  }
+}
+
+/* --Methode-- */
+PCIEToEthernet::~PCIEToEthernet()
+{
+  for(size_t i=0; i<vec_pciw_.size(); i++) {
+    vector<ClientSocket>& vskt = vvec_skt_[i];
+    for(size_t j=0; j<destname_.size(); j++) vskt[j].Close();
+  }
+}
+
+/* --Methode-- */
+void PCIEToEthernet::run()
+{
+  
+  struct timeval tv1,tv2;
+  gettimeofday(&tv1, NULL);
+  uint_8 totrdsnd = 0;
+  
+  cout << " PCIEToEthernet::run() - Starting , NMaxMemZones=" <<  par_.MaxNbBlocs()
+       << " MMgrNbPaquet=" << par_.MMgrNbPaquet() << " MMgr.PaqSiz=" << par_.MMgrPaquetSize()
+       << " DMA-Paqsize " << packSize_ << "  " << BRPaquet::FmtConvToString(swapall_) << endl;	
+  setRC(1);	
+
+  // sigaddset(&act.sa_mask,SIGINT);  // pour proteger le transfert DMA
+  //sigaction(SIGINT,&act,NULL);  	
+  uint_4 paqszmm = par_.MMgrNbPaquet();
+  uint_4 paqsz =  packSize_;
+  uint_4 dmasz = vec_pciw_[0]->TransferSize();
+  //DEL  vec_pciw_[0]->StartTransfers();
+
+  BRPaqChecker pcheck[MAXNBFIB];  // Verification/comptage des paquets  
+  Byte* Datas[MAXNBFIB];
+  Byte* tampon[MAXNBFIB] ; 
+  Byte* nexpaq[MAXNBFIB] ;  // Pour recevevoir les paquets apres reduction de taille 
+
+  Byte* predtampon=NULL;  // tampon de recopie pour la reduction des tailles de paquets 
+  Byte* nextpaq=NULL;
+  uint_4 off_acheval=0;
+  
+  int nerrdma = 0;
+  int maxerrdma = 10;
+  bool fgarret = false;
+  
+  // Initialisation des tampons pour recopie des paquets a cheval pour chaque DMA
+  for (int i=0;i< (int)nbDma_ ;i++) {  
+    tampon[i] = new Byte[paqsz];
+    nexpaq[i] = new Byte[paqszmm];
+  }
+
+  bool fgdirectsend = (par_.pci2eth_fgdirect && (swapall_==BR_Copy) ) ? true : false;   //  true -> direct transfer of data to ethernet
+  if (fgdirectsend) 
+    cout << " PCIEToEthernet::run() Direct transfer mode DMA to Ethernet ... " << endl;
+  bool fgredpaq=par_.fgreducpsize;
+  if (fgredpaq) {
+    cout << " PCIEToEthernet::run() - PaquetSizeReduction - RedSize=" << par_.redpqsize 
+	 << " Offset=" << par_.reducoffset << " " << ((par_.reducneedcopy)?"NeedCopy":"NOCopy") 
+	 << "  " << BRPaquet::ReducActionToString(par_.pqreducmode) << endl;
+    predtampon = new Byte[paqsz];
+  }
+  
+  
+  uint_8 trnbytes[MAXNBFIB];
+  uint_4 npaqfait[MAXNBFIB];
+  for (int i=0;i< (int)nbDma_ ;i++) {
+    npaqfait[i]=0; trnbytes[i]=0; 
+  }
+  // Attente du message GO des taches lecteurs
+  cout << " PCIEToEthernet::run() Waiting for GO message from EthernetReader's ..." << endl;
+  char msg[BRTCPMSGLEN];
+  for(size_t i=0; i<vec_pciw_.size(); i++) {
+    vector<ClientSocket>& vskt=vvec_skt_[i];
+    for(size_t j=0; j<vskt.size(); j++) {
+      for(int ii=0; ii<BRTCPMSGLEN; ii++) msg[ii]='\0';
+      vskt[i].Receive(msg,BRTCPMSGLEN);
+      if (strncmp(msg,"BAORadio-EthernetReader-Ready-GO",32)!=0)
+	throw SocketException("PCIEToEthernet:ERROR/  BAD Go message from EthernetReader ");
+    }
+    cout << " PCIEToEthernet::run() Received GO message for Fiber/DMA " << i << " from " << destname_[i] << endl;
+  }
+
+  cout << " PCIEToEthernet::run()  Starting DMA to Ethernet transfers - NbFibers=NbDMA=" << vec_pciw_.size() 
+       << " x NbEthDestinations=" << destname_.size() << endl;
+
+    // Byte* nextdma = locdata+((kmz%memgr.NbZones())*(paqsz*memgr.NbPaquets()));
+  uint_4 npaqfaitg = 0; 
+  while (npaqfaitg < nmaxpaq_) {  // Boucle global G 
+    if (fgarret) break;
+    if (stop_) break;
+    
+    // Lancement des DMA 
+    for (int dma=0; dma < (int)nbDma_ ;dma++) vec_pciw_[dma]->StartTransfers();
+    
+    // On pointe vers le debut de la zone a remplir aver le prochain DMA
+    //-- Zone memoire locale Byte* nextdma = buff+i*paqsz;
+    
+    bool fgbaddma=false;
+    // On boucle sur les nbDma_ en attente de leurs terminaison    
+    for (int dma=0; dma <(int) nbDma_ ;dma++)  {
+      Datas[dma]=vec_pciw_[dma]->GetData();
+      if (Datas[dma] == NULL) { // No data Read in DMA 
+	nerrdma ++;   fgbaddma=true;
+	cout << "PCIEToEthernetChecker/Erreur Waiting for datas ..." << endl;
+	vec_pciw_[dma]->PrintStatus(cout);
+	if (nerrdma>=maxerrdma) { fgarret = true; break; }
+      }
+    }
+    if (fgbaddma) continue;  
+    if (fgdirectsend) {  // Pas de copie / reduction de taille de paquet, on rebalance tel quel ...
+      for (int fib=0; fib<(int) nbDma_ ;fib++) {
+	vector<ClientSocket>& vskt = vvec_skt_[fib];
+	for(size_t j=0; j<vskt.size(); j++) {
+	  vskt[j].Send((const char *)Datas[fib], dmasz);
+	  totrdsnd += dmasz;
+	}
+	trnbytes[fib] += (uint_8)dmasz;
+	npaqfait[fib] += (trnbytes[fib]/(uint_8)paqszmm);
+	if (fib==nbDma_-1) npaqfaitg += (trnbytes[fib]/(uint_8)paqszmm);
+	trnbytes[fib] = trnbytes[fib]%(uint_8)paqszmm;
+      }
+      continue;  // On bypasse le reste 
+    }
+    // Si on arrive ici, c'est qu'il faut copier / reduire les paquets ....
+    uint_4 curoff=0;
+    //1- On traite le paquet a cheval, rempli partiellement avec le DMA d'avant si necessaire pour les n fibres
+    if (off_acheval  > 0) {  // IF Numero B
+      if ((paqsz-off_acheval)< dmasz) {  // IF Numero A
+	for(uint_4 fib=0; fib<nbDma_; fib++) 
+	  memcpy((void *)((tampon[fib])+off_acheval), (void *)Datas[fib], paqsz-off_acheval);
+	curoff = paqsz-off_acheval;  off_acheval = 0;
+	for(uint_4 fib=0; fib<nbDma_; fib++) {
+	  // CHECK  S'il faut faire une reduction de taille de paquet
+	  if (fgredpaq) { // reduction taille de paquet
+	    if (par_.reducneedcopy) {
+	      BRPaquet paqc1(tampon[fib], predtampon, paqsz, swapall_);
+	      BRPaquet paqc2(nexpaq[fib], par_.redpqsize);
+	      paqc2.CopyFrom(paqc1, par_.pqreducmode, par_.reducoffset);
+	    }
+	    else {
+	      BRPaquet paqc1(tampon[fib], paqsz);
+	      BRPaquet paqc2(nexpaq[fib], par_.redpqsize);
+	      paqc2.CopyFrom(paqc1, par_.pqreducmode, par_.reducoffset);
+	    }
+	  }
+	  else  { 
+	    BRPaquet paqc(tampon[fib], nexpaq[fib], paqsz, swapall_);
+	  }
+	  BRPaquet paq(nexpaq[fib], packSizeInMgr_);
+	  vector<ClientSocket>& vskt = vvec_skt_[fib];
+	  for(size_t j=0; j<vskt.size(); j++) {
+	    vskt[j].Send((const char *)nexpaq[fib], packSizeInMgr_);
+	    totrdsnd += packSizeInMgr_;
+	  }
+	  npaqfait[fib]++;
+	  if (fib==nbDma_-1) npaqfaitg++;  // Ne pas oublier le compteur de paquets faits 
+	  pcheck[fib].Check(paq);   // Verification du paquet / FrameCounter 
+	}
+      }
+      else {  // se rapporte au IF numero A
+	for(uint_4 fib=0; fib<nbDma_; fib++) 
+	  memcpy((void *)(tampon[fib]+off_acheval), (void *)Datas[fib], dmasz);
+	curoff =dmasz;
+	off_acheval = (dmasz+off_acheval);
+      } 
+    }  // Fin IF Numero B
+
+    //2- On traite les paquets complets qui se trouvent dans la zone du DMA 
+    while ((curoff+paqsz)<=dmasz) {  // while numero C 
+      //	  if ((dma==nbDma_-1)&&(npaqfait >= nmax_* memgr.NbPaquets())) break;
+      // CHECK  S'il faut faire une reduction de taille de paquet
+      for(uint_4 fib=0; fib<nbDma_; fib++) {
+	  if (fgredpaq) { // reduction taille de paquet
+	    if (par_.reducneedcopy) {
+	      BRPaquet paqc1(Datas[fib]+curoff, predtampon, paqsz, swapall_);
+	      BRPaquet paqc2(nexpaq[fib], par_.redpqsize);
+	      paqc2.CopyFrom(paqc1, par_.pqreducmode, par_.reducoffset);
+	    }
+	    else {
+	      BRPaquet paqc1(Datas[fib]+curoff, paqsz);
+	      BRPaquet paqc2(nexpaq[fib], par_.redpqsize);
+	      paqc2.CopyFrom(paqc1, par_.pqreducmode, par_.reducoffset);
+	    }
+	  }
+	  else { 
+	    BRPaquet paqc(Datas[fib]+curoff, nexpaq[fib], paqsz, swapall_);
+	  }
+	  BRPaquet paq(nexpaq[fib], packSizeInMgr_);
+	  vector<ClientSocket>& vskt = vvec_skt_[fib];
+	  for(size_t j=0; j<vskt.size(); j++) {
+	    vskt[j].Send((const char *)nexpaq[fib], packSizeInMgr_);
+	    totrdsnd += packSizeInMgr_;
+	  }
+	  npaqfait[fib]++;
+	  if (fib==nbDma_-1) npaqfaitg++;  // Ne pas oublier le compteur de paquets faits 
+	  pcheck[fib].Check(paq);   // Verification du paquet / FrameCounter 
+	}
+      curoff += paqsz;  // On avance l'index dans le buffer du DMA
+    } // -- FIN traitement des paquets complets ds un DMA - FIN du while numero C 
+      //3- On copie si besoin la fin du DMA dans la zone tampon
+    if (curoff < dmasz) {  // IF numero D 
+      off_acheval = dmasz-curoff;
+      for(uint_4 fib=0; fib<nbDma_; fib++) 
+	memcpy(tampon[fib], (void*)(Datas[fib]+curoff), off_acheval);
+      // ne sert a rien 	curoff += off_acheval; 
+    } // FIN du if numero D 
+  }  //   FIN  Boucle global G 
+ 
+  setRC(0);
+  gettimeofday(&tv2, NULL);
+  double tmelaps2 = (tv2.tv_sec-tv1.tv_sec)*1000.+(tv2.tv_usec-tv1.tv_usec)/1000.;
+  if (tmelaps2<0.1) tmelaps2=0.1; 
+  cout << " ---------- PCIEToEthernet::run()-End summary NPaqFait=" << npaqfaitg 
+       << " TotSend (kb)=" << totrdsnd/1024 << "------ " << endl;
+  for (int dma=0; dma < (int)nbDma_ ;dma++)   {
+    cout << " --Fib=" << dma << " NPaqFait=" << npaqfait[dma] <<  " TotDMATransfer=" 
+	 << vec_pciw_[dma]->TotTransferBytes()/1024 
+	 << " ElapsTime=" << tmelaps2 << " ms ->" 
+	 << (double)vec_pciw_[dma]->TotTransferBytes()/tmelaps2 << " kb/s" << endl;
+
+	vector<ClientSocket>& vskt = vvec_skt_[dma];
+	cout << " TotEthTransfer="; 
+	for(size_t j=0; j<vskt.size(); j++)
+	  cout << vskt[j].NBytesSent()/1024 << " , ";
+	cout << " kb" << endl;
+	
+    if (!fgdirectsend) pcheck[dma].Print(cout);
+  }
+  cout << " --------------------------------------------------------------------" << endl;
+
+  for (int i=0;i< (int)nbDma_ ;i++) { 
+    delete[] tampon[i]; 
+    delete[] nexpaq[i];
+  }
+  if ((fgredpaq)&&predtampon) delete[] predtampon;
+
+  //DBG  cout << " fin thread ========================" <<endl;  
+  return;
+}
+
+
+/* --Methode-- */
+void PCIEToEthernet::Stop()
+{ 
+  // cout << " PCIEReaderChecker::stop()  ........ STOP" <<endl; 
+  stop_ = true;
+
+}
+
+
+//------------------------------------------------------------------
+// Classe thread de lecture sur interface reseau (Ethernet) 
+//------------------------------------------------------------------
+
+/* --Methode-- */
+EthernetReader::EthernetReader(RAcqMemZoneMgr& mem, BRParList const& par, int portid, bool rdsamefc)
+  :  memgr_(mem), par_(par), stop_(false), rdsamefc_(rdsamefc), tcpportid_(portid)
+{
+  SetPrintLevel();
+  totnbytesrd_ = 0;
+  totnpaqrd_ = 0;
+  totsamefc_ = 0;
+  if (memgr_.NbFibres() > MAXANAFIB) 
+    throw BAORadioException("EthernetReader::EthernetReader/ NbFibres>MAXANAFIB "); 
+  if (par_.ethr_nlink != memgr_.NbFibres()) 
+    throw BAORadioException("EthernetReader::EthernetReader/ NbFibres != ethr_nlink"); 
+
+  packsize_=memgr_.PaqSize();
+  mid_=-2; 
+  mmbuf_=NULL;
+  max_targ_npaq = memgr_.NbPaquets();
+  for(size_t fib=0; fib<(size_t)memgr_.NbFibres(); fib++) mmbufib_[fib]=NULL;
+
+  for(size_t fib=0; fib<(size_t)memgr_.NbFibres(); fib++) {
+    vpaq_.push_back(BRPaquet(NULL,memgr_.PaqSize()));
+    vpchk_.push_back(BRPaqChecker(true,0)); 
+    curfc_.push_back(0);
+    totnpqrd_.push_back(0);
+    totnpqok_.push_back(0);    
+  }
+  ServerSocket srv(tcpportid_, par_.ethr_nlink);
+  char msg[BRTCPMSGLEN];
+  for(size_t fib=0; fib<(size_t)memgr_.NbFibres(); fib++) {
+    Socket sok=srv.WaitClientConnection();
+    for(int ii=0; ii<BRTCPMSGLEN; ii++) msg[ii]='\0';
+    sok.Receive(msg,BRTCPMSGLEN);
+    if (strncmp(msg,"BAORadio-PCIEToEthernet",23)!=0) 
+      throw SocketException("EthernetReader:ERROR/  Bad message from PCIEToEthernet client !");
+    for(int ii=0; ii<BRTCPMSGLEN; ii++) msg[ii]='\0';
+    strcpy(msg,"BAORadio-EthernetReader-OK");
+    sok.Send(msg,BRTCPMSGLEN);
+    vsok_.push_back(sok);
+    cout << " EthernetReader/Info connection/link" << fib << " established." << endl; 
+  }
+}
+
+
+/* --Methode-- */
+void EthernetReader::run()
+{
+  setRC(1); 
+  try {
+    TimeStamp ts; 
+    Timer tm("EthernetReader", false);
+    cout << " EthernetReader::run() - Starting " << ts << " NbFibres()=" << memgr_.NbFibres()
+	 << "  PaqSize() = " << memgr_.PaqSize() << endl;
+    cout << " ...ReadMode: " << ((rdsamefc_)?"Paquets With SameFrameCounter":"All OK paquets") << endl;
+
+    cout << " Sending GO message to all PCIEToEthernet clients ... " << endl;
+    char msg[BRTCPMSGLEN];
+    for(int ii=0; ii<BRTCPMSGLEN; ii++) msg[ii]='\0';
+    strcpy(msg,"BAORadio-EthernetReader-Ready-GO");
+    for(size_t fib=0; fib<(size_t)memgr_.NbFibres(); fib++) {
+      vsok_[fib].Send(msg,BRTCPMSGLEN);
+    }
+    Byte* nextpaq=NULL;
+    bool fgok=true;
+    while (fgok&&(totnpaqrd_<par_.MaxNbPaquets())) {
+      if (stop_) break;
+      if ( MoveToNextTarget() ) {
+	cout << "EthernetReader::run()/Error-A- MoveToNextTarget() returned true ->STOP 9" << endl;
+	setRC(7);  fgok=false;  break;
+      }
+      for(size_t fib=0; fib<(size_t)memgr_.NbFibres(); fib++) {
+	nextpaq=GetPaquetTarget(fib);
+	if (nextpaq == NULL) { // Cela ne devrait pas arriver 
+	  cout << "EthernetReader::run()/Error-A2- GetPaquetTarget(fib)  returned NULL ->STOP 9" << endl;
+	  setRC(9);  fgok=false;  break;
+	}
+	vpaq_[fib].Set(nextpaq);
+      }
+      if (ReadNextAllFibers()) { fgok=false;  break; }
+      totnpaqrd_++;
+    }
+
+    MoveToNextTarget();  // Pour faire traiter le dernier paquet si plein 
+    MZoneManage(true);   // Nettoyage final 
+    usleep(50000);       // Attente de traitement du dernier paquet
+    memgr_.Stop();        // Arret 
+
+    cout << " ------------------  EthernetReader::run() END ----------------- " << endl;
+    ts.SetNow();
+    tm.SplitQ();
+    cout << "  END reading TotNPaq/Link=" << totnpaqrd_ << " :"  << ts ;
+    if (rdsamefc_) cout << " NSameFC=" << totsamefc_ << endl;
+    else cout << endl;
+    for(size_t fib=0; fib<(size_t)memgr_.NbFibres(); fib++)  {
+      int perc=0;
+      if (totnpqrd_[fib]>0) perc=100*totsamefc_/totnpqrd_[fib];
+      cout << " Fiber" << fib << " TotNPaqRd=" << totnpqrd_[fib] << " TotNPaqOK=" << totnpqok_[fib] 
+	   << " FracSameFC=" << perc << " %" << endl;
+      if (prtlev_ > 0)  vpchk_[fib].Print(cout);
+    }
+    cout << "  TotalEthernetRead= " << totnbytesrd_/(1024*1024) << " MBytes Ethernet-Read rate= " 
+         << (double)(totnbytesrd_)/1024./tm.PartialElapsedTimems() << " MB/s" << endl;    
+    cout << " EthernetReader::run()/Timing: \n"; 
+    tm.Print();
+    cout << " ---------------------------------------------------------- " << endl;
+
+  }  // Fin du bloc try 
+  catch (std::exception& exc) {
+    cout << " EthernetReader::run()/catched execption msg=  " << exc.what() << endl;
+    setRC(3);	
+    return; 
+  }
+  catch(...) {
+    cout << " EthernetReader::run()/catched unknown ... exception " << endl;
+    setRC(4);	
+    return; 
+  }
+  setRC(0);
+  return;
+}
+
+/* --Methode-- */
+bool EthernetReader::ReadNextAllFibers()
+{
+  for(size_t fib=0; fib<(size_t)memgr_.NbFibres(); fib++)  {
+    if (ReadNext(fib)) return true;  // probleme 
+  }
+  if (!rdsamefc_ || (memgr_.NbFibres()<2))  { 
+    totsamefc_++;  return false;  // c'est OK 
+  }
+  uint_8 cfc=curfc_[0];
+  bool fgsamefc=true;
+  for(size_t fib=1; fib<memgr_.NbFibres(); fib++) {
+    if (curfc_[fib]!=cfc) {
+      fgsamefc=false;
+      if (curfc_[fib] > cfc)  cfc=curfc_[fib]; 
+    }
+  }
+  if (fgsamefc) { 
+    totsamefc_++;  return false;  // c'est OK  , same framecounter
+  }
+  else {  // else !fgsame
+    for(uint_4 fib=0; fib<memgr_.NbFibres(); fib++) {
+      while (curfc_[fib]<cfc) {
+	if (ReadNext(fib)) return true;  // probleme 
+      }
+    }
+  }   // fin de  else !fgsame 
+  totsamefc_++; 
+  return false; // c'est OK
+}
+
+/* --Methode-- */
+bool EthernetReader::ReadNext(int fib)
+{
+  bool fggood=false;
+  while(!fggood) { 
+    vsok_[fib].Receive((char *)vpaq_[fib].Begin(), packsize_);
+    totnbytesrd_+=packsize_;
+    totnpqrd_[fib]++;
+    fggood = vpchk_[fib].Check(vpaq_[fib],curfc_[fib]);
+  }
+  totnpqok_[fib]++;
+  return false;
+}
+
+/* --Methode-- */
+bool EthernetReader::MZoneManage(bool fgclean)    // Retourne true si probleme 
+{
+  /* Pour debug 
+  cout << " EthernetReader::MZoneManage() mid_=" << mid_ << " arg_npaq_= " << targ_npaq_  
+       << " max_targ_npaq=" << max_targ_npaq << endl;
+  */
+  if (mid_ >= 0)  { 
+    if (fgclean) memgr_.FreeMemZone(mid_, MemZS_Free);    
+    else memgr_.FreeMemZone(mid_, MemZS_Filled);
+  }
+  mmbuf_ = NULL;  targ_npaq_ = 0;  mid_ = -2;
+  for (int fib=0;fib<(int)memgr_.NbFibres() ;fib++) mmbufib_[fib]=NULL;
+  if (fgclean)  return false;
+  mid_ = memgr_.FindMemZoneId(MemZA_Fill);
+  mmbuf_ = memgr_.GetMemZone(mid_);
+  if (mmbuf_==NULL)   return true;
+  for(size_t fib=0; fib<(size_t)memgr_.NbFibres(); fib++)
+    mmbufib_[fib]=memgr_.GetMemZone(mid_,fib);
+  return false;
+}
Index: trunk/AddOn/TAcq/racqueth.h
===================================================================
--- trunk/AddOn/TAcq/racqueth.h	(revision 3757)
+++ trunk/AddOn/TAcq/racqueth.h	(revision 3757)
@@ -0,0 +1,129 @@
+#ifndef  RACQUETH_H_SEEN
+#define  RACQUETH_H_SEEN
+
+//----------------------------------------------------------------
+// ---- classes de threads pour lecture/ecriture des paquets (transfert DMA) 
+//      et ecriture disque pour acquisition   BAORadio       -----
+// LAL -      R. Ansari - Juin/Juillet 2008 
+//----------------------------------------------------------------
+
+#include "racqumem.h"
+#include <string>
+#include <vector>
+#include <iostream>
+#include "sopnamsp.h"
+#include "zthread.h"
+#include "pciewrap.h"
+#include "swrapsock.h"
+#include "brtypes.h"
+#include "brpaqu.h"
+#include "brparam.h"
+#include "minifits.h"
+
+using namespace std;
+
+// Quelques definitions globales
+// Nombre maximum de fibres geres par les classes PCIEToEthernet ...
+//  ATTENTION cette definition (MAXANAFIB) se trouve dans plusieurs fichiers 
+#ifndef MAXNBFIB
+#define MAXNBFIB  16   
+#endif
+//  ATTENTION cette definition (MAXANAFIB) se trouve dans plusieurs fichiers 
+#ifndef MAXANAFIB 
+#define MAXANAFIB  32
+#endif
+
+#ifndef BRSPORTID
+#define BRSPORTID 6912
+#endif
+#ifndef BRTCPMSGLEN
+#define BRTCPMSGLEN 128
+#endif
+
+
+//----------------------------------------------------------------------------------
+// Classe thread de lecture PCI-Express et recopie sur interface reseau (Ethernet)
+//----------------------------------------------------------------------------------
+
+class PCIEToEthernet : public ZThread {
+public:
+  PCIEToEthernet(vector<PCIEWrapperInterface*> vec_pciw , vector<string>& destname, BRParList const& par, int portid=BRSPORTID);
+  virtual ~PCIEToEthernet();
+  virtual void run(); 
+   void Stop();
+  inline void STOP() { stop_ = true; }	
+
+protected: 
+  BRParList par_;   // Parametres divers d'acquisition 
+
+  uint_8 nmaxpaq_;  // Nombre maxi de paquets traites
+  BRDataFmtConv swapall_;  // select data swap/format conversion for BRPaquet
+  bool stop_;  
+  unsigned int sizeFr_ ;
+  vector<PCIEWrapperInterface *> vec_pciw_;
+  vector<string> destname_; 
+  int tcpportid_;
+  vector< vector<ClientSocket> > vvec_skt_;
+  uint_4 packSize_;
+  uint_4 packSizeInMgr_;
+  uint_4 nbDma_;
+
+};
+
+//------------------------------------------------------------------
+// Classe thread de lecture sur interface reseau (Ethernet) 
+//------------------------------------------------------------------
+class EthernetReader : public ZThread {
+public:
+  EthernetReader(RAcqMemZoneMgr& mem, BRParList const& par, int portid=BRSPORTID, bool rdsamefc=false);
+  virtual void run();
+  inline void Stop() { stop_ = true; }
+  inline void STOP() { stop_ = true; }	
+
+  inline int SetPrintLevel(int lev=0) { prtlev_=lev; return 0;}
+protected:
+  bool ReadNextAllFibers();      // Renvoie true si probleme 
+  bool ReadNext(int fib);   // Renvoie true si probleme 
+  // Permet d'avancer d'un paquet dans la zone - renvoie true si probleme
+  inline bool MoveToNextTarget()  {
+    if ((mmbuf_ == NULL )||(targ_npaq_ >= max_targ_npaq)) 
+      if (MZoneManage()) return true;
+    targ_npaq_++;
+    return false;
+  }
+  inline Byte* GetPaquetTarget(int numfib)  {
+    if ((mmbufib_[numfib] == NULL )||(targ_npaq_ > max_targ_npaq)||(targ_npaq_ == 0))  return NULL; 
+    Byte* rb=mmbufib_[numfib]+(targ_npaq_-1)*packsize_;
+    return rb;
+  }
+  bool MZoneManage(bool clean=false);  // Renvoie true si probleme
+
+  RAcqMemZoneMgr& memgr_;
+  BRParList par_;   // Parametres divers d'acquisition 
+  int tcpportid_;
+  vector< Socket > vsok_;  //  Les sockets de lecture pour chaque fibre/lien 
+  bool stop_;
+  bool rdsamefc_;  // if true, read paquets with same value of FrameCounter on different fibers/link 
+  uint_8 totnbytesrd_;
+  uint_8 totnpaqrd_;
+  uint_8 totsamefc_;   // nombre total de paquets avec meme framecounter  
+
+  vector<BRPaquet> vpaq_; 
+  vector<BRPaqChecker> vpchk_;
+  vector<uint_8> curfc_;       // Numeros des FrameCounter des paquets courants
+  vector<uint_8> totnpqrd_;    // nombre total de paquets lus / lien 
+  vector<uint_8> totnpqok_;    // nombre total de paquets OK / lien   
+
+  uint_4 packsize_;
+  int mid_;  // Identificateur zone memoire
+  uint_4 targ_npaq_;  // Numero de paquet dans une seule zone memoire 
+  uint_4 max_targ_npaq; // =  mmgr.NbPaquets() = Max de targ_npaq_
+  Byte* mmbuf_;  // Pointeur zone memoire rendu par RAcqMemZoneMgr 
+  Byte* mmbufib_[MAXANAFIB];  // Pointeurs zone memoire de chaque fibre rendu par RAcqMemZoneMgr 
+
+  int prtlev_;
+};
+
+
+
+#endif
Index: trunk/AddOn/TAcq/racqurw.h
===================================================================
--- trunk/AddOn/TAcq/racqurw.h	(revision 3756)
+++ trunk/AddOn/TAcq/racqurw.h	(revision 3757)
@@ -26,5 +26,5 @@
 // Nombre maximum de fibres geres par les classes MultiReader / MultiDiskWriter
 #ifndef MAXNBFIB
-#define MAXNBFIB  4   
+#define MAXNBFIB  16   
 #endif
 
Index: trunk/AddOn/TAcq/swrapsock.cc
===================================================================
--- trunk/AddOn/TAcq/swrapsock.cc	(revision 3756)
+++ trunk/AddOn/TAcq/swrapsock.cc	(revision 3757)
@@ -23,4 +23,5 @@
   The class Socket is not intended for direct use. Only the derived classes 
   ServerSocket and ClientSocket should be used.
+  The Close() method should be called explicitly. 
 */
 
@@ -38,6 +39,18 @@
 
 /* --Methode-- */
-/*  ---  A faire plus tard ...
 Socket::Socket(Socket const & a)
+{
+  Set(a);
+}
+
+
+/* --Methode-- */
+Socket::~Socket()
+{
+  //  Close();
+}
+
+/* --Methode-- */
+void Socket::Set(Socket const & a)
 {
   skt = a.skt;
@@ -49,11 +62,5 @@
   errcnt = a.errcnt;
 }
-*/
-
-/* --Methode-- */
-Socket::~Socket()
-{
-  Close();
-}
+
 
 /* --Methode-- */
@@ -191,4 +198,23 @@
   InitConnection(srvname, port);
 }
+
+/* --Methode-- */
+ClientSocket::ClientSocket(ClientSocket const& a)
+  : Socket(a)
+{
+  portid=a.portid;
+  ipskt=a.ipskt;
+}
+
+
+/* --Methode-- */
+void ClientSocket::SetC(ClientSocket const& a)
+{
+  Set(a);
+  portid=a.portid;
+  ipskt=a.ipskt;
+  return;
+}
+
 
 /* --Methode-- */
Index: trunk/AddOn/TAcq/swrapsock.h
===================================================================
--- trunk/AddOn/TAcq/swrapsock.h	(revision 3756)
+++ trunk/AddOn/TAcq/swrapsock.h	(revision 3757)
@@ -36,5 +36,5 @@
 public:
   Socket(int s=-1);
-  //  Socket(Socket const & a);
+  Socket(Socket const & a);
   ~Socket();
 
@@ -42,9 +42,16 @@
   size_t Receive(char * buff, size_t len, int flag=0);
   int Close();
+  
+  inline Socket& operator=(Socket const & a)
+  { Set(a);  return (*this); }
+
   inline int SetPrtLevel(int lev=0) 
     { if (lev > 0) prtlev = lev; return prtlev; }
+  inline long NBytesSent() { return totsnd; }
+  inline long NBytesRecv() { return totrcv; }
+  
+protected:
+  void Set(Socket const & a);
 
-protected:
-  
   int skt;
   long tstart;    /*  Temps de demarrage en sec  */
@@ -89,6 +96,11 @@
   ClientSocket(string const& srvname, int port);
   ClientSocket(const char* srvname, int port);
+  ClientSocket(ClientSocket const& a);
+  inline ClientSocket& operator=(ClientSocket const& a)
+  { SetC(a);  return (*this); }
 protected:
+  void SetC(ClientSocket const& a);
   void InitConnection(const char* srvname, int port);
+
   int portid;
   struct sockaddr_in  ipskt;
