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

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/hxsymbiantcpsock.h"
  36. #include "hxsymbiansockhlp.h"
  37. #include "debug.h"
  38. #include "hxassert.h"
  39. #include "ihxpckts.h"
  40. #include "smartptr.h"
  41. #include <in_sock.h>
  42. #define D_TCPSOCKET 0x10000000
  43. class HXSymbianTCPResolvResp : public IHXResolverResponse
  44. {
  45. public:
  46.     HXSymbianTCPResolvResp(HXSymbianTCPSocket* pParent);
  47.     ~HXSymbianTCPResolvResp();
  48.     /*
  49.      *  IUnknown methods
  50.      */
  51.     STDMETHOD(QueryInterface) (THIS_
  52. REFIID riid,
  53. void** ppvObj);
  54.     STDMETHOD_(ULONG32,AddRef) (THIS);
  55.     STDMETHOD_(ULONG32,Release) (THIS);
  56.     /*
  57.      * IHXResolverResponse methods
  58.      */
  59.     STDMETHOD(GetHostByNameDone) (THIS_
  60. HX_RESULT status,
  61. ULONG32 ulAddr);
  62. private:
  63.     ULONG32 m_lRefCount;
  64.     HXSymbianTCPSocket* m_pParent;
  65. };
  66. HXSymbianTCPResolvResp::HXSymbianTCPResolvResp(HXSymbianTCPSocket* pParent) :
  67.     m_lRefCount(0),
  68.     m_pParent(pParent)
  69. {}
  70. HXSymbianTCPResolvResp::~HXSymbianTCPResolvResp()
  71. {}
  72.     /*
  73.      *  IUnknown methods
  74.      */
  75. STDMETHODIMP HXSymbianTCPResolvResp::QueryInterface(THIS_
  76.     REFIID riid,
  77.     void** ppvObj)
  78. {
  79.     QInterfaceList qiList[] =
  80. {
  81. { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXResolverResponse*)this },
  82. { GET_IIDHANDLE(IID_IHXResolverResponse), (IHXResolverResponse*) this },
  83. };
  84.     return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  85. }
  86. STDMETHODIMP_(ULONG32) HXSymbianTCPResolvResp::AddRef(THIS)
  87. {
  88.     return InterlockedIncrement(&m_lRefCount);
  89. }
  90. STDMETHODIMP_(ULONG32) HXSymbianTCPResolvResp::Release(THIS)
  91. {
  92.     if (InterlockedDecrement(&m_lRefCount) > 0)
  93.     {
  94.         return m_lRefCount;
  95.     }
  96.     delete this;
  97.     return 0;
  98. }
  99.     /*
  100.      * IHXResolverResponse methods
  101.      */
  102. STDMETHODIMP HXSymbianTCPResolvResp::GetHostByNameDone(THIS_
  103.        HX_RESULT status,
  104.        ULONG32 ulAddr)
  105. {
  106.     return m_pParent->GetHostByNameDone(status, ulAddr);
  107. }
  108. class HXSymbianTCPConnector : public CActive
  109. {
  110. public:
  111.     HXSymbianTCPConnector(HXSymbianTCPSocket* pParent);
  112.     ~HXSymbianTCPConnector();
  113.     void Connect(RSocket& socket, ULONG32 ulAddr, UINT16 nPort);
  114. private:
  115.     void RunL();
  116.     void DoCancel();
  117.     HXSymbianTCPSocket* m_pParent;
  118.     TInetAddr m_addr;
  119. };
  120. HXSymbianTCPConnector::HXSymbianTCPConnector(HXSymbianTCPSocket* pParent) :
  121.     CActive(EPriorityStandard),
  122.     m_pParent(pParent)
  123. {
  124.     CActiveScheduler::Add(this);
  125. }
  126. HXSymbianTCPConnector::~HXSymbianTCPConnector()
  127. {
  128.     if (IsActive())
  129. Cancel();
  130.     m_pParent = 0;
  131. }
  132. void HXSymbianTCPConnector::Connect(RSocket& socket,
  133.     ULONG32 ulAddr, UINT16 nPort)
  134. {
  135.     m_addr.SetAddress(ulAddr);
  136.     m_addr.SetPort(nPort);
  137.     iStatus = KRequestPending;
  138.     socket.Connect(m_addr, iStatus);
  139.     SetActive();
  140. }
  141. void HXSymbianTCPConnector::RunL()
  142. {
  143.     m_pParent->OnConnect((iStatus == KErrNone) ? HXR_OK : HXR_NET_CONNECT);
  144. }
  145. void HXSymbianTCPConnector::DoCancel()
  146. {}
  147. class HXSymbianTCPWriter : public CActive
  148. {
  149. public:
  150.     HXSymbianTCPWriter(HXSymbianTCPSocket* pParent);
  151.     ~HXSymbianTCPWriter();
  152.     void Write(RSocket& socket, IHXBuffer* pBuffer);
  153. private:
  154.     void RunL();
  155.     void DoCancel();
  156.     HXSymbianTCPSocket* m_pParent;
  157.     IHXBuffer* m_pBuffer;
  158.     TPtrC8 m_bufDes;
  159. };
  160. HXSymbianTCPWriter::HXSymbianTCPWriter(HXSymbianTCPSocket* pParent) :
  161.     CActive(EPriorityStandard),
  162.     m_pParent(pParent),
  163.     m_pBuffer(0)
  164. {
  165.     CActiveScheduler::Add(this);
  166. }
  167. HXSymbianTCPWriter::~HXSymbianTCPWriter()
  168. {
  169.     if (IsActive())
  170. Cancel();
  171.     HX_RELEASE(m_pBuffer);
  172.     m_pParent = 0;
  173. }
  174. void HXSymbianTCPWriter::Write(RSocket& socket, IHXBuffer* pBuffer)
  175. {
  176.     HX_RELEASE(m_pBuffer);
  177.     m_pBuffer = pBuffer;
  178.     if (m_pBuffer)
  179.     {
  180. m_pBuffer->AddRef();
  181. m_bufDes.Set(m_pBuffer->GetBuffer(), m_pBuffer->GetSize());
  182. iStatus = KRequestPending;
  183. socket.Write(m_bufDes, iStatus);
  184. SetActive();
  185.     }
  186. }
  187. void HXSymbianTCPWriter::RunL()
  188. {
  189.     HX_RESULT res = HXR_FAILED;
  190.     if (iStatus == KErrNone)
  191.     {
  192. res = HXR_OK;
  193.     }
  194.     else if(iStatus == KErrEof)
  195.     {
  196. res = HXR_STREAM_DONE;
  197.     }
  198.     else if(iStatus == KErrNoMemory)
  199.     {
  200. res = HXR_OUTOFMEMORY;
  201.     }
  202.     HX_RELEASE(m_pBuffer);
  203.     m_pParent->OnWriteDone(res);
  204. }
  205. void HXSymbianTCPWriter::DoCancel()
  206. {}
  207. class HXSymbianTCPReader : public CActive
  208. {
  209. public:
  210.     HXSymbianTCPReader(HXSymbianTCPSocket* pParent,
  211.                        IHXCommonClassFactory* pCCF);
  212.     ~HXSymbianTCPReader();
  213.     HX_RESULT Read(RSocket& socket, UINT16 uSize);
  214. private:
  215.     void RunL();
  216.     void DoCancel();
  217.     HXSymbianTCPSocket* m_pParent;
  218.     IHXBuffer* m_pBuffer;
  219.     TPtr8 m_bufDes;
  220.     TSockXfrLength m_amountRead;
  221.     IHXCommonClassFactory* m_pCCF;
  222. };
  223. HXSymbianTCPReader::HXSymbianTCPReader(HXSymbianTCPSocket* pParent,
  224.                                        IHXCommonClassFactory* pCCF) :
  225.     CActive(EPriorityStandard),
  226.     m_pParent(pParent),
  227.     m_pBuffer(0),
  228.     m_bufDes(0, 0),
  229.     m_pCCF(pCCF)
  230. {
  231.     CActiveScheduler::Add(this);
  232.     if (m_pCCF)
  233.     {
  234.         m_pCCF->AddRef();
  235.     }
  236. }
  237. HXSymbianTCPReader::~HXSymbianTCPReader()
  238. {
  239.     if (IsActive())
  240. Cancel();
  241.     HX_RELEASE(m_pBuffer);
  242.     HX_RELEASE(m_pCCF);
  243.     m_pParent = 0;
  244. }
  245. HX_RESULT HXSymbianTCPReader::Read(RSocket& socket, UINT16 uSize)
  246. {
  247.     HX_RESULT res = HXR_FAILED;
  248.     if (m_pParent)
  249.     {
  250.         res = HXSymbianSocketHelper::ResizeOrCreate(m_pCCF, uSize, m_pBuffer);
  251.         
  252.         if (HXR_OK == res)
  253.         {
  254.             m_bufDes.Set(m_pBuffer->GetBuffer(), 0, m_pBuffer->GetSize());
  255.             iStatus = KRequestPending;
  256.             socket.RecvOneOrMore(m_bufDes, 0, iStatus, m_amountRead);
  257.             SetActive();
  258.         }
  259.     }
  260.     return res;
  261. }
  262. void HXSymbianTCPReader::RunL()
  263. {
  264.     HX_RESULT res = HXR_FAILED;
  265.     if (iStatus == KErrNone)
  266.     {
  267. res = HXR_OK;
  268.     }
  269.     else if(iStatus == KErrEof)
  270.     {
  271. res = HXR_STREAM_DONE;
  272.     }
  273.     else if(iStatus == KErrNoMemory)
  274.     {
  275. res = HXR_OUTOFMEMORY;
  276.     }
  277.     IHXBuffer* pBuffer = 0;
  278.     if(res == KErrNone)
  279.     {
  280.         HXSymbianSocketHelper::CopyOrTransfer(m_pCCF, m_amountRead(), 
  281.                                               m_pBuffer, pBuffer);
  282.     }
  283.     m_pParent->OnReadDone(res, pBuffer);
  284.     HX_RELEASE(pBuffer);
  285. }
  286. void HXSymbianTCPReader::DoCancel()
  287. {}
  288. HXSymbianTCPSocket::HXSymbianTCPSocket(IHXCommonClassFactory* pCCF,
  289.        IHXResolver* pResolver) :
  290.     m_lRefCount(0),
  291.     m_pResponse(0),
  292.     m_pResolver(0),
  293.     m_state(tcpNotInitialized),
  294.     m_pConnector(0),
  295.     m_nConnectPort(0),
  296.     m_pWriter(0),
  297.     m_bWantWrite(FALSE),
  298.     m_pReader(0)
  299. {
  300.     IHXResolverResponse* pResolvResp = new HXSymbianTCPResolvResp(this);
  301.     m_pConnector = new HXSymbianTCPConnector(this);
  302.     m_pWriter = new HXSymbianTCPWriter(this);
  303.     m_pReader = new HXSymbianTCPReader(this, pCCF);
  304.     if (pResolvResp)
  305.     {
  306. pResolvResp->AddRef();
  307.     }
  308.     if (pCCF && pResolver && m_pConnector && m_pWriter && m_pReader &&
  309. (pResolvResp) &&
  310. (pResolver->Init(pResolvResp) == HXR_OK) &&
  311. (m_socketServ.Connect() == KErrNone) &&
  312. (m_socket.Open(m_socketServ, KAfInet,
  313.        KSockStream, KProtocolInetTcp) == KErrNone))
  314.     {
  315. m_pResolver = pResolver;
  316. m_pResolver->AddRef();
  317. m_state = tcpInitialized;
  318.     }
  319.     HX_RELEASE(pResolvResp);
  320. }
  321. HXSymbianTCPSocket::~HXSymbianTCPSocket()
  322. {
  323.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::~HXSymbianTCPSocket()n"));
  324.     HX_RELEASE(m_pResponse);
  325.     HX_RELEASE(m_pResolver);
  326.     if (m_state != tcpNotInitialized)
  327.     {
  328. CloseConnection(HXR_OK);
  329. m_socket.Close();
  330. m_socketServ.Close();
  331.     }
  332.     HX_DELETE(m_pConnector);
  333.     HX_DELETE(m_pWriter);
  334.     HX_DELETE(m_pReader);
  335. }
  336.     /*
  337.      *  IUnknown methods
  338.      */
  339. STDMETHODIMP HXSymbianTCPSocket::QueryInterface(THIS_
  340. REFIID riid,
  341. void** ppvObj)
  342. {
  343.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::QueryInterface()n"));
  344. QInterfaceList qiList[] =
  345. {
  346. { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXTCPSocket*)this },
  347. { GET_IIDHANDLE(IID_IHXTCPSocket), (IHXTCPSocket*) this },
  348. { GET_IIDHANDLE(IID_IHXSetSocketOption), (IHXSetSocketOption*) this },
  349. };
  350.     return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  351. }
  352. STDMETHODIMP_(ULONG32) HXSymbianTCPSocket::AddRef(THIS)
  353. {
  354.     return InterlockedIncrement(&m_lRefCount);
  355. }
  356. STDMETHODIMP_(ULONG32)HXSymbianTCPSocket::Release(THIS)
  357. {
  358.     if (InterlockedDecrement(&m_lRefCount) > 0)
  359.     {
  360.         return m_lRefCount;
  361.     }
  362.     delete this;
  363.     return 0;
  364. }
  365.     /*
  366.      * IHXTCPSocket methods
  367.      *
  368.      *  Network addresses and ports are in native byte order
  369.      *
  370.      */
  371. STDMETHODIMP HXSymbianTCPSocket::Init(THIS_
  372.       IHXTCPResponse* /*IN*/ pTCPResponse)
  373. {
  374.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Init()n"));
  375.     HX_RELEASE(m_pResponse);
  376.     m_pResponse = pTCPResponse;
  377.     if (m_pResponse)
  378. m_pResponse->AddRef();
  379.     return (m_pResponse) ? HXR_OK : HXR_FAILED;
  380. }
  381. STDMETHODIMP HXSymbianTCPSocket::SetResponse(THIS_
  382.      IHXTCPResponse* pTCPResponse)
  383. {
  384.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::SetResponse()n"));
  385.     HX_RELEASE(m_pResponse);
  386.     m_pResponse = pTCPResponse;
  387.     if (m_pResponse)
  388. m_pResponse->AddRef();
  389.     return (m_pResponse) ? HXR_OK : HXR_FAILED;
  390. }
  391. STDMETHODIMP HXSymbianTCPSocket::Bind(THIS_
  392.       UINT32 ulLocalAddr,
  393.       UINT16 nPort)
  394. {
  395.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Bind(%08lx, %u)n",
  396.   ulLocalAddr, nPort));
  397.     HX_RESULT res = HXR_FAILED;
  398.     TInetAddr addr(ulLocalAddr, nPort);
  399.     if ((m_state == tcpInitialized) &&
  400. (m_socket.Bind(addr) == KErrNone))
  401.     {
  402. m_state = tcpBound;
  403. res = HXR_OK;
  404.     }
  405.     return res;
  406. }
  407.     /*
  408.      * pDestination is a string containing host name or dotted-ip notation
  409.      */
  410. STDMETHODIMP HXSymbianTCPSocket::Connect(THIS_
  411.  const char* pDestination,
  412.  UINT16 nPort)
  413. {
  414.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Connect('%s', %u)n",
  415.   pDestination, nPort));
  416.     HX_RESULT res = HXR_FAILED;
  417.     if (m_state == tcpInitialized)
  418. Bind(0, 0);
  419.     if (m_state == tcpBound)
  420.     {
  421. m_state = tcpResolving;
  422. m_nConnectPort = nPort;
  423. res = m_pResolver->GetHostByName(pDestination);
  424. if (HXR_OK != res)
  425. {
  426.     m_state = tcpBound;
  427. }
  428.     }
  429.     return res;
  430. }
  431. STDMETHODIMP HXSymbianTCPSocket::Read(THIS_ UINT16 Size)
  432. {
  433.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Read(%u)n", Size));
  434.     HX_RESULT res = HXR_FAILED;
  435.     HX_ASSERT(m_state == tcpConnected);
  436.     if ((m_state == tcpConnected) && (!m_pReader->IsActive()))
  437.     {
  438. res = DoRead(Size);
  439.     }
  440.     return res;
  441. }
  442. STDMETHODIMP HXSymbianTCPSocket::Write(THIS_ IHXBuffer* pBuffer)
  443. {
  444.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::Write()n"));
  445.     HX_RESULT res = HXR_FAILED;
  446.     HX_ASSERT(m_state == tcpConnected);
  447.     if ((m_state == tcpConnected) && pBuffer)
  448.     {
  449. if (m_pWriter->IsActive())
  450. {
  451.     // A write is in progress. Add the buffer
  452.     // to the write list
  453.     pBuffer->AddRef();
  454.     LISTPOSITION listRet = m_writeList.AddTail(pBuffer);
  455.             if( listRet == NULL )
  456.             {
  457.                 res = HXR_OUTOFMEMORY;
  458.                 HX_RELEASE(pBuffer);
  459.             }
  460. }
  461. else
  462. {
  463.     // Do the write now
  464.     m_pWriter->Write(m_socket, pBuffer);
  465. }
  466. res = HXR_OK;
  467.     }
  468.     return res;
  469. }
  470.     /************************************************************************
  471.      * Method:
  472.      *     IHXTCPSocket::WantWrite
  473.      * Purpose:
  474.      *     This method is called when you wish to write a large amount of
  475.      *     data.  If you are only writing small amounts of data, you can
  476.      *     just call Write (all data not ready to be transmitted will be
  477.      *     buffered on your behalf).  When the TCP channel is ready to be
  478.      *     written to, the response interfaces WriteReady method will be
  479.      *     called.
  480.      */
  481. STDMETHODIMP HXSymbianTCPSocket::WantWrite(THIS)
  482. {
  483.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::WantWrite()n"));
  484.     m_bWantWrite = TRUE;
  485.     return HXR_OK;
  486. }
  487.     /************************************************************************
  488.      * Method:
  489.      *     IHXTCPSocket::GetForeignAddress
  490.      * Purpose:
  491.      *     Returns the address of the other end of the TCP socket as a
  492.      *     ULONG32 in local host order
  493.      */
  494. STDMETHODIMP HXSymbianTCPSocket::GetForeignAddress(THIS_ REF(ULONG32) lAddress)
  495. {
  496.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::GetForeignAddress()n"));
  497.     HX_RESULT res = HXR_FAILED;
  498.     if (m_state == tcpConnected)
  499.     {
  500. TInetAddr addr;
  501. m_socket.RemoteName(addr);
  502. lAddress = (ULONG32)addr.Address();
  503. res = HXR_OK;
  504.     }
  505.     return res;
  506. }
  507. STDMETHODIMP HXSymbianTCPSocket::GetLocalAddress(THIS_ REF(ULONG32) lAddress)
  508. {
  509.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::GetLocalAddress()n"));
  510.     HX_RESULT res = HXR_FAILED;
  511.     if ((m_state != tcpNotInitialized) &&
  512. (m_state != tcpInitialized))
  513.     {
  514. TInetAddr addr;
  515. m_socket.LocalName(addr);
  516. lAddress = (ULONG32)addr.Address();
  517. res = HXR_OK;
  518.     }
  519.     return res;
  520. }
  521.     /************************************************************************
  522.      * Method:
  523.      *     IHXTCPSocket::GetForeignPort
  524.      * Purpose:
  525.      *     Returns the port of the other end of the TCP socket in local
  526.      *      host order.
  527.      */
  528. STDMETHODIMP HXSymbianTCPSocket::GetForeignPort(THIS_ REF(UINT16) port)
  529. {
  530.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::GetForeignPort()n"));
  531.     HX_RESULT res = HXR_FAILED;
  532.     if (m_state == tcpConnected)
  533.     {
  534. TInetAddr addr;
  535. m_socket.RemoteName(addr);
  536. port = addr.Port();
  537. res = HXR_OK;
  538.     }
  539.     return res;
  540. }
  541. STDMETHODIMP HXSymbianTCPSocket::GetLocalPort(THIS_ REF(UINT16) port)
  542. {
  543.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::GetLocalPort()n"));
  544.     HX_RESULT res = HXR_FAILED;
  545.     if ((m_state != tcpNotInitialized) &&
  546. (m_state != tcpInitialized))
  547.     {
  548. port = m_socket.LocalPort();
  549. res = HXR_OK;
  550.     }
  551.     return res;
  552. }
  553. STDMETHODIMP HXSymbianTCPSocket::SetOption(THIS_
  554.    HX_SOCKET_OPTION option,
  555.    UINT32 ulValue)
  556. {
  557.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::SetOption(%d, %lu)n",
  558.   option, ulValue));
  559.     HX_RESULT res = HXR_FAILED;
  560.     if (m_state == tcpNotInitialized)
  561.     {
  562. switch(option)
  563. {
  564. case  HX_SOCKOPT_REUSE_ADDR:
  565. case HX_SOCKOPT_REUSE_PORT:
  566.     if (m_socket.SetOpt(KSoReuseAddr, KSOLSocket, ulValue) == KErrNone)
  567.     {
  568. res = HXR_OK;
  569.     }
  570.     break;
  571. case HX_SOCKOPT_BROADCAST:
  572. case HX_SOCKOPT_SET_RECVBUF_SIZE:
  573. case HX_SOCKOPT_SET_SENDBUF_SIZE:
  574. case HX_SOCKOPT_MULTICAST_IF:
  575.     res = HXR_UNEXPECTED;
  576.     break;
  577. default:
  578.     res = HXR_FAILED;
  579.     break;
  580. };
  581.     }
  582.     return res;
  583. }
  584. HX_RESULT HXSymbianTCPSocket::GetHostByNameDone(HX_RESULT status,
  585. ULONG32 ulAddr)
  586. {
  587.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::ResolveDone(%ld, %08lx)n",
  588.   status, ulAddr));
  589.     HX_ASSERT(m_state == tcpResolving);
  590.     DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this);
  591.     if (m_state == tcpResolving)
  592.     {
  593. if (status == HXR_OK)
  594. {
  595.     m_pConnector->Connect(m_socket, ulAddr, m_nConnectPort);
  596.     m_state = tcpConnecting;
  597. }
  598. else if (m_pResponse)
  599. {
  600.     m_pResponse->ConnectDone(status);
  601.     m_state = tcpBound;
  602. }
  603.     }
  604.     return HXR_OK;
  605. }
  606. void HXSymbianTCPSocket::OnConnect(HX_RESULT status)
  607. {
  608.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::OnConnect(%ld)n",
  609.   status));
  610.     HX_ASSERT(m_state == tcpConnecting);
  611.     DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this);
  612.     if (status == HXR_OK)
  613.     {
  614. m_state = tcpConnected;
  615.     }
  616.     else
  617.     {
  618. m_state = tcpBound;
  619.     }
  620.     if (m_pResponse)
  621.     {
  622. m_pResponse->ConnectDone(status);
  623.     }
  624. }
  625. void HXSymbianTCPSocket::OnWriteDone(HX_RESULT status)
  626. {
  627.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::OnWriteDone(%ld)n", status));
  628.     DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this);
  629.     if (status == HXR_OK)
  630.     {
  631. if (m_writeList.GetCount() > 0)
  632. {
  633.     // Write the next buffer in the list
  634.     IHXBuffer* pBuffer = (IHXBuffer*)m_writeList.RemoveHead();
  635.     m_pWriter->Write(m_socket, pBuffer);
  636.     HX_RELEASE(pBuffer);
  637. }
  638. // Signal WriteReady() if we don't have any
  639. // writes pending and the response object
  640. // wants these calls
  641. if (!m_pWriter->IsActive() && m_bWantWrite && m_pResponse)
  642. {
  643.     m_pResponse->WriteReady(HXR_OK);
  644. }
  645.     }
  646.     else
  647.     {
  648. CloseConnection(status);
  649.     }
  650. }
  651. void HXSymbianTCPSocket::OnReadDone(HX_RESULT status, IHXBuffer* pBuffer)
  652. {
  653.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::OnReadDone(%ld)n", status));
  654.     DECLARE_SMART_POINTER_UNKNOWN scopeRef((IHXTCPSocket*)this);
  655.     if (m_pResponse)
  656.     {
  657.         // We assume error reporting/handling is done in the response object
  658.         // via the value of status passed here.
  659. m_pResponse->ReadDone(status, pBuffer);
  660.     }
  661.     if (status != HXR_OK)
  662.     {
  663. CloseConnection(status);
  664.     }
  665. }
  666. HX_RESULT HXSymbianTCPSocket::DoRead(UINT16 size)
  667. {
  668.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::DoRead(%u)n", size));
  669.     HX_RESULT res = HXR_FAILED;
  670.     if (m_pReader)
  671.     {
  672.         res = m_pReader->Read(m_socket, size);
  673.     }
  674.     return res;
  675. }
  676. void HXSymbianTCPSocket::CloseConnection(HX_RESULT status)
  677. {
  678.     DPRINTF(D_TCPSOCKET, ("HXSymbianTCPSocket::CloseConnection(%ld)n",
  679.   status));
  680.     if (m_state != tcpNotInitialized)
  681.     {
  682. // Cancel any connector
  683. if (m_pConnector->IsActive())
  684. {
  685.     m_socket.CancelConnect();
  686.     m_pConnector->Cancel();
  687. }
  688. // Cancel writer
  689. if (m_pWriter->IsActive())
  690. {
  691.     m_socket.CancelWrite();
  692.     m_pWriter->Cancel();
  693. }
  694. if (m_pReader->IsActive())
  695. {
  696.     m_socket.CancelRecv();
  697.     m_pReader->Cancel();
  698. }
  699. // Clear the writer list
  700. while (m_writeList.GetCount() > 0)
  701. {
  702.     // Write the next buffer in the list
  703.     IHXBuffer* pBuffer = (IHXBuffer*)m_writeList.RemoveHead();
  704.     HX_RELEASE(pBuffer);
  705. }
  706. if ((m_state != tcpInitialized) && m_pResponse)
  707. {
  708.     m_pResponse->Closed(HXR_OK);
  709. }
  710. m_state = tcpInitialized;
  711.     }
  712. }