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

Symbian

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Source last modified: $Id: ot_tcp.cp,v 1.3.42.1 2004/07/09 02:06:38 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 "OT_TCP.h"
  51. #include "MWDebug.h"
  52. #include "hxerrors.h"
  53. #include <string.h>
  54. #include <stdio.h>
  55. #include <stdlib.h>
  56. #include <ctype.h>
  57. #include "hxmm.h"
  58. //#define _LOG_DATA 1
  59. //#define USE_DEFERRED_IMPL 1
  60. #if defined(_DEBUG) && defined (_LOG_DATA)
  61. #define DEBUGSTR(x) DebugStr(x)
  62. #else
  63. #define DEBUGSTR(x)
  64. #endif
  65. //#include "dcon.h"
  66. OT_TCP::OT_TCP (void)
  67. : mDNSOpen (FALSE)
  68. , mSocketOpen (FALSE)
  69. , mState (TCP_STATE_CLOSED)
  70. , mDNSRef (0)
  71. , mRemoteHostName (0)
  72. , mNewConnection(NULL)
  73. , mDataReady(FALSE)
  74. { /* begin OT_TCP */
  75. //dprintf("this:%X OT_TCP::OT_TCPn", this);
  76. } /* end OT_TCP */
  77. OT_TCP::~OT_TCP (void)
  78. { /* begin ~OT_TCP */
  79. //dprintf("this:%X OT_TCP::~OT_TCPn", this);
  80. Cleanup(TRUE); 
  81. if(mRemoteHostName)
  82. {
  83. delete mRemoteHostName;
  84. mRemoteHostName = NULL;
  85. }
  86. } /* end ~OT_TCP */
  87. void
  88. OT_TCP::done(void)
  89. {
  90. //dprintf("this:%X OT_TCP::donen", this);
  91. Cleanup(TRUE);
  92. }
  93. /*----------------------------------------------------------------------------
  94. Cleanup 
  95. Cleanup a TCP stream.
  96. Exit: function result = error code.
  97. Any active connection is also aborted, if necessary, before releasing 
  98. the stream.
  99. ----------------------------------------------------------------------------*/
  100. OSErr OT_TCP::Cleanup (Boolean orderly /* = FALSE */ )
  101. {
  102. //dprintf("this:%X OT_TCP::Cleanup orderly:%sn", this, (orderly? "TRUE" : "FALSE"));
  103. OSErr theErr = HXR_OK;
  104. Boolean abort;
  105. mState = TCP_STATE_CLOSED;
  106. close_resolver();
  107. if(mRef)
  108. {
  109. abort = (!mOtherSideHasClosed || !mWeHaveClosed) && mConnectionOpen;
  110. if (abort) 
  111. {
  112. mComplete = FALSE;
  113. if (orderly && mStartedReceivingData)
  114. {
  115. mComplete = FALSE;
  116. theErr = ::OTSndOrderlyDisconnect(mRef);
  117. EventRecord macEvent;
  118. long ticks = TickCount();
  119. do 
  120. {
  121. #ifndef THREADS_SUPPORTED
  122. // xxxbobclark when threading networking is
  123. // on, this code may be executing on a non-main-
  124. // app thread. I don't even know what WNE would
  125. // do in that scenario, but that it'd be bad.
  126. WaitNextEvent(nullEvent, &macEvent, 6,NULL);
  127. #endif
  128. }
  129. while (!mComplete && ((TickCount() - ticks) < 120)); 
  130. }
  131. else
  132. theErr = ::OTSndDisconnect(mRef, nil);
  133. }
  134. ::OTRemoveNotifier(mRef); // DS 12.4.95
  135. theErr = ::OTCloseProvider(mRef);
  136. }
  137. if ( mNewConnection )
  138. {
  139. mNewConnection->done();
  140. HX_RELEASE(mNewConnection);
  141. }
  142. mRef = 0;
  143. return theErr;
  144. }
  145.  HX_RESULT
  146.  OT_TCP::connect (
  147.  
  148. const char *host, 
  149. UINT16  port,
  150. UINT16  blocking,
  151. ULONG32 ulPlatform )
  152. {
  153. //dprintf("this:%X OT_TCP::connect - host:%s port:%un", this, host, port);
  154. HX_RESULT theErr = HXR_OK;
  155. // check if socket is in a valid state
  156. if(mState != TCP_STATE_CLOSED)
  157. return HXR_SOCKET_CREATE;  // should be PN_SOCKET_STATE_ERROR
  158. if(mRemoteHostName)
  159. {
  160.  delete mRemoteHostName; 
  161.  mRemoteHostName = NULL;
  162. }
  163. // allocate a buffer to hold the host name
  164. mRemoteHostName = new char[::strlen(host) + 1];
  165. if(mRemoteHostName == NULL)
  166. theErr = HXR_OUTOFMEMORY;
  167. if(!theErr)
  168. {
  169. mConnectionOpen = FALSE;
  170. mRemotePort = port;
  171. mDataFlowOn = FALSE;
  172. mDataArrived = FALSE;
  173. mAsyncError = HXR_OK;
  174. // save a copy of the host name 
  175. ::strcpy(mRemoteHostName,host);
  176. // check if host name is already in IP format or has been cached
  177. if((::OTInetStringToHost(mRemoteHostName, &mRemoteHost) == HXR_OK) || 
  178.   (conn::is_cached(mRemoteHostName,&mRemoteHost)))
  179. {
  180. // open the socket, bind and connect to remote host
  181. mState = TCP_STATE_OPEN_SOCKET;
  182. theErr = open_socket();
  183. }
  184. else // DNR is required on host name
  185. {
  186. // do DNR,open the socket, bind and connect to remote host
  187. theErr = open_resolver();
  188. }
  189. }
  190. if(!theErr && blocking)
  191. {
  192. // wait for mConnectionOpen == TRUE or cancel
  193. }
  194. return theErr;
  195. }
  196.  HX_RESULT
  197.  OT_TCP::init (
  198.   UINT32 local_addr,
  199. UINT16  port,
  200. UINT16  blocking)
  201. {
  202. //dprintf("this:%X OT_TCP::initn", this);
  203. return (HXR_INVALID_OPERATION);
  204. }
  205. /*----------------------------------------------------------------------------
  206. write 
  207. Send data on a stream.
  208. Entry: data = pointer to data to send.
  209. len = length of data to send.
  210. Exit: function result = error code.
  211. ----------------------------------------------------------------------------*/
  212. HX_RESULT 
  213. OT_TCP::write (
  214. void *data, 
  215. UINT16 *len)
  216. {
  217. //dprintf("this:%X OT_TCP::writen", this);
  218. HX_RESULT theErr = HXR_OK;
  219. mLastError=HXR_OK;
  220. if(mAsyncError)
  221. {
  222. theErr = mAsyncError;
  223. mAsyncError = HXR_OK;
  224. return theErr;
  225. }
  226. OTResult  result;
  227. unsigned short  length, count;
  228. count = 0;
  229. if (mOtherSideHasClosed) //cz 
  230. theErr = HXR_SERVER_DISCONNECTED;
  231. else if (!mOtherSideHasClosed && !mConnectionOpen) 
  232. theErr = HXR_WOULD_BLOCK;
  233. else
  234. {
  235. #if 1
  236. if(mDataFlowOn)
  237. {
  238. // DebugStr("pDataFlowOn");
  239. *len = 0;
  240.  return(HXR_WOULD_BLOCK);
  241. }
  242. #endif
  243. length = *len;
  244. while (length > 0 && !theErr) 
  245. {
  246. result = ::OTSnd(mRef, data, length, 0);
  247. if (result >= 0) 
  248. {
  249. count += result;
  250. length -= result;
  251. else
  252. {
  253. #if 0
  254. Str255 s;
  255. NumToString(result,s);
  256. DebugStr(s);
  257. #endif
  258. switch(result)
  259. {
  260. case kOTFlowErr:
  261. mWriteReady = FALSE;
  262. mDataFlowOn = TRUE;
  263. theErr = HXR_WOULD_BLOCK;
  264. break;
  265. case kENOMEMErr:
  266. case kEBUSYErr:
  267. case kOTOutStateErr:
  268. case kEWOULDBLOCKErr:
  269. case kOTStateChangeErr:
  270. case kOTLookErr:
  271. mLastError = HXR_WOULD_BLOCK;
  272. theErr = HXR_WOULD_BLOCK;
  273. break;
  274. default:
  275. #if 0
  276. Str255 s;
  277. DebugStr("pOT_TCP::read");
  278. NumToString(result,s);
  279. DebugStr(s);
  280. #endif
  281. mLastError = HXR_SERVER_DISCONNECTED;
  282. theErr = HXR_SERVER_DISCONNECTED; 
  283. break;
  284. }
  285. break; // break out of the while loop
  286. }
  287. }
  288. }
  289. *len = count; // return actual number of bytes written
  290. return theErr;
  291. }
  292. /*----------------------------------------------------------------------------
  293. read 
  294. read data on a stream.
  295. Entry: data = pointer to data buffer.
  296. *len = length of data buffer.
  297. Exit: function result = error code.
  298. *len = number of bytes received.
  299. ----------------------------------------------------------------------------*/
  300. HX_RESULT
  301. OT_TCP::read (void *data, UINT16 *len)
  302. {
  303. //dprintf("this:%X OT_TCP::readn", this);
  304. //dprintf("mConnectionOpen: %sn", (mConnectionOpen ? "TRUE" : "FALSE") );
  305. //dprintf("mOtherSideHadClosed: %sn", (mOtherSideHasClosed ? "TRUE" : "FALSE")); 
  306. //dprintf("mDataArrived: %sn", (mDataArrived ? "TRUE" : "FALSE"));
  307. HX_RESULT theErr = HXR_OK;
  308. OTResult result;
  309. mLastError=HXR_OK;
  310. if(mAsyncError)
  311. {
  312. theErr = mAsyncError;
  313. mAsyncError = HXR_OK;
  314. return theErr;
  315. }
  316. if (mOtherSideHasClosed)  
  317. theErr = HXR_SERVER_DISCONNECTED;
  318. else if (!mOtherSideHasClosed && !mConnectionOpen) 
  319. theErr = HXR_WOULD_BLOCK;
  320. else
  321. {
  322. if(!mDataArrived)
  323. {
  324. *len = 0;
  325. mLastError = HXR_WOULD_BLOCK;
  326. return HXR_WOULD_BLOCK;
  327. }
  328. result = ::OTRcv(mRef, data, *len, nil);
  329. if (result >= 0) 
  330. {
  331. //dprintf("data readn");
  332. *len = result;
  333. theErr = HXR_OK;
  334. else
  335. {
  336. //dprintf("read errorn");
  337. switch(result)
  338. {
  339. /* take out this case after HXTCPSocket::TCPSchedulerCallbackProc
  340.    gets implemented - we're not getting data fast enough now XXXZach */
  341. case kOTNoDataErr:  
  342. *len = 0;
  343. theErr = HXR_OK;
  344. break;
  345. case kEBUSYErr:
  346. case kOTOutStateErr:
  347. case kEWOULDBLOCKErr:
  348. case kOTStateChangeErr:
  349. case kOTLookErr:
  350. *len = 0;
  351. mLastError = HXR_WOULD_BLOCK;
  352. theErr = HXR_WOULD_BLOCK;
  353. break;
  354. default:
  355. #if 0
  356. Str255 s;
  357. DebugStr("pOT_TCP::read");
  358. NumToString(result,s);
  359. DebugStr(s);
  360. #endif
  361. *len = 0;
  362. mLastError = HXR_SERVER_DISCONNECTED;
  363. theErr = HXR_SERVER_DISCONNECTED; //cz
  364. break;
  365. }
  366. }
  367. }
  368. return theErr;
  369. }
  370. HX_RESULT
  371. OT_TCP::readfrom (REF(IHXBuffer*)   pBuffer,
  372.   REF(UINT32)     ulAddress,
  373.   REF(UINT16)     ulPort)
  374. {
  375. //dprintf("this:%X OT_TCP::readfromn", this);
  376. pBuffer = NULL;
  377. ulAddress = 0;
  378. ulPort = 0;
  379. return HXR_NOTIMPL;
  380. }
  381. HX_RESULT OT_TCP::listen(ULONG32 ulLocalAddr,
  382.  UINT16 port,
  383.  UINT16 backlog, 
  384.  UINT16 blocking, 
  385.  ULONG32 ulPlatform)
  386. {
  387. //dprintf("this:%X OT_TCP::listen address:%X port:%un", this, ulLocalAddr, port);
  388. // check if socket is in a valid state
  389. if(mState != TCP_STATE_CLOSED)
  390. return HXR_UNEXPECTED;  // should be PN_SOCKET_STATE_ERROR
  391. OSErr theErr = HXR_OK;
  392. InetAddress reqAd,retAd;
  393. TBind req,ret;
  394. // Open TCP endpoint
  395. mState = TCP_STATE_OPEN_LISTEN;
  396. mComplete = false;
  397. // Note:  We are using the UDPTCPNotifyProc... Therefore we do
  398. // not get a Proccess command call at interupt time.  Normal
  399. // operation somehow gets away with it...
  400. #ifdef _CARBON
  401. theErr = ::OTAsyncOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0,NULL,
  402. (OTNotifyUPP)UDPTCPNotifyProc, this, NULL);
  403. #else
  404. theErr = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName), 
  405. 0,NULL, UDPTCPNotifyProc, this);
  406. #endif
  407. if ( theErr )
  408. {
  409. mLastError = theErr;
  410. theErr = HXR_SOCKET_CREATE;
  411. }
  412. // wait for open completion
  413. if(!theErr)
  414. {
  415. theErr = OTWait();
  416. if(theErr == kOTNoDataErr) theErr = HXR_OK;
  417. if(theErr || mCode != T_OPENCOMPLETE) 
  418. {
  419. theErr = theErr ? theErr : HXR_SOCKET_CREATE;
  420. mLastError = theErr;
  421. theErr = HXR_SOCKET_CREATE;
  422. }
  423. }
  424. if ( !theErr )
  425. {
  426. // get Inet address of port
  427. OTInitInetAddress(&reqAd, port, (InetHost) ulLocalAddr);
  428. // bind tcp to current address and requested port
  429. req.addr.maxlen = sizeof(struct InetAddress);
  430. req.addr.len = sizeof(struct InetAddress);
  431. req.addr.buf = (unsigned char *) &reqAd;
  432. req.qlen = 1;
  433. ret.addr.maxlen = sizeof(struct InetAddress);
  434. ret.addr.len = sizeof(struct InetAddress);
  435. ret.addr.buf = (unsigned char *) &retAd;
  436. // clear completion flag
  437. mComplete = false;
  438. mState = TCP_STATE_BIND_LISTEN;
  439. // bind provider to return structure
  440. theErr = OTBind(mRef, &req, &ret);
  441. }
  442. if(theErr)
  443. {
  444. mLastError = theErr;
  445. theErr = HXR_BIND;
  446. }
  447. // wait for bind completion
  448. if(!theErr)
  449. {
  450. theErr = OTWait();
  451. if(theErr == kOTNoDataErr) theErr = HXR_OK;
  452. if(theErr || mCode != T_BINDCOMPLETE) 
  453. {
  454. theErr = theErr ? theErr : HXR_BIND;
  455. mLastError = theErr;
  456. theErr = HXR_BIND;
  457. }
  458. }
  459. // get local port
  460. if(!theErr)
  461. {
  462. mConnectionOpen = FALSE;
  463. mRemotePort = port;
  464. mDataFlowOn = FALSE;
  465. mDataArrived = FALSE;
  466. mAsyncError = HXR_OK;
  467. mState = TCP_STATE_LISTEN;
  468. }
  469. if ( !theErr )
  470. {
  471. // check to see if we are not being called again...
  472. // calling done() on mNewConnection should be fine, because
  473. // it should be released after a connection has been accepted. 
  474. if ( mNewConnection )
  475. {
  476. mNewConnection->done();
  477. HX_RELEASE(mNewConnection);
  478. }
  479. mNewConnection = conn::actual_new_socket(HX_TCP_SOCKET);
  480. mNewConnection->AddRef();
  481. // we can wait here, because we should not be called
  482. // from deffered task time.
  483. theErr = mNewConnection->SetupEndpoint(TRUE);
  484. }
  485. return theErr;
  486. }
  487. HX_RESULT OT_TCP::resolve_address (void)
  488. {
  489. //dprintf("this:%X OT_TCP::resulve_addressn", this);
  490. mState = TCP_STATE_RESOLVE_DNS;
  491. return ::OTInetStringToAddress(mDNSRef, mRemoteHostName, &mHInfoOT);
  492. }
  493. HX_RESULT
  494. OT_TCP::open_resolver(void)
  495. {
  496. //dprintf("this:%X OT_TCP::open_resolvern", this);
  497. mState = TCP_STATE_OPEN_RESOLVER;
  498. #ifdef USE_DEFERRED_IMPL
  499. HX_RESULT theErr = ::OTAsyncOpenInternetServices(kDefaultInternetServicesPath, 0,UDPTCPNotifyProc, this);
  500. #else
  501. #ifdef _CARBON
  502. HX_RESULT theErr = ::OTAsyncOpenInternetServicesInContext(kDefaultInternetServicesPath,
  503. 0,::NewOTNotifyUPP(TCPNotifyProc), this, NULL);
  504. #else
  505. HX_RESULT theErr = ::OTAsyncOpenInternetServices(kDefaultInternetServicesPath,
  506. 0,TCPNotifyProc, this);
  507. #endif
  508. #endif
  509. if (theErr != HXR_OK) 
  510. theErr = HXR_BIND;
  511. return theErr;
  512. }
  513. void
  514. OT_TCP::close_resolver(void)
  515. {
  516. //dprintf("this:%X OT_TCP::close_resolvern", this);
  517. if(mDNSRef != 0)
  518. {
  519. ::OTRemoveNotifier(mDNSRef); // remove the DNR notification function
  520. ::OTCloseProvider(mDNSRef); // close the DNR endpoint
  521. mDNSRef = 0;
  522. }
  523. }
  524. HX_RESULT
  525. OT_TCP::open_socket(void)
  526. {
  527. //dprintf("this:%X OT_TCP::open_socketn", this);
  528. HX_RESULT theErr = HXR_OK;
  529. // Open TCP endpoint
  530. mState = TCP_STATE_OPEN_SOCKET;
  531. #ifdef USE_DEFERRED_IMPL
  532. theErr = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName), 0,NULL, UDPTCPNotifyProc, this);
  533. #else
  534. #ifdef _CARBON
  535. theErr = ::OTAsyncOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0,NULL,
  536. ::NewOTNotifyUPP(TCPNotifyProc), this, NULL);
  537. #else
  538. theErr = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName), 0,NULL,
  539. TCPNotifyProc, this);
  540. #endif
  541. #endif
  542.  
  543. return theErr;
  544. }
  545.  HX_RESULT
  546.  OT_TCP::do_bind (void)
  547. {
  548. //dprintf("this:%X OT_TCP::do_bindn", this);
  549. HX_RESULT theErr = HXR_OK;
  550. mState = TCP_STATE_BIND_SOCKET;
  551. mBindRet.addr.maxlen = sizeof(struct InetAddress);
  552. mBindRet.addr.len = sizeof(struct InetAddress);
  553. mBindRet.addr.buf = (unsigned char *) &mAddr;
  554. // bind provider to return structure
  555. theErr = ::OTBind(mRef, nil, &mBindRet);
  556. if(theErr == kOTNoDataErr) 
  557. theErr = HXR_OK;
  558. if(theErr)
  559. theErr = HXR_BIND;
  560. return theErr;
  561. }
  562.  HX_RESULT
  563.  OT_TCP::do_connect(void)
  564. {
  565. //dprintf("this:%X OT_TCP::do_connectn", this);
  566. mState = TCP_STATE_CONNECT_SOCKET;
  567. ::memset(&mCall,0,sizeof(TCall));
  568. mCall.addr.buf = (UInt8 *)&mAddr;
  569. mCall.addr.maxlen = sizeof(InetAddress);
  570. mCall.addr.len = sizeof(InetAddress);
  571. // set up address of remote host
  572. ::OTInitInetAddress((InetAddress*)mCall.addr.buf, mRemotePort, mRemoteHost);
  573. // connect client to remote endpoint
  574. HX_RESULT theErr = ::OTConnect(mRef, &mCall, nil);
  575. if(theErr == kOTNoDataErr) 
  576. theErr = HXR_OK;
  577. if(theErr)
  578. theErr = HXR_SERVER_DISCONNECTED;
  579. return theErr;
  580. }
  581. /*----------------------------------------------------------------------------
  582. TCPNotifyProc 
  583. Open Transport notifier proc for TCP streams.
  584. Entry: s = pointer to stream.
  585. code = OT event code.
  586. result = OT result.
  587. cookie = OT cookie.
  588. ----------------------------------------------------------------------------*/
  589. pascal void OT_TCP::TCPNotifyProc (
  590.  void  *stream, 
  591.  OTEventCode  code,
  592.  OTResult  result, 
  593.  void  *cookie)
  594.  
  595. {
  596. //dprintf("this:%X OT_TCP::TCPNotifyProc cookie:%X code:%X result:%Xn", stream, cookie, code, result);
  597. HX_RESULT theErr = HXR_OK;
  598. OT_TCP* s =  (OT_TCP*) stream;
  599. HXMM_INTERRUPTON();
  600. s->ProcessCmd(code, result, cookie);
  601. HXMM_INTERRUPTOFF();
  602. return;
  603. }
  604. void OT_TCP::ProcessCmd(OTEventCode code, OTResult result, void* cookie)  
  605. {
  606. HX_RESULT theErr = HXR_OK;
  607. switch (code) 
  608. {
  609. case T_OPENCOMPLETE:
  610. {
  611. //dprintf("this:%X T_OPENCOMPLETE ", this);
  612. // check if T_OPENCOMPLETE was for DNS or socket
  613. if(mState == TCP_STATE_OPEN_RESOLVER)
  614. {
  615. //dprintf(" TCP_STATE_OPEN_RESOLVERn");
  616. theErr = result;
  617. if(!theErr)
  618. {
  619. // save DNS provider endpoint ref
  620. mDNSRef = (InetSvcRef) cookie;
  621. mDNSOpen = TRUE;
  622. theErr = resolve_address();
  623. }
  624. else
  625. theErr = HXR_BIND;
  626. }
  627. else if(mState == TCP_STATE_OPEN_SOCKET)
  628. {
  629. // DebugWrite("T_OPENCOMPLETE  TCP_STATE_OPEN_SOCKET");
  630. //dprintf(" TCP_STATE_OPEN_SOCKETn");
  631. theErr = result;
  632. if(!theErr)
  633. {
  634. // save TCP provider endpoint ref
  635. mRef = (EndpointRef) cookie;
  636. mSocketOpen = TRUE;
  637. theErr = do_bind();
  638. }
  639. else
  640. theErr = HXR_SOCKET_CREATE;
  641. }
  642. else if (mState == TCP_STATE_OPEN_LISTEN)
  643. {
  644. //dprintf(" TCP_STATE_OPEN_LISTENn");
  645. theErr = result;
  646. if ( !theErr )
  647. {
  648.     mRef = (EndpointRef) cookie;
  649.     mSocketOpen = TRUE;
  650.     mCode = code;
  651.     mComplete = true;
  652. }
  653. else
  654. theErr = HXR_SOCKET_CREATE;
  655. }
  656. else if (mState == TCP_STATE_OPEN_ACCEPT)
  657. {
  658. //dprintf(" TCP_STATE_OPEN_ACCEPTn");
  659. theErr = result;
  660. if ( !theErr )
  661. {
  662.     mRef = (EndpointRef) cookie;
  663.     mSocketOpen = TRUE;
  664.     mCode = code;
  665.     mState = TCP_STATE_READY;
  666.     mComplete = true;
  667. }
  668. else
  669. theErr = HXR_SOCKET_CREATE;
  670. }
  671. break;
  672. }
  673. case T_DNRSTRINGTOADDRCOMPLETE:
  674. case T_DNRADDRTONAMECOMPLETE:
  675. {
  676. // DebugWrite("T_DNRSTRINGTOADDRCOMPLETE");
  677. //dprintf("this:%X T_DNRSTRINGTOADDRCOMPLETEn", this);
  678. theErr = result;
  679. if(!theErr)
  680. {
  681. // extract DNS result from InetHostInfo struct
  682. mRemoteHost = mHInfoOT.addrs[0];
  683. // close the DNS endpoint
  684. // close_resolver();
  685. // open a TCP socket
  686. // next message should be T_OPEN_COMPLETE
  687. theErr = open_socket();
  688.   }
  689. else
  690. theErr = HXR_BIND;
  691. break;
  692. }
  693. case T_BINDCOMPLETE:
  694. {
  695. // DebugWrite("T_BINDCOMPLETE");
  696. //dprintf("this:%X T_BINDCOMPLETE ", this); 
  697. if ( mState == TCP_STATE_BIND_LISTEN )
  698. {
  699. //dprintf(" - Listenn");
  700. theErr = result;
  701. if ( !theErr )
  702. {
  703. mCode = code;
  704. mComplete = true;
  705. }
  706. else
  707. {
  708. theErr = HXR_BIND;
  709. }
  710. }
  711. else
  712. {
  713. //dprintf(" - Regularn");
  714. theErr = result;
  715. if(!theErr)
  716. {
  717. mComplete = true;
  718. // get inet address
  719. InetAddress *inetAddr = (InetAddress*)mBindRet.addr.buf;
  720. // save local port we are bound to
  721. mLocalPort = inetAddr->fPort;
  722. // now connect to the remote host
  723. theErr = do_connect();
  724. }
  725. else
  726. theErr = HXR_BIND;
  727. }
  728. break;
  729. }
  730. case T_CONNECT:
  731. // DebugWrite("T_CONNECT");
  732. //dprintf("this:%X T_CONNECTn", this);
  733. theErr = result;
  734. if(!theErr)
  735. theErr = ::OTRcvConnect(mRef, nil);
  736. if(!theErr)
  737. {
  738. mConnectionOpen = TRUE;
  739. mWriteReady = TRUE;
  740. mCallBack->Func(CONNECT_NOTIFICATION); //z
  741. }
  742. else
  743. theErr = HXR_SERVER_DISCONNECTED;
  744. break;
  745. case T_DISCONNECT:
  746. // DebugWrite("T_DISCONNECT");
  747. //dprintf("this:%X T_DISCONNECTn", this);
  748. /* Other side has aborted. */
  749. mCode = code;
  750. mOtherSideHasClosed = true;
  751. mComplete = true;
  752. mConnectionOpen = FALSE;
  753. mWeHaveClosed = TRUE; //cz
  754. mStartedReceivingData = FALSE;
  755. mWriteReady = FALSE;
  756. ::OTRcvDisconnect(mRef, NULL);
  757. if (mCallBack) mCallBack->Func(CONNECT_NOTIFICATION, FALSE); // rml cr zach, rahul
  758. break;
  759. case T_ORDREL:
  760. // DebugWrite("T_ORDREL");
  761. //dprintf("this:%X T_ORDRELn", this);
  762. /* Other side has closed. Close our side if necessary. */
  763. mCode = code;
  764. mOtherSideHasClosed = true;
  765. mComplete = true;
  766. mConnectionOpen = FALSE;
  767. mStartedReceivingData = FALSE;
  768. mWriteReady = FALSE;
  769. ::OTRcvOrderlyDisconnect(mRef);
  770. if (!mWeHaveClosed) 
  771. {
  772. ::OTSndOrderlyDisconnect(mRef);
  773. mWeHaveClosed = true;
  774. }
  775. if (mClosing) mRelease = true;
  776. break;
  777. case T_DATA:
  778. // DebugWrite("T_DATA");
  779. //dprintf("this:%X T_DATAn", this);
  780. mStartedReceivingData = TRUE;
  781. if (mClosing) 
  782. {
  783. /* Consume and discard response to "QUIT" comand. */
  784. do 
  785. {
  786. result = ::OTRcv(mRef, mBuf, kBufSize, nil);
  787. } while (result >= 0);
  788. }
  789. else if ( mState == TCP_STATE_ACCEPT_PENDING )
  790. {
  791. //dprintf("TCP_STAT_ACCEPT_PENDING - hold data.n");
  792. mDataReady = TRUE;
  793. }
  794. else
  795. {
  796. mDataArrived = TRUE;
  797. if(mCallBack) 
  798. // mCallBack->callback_task(HX_TCP_CALLBACK);
  799. mCallBack->Func(READ_NOTIFICATION);
  800. }
  801. break;
  802. case T_DISCONNECTCOMPLETE:
  803. case T_PASSCON:
  804. //dprintf("this:%X T_PASSCON ", this);
  805. // DebugWrite("T_DISCONNECTCOMPLETE");
  806. if ( mState == TCP_STATE_ACCEPT_PENDING )
  807. {
  808. //dprintf("TCP_STATE_ACCEPT_PENDINGn");
  809. mConnectionOpen = TRUE;
  810. mWriteReady = TRUE;
  811. mOtherSideHasClosed = false;
  812. mState = TCP_STATE_READY;
  813. if ( mDataReady )
  814. {
  815. //dprintf("Data is waiting so give notificationn");
  816. mDataArrived = TRUE;
  817. if ( mCallBack )
  818. mCallBack->Func(READ_NOTIFICATION);
  819. }
  820. }
  821. else
  822. {
  823. //dprintf("Regularn");
  824. mComplete = true;
  825. mCode = code;
  826. mResult = result;
  827. mCookie = cookie;
  828. }
  829. break;
  830. case T_GODATA:
  831. // DebugWrite("T_GODATA");
  832. //dprintf("this:%X T_GODATAn", this);
  833. mDataFlowOn = FALSE;
  834. mWriteReady = TRUE;
  835. break;
  836. case T_LISTEN:
  837. //dprintf("this:%X T_LISTENn", this);
  838. ::memset(&mNewAddr,0,sizeof(TCall));
  839. mCall.addr.buf = (UInt8 *)&mNewAddr;
  840. mCall.addr.maxlen = sizeof(InetAddress);
  841. mCall.addr.len = sizeof(InetAddress);
  842. //HX_ASSERT(mState == TCP_SOCKET_LISTEN);
  843. HX_ASSERT(mNewConnection);
  844. EndpointRef pRef;
  845. #ifdef _CARBON
  846. mNewConnection->GetEndpoint((void*&)pRef);
  847. #else
  848. mNewConnection->GetEndpoint((void*)pRef);
  849. #endif
  850. if ( pRef )
  851. {
  852.     theErr = OTListen(mRef,&mCall);
  853.     if ( !theErr )
  854.     {
  855. if ( !theErr )
  856. {
  857.     theErr = OTAccept(mRef, pRef, &mCall);
  858. }
  859.     }
  860. }
  861. else
  862. {
  863. // some how we got messed up
  864. // not much we can do... we will
  865. // just ignor the listen request...
  866. }
  867. break;
  868. case T_ACCEPTCOMPLETE:
  869. {
  870. //dprintf("this:%X T_ACCEPTCOMPLETEn", this);
  871. mCallBack->Func(ACCEPT_NOTIFICATION, 
  872. TRUE, mNewConnection);
  873. // it is the callback's job to call done...
  874. HX_RELEASE(mNewConnection);
  875. mNewConnection = conn::actual_new_socket(HX_TCP_SOCKET);
  876. mNewConnection->AddRef();
  877. // we are in deffered task time so this will not finish
  878. // until wait for event is called again...  therefore
  879. // we pass in false for wait.  We will wait at the
  880. // beginning to GetEndpoint() if it hasn't finished yet.
  881. HX_RESULT theErr = mNewConnection->SetupEndpoint(FALSE);
  882. }
  883. break;
  884. case kOTProviderIsClosed:
  885. {
  886. // This event is triggered by OpenTransport when the network is gone
  887. // i.e. network cable has been unpluged
  888. mCode = code;
  889. mResult = result;
  890. mOtherSideHasClosed = true;
  891. mComplete = true;
  892. mConnectionOpen = FALSE;
  893. mWeHaveClosed = TRUE;
  894. mStartedReceivingData = FALSE;
  895. mWriteReady = FALSE;
  896. ::OTRcvDisconnect(mRef, NULL);
  897. if (mCallBack) mCallBack->Func(CONNECT_NOTIFICATION, FALSE);
  898. }
  899. break;
  900. default:
  901. //dprintf("this:%X Uncaugt message - %Xn", this, code);
  902. break;
  903. }
  904. mAsyncError = theErr;
  905. }
  906. HX_RESULT OT_TCP::SetupEndpoint(BOOL bWait)
  907. {
  908. //dprintf("this:%X OT_TCP::SetupEndpointn", this);
  909. // Open TCP endpoint
  910. mState = TCP_STATE_OPEN_ACCEPT;
  911. mComplete = false;
  912. mConnectionOpen = FALSE;
  913. mDataFlowOn = FALSE;
  914. mDataArrived = FALSE;
  915. mDataReady = FALSE;
  916. mAsyncError = HXR_OK;
  917. #ifdef USE_DEFERRED_IMPL
  918. HX_RESULT theErr = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName), 0,NULL, UDPTCPNotifyProc, this);
  919. #else
  920. #ifdef _CARBON
  921. HX_RESULT theErr = ::OTAsyncOpenEndpointInContext(OTCreateConfiguration(kTCPName),
  922. 0,NULL, (OTNotifyUPP)TCPNotifyProc, this, NULL);
  923. #else
  924. HX_RESULT theErr = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName),
  925. 0,NULL, TCPNotifyProc, this);
  926. #endif
  927. #endif
  928. if ( theErr )
  929. {
  930. mLastError = theErr;
  931. theErr = HXR_SOCKET_CREATE;
  932. }
  933. // wait for open completion.. if we were called from deffered task time
  934. // or Interupt time we don't want to wait though...  Because the creation
  935. // of the end point will not finish until control is passed back to the
  936. // application.
  937. if( bWait )
  938. {
  939. if ( !theErr)
  940. {
  941. theErr = OTWait();
  942. if(theErr == kOTNoDataErr) theErr = HXR_OK;
  943. if(theErr || mCode != T_OPENCOMPLETE) 
  944. {
  945. theErr = theErr ? theErr : HXR_SOCKET_CREATE;
  946. mLastError = theErr;
  947. theErr = HXR_SOCKET_CREATE;
  948. }
  949. }
  950. }
  951. return theErr;
  952. }
  953. HX_RESULT OT_TCP::GetEndpoint(REF(void*) pRef)
  954. {
  955. ////dprintf("this:%X OT_TCP::GetEndpointn", this);
  956. HX_RESULT theErr = HXR_OK;
  957. if ( mState == TCP_STATE_OPEN_ACCEPT )
  958. {
  959. theErr = OTWait();
  960. if(theErr == kOTNoDataErr) theErr = HXR_OK;
  961. if ( theErr || mCode != T_OPENCOMPLETE )
  962. {
  963. theErr = theErr ? theErr : HXR_SOCKET_CREATE;
  964. mLastError = theErr;
  965. return HXR_SOCKET_CREATE;
  966. }
  967. }
  968. if ( mRef )
  969. {
  970. mState = TCP_STATE_ACCEPT_PENDING;
  971. pRef = (void*)mRef;
  972. return HXR_OK;
  973. }
  974. else
  975. {
  976. return HXR_NOT_INITIALIZED;
  977. }
  978. }