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

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2003 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 "platform/symbian/hxsymbianapman.h"
  36. #include "ihxpckts.h"
  37. #include "debug.h"
  38. #define D_AP_MANAGER 0x20000000
  39. const UINT32 DefaultNumOfRetries = 1; /* Number of connect retries before
  40.        * reporting the error. The retry
  41.        * mechanism is needed because switching
  42.        * access points can cause the first
  43.        * connect to fail. This is a documented
  44.        * Symbian bug.
  45.        */
  46. class HXSymbianAPManAO : public CActive
  47. {
  48. public:
  49.     HXSymbianAPManAO(HXSymbianAccessPointManager* pParent,
  50.      CIntConnectionInitiator* pConnInit);
  51.     ~HXSymbianAPManAO();
  52.     HX_RESULT Connect(UINT32 ulAccessPointId);
  53.     HX_RESULT Disconnect();
  54.     void RunL();
  55.     void DoCancel();
  56. private:
  57.     HXSymbianAccessPointManager* m_pParent;
  58.     CIntConnectionInitiator* m_pConnInit;
  59.     CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref m_connPref;
  60.     BOOL m_bConnecting;
  61. };
  62. HXSymbianAPManAO::HXSymbianAPManAO(HXSymbianAccessPointManager* pParent,
  63.    CIntConnectionInitiator* pConnInit) :
  64.     CActive(EPriorityStandard),
  65.     m_pParent(pParent),
  66.     m_pConnInit(pConnInit),
  67.     m_bConnecting(FALSE)
  68. {
  69.     CActiveScheduler::Add(this);
  70. }
  71. HXSymbianAPManAO::~HXSymbianAPManAO()
  72. {
  73.     if (IsActive())
  74.     {
  75. Cancel();
  76.     }
  77.     
  78.     m_pParent = 0;
  79.     m_pConnInit = 0;
  80. }
  81. HX_RESULT HXSymbianAPManAO::Connect(UINT32 ulAccessPointId)
  82. {
  83.     HX_RESULT res = HXR_UNEXPECTED;
  84.     if (m_pConnInit && !IsActive())
  85.     {
  86. TInt theErr = KErrNone;
  87. m_bConnecting = TRUE;
  88. iStatus = KRequestPending;
  89. m_connPref.iRanking = 1; // Means always try this pref
  90. m_connPref.iDirection = ECommDbConnectionDirectionOutgoing;
  91. m_connPref.iDialogPref = ECommDbDialogPrefDoNotPrompt;
  92. m_connPref.iBearer.iBearerSet = (ECommDbBearerGPRS | ECommDbBearerCSD);
  93. m_connPref.iBearer.iIapId = ulAccessPointId;
  94. TRAP(theErr, m_pConnInit->ConnectL(m_connPref, iStatus));
  95. if (KErrNone == theErr)
  96. {
  97.     SetActive();
  98.     res = HXR_OK;
  99. }
  100. else
  101. {
  102.     res = HXR_NET_CONNECT;
  103. }
  104.     }
  105.     return res;
  106. }
  107. HX_RESULT HXSymbianAPManAO::Disconnect()
  108. {
  109.     HX_RESULT res = HXR_FAILED;
  110.     if (m_pConnInit && !IsActive())
  111.     {
  112. m_bConnecting = FALSE;
  113. iStatus = KRequestPending;
  114. if (KErrNone == m_pConnInit->TerminateActiveConnection(iStatus))
  115. {
  116.     SetActive();
  117.     res = HXR_OK;
  118. }
  119.     }
  120.     return res;
  121. }
  122. void HXSymbianAPManAO::RunL()
  123. {
  124.     if (m_pParent)
  125.     {
  126. HX_RESULT status = HXR_NET_CONNECT;
  127. if (m_bConnecting)
  128. {
  129.     if ((iStatus == KErrNone) ||
  130. (iStatus == KConnectionPref1Exists) ||
  131. (iStatus == KConnectionExists) ||
  132. (iStatus == KConnectionPref1Created) ||
  133. (iStatus == KConnectionCreated) ||
  134. (iStatus == KErrOutstandingRequest))
  135.     {
  136. status = HXR_OK;
  137.     }
  138.     m_pParent->ConnectDone(status);
  139. }
  140. else 
  141. {
  142.     if ((iStatus == KErrNone) ||
  143. (iStatus == KConnectionTerminated) ||
  144. (iStatus == KErrOutstandingRequest))
  145.     {
  146. status = HXR_OK;
  147.     }
  148.     m_pParent->DisconnectDone(status);
  149. }
  150.     }
  151. }
  152. void HXSymbianAPManAO::DoCancel()
  153. {
  154.     // Cancel possible outstanding request 
  155.     if(m_pConnInit && m_pConnInit->IsActive())
  156.     {
  157.         m_pConnInit->Cancel();
  158.     }
  159. }
  160. BEGIN_INTERFACE_LIST(HXSymbianAccessPointManager)
  161.     INTERFACE_LIST_ENTRY_SIMPLE(IHXAccessPointManager)
  162.     INTERFACE_LIST_ENTRY_SIMPLE(IHXAccessPointSelectorResponse)
  163. END_INTERFACE_LIST
  164. HXSymbianAccessPointManager::HXSymbianAccessPointManager():
  165.     m_state(apError),
  166.     m_pConnInit(0),
  167.     m_pConnector(0),
  168.     m_pPreferredInfo(NULL),
  169.     m_pCCF(NULL),
  170.     m_pAPSelector(NULL),
  171.     m_bSelectAPPending(FALSE)
  172. {
  173. #ifdef _DEBUG
  174.     debug_level() |= D_AP_MANAGER;
  175. #endif /* _DEBUG */
  176.     DPRINTF(D_AP_MANAGER, ("HXSymbianAccessPointManager::HXSymbianAccessPointManager()n"));
  177.     TRAPD(theErr, m_pConnInit = CIntConnectionInitiator::NewL());
  178.     m_pConnector = new HXSymbianAPManAO(this, m_pConnInit);
  179.     if (m_pConnInit && m_pConnector &&
  180. (KErrNone == m_sockServ.Connect()) &&
  181. (KErrNone == theErr))
  182.     {
  183. m_state = apIdle;
  184.     }
  185. }
  186. HXSymbianAccessPointManager::~HXSymbianAccessPointManager()
  187. {
  188.     DPRINTF(D_AP_MANAGER, ("HXSymbianAccessPointManager::~HXSymbianAccessPointManager()n"));
  189.     HX_DELETE(m_pConnector);
  190.     HX_DELETE(m_pConnInit);
  191.     HX_RELEASE(m_pPreferredInfo);
  192.     HX_RELEASE(m_pCCF);
  193.     HX_RELEASE(m_pAPSelector);
  194.     m_sockServ.Close();
  195.     DispatchConnectDones(HXR_FAILED);
  196. }
  197. /*
  198.  * IHXAccessPointManager methods
  199.  */
  200. /************************************************************************
  201.  * Method:
  202.  *     IHXAccessPointManager::Connect
  203.  * Purpose:
  204.  *     Notifies the access point manager that an object wants the access
  205.  *      point to connect to it's ISP.
  206.  *
  207.  */
  208. STDMETHODIMP
  209. HXSymbianAccessPointManager::Connect(THIS_ IHXAccessPointConnectResponse* pResp)
  210. {
  211.     DPRINTF(D_AP_MANAGER, ("HXSymbianAccessPointManager::Connect()n")); 
  212.     HX_RESULT res = HXR_FAILED;
  213.     if (pResp)
  214.     {
  215. res = DoConnect(pResp);
  216.     }
  217.     
  218.     return res;
  219. }
  220. /************************************************************************
  221.  * Method:
  222.  *     IHXAccessPointManager::RegisterSelector
  223.  * Purpose:
  224.  *      Provides the IHXAccessPointManager with an IHXAccessPointSelector 
  225.  *      to use when it needs information about the desired access point.
  226.  *
  227.  */
  228. STDMETHODIMP 
  229. HXSymbianAccessPointManager::RegisterSelector(THIS_ IHXAccessPointSelector* pSelector)
  230. {
  231.     HX_RESULT res = HXR_FAILED;
  232.     // Currently we only support 1 registered selector so
  233.     // we only allow this call to succeed if m_pAPSelector
  234.     // is not set.
  235.     if (pSelector && !m_pAPSelector)
  236.     {
  237. m_pAPSelector = pSelector;
  238. m_pAPSelector->AddRef();
  239. res = HXR_OK;
  240.     }
  241.     return res;
  242. }
  243.     
  244. /************************************************************************
  245.  * Method:
  246.  *     IHXAccessPointManager::UnregisterSelector
  247.  * Purpose:
  248.  *      Unregisters a previously registered IHXAccessPointSelector
  249.  *
  250.  */
  251. STDMETHODIMP
  252. HXSymbianAccessPointManager::UnregisterSelector(THIS_ IHXAccessPointSelector* pSelector) 
  253. {
  254.     HX_RESULT res = HXR_FAILED;
  255.     // We only allow one registered selector so this call
  256.     // will only succeed if the pSelector is a valid pointer
  257.     // and matches the selector that was registered.
  258.     if (pSelector && (pSelector == m_pAPSelector))
  259.     {
  260. HX_RELEASE(m_pAPSelector);
  261.     }
  262.     return res;
  263. }
  264.     
  265. /************************************************************************
  266.  * Method:
  267.  *     IHXAccessPointManager::GetActiveAccessPointInfo
  268.  * Purpose:
  269.  *      Returns information about the access point we are currently 
  270.  *      connected to. This function returns an error if we are 
  271.  *      not connected to an access point.
  272.  *
  273.  */
  274. STDMETHODIMP
  275. HXSymbianAccessPointManager::GetActiveAccessPointInfo(THIS_ REF(IHXValues*) pInfo)
  276. {
  277.     HX_RESULT res = HXR_UNEXPECTED;
  278.     pInfo = NULL;
  279.     if (m_pCCF)
  280.     {
  281. ULONG32 ulActiveID = 0;
  282. res = GetActiveID(ulActiveID);
  283. if (HXR_OK == res)
  284. {
  285.     res = m_pCCF->CreateInstance(CLSID_IHXValues, (void**)&pInfo);
  286.     
  287.     if (HXR_OK == res)
  288.     {
  289. res = pInfo->SetPropertyULONG32("ID", ulActiveID);
  290. if (HXR_OK != res)
  291. {
  292.     HX_RELEASE(pInfo);
  293. }
  294.     }
  295. }
  296.     }
  297.     DPRINTF(D_AP_MANAGER, 
  298.     ("HXSymbianAccessPointManager::GetActiveAccessPointInfo() : %08xn",
  299.      res));
  300.     
  301.     return res;
  302. }
  303. /************************************************************************
  304.  * Method:
  305.  *     IHXAccessPointManager::GetPreferredAccessPointInfo
  306.  * Purpose:
  307.  *      Returns information about the access point we want to connect to.
  308.  */
  309. STDMETHODIMP
  310. HXSymbianAccessPointManager::GetPreferredAccessPointInfo(THIS_ REF(IHXValues*) pInfo)
  311. {
  312.     HX_RESULT res = HXR_FAILED;
  313.     pInfo = m_pPreferredInfo;
  314.     if (pInfo)
  315.     {
  316. res = HXR_OK;
  317.     }
  318.     DPRINTF(D_AP_MANAGER, 
  319.     ("HXSymbianAccessPointManager::GetPreferredAccessPointInfo() : %08xn",
  320.      res));
  321.     return res;
  322. }
  323. /************************************************************************
  324.  * Method:
  325.  *     IHXAccessPointManager::SetPreferredAccessPointInfo
  326.  * Purpose:
  327.  *      Tells the access point manager about the access 
  328.  *      point we would like it to connect to.
  329.  */
  330. STDMETHODIMP
  331. HXSymbianAccessPointManager::SetPreferredAccessPointInfo(THIS_ IHXValues* pInfo)
  332. {
  333.     HX_RESULT res = HXR_FAILED;
  334.     ULONG32 ulAccessPointID = 0;
  335.     if (pInfo && (HXR_OK == pInfo->GetPropertyULONG32("ID", ulAccessPointID)))
  336.     {
  337. HX_RELEASE(m_pPreferredInfo);
  338. m_pPreferredInfo = pInfo;
  339. m_pPreferredInfo->AddRef();
  340. res = HXR_OK;
  341.     }
  342.     else
  343.     {
  344. HX_RELEASE(m_pPreferredInfo);
  345.     }
  346.     return res;
  347. }
  348. /*
  349.  * IHXAccessPointSelectorResponse methods
  350.  */
  351. /************************************************************************
  352.  * Method:
  353.  *     IHXAccessPointSelectorResponse::SelectAccessPointDone
  354.  * Purpose:
  355.  *      Returns the selected access point info
  356.  */
  357. STDMETHODIMP
  358. HXSymbianAccessPointManager::SelectAccessPointDone(THIS_ HX_RESULT status, 
  359.    IHXValues* pInfo)
  360. {
  361.     HX_RESULT res = HXR_UNEXPECTED;
  362.     if (m_bSelectAPPending)
  363.     {
  364. m_bSelectAPPending = FALSE;
  365. if ((HXR_OK == status) &&
  366.     (HXR_OK == SetPreferredAccessPointInfo(pInfo)))
  367. {
  368.     status = DoConnect(0);
  369. }
  370. if (HXR_OK != status)
  371. {
  372.     if (HXR_OUTOFMEMORY != status)
  373.     {
  374. status = HXR_NET_CONNECT;
  375.     }
  376.     DispatchConnectDones(status);
  377. }
  378. res = HXR_OK;
  379.     }
  380.     return res;
  381. }
  382. void HXSymbianAccessPointManager::SetContext(IUnknown* pContext)
  383. {
  384.     if (pContext)
  385.     {
  386. pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&m_pCCF);
  387.     }
  388. }
  389. HX_RESULT 
  390. HXSymbianAccessPointManager::DoConnect(IHXAccessPointConnectResponse* pResp)
  391. {
  392.     DPRINTF(D_AP_MANAGER, ("HXSymbianAccessPointManager::DoConnect(%p)n", 
  393.    pResp));
  394.     HX_RESULT res = HXR_FAILED;
  395.     ULONG32 ulActiveId = 0;
  396.     ULONG32 ulPreferredId = 0;
  397.     BOOL bQueueResponse = (pResp) ? TRUE : FALSE;
  398.     if (HXR_OK == GetPreferredID(ulPreferredId))
  399.     {
  400. // We have a preferred access point set
  401. if (HXR_OK != GetActiveID(ulActiveId))
  402. {
  403.     // We don't have an active access point
  404.     if (apConnected == m_state)
  405.     {
  406. // The access point disconnected without
  407. // our knowledge. Update our state.
  408. m_state = apIdle;
  409.     }
  410.     // Start to connect
  411.     res = StartConnection();
  412. }
  413. else if (ulActiveId == ulPreferredId)
  414. {
  415.     // We have a preferred access point and we are connected
  416.     // to it.
  417.     // Dispatch the callbacks now.
  418.     if (pResp)
  419.     {
  420. pResp->ConnectDone(HXR_OK);
  421. bQueueResponse = FALSE;
  422.     }
  423.     if (apIdle == m_state)
  424.     {
  425. m_state = apConnected;
  426. // Dispatch any other pending callbacks
  427. DispatchConnectDones(HXR_OK);
  428.     }
  429.     
  430.     res = HXR_OK;
  431. }
  432. else
  433. {
  434.     // We need to disconnect from the current access
  435.     // point
  436.     
  437.     res = StartDisconnect();
  438. }
  439.     }
  440.     else
  441.     {
  442. // We don't have a preferred access point
  443. if (m_pAPSelector)
  444. {
  445.     if (!m_bSelectAPPending)
  446.     {
  447. // Use the Selector to get the preferred access point
  448. m_bSelectAPPending = TRUE;
  449. res = m_pAPSelector->SelectAccessPoint(this);
  450. if (HXR_OK != res)
  451. {
  452.     m_bSelectAPPending = FALSE;
  453. }
  454.     }
  455.     else
  456.     {
  457. // A SelectAccessPoint() request is currently
  458. // pending
  459. res = HXR_OK;
  460.     }
  461. }
  462. else
  463. {
  464.     // We have no way to get access point information.
  465.     res = HXR_NET_CONNECT;
  466. }
  467.     }
  468.     if ((HXR_OK == res) && bQueueResponse)
  469.     {
  470. pResp->AddRef();
  471. m_respList.AddTail(pResp);
  472.     }
  473.     return res;
  474. }
  475. HX_RESULT HXSymbianAccessPointManager::StartConnection()
  476. {
  477.     DPRINTF(D_AP_MANAGER, ("HXSymbianAccessPointManager::StartConnection()n"));
  478.     HX_RESULT res = HXR_UNEXPECTED;
  479.     BOOL bConnect = TRUE;
  480.     if (apIdle == m_state)
  481.     {
  482. m_ulRetryCount = DefaultNumOfRetries;
  483.     }
  484.     else if (apConnecting != m_state)
  485.     {
  486. bConnect = FALSE;
  487.     }
  488.     if (bConnect && m_pPreferredInfo)
  489.     {
  490. ULONG32 ulAccessPointID = 0;
  491. res = m_pPreferredInfo->GetPropertyULONG32("ID", ulAccessPointID);
  492. if (HXR_OK == res)
  493. {
  494.     res = m_pConnector->Connect(ulAccessPointID);
  495.     if (HXR_OK == res)
  496.     {
  497. m_state = apConnecting;
  498.     }
  499. }
  500.     }
  501.     DPRINTF(D_AP_MANAGER, 
  502.     ("HXSymbianAccessPointManager::StartConnection() : res %08xn",
  503.      res));
  504.     return res;
  505. }
  506. void HXSymbianAccessPointManager::ConnectDone(HX_RESULT status)
  507. {
  508.     DPRINTF(D_AP_MANAGER, 
  509.     ("HXSymbianAccessPointManager::ConnectDone(%08x)n",
  510.      status));
  511.     HX_ASSERT(apConnecting == m_state);
  512.     BOOL bReportStatus = TRUE;
  513.     if (HXR_OK == status)
  514.     {
  515. m_state = apConnected;
  516.     }
  517.     else if (m_ulRetryCount)
  518.     {
  519. // Sometimes the first connect fails if we
  520. // disconnect from an access point and then
  521. // connect to a different one. This is a
  522. // documented Symbian bug.
  523. // Try to connect again
  524. m_ulRetryCount--;
  525. status = StartConnection();
  526. if (HXR_OK == status)
  527. {
  528.     bReportStatus = FALSE;
  529. }
  530.     }
  531.     else
  532.     {
  533. // Connect and all retries failed.
  534. // Transition back to the idle state
  535. m_state = apIdle;
  536.     }
  537.     if (bReportStatus)
  538.     {
  539. DispatchConnectDones(status);
  540.     }
  541. }
  542. HX_RESULT HXSymbianAccessPointManager::StartDisconnect()
  543. {
  544.     DPRINTF(D_AP_MANAGER, ("HXSymbianAccessPointManager::StartDisconnect()n"));
  545.     HX_RESULT res = HXR_FAILED;
  546.     
  547.     if (HXR_OK == m_pConnector->Disconnect())
  548.     {
  549. m_state = apDisconnecting;
  550. res = HXR_OK;
  551.     }
  552.     DPRINTF(D_AP_MANAGER, 
  553.     ("HXSymbianAccessPointManager::StartDisconnect() : res %08xn",
  554.      res));
  555.     return res;
  556. }
  557. void HXSymbianAccessPointManager::DisconnectDone(HX_RESULT status)
  558. {
  559.     DPRINTF(D_AP_MANAGER, 
  560.     ("HXSymbianAccessPointManager::DisconnectDone(%08x)n",
  561.      status));
  562.     HX_ASSERT(apDisconnecting == m_state);
  563.     m_state = apIdle;
  564.     if (HXR_OK == status)
  565.     {
  566. // Try to connect now
  567. status = DoConnect(0);
  568.     }
  569.     
  570.     if (HXR_OK != status)
  571.     {
  572. // We failed to reconnect. Send the
  573. // failure code to the response objects
  574. DispatchConnectDones(status);
  575.     }
  576. }
  577. void HXSymbianAccessPointManager::DispatchConnectDones(HX_RESULT status)
  578. {
  579.     DPRINTF(D_AP_MANAGER, 
  580.     ("HXSymbianAccessPointManager::DispatchConnectDones(%08x)n",
  581.      status));
  582.     // Handle any pending connect requests
  583.     while(!m_respList.IsEmpty())
  584.     {
  585. IHXAccessPointConnectResponse* pResp = 
  586.     (IHXAccessPointConnectResponse*)m_respList.RemoveHead();
  587. pResp->ConnectDone(status);
  588. HX_RELEASE(pResp);
  589.     }
  590. }
  591. HX_RESULT HXSymbianAccessPointManager::GetPreferredID(REF(ULONG32) ulID)
  592. {
  593.     HX_RESULT res = HXR_FAILED;
  594.     if (m_pPreferredInfo)
  595.     {
  596. res = m_pPreferredInfo->GetPropertyULONG32("ID", ulID);
  597.     }
  598.     return res;
  599. }
  600. HX_RESULT HXSymbianAccessPointManager::GetActiveID(REF(ULONG32) ulID)
  601. {
  602.     HX_RESULT res = HXR_FAILED;
  603.     TUint32 aIAPId = 0;
  604.     if (m_pConnInit && (KErrNone == m_pConnInit->GetActiveIap(aIAPId)))
  605.     {
  606. ulID = aIAPId;
  607. res = HXR_OK;
  608.     }
  609.     return res;
  610. }