text: /*
   * (c) Copyright 2004 Agilent Technologies, Inc.  All Rights Reserved.
   *
   *                       RESTRICTED RIGHTS LEGEND
   *
   * Use, duplication or disclosure by the U.S. Government is subject to
   * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
   * Technical Data and Computer Software clause at DFARS 252.227-7013 for
   * DOD agencies, and subparagraphs (c)(1) and (c)(2) of the Commercial
   * Computer Software Restricted Rights clause at FAR 52.227-19 for other
   * agencies.
   *
   *                        Agilent Technologies, Inc.
   *                           395, Page Mill Rd,
   *                 Palo Alto, California 94306-2024 U.S.A.
   *  $Source: /src/multiuser/MultiUserDNAServer.h $
   *  $Revision: 3 $
   *  $Date: 2012/02/17 04:56:11 +0800 $
   *  Author: Scott Blomquist
   *
   *  Description:
   *     The MultiUserServer class handles all of the socket connections and
   *  data transfer for SART MultiUser.
   *
   *  Maintenance Notes:
   *
   *	$Log: MultiUserDNAServer.h $
   *	Revision 3 2012/02/17 04:56:11 +0800 jennint deleted(id=28991)
   *	- fixed MUS connection issues: IQ00334500, IQ00348680, IQ00348703, IQ00333377, Q00333471
   *	- added authentication: IQ00349051, IQ00349052
   *	
   *	Revision 2 2011/02/08 02:22:38 -0500 blo55201 /MassTransit/MT1.00.100_Tip/DemoIntegration/Scott
   *	Initial Port to Linux
   *	
   *	Revision 1 2011/01/27 08:27:33 -0700 blo55201 /MassTransit/MT1.00.100_Tip/DemoIntegration/Scott
   *	 Importing original Multi-User server code from 7.00.100_Tip/COS/MassTransitMUSPort 
   *	
   *	Revision 46 2010/11/15 22:03:56 -0700 and55460 /mobile/7.00.100_Tip/CTO-Apps/7.00.100.064/z7.00.100.064-Bob/7.00.100.064-dual_rock_mus-1-Bob
   *	DualRocket - MUS support
   *	
   *	Revision 45 2010/10/04 10:39:27 +0800 hen55546 /mobile/7.00.100_Tip/CTO-Apps/7.00.100.050/7.00.100.050_IQ00341460_CM
   *	Add MUS lag display when BTD.
   *	
   *	Revision 44 2010/05/16 14:18:39 +0800 sb4450 /mobile/6.70.100_Tip/COS/SARTRocket/Scott
   *	Added UPStats and CP Only filtering in MUS Direct Connect mode.
   *	
   *	Revision 43 2010/05/12 00:58:20 -0600 sb4450 /mobile/6.70.100_Tip/SartRocket_Tip/SartRocket_Int/Scott/MUS-BTD
   *	Merged in latest fixes for Kbps overflow.
   *	
   *	Revision 42 2010/05/11 16:00:42 -0600 sb4450 /mobile/6.70.100_Tip/SartRocket_Tip/SartRocket_Int/Scott/MUS-BTD
   *	Implemented BladeRocket support for MUS in direct connect mode.
   *	Removed old playback code that is now in RecFileUtil.dll.
   *	
   *	Revision 41 2010/03/24 21:59:34 -0600 hanjiayu deleted(id=40767)
   *	Content copied from revision 38
   *	
   *	Revision 39 2010/02/20 18:21:36 -0700 sb4450 /mobile/6.70.100_Tip/COS/SARTRocket
   *	Fixed issues with 32-bit counter overflow for Kbps.
   *
   *	Revision 37 2009/10/09 04:32:55 +0800 sb4450 /mobile/6.60.100_Tip/COS/SARTRocket/Scott
   *	Moved file replay code into RecFileUtil.dll
   *	
   *	Revision 36 2009/07/20 11:08:20 -0600 sb4450 /mobile/6.60.100_Tip/ANT_SASE_RELEASE_6.60.100.035/6.60.100.035-Scott-TT27010WorkAround
   *	MUS AutoRestart code (Workaround for TT27010 - MUS Crash during long run under heavy load)
   *	
   *	Revision 33 2008/08/05 23:49:35 -0600 sb4450 /mobile/6.10.100_Tip/COS/Scott/TT24113
   *	Fix for TT 24113 - time adjustments caused MU Server playback to stall.
   *	
   *	Revision 32 2007/10/26 03:01:31 -0600 robandre /mobile/5.60.100_Tip/CTO-Apps/5.60.100.005/z5.60.100.005-Bob/5.60.100.005-Bob-Submission/5.60.100.005-TT20396-1-Bob
   *	TT20396 (Bob): VS2005: Tidy-up SART sourceCode
   *	
   *	Revision 31 2007/09/08 02:58:27 +0800 sb4450 /mobile/5.50.100_Tip/COS/Scott
   *	Content copied from revision 30
   *	
   *	Revision 29 2007/07/02 10:00:08 -0600 jp4673 /mobile/5.50.100_Tip/COS/JohnPage
   *	Automatic merge of parallel changes into revision [26]
   *	DS 181 - integrate MUS Admin into MU Server
   *	
   *	Revision 27 2007/06/06 23:58:23 -0600 robandre /mobile/5.50.100_Tip/CTO-Apps/5.50.100.022/9.5.50.100.021-5.40.100.055_SyncTarget/5.40.100.055SyncTo5.50.100.021_SyncSource_540
   *	Automatic merge of parallel changes into revision [25]
   *
   *	Revision 26 2007/06/05 10:19:59 -0600 jp4673 /mobile/5.50.100_Tip/COS/JohnPage
   *	MultiUserAdmin initial checkin
   *	
   *	Revision 25 2007/05/31 01:12:07 +0800 sb4450 /mobile/5.40.100_Tip/COS/Scott
   *	Fix for Concorde SCR #3772.  Fixed memory leaks that happened because
   *	MultiUserStreamingSocket objects where not deleted in some cases.
   *	
   *	Revision 24 2007/05/10 23:17:38 -0600 robandre /mobile/5.50.100_Tip/CTO-Apps/5.50.100.013/AppsMergeIncluding40Sync/07Bob5.40.100_ToSync
   *	Automatic merge of parallel changes into revision [20]
   *
   *	Revision 23 2007/05/02 15:48:02 -0600 sb4460 /mobile/5.40.100_Tip/MobileDNA/sb4460/MDNA Phase1 Work/MDNA Phase1 Work - ifKey Work
   *	Propagate ifKey down to MultiUserBuffer object for 5.50 & NextGen DNA.
   *	
   *	Revision 20 2007/04/23 11:00:48 -0600 sb4450 /mobile/5.40.100_Tip/COS/Scott
   *	Increased max DNA index supported in MU Server for replay.  This is so MUS can replay .rec files
   *	that where captured from >1 MUS. Even though the max number of DNAs captured does not exceed
   *	the limit (currently 13), the indexes of the DNAs being replayed may exceed the limit.
   *	
   *	Revision 19 2007/04/19 14:02:45 -0600 sb4450 /mobile/5.40.100_Tip/COS/Scott
   *	Fix for CTL 3231/3502 - NASocket Index Too Large error when replaying from multiple MU Servers
   *	with a large number of DNAs.  Had to allow for DNA indexes in .rec file to be larger than the
   *	NA_MAX_NUM_SOCKETS.
   *	
   *	Revision 18 2007/02/17 13:08:23 -0700 sb4450 /mobile/5.40.100_Tip/03_Fixup_5.40.200_mege
   *	Performed a merge from 5.40.200 to 5.40.100 and fixed up comments.  Previously the file had been
   *	checked out, modified with 5.40.200 changes, and checked in.
   *	
   *	Revision 16 2007/01/24 20:03:29 -0700 limyanto /mobile/5.40.100_Tip/CTO-Apps/5.40.100.018/5.40.100.018-AppMerge/ANT_SASE_RELEASE_5.40.200.008
   *	Merge to SART 5.40.200.008
   *	
   *	Revision 15 2007/01/19 15:44:03 +0800 ch4726 /mobile/5.40.100_Tip/CH4726_SmartonMerge/SmartoneRecFileReplay_Merge
   *	1) Add Multi-Rec File Replay to Server
   *	2) Add the UI to allow user to decide whether to replay all files or just the single selected file
   *	
   *	Revision 14 2007/01/12 14:21:24 -0700 ch4726 /mobile/5.40.100_Tip/CH4726_SmartonMerge/SmartoneRecFileReplay_Merge
   *	Automatic merge of parallel changes into revision [9]
   *	Merging Smartone Rec File Replay features to 5.40.100.
   *	
   *	Feature summary:
   *	1) SART Client user can select a group of consecutive files to replay
   *	2) Each rec file name has a time stamp in brackets indication the time of file creation
   *	
   *	Revision 9 2006/07/13 10:54:07 -0600 ch4726 /mobile/SASE-5.00_Extensions/Specials/5.06_SmarttoneRecFileReplay
   *	Add code for Smartone Multi-RecFile Replay:
   *	
   *	1) Individual rec file names are appended with timestamps enclosed in brackets
   *	2) 'Run From File' dialog in the client is changed so that mutiple files can be selected and replayed
   *	
   *	Revision 13 2006/11/06 07:35:20 -0700 sc2 /mobile/5.30.200_Tip/COS/Stephen
   *	Changes to support BTD for AR
   *	
   *	Revision 10 2006/08/02 14:40:44 -0400 sc2 /mobile/SASE-CTO-5.10.100_Tip/MultipleBTS/SASE-5.10.100.705-Build/SASE-5.10.100.705-SCR2722 Sc2
   *	Found bug where the address of a interger should be passed to the member as it wasn't being
   *	modified
   *	
   *	Revision 7 2006/06/26 02:51:04 -0600 engwekoo /mobile/SASE-CTO-5.00_Extensions/Patches/SASE-5.00.101-Build/SASE-5.00.101.004.0-Build/SASE-5.00.101.004.0-SCR2371-1-Koo
   *	
   *	Revision 5 2006/02/12 22:48:10 -0700 donaghey deleted(id=9965)
   *      Added extra button to allow to connect to MU DNAs before starting data
   *	Rewrote MU Filtering buffer parsing
   *	Added extra button to allow to connect to MU DNAs before starting data
   *	
   *	Revision 4 2005/10/10 17:40:55 +0100 sb4450 /mobile/SASE-4.90.100_Tip/NSTD/Scott/Hemi
   *	Changes for 40 Mbps RTSM (hemi)
   *	
   *	Revision 3 2005/05/18 22:24:15 -0600 sb4450 /mobile/SASE-4.8_Tip/NSTD/RunFromFileAndBufferToDisk
   *	Bug fix for time stamp adjustments.
   *	
   *	Revision 2 2005/05/14 00:16:36 -0600 sb4450 /mobile/SASE-4.8_Tip/NSTD/MUPlay/CopyOfCingularMUReplay/Merge_4.8_with_CingularMUPlay
   *	merged in MultiUser Replay code
   *	
   *	Revision 1 2005/05/11 21:55:07 -0600 sb4450 /mobile/SASE-4.6_Tip/Cingular/MultiUserReplayInto4.8
   *	Import of MU Play code from Cingular snapshot
   *	
   *	Revision 16 2005/05/11 00:41:42 -0600 sb4450 /COS-Mobile/Cingular_Tip/Development-4.61.7/MUPlayback/Playback-Scott
   *	Automatic merge of parallel changes into revision [15]
   *	
   *	Revision 15 2005/05/10 13:02:04 -0600 sb4450 /COS-Mobile/Cingular_Tip/Development-4.61.7/MUPlayback/Playback-Scott/AppsMerge
   *	Automatic merge of parallel changes into revision [8]
   *	
   *	Revision 14 2005/05/10 12:02:36 -0600 mr3079 /COS-Mobile/Cingular_Tip/Development-4.61.7/MUPlayback
   *	Added mbps limiting, fixed bug in progress indicator, added timestamp adjustments
   *	
   *	Revision 13 2005/05/09 21:12:55 -0600 sb4450 /COS-Mobile/Cingular_Tip/Development-4.61.7/MUPlayback/Playback-Scott
   *	Automatic merge of parallel changes into revision [12]
   *	
   *	Revision 12 2005/05/09 16:46:51 -0600 sb4450 /COS-Mobile/Cingular_Tip/Development-4.61.7/MUPlayback/Playback-Scott
   *	Changes to allow Replay to not kick off slow clients and instead throttle the replay rate.
   *	
   *	Revision 11 2005/05/09 15:04:24 -0600 mr3079 /COS-Mobile/Cingular_Tip/Development-4.61.7/MUPlayback
   *	Added speed type gui changes for playback
   *	
   *	Revision 10 2005/05/09 13:52:05 -0600 mr3079 /COS-Mobile/Cingular_Tip/Development-4.61.7/MUPlayback
   *	Added Preserve Slow Client check box, started adding mbps limiting.
   *	
   *	Revision 9 2005/04/18 16:17:49 -0700 mr3079 /COS-Mobile/Cingular_Tip/Development-4.61.7/MUPlayback
   *	Added playback filename and progress.
   *	
   *	Revision 8 2005/04/07 14:31:11 -0600 sb4450 /COS-Mobile/Cingular_Tip/Development-4.61.7/Apps/ScottsMerge/Scott-PlaybackDebugging-1
   *	Changed critical section code to be more reliable and avoid deadlock
   *	conditions.  Also added logging of which file is being played back.
   *	
   *	Revision 7 2005/03/30 16:02:23 -0700 mr3079 /COS-Mobile/Cingular_Tip/Development-4.61.7/MUPlayback
   *	Added multiple file support.
   *	
   *	Revision 4 2005/03/21 07:59:55 -0700 mr3079 /COS-Mobile/Cingular_Tip/Development-4.61.3/Apps/Purifier_Integration/MUPlayback
   *	Added playback dialog
   *	
   *	Revision 1 2005/03/10 12:51:34 -0700 sb4450 /COS-Mobile/Cingular_Tip/Development-4.61.3/Apps/Purifier_Integration/Scott-Purifier-1
   *	New class - made MultiUserServer a base class for traditional Streaming Server
   *	and will be used for the Purifier Server too.
   *	
   *
   */
  
  #ifndef _MultiUserDNAServer_INCLUDED_
  #define _MultiUserDNAServer_INCLUDED_
  
  #include <string>
  #include <vector>
  using namespace std;
  
  #ifdef _WIN32
  #include <winsock2.h>
  #include <Ws2tcpip.h>
  #include <afxtempl.h>
  #include <afxmt.h>
  
  #include "LibraTypes.h"
  #include "NASocketExports.h"
  #include "NAAPIExports.h"
  #include "FilePlay.h"
  #endif
  
  #include "basetypes.h"
  #include "SartNAAPISharedDefs.h"
  #include "RtsdSupport.h"
  #include "MultiUserExports.h"
  #include "MultiUserServer.h"
  
  struct MUDNAStats
  {
      TCHAR               pszName[MAX_DNA_NAME];
      uint64              nBytesRx;
      uint64              nKbps;
      int                 nPlaybackLoopCount;
      int                 nPlaybackProgress;
      string              sPlaybackFilename;
      string              sBTDLagTime;    //!< Indicate lag time in BTD, update in Total Stats only
  };
  
  typedef vector<MUDNAStats> MU_DNA_STATS_ARRAY;
  
  
  // Utility class to store the DNA socket creation info so we can recreate
  // the DNA socket on the fly if it has an error and needs to be closed.
  class DnaSocketCreateInfo
  {
  public:
      DnaSocketCreateInfo()
      {
          m_pszAddress = NULL;
          m_nPort = 0;
          m_pszName = NULL; 
          m_pszType = NULL; 
          m_pszIfKey = NULL; 
          m_nTransportMode = NA_MASSTRANSIT_RTSM; 
          m_pNAInfo = NULL;
      }
  
      
      DnaSocketCreateInfo(LPCTSTR pszAddress, 
                          UINT16  nPort,
                          LPCTSTR pszName, 
                          LPCTSTR pszType, 
                          LPCTSTR pszIfKey, 
                          NARtsmTransportMode nTransportMode, 
                          NAInfo *pInfo)
      {
          m_pszAddress = pszAddress;
          m_nPort = nPort;
          m_pszName = pszName; 
          m_pszType = pszType; 
          m_pszIfKey = pszIfKey; 
          m_nTransportMode = nTransportMode; 
          m_pNAInfo = pInfo;
      }
  
  
      ~DnaSocketCreateInfo()
      {
          m_pszAddress = NULL;
          m_nPort = 0;
          m_pszName = NULL; 
          m_pszType = NULL; 
          m_pszIfKey = NULL; 
          m_nTransportMode = NA_MASSTRANSIT_RTSM; 
          m_pNAInfo = NULL;
      }
  
      LPCTSTR GetAddress() { return (m_pszAddress); }
      UINT16 GetPort() { return (m_nPort); }
      LPCTSTR GetName() { return (m_pszName); }
      LPCTSTR GetType()  { return (m_pszType); }
      LPCTSTR GetIfKey() { return (m_pszIfKey); }
      NAInfo* GetNAInfo() { return (m_pNAInfo); }
      NARtsmTransportMode GetTransportMode()  { return (m_nTransportMode); }
  
  private:
      LPCTSTR             m_pszAddress; 
      UINT16              m_nPort;
      LPCTSTR             m_pszName; 
      LPCTSTR             m_pszType; 
      LPCTSTR             m_pszIfKey; 
      NARtsmTransportMode m_nTransportMode; 
      NAInfo*             m_pNAInfo;
  };
  
  
  
  class MultiUserDNAServer : public MultiUserServer
  {
  public:    
      MultiUserDNAServer();
      virtual ~MultiUserDNAServer();
  
      virtual bool Init();
      virtual bool Shutdown();
      virtual bool Start();
      virtual bool Stop();
      virtual bool RemoveSocket(MultiUserSocket *pSocket, bool bIOError = false);
      virtual bool NewStreamConnection(MultiUserStreamingSocket *pSocket, UINT16 nPortNumber);
      virtual bool StartPlayback();
      virtual bool IsDataSourceHung();
      /// Returns true, unless all data sources are Uu Data Sources.
      virtual bool HwStatsEnabled();
      bool CreateDNASocket(int     dnaIndex,  // -1 to add in first available slot
                           LPCTSTR pszAddress, 
                           UINT16  nPort,
                           LPCTSTR pszName, 
                           LPCTSTR pszType, 
                           LPCTSTR pszIfKey, 
                           NARtsmTransportMode nTransportMode, 
                           NAInfo *pInfo);
      bool StartAllSockets();
      bool GetDNAStats( MU_DNA_STATS_ARRAY &statsArray );
  
      bool GetPreserveSlowClients() 
      { 
  #ifdef _WIN32
          CFilePlay *pFilePlay = CFilePlay::GetInstance();
          if(pFilePlay && pFilePlay->GetPreserveSlowClients())
              return true;
          else
              return false; 
  #else
          return false;
  #endif
      }
  
      static bool ReplayCallback(UINT8 nSocketIndex, UINT8 *pRecordData, UINT32 nLength);
      static bool WriteBlockToBuffer(UINT8 nSocketIndex, UINT8 *pRecordData, UINT32 nLength);
  
  protected:
      bool DestroyDNASockets();
      uint16 LookupDNAListenPort(LPCTSTR pszDNAIpAddr);
      MultiUserStreamingSocket* CreateStreamListenerSocket(
                                      LPCTSTR pszName, 
                                      LPCTSTR pszIfKey, 
                                      NARtsmTransportMode nTransportMode);
      bool LookupAndRemoveDNASocket(MultiUserSocket *pSocket);
  
      // critical sections work differently in MultiUserDNAServer
      virtual void LockServerCriticalSection();
      virtual void UnlockServerCriticalSection();
  
      // DNA sockets
      MultiUserDNASocket *m_pDnaSockets[NA_MAX_RECFILE_DNAS];
      NARtsmTransportMode m_nDnaSocketTypes[NA_MAX_RECFILE_DNAS];
      bool m_nActiveDnas[NA_MAX_RECFILE_DNAS];
      DnaSocketCreateInfo* m_pDnaSocketCreateInfo[NA_MAX_RECFILE_DNAS]; 
  
      virtual void CheckSockets();
      void CheckDNASockets();
      void CheckStreamingListenerSockets();
  
  private:
      void StopPlayback(void);
  
      uint32  m_nDNATimeoutSeconds;
  };
  
  
  
  // Stub to start the playback thread
  void startPlayback(void * param);
  
  
  #endif // _MultiUserDNAServer_INCLUDED_
  