hxprotocol.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:14k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxcom.h"
  36. #include "hlxclib/string.h"
  37. #include "hxresult.h"
  38. #include "hxtypes.h"
  39. #include "hxassert.h"
  40. #if defined(_WINDOWS) || defined(WIN32)
  41. #include "platform/win/win_net.h"
  42. #endif
  43. #include "hxcomm.h"
  44. #include "ihxpckts.h"
  45. #include "hxfiles.h"
  46. #include "hxengin.h"
  47. #include "chxpckts.h"
  48. #include "hxcore.h"
  49. #include "hxprefs.h"
  50. #include "hxpref.h"
  51. #include "hxpends.h"
  52. #include "hxslist.h"
  53. #include "hxstring.h"
  54. #include "chxelst.h"
  55. #include "chxeven.h"
  56. #include "strminfo.h"
  57. #include "hxntsrc.h"
  58. #include "hxtick.h"
  59. #include "hxmangle.h"
  60. #include "hxprotocol.h"
  61. #include "hxheap.h"
  62. #ifdef _DEBUG
  63. #undef HX_THIS_FILE
  64. static const char HX_THIS_FILE[] = __FILE__;
  65. #endif
  66. HXProtocol::HXProtocol(HXNetSource* owner, ULONG32 ulPlatformData) :
  67.   mOwner (owner)
  68. , m_pPreferences(0)
  69. , m_bConnectDone (FALSE)
  70. , mProtocolValid (FALSE)
  71. , mSendStatsMask (1)
  72. , mLocked (0)
  73. , mAtInterrupt (0)
  74. , m_bPaused (FALSE)
  75. , mSourceEnd (FALSE)
  76. , mLocale (0)
  77. , mUseUDPPort (FALSE)
  78. , m_uUDPPort (0)
  79. , mHost (0)
  80. , mPath (0)
  81. , mLossCorrection (FALSE)
  82. , m_pszClientID (NULL)
  83. , m_pszGUID (NULL)
  84. , mServerAddr (0)
  85. , mServerTimeout (0)
  86. , mPort (0)
  87. , mUseProxy (FALSE)
  88. , mProxy (0)
  89. , mProxyPort (0)
  90. , mProxyVersion (0)
  91. , mFlowControl (FALSE)
  92. , mProtocolVersion (0)
  93. , m_bPerfectPlay (FALSE)
  94. , m_bPrefetch(FALSE)
  95. , m_bFastStart(FALSE)
  96. , mMulticastAddr (0)
  97. , mMulticastPort (0)
  98. , mUsingMulticast (FALSE)
  99. , mCurrentTransport(UnknownMode)
  100. , m_ulTransportPrefMask(0)
  101. , mLiveStream(FALSE)
  102. , mSaveAsAllowed(FALSE)
  103. , m_bPerfectPlayAllowed(FALSE)
  104. , mNumFlowControl(0)
  105. , m_ulRegistryID (0)
  106. , m_pRegistry (0)
  107. , m_lRefCount(0)
  108. , m_bIsFirstResume(TRUE)
  109. , m_bHTTPOnly(FALSE)
  110. , mCloakPort(0)
  111. , m_pCredentialsCache(NULL)
  112. , m_LastError(HXR_OK)
  113. , m_pTextBuf(NULL)
  114. , m_bHTTPvProxy(FALSE)
  115. , m_pCloakPorts(NULL)
  116. , m_nCloakPorts(0)
  117. , m_bAreResuming(FALSE)
  118. , m_ulLastAlert(0)
  119.         , m_bSDPInitiated(FALSE)
  120. {
  121.     if (mOwner)
  122.     {
  123. mOwner->AddRef();
  124. mOwner->QueryInterface(IID_IHXPreferences, (void **) &m_pPreferences);
  125. m_pRegistry = mOwner->m_pRegistry;  
  126. if (HXR_OK != mOwner->QueryInterface(IID_IHXCredentialsCache, (void**)&m_pCredentialsCache))
  127. {
  128.     m_pCredentialsCache = NULL;
  129. }
  130.     }
  131. }
  132. HXProtocol::~HXProtocol(void)
  133. {
  134.     HX_RELEASE(m_pPreferences);
  135.     HX_RELEASE(m_pCredentialsCache);
  136.     HX_RELEASE(mOwner);
  137.     HX_VECTOR_DELETE(mHost);
  138.     HX_VECTOR_DELETE(mPath);
  139.     HX_VECTOR_DELETE(m_pszClientID);
  140.     HX_VECTOR_DELETE(m_pszGUID);
  141.     HX_VECTOR_DELETE(mProxy);
  142.     HX_VECTOR_DELETE(m_pTextBuf);
  143. }
  144. // these get initialized every time we make a new connection with 
  145. // the server
  146. void HXProtocol::initialize_members()
  147. {
  148.     IHXBuffer* pBuffer = NULL;
  149.     mProtocolValid = FALSE;
  150.     mFlowControl = FALSE;
  151.     mLiveStream = FALSE;
  152.     mSaveAsAllowed = FALSE;
  153.     m_bPerfectPlayAllowed = FALSE;
  154.     mNumFlowControl = 0;
  155.     HX_VECTOR_DELETE(m_pszGUID);
  156.     BOOL     bCanSendGUID    = FALSE;
  157.     ReadPrefBOOL(m_pPreferences, "AllowAuthID", bCanSendGUID);  
  158.     if(bCanSendGUID &&
  159.        m_pPreferences && m_pPreferences->ReadPref(CLIENT_GUID_REGNAME, pBuffer) == HXR_OK)
  160.     {
  161. m_pszGUID = DeCipher((char*)pBuffer->GetBuffer());
  162.     }
  163.     else
  164.     {
  165. m_pszGUID = new char[sizeof(CLIENT_ZERO_GUID) + 1];
  166. ::strcpy(m_pszGUID, CLIENT_ZERO_GUID); /* Flawfinder: ignore */
  167.     }
  168.     HX_ASSERT(m_pszGUID);
  169.     HX_RELEASE(pBuffer);
  170. }
  171. HX_RESULT
  172. HXProtocol::setup(const char *host, const char *path, UINT16 port, BOOL LossCorrection, 
  173.   BOOL bHTTPCloak, BOOL bSDPInitiated, UINT16 cloakPort) 
  174. {
  175.     HX_RESULT theErr = HXR_OK;
  176.     if (bSDPInitiated)
  177.     {
  178.         mPath = new char[::strlen(path) + 1];
  179.         ::strcpy(mPath, path);
  180.     }
  181.     else
  182.     {
  183.         // get out immediately if we have bogus parameters
  184.         if(!host || !*host)
  185.     theErr = HXR_DNR;
  186.     
  187.         if(!theErr && !path)
  188.     theErr = HXR_INVALID_PATH;
  189.     
  190.         if(!theErr)
  191.         {
  192.     HX_VECTOR_DELETE(mHost);
  193.     HX_VECTOR_DELETE(mPath);
  194.     
  195.     // Save a copy of the parameters
  196.     mHost = new char[::strlen(host) + 1];
  197.     mPath = new char[::strlen(path) + 1];
  198.     
  199.     if(!mHost || !mPath)
  200.         theErr = HXR_OUTOFMEMORY;
  201.         }
  202.         // initialize member variables
  203.         if(!theErr)
  204.         {
  205.     ::strcpy(mHost, host); /* Flawfinder: ignore */
  206.     ::strcpy(mPath, path); /* Flawfinder: ignore */
  207.     
  208.     // strip off fragment
  209.     char* pFragment = strchr(mPath, '#');
  210.     if(pFragment)
  211.     {
  212.         *pFragment = '';
  213.     }
  214.     mPort = port;
  215.     mLossCorrection = LossCorrection;
  216.     m_bHTTPOnly = bHTTPCloak;
  217.     mCloakPort = cloakPort;
  218.         }
  219.     }
  220.     return(theErr);
  221. }
  222. HX_RESULT
  223. HXProtocol::process_idle (BOOL atInterrupt)
  224. {
  225.     HX_RESULT theErr = HXR_OK;
  226.     if(mLocked)  // process is locked
  227. return HXR_OK;
  228.     mLocked = 1; // lock out interrupt processing
  229.     if (atInterrupt)
  230.     {
  231. mAtInterrupt = 1;
  232.     }
  233.     theErr = process();
  234.     
  235.     mAtInterrupt = 0;
  236.     mLocked = 0; // enable interrupt processing
  237.     return(theErr);
  238. }
  239. HX_RESULT
  240. HXProtocol::set_client_id(char *clientID) 
  241. {
  242.     HX_VECTOR_DELETE(m_pszClientID);
  243.     // check if the clientID is not null
  244.     if(clientID == 0) return HXR_OK;
  245.     m_pszClientID = new char[::strlen(clientID) + 1];
  246.     if(m_pszClientID == 0) return HXR_OUTOFMEMORY;
  247.     ::strcpy(m_pszClientID, clientID); /* Flawfinder: ignore */
  248.     return HXR_OK;
  249. }
  250. // sets up HXProtocol to use a RealAudio proxy
  251. HX_RESULT
  252. HXProtocol::set_proxy(const char* proxy, UINT16 port)
  253. {
  254.     HX_RESULT theErr = HXR_OK;
  255.     if(proxy == 0 || *proxy == 0) return HXR_OK;
  256.     HX_VECTOR_DELETE(mProxy);
  257.     mProxy = new char[::strlen(proxy) + 1];
  258.     if(mProxy == NULL) theErr = HXR_OUTOFMEMORY;
  259.     if(!theErr)
  260.     {
  261. ::strcpy(mProxy, proxy); /* Flawfinder: ignore */
  262. mProxyPort = port;
  263.     }
  264.     mUseProxy = theErr == HXR_OK;
  265.     return(theErr);
  266. }
  267. void
  268. HXProtocol::LeavePrefetch(void)
  269. {
  270.     m_bPrefetch = FALSE;
  271.     return;
  272. }
  273. void
  274. HXProtocol::SetCloakPortAttempted(UINT16* pCloakPorts, UINT8 nCloakPorts)
  275. {
  276.     m_pCloakPorts = pCloakPorts;
  277.     m_nCloakPorts = nCloakPorts;
  278. }
  279. HX_RESULT
  280. HXProtocol::stop(void)
  281. {
  282.     mSourceEnd = TRUE;
  283.     HX_RELEASE(mOwner);
  284.     return HXR_OK;
  285. }
  286. #if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
  287. void 
  288. HXProtocol::statistics_cat(char* pStats, UINT32 ulBufLen, LONG32 lData)
  289. {
  290.     char numb[12]; /* Flawfinder: ignore */
  291.     SafeSprintf(numb, 12, "%10lu ", lData); /* Flawfinder: ignore */
  292.     SafeStrCat(pStats,numb, ulBufLen);
  293. }
  294. void
  295. HXProtocol::statistics_cat_ext(char* pszStats, UINT32 ulBufLen, LONG32 lData, char* pszSep, UINT32& ulCount)
  296. {
  297.     char numb[12]; /* Flawfinder: ignore */
  298.     if (pszSep)
  299.     {
  300. SafeSprintf(numb, 12, "%lu%s", lData, pszSep);
  301.     }
  302.     else
  303.     {
  304. SafeSprintf(numb,12, "%lu", lData);
  305.     }
  306.     SafeStrCat(pszStats, numb, ulBufLen);
  307.     ulCount += strlen(numb);
  308. }
  309. HX_RESULT
  310. HXProtocol::prepare_statistics(UINT32 ulStatsMask, char*& pszStats)
  311. {
  312.     HX_RESULT     rc = HXR_OK;
  313.     char     szRegKeyName[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
  314.     char*     pszCodec = NULL;
  315.     INT32     lRAStreamNumber = -1;
  316.     UINT32     i = 0;
  317.     UINT32     ulStatsLength = 0;
  318.     UINT32     ulTransport = 0;
  319.     UINT32     ulLength = 0;
  320.     STREAM_STATS*   pStreamStats = NULL;
  321.     CHXSimpleList*  pLogInfoList = NULL;
  322.     IHXBuffer*     pParentName = NULL;
  323.     IHXBuffer*     pValue = NULL;
  324.     pszStats = NULL;
  325.     // collect level 3 stats info.
  326.     ulStatsLength = MAX_DISPLAY_NAME + mOwner->GetLogInfo(pLogInfoList);
  327.     if (!(ulStatsMask & 8UL))
  328.     {
  329. // get the RA stream number
  330. // Level 1,2 pszStats only apply to RealAudio
  331. lRAStreamNumber = mOwner->GetRAStreamNumber();
  332. if (lRAStreamNumber >= 0)
  333. {
  334.     // retrieve the pszStats
  335.     if (HXR_OK != GetStreamStatistics((UINT32)lRAStreamNumber, &pStreamStats))
  336.     {
  337. goto cleanup;
  338.     }
  339.     if (!pStreamStats || !pStreamStats->m_bInitialized)
  340.     {
  341. goto cleanup;
  342.     }
  343.     // retreive the pszStats set by the renderer
  344.     if (m_pRegistry &&
  345.                 HXR_OK == m_pRegistry->GetPropName(pStreamStats->m_pRenderer->m_ulRegistryID, pParentName))
  346.     {
  347. SafeSprintf(szRegKeyName, MAX_DISPLAY_NAME, "%s.Codec", pParentName->GetBuffer());
  348.     
  349. if (HXR_OK == m_pRegistry->GetStrByName(szRegKeyName, pValue) && pValue)
  350. {
  351.     ulLength = pValue->GetSize();
  352.     pszCodec = new char[ulLength + 1];
  353.     strcpy(pszCodec, (const char*)pValue->GetBuffer()); /* Flawfinder: ignore */
  354.     // replace space with underscore
  355.     for (i = 0; i < ulLength; i++)
  356.     {
  357. if (pszCodec[i] == ' ')
  358. {
  359.     pszCodec[i] = '_';
  360. }
  361.     }
  362.     HX_RELEASE(pValue);
  363. }
  364.     }
  365.     HX_RELEASE(pParentName);
  366.     if (pszCodec)
  367.     {
  368. ulStatsLength += 2 * strlen(pszCodec);
  369.     }
  370.     pszStats = new CHAR[ulStatsLength];
  371.     memset(pszStats, 0, ulStatsLength);
  372.     if (ulStatsMask & 1UL)
  373.     {
  374. SafeStrCat(pszStats, "Stat1:", ulStatsLength);
  375. // build statistics string
  376. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pReceived->GetInt());
  377. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pReceived->GetInt() -
  378.  pStreamStats->m_pNormal->GetInt());
  379. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pLost->GetInt());
  380. statistics_cat(pszStats, ulStatsLength, 0); // no packets sent early in 6.0
  381. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pLate->GetInt());
  382. if (!pszCodec)
  383. {
  384.     SafeStrCat(pszStats, "N/A", ulStatsLength);
  385. }
  386. else
  387. {
  388.     SafeStrCat(pszStats, pszCodec, ulStatsLength);
  389. }
  390.     }
  391.     if (ulStatsMask & 2UL)
  392.     {
  393. // divide pszStats levels if necessary
  394. if (ulStatsMask & 1UL)
  395. {
  396.     SafeStrCat(pszStats, "][", ulStatsLength);
  397. }
  398. SafeStrCat(pszStats, "Stat2:", ulStatsLength);
  399.        
  400. // Bandwidth info
  401. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pClipBandwidth->GetInt());
  402. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pAvgBandwidth->GetInt());
  403. // Latency info
  404. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pHighLatency->GetInt());
  405. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pLowLatency->GetInt());
  406. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pAvgLatency->GetInt());
  407. // Resend info
  408. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pResendRequested->GetInt());
  409. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pResendReceived->GetInt());
  410. statistics_cat(pszStats, ulStatsLength, pStreamStats->m_pLate->GetInt());
  411. // rebuffer info (in percent)
  412. statistics_cat(pszStats, ulStatsLength, 0);
  413. // Transport
  414. // 0 or UDP, 1 for TCP, 2 for Multicast...
  415. if (mCurrentTransport == UDPMode)
  416. {
  417.     ulTransport = 0L;
  418. }     
  419. else if (mCurrentTransport == TCPMode)
  420. {
  421.     ulTransport = 1L;
  422. }
  423. else if (mCurrentTransport == MulticastMode)
  424. {
  425.     ulTransport = 2L;
  426. }
  427. statistics_cat(pszStats, ulStatsLength, ulTransport);
  428. // Startup latency, first data packet arrives!
  429. statistics_cat(pszStats, ulStatsLength, mOwner->GetFirstDataArriveTime());
  430. if (!pszCodec)
  431. {
  432.     SafeStrCat(pszStats, "N/A", ulStatsLength);
  433. }
  434. else
  435. {
  436.     SafeStrCat(pszStats, pszCodec, ulStatsLength);
  437. }
  438.     }
  439. }
  440.     }
  441.     if ((ulStatsMask & 4UL) && pLogInfoList && pLogInfoList->GetCount())
  442.     {
  443. if (!pszStats)
  444. {
  445.     pszStats = new CHAR[ulStatsLength];
  446.     memset(pszStats, 0, ulStatsLength);
  447. }
  448. // divide stats levels if necessary
  449.         if((lRAStreamNumber >= 0) && ((ulStatsMask & 1UL) || (ulStatsMask & 2UL)))
  450.         {
  451.             SafeStrCat(pszStats, "][", ulStatsLength);
  452.         }
  453.         SafeStrCat(pszStats, "Stat3:", ulStatsLength);
  454. CHXSimpleList::Iterator ndx = pLogInfoList->Begin();
  455. for (; ndx != pLogInfoList->End(); ++ndx)
  456. {
  457.     char* pszInfo = (char*) (*ndx);
  458.     SafeStrCat(pszStats, pszInfo, ulStatsLength);
  459. }
  460.     }
  461.     if (!pszStats || strlen(pszStats) == 0)
  462.     {
  463. // nothing to send
  464. goto cleanup;
  465.     }
  466.     else
  467.     {
  468. SafeStrCat(pszStats, "]", ulStatsLength);
  469.     }
  470. cleanup:
  471.     HX_VECTOR_DELETE(pszCodec);
  472.     return HXR_OK;
  473. }
  474. #endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY */