hxprotocol.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:15k
源码类别:

Symbian

开发平台:

Visual C++

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