⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ot_tcp.cp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CP
📖 第 1 页 / 共 2 页
字号:
		if ( mNewConnection )
		{
			mNewConnection->done();
			HX_RELEASE(mNewConnection);
		}
		mNewConnection = conn::actual_new_socket(HX_TCP_SOCKET);
		mNewConnection->AddRef();
		// we can wait here, because we should not be called
		// from deffered task time.
		theErr = mNewConnection->SetupEndpoint(TRUE);
	}
	return theErr;
}

HX_RESULT OT_TCP::resolve_address (void)
{
	//dprintf("this:%X OT_TCP::resulve_address\n", this);
	mState = TCP_STATE_RESOLVE_DNS;
	return ::OTInetStringToAddress(mDNSRef, mRemoteHostName, &mHInfoOT);
}

HX_RESULT
OT_TCP::open_resolver(void)
{
	//dprintf("this:%X OT_TCP::open_resolver\n", this);
	mState = TCP_STATE_OPEN_RESOLVER;
#ifdef USE_DEFERRED_IMPL	
	HX_RESULT theErr = ::OTAsyncOpenInternetServices(kDefaultInternetServicesPath, 0,UDPTCPNotifyProc, this);
#else
#ifdef _CARBON
	HX_RESULT theErr = ::OTAsyncOpenInternetServicesInContext(kDefaultInternetServicesPath,
			0,::NewOTNotifyUPP(TCPNotifyProc), this, NULL);
#else
	HX_RESULT theErr = ::OTAsyncOpenInternetServices(kDefaultInternetServicesPath,
			0,TCPNotifyProc, this);
#endif
#endif
	if (theErr != HXR_OK) 
		theErr = HXR_BIND;
	
	return theErr;
}

void
OT_TCP::close_resolver(void)
{
	//dprintf("this:%X OT_TCP::close_resolver\n", this);
	if(mDNSRef != 0)
	{
		::OTRemoveNotifier(mDNSRef);	// remove the DNR notification function
		::OTCloseProvider(mDNSRef);		// close the DNR endpoint
		mDNSRef = 0;
	}
}


HX_RESULT
OT_TCP::open_socket(void)
{
	//dprintf("this:%X OT_TCP::open_socket\n", this);
	HX_RESULT theErr = HXR_OK;
		
	// Open TCP endpoint
	mState = TCP_STATE_OPEN_SOCKET;
#ifdef USE_DEFERRED_IMPL	
	theErr = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName), 0,NULL, UDPTCPNotifyProc, this);
#else
#ifdef _CARBON
	theErr = ::OTAsyncOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0,NULL,
			::NewOTNotifyUPP(TCPNotifyProc), this, NULL);
#else
	theErr = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName), 0,NULL,
			TCPNotifyProc, this);
#endif
#endif
								 
	return theErr;
}

 HX_RESULT
 OT_TCP::do_bind (void)
{
	//dprintf("this:%X OT_TCP::do_bind\n", this);
	HX_RESULT	theErr = HXR_OK;
			
	mState = TCP_STATE_BIND_SOCKET;

	mBindRet.addr.maxlen = sizeof(struct InetAddress);
	mBindRet.addr.len = sizeof(struct InetAddress);
	mBindRet.addr.buf = (unsigned char *) &mAddr;

	// bind provider to return structure
	theErr = ::OTBind(mRef, nil, &mBindRet);
	
	if(theErr == kOTNoDataErr) 
		theErr = HXR_OK;
	
	if(theErr)
		theErr = HXR_BIND;

	return theErr;	
}

 HX_RESULT
 OT_TCP::do_connect(void)
{
	//dprintf("this:%X OT_TCP::do_connect\n", this);
	mState = TCP_STATE_CONNECT_SOCKET;

	::memset(&mCall,0,sizeof(TCall));
	mCall.addr.buf = (UInt8 *)&mAddr;
	mCall.addr.maxlen = sizeof(InetAddress);
	mCall.addr.len = sizeof(InetAddress);
	
	// set up address of remote host
	::OTInitInetAddress((InetAddress*)mCall.addr.buf, mRemotePort, mRemoteHost);
	
	// connect client to remote endpoint
	HX_RESULT theErr = ::OTConnect(mRef, &mCall, nil);
	if(theErr == kOTNoDataErr) 
		theErr = HXR_OK;

	if(theErr)
		theErr = HXR_SERVER_DISCONNECTED;
		
	return theErr;
}

/*----------------------------------------------------------------------------
	TCPNotifyProc 
	
	Open Transport notifier proc for TCP streams.
	
	Entry:	s = pointer to stream.
			code = OT event code.
			result = OT result.
			cookie = OT cookie.
----------------------------------------------------------------------------*/

pascal void OT_TCP::TCPNotifyProc (

	 void 			*stream, 
	 OTEventCode 	code,
	 OTResult 		result, 
	 void 			*cookie)
	 
{
	//dprintf("this:%X OT_TCP::TCPNotifyProc cookie:%X code:%X result:%X\n", stream, cookie, code, result);
	HX_RESULT theErr = HXR_OK;
	
	OT_TCP* s =  (OT_TCP*) stream;
	
	HXMM_INTERRUPTON();
	s->ProcessCmd(code, result, cookie);
	HXMM_INTERRUPTOFF();
	return;	
}


void OT_TCP::ProcessCmd(OTEventCode code, OTResult result, void* cookie)	 
{
	HX_RESULT theErr = HXR_OK;
	switch (code) 
	{
		case T_OPENCOMPLETE:
		{
			//dprintf("this:%X T_OPENCOMPLETE ", this);
			// check if T_OPENCOMPLETE was for DNS or socket
			if(mState == TCP_STATE_OPEN_RESOLVER)
			{
				//dprintf(" TCP_STATE_OPEN_RESOLVER\n");
				theErr = result;
				if(!theErr)
				{
					// save DNS provider endpoint ref
					mDNSRef = (InetSvcRef) cookie;
					mDNSOpen = TRUE;
					theErr = resolve_address();
				}
				else
					theErr = HXR_BIND;
			}
			else if(mState == TCP_STATE_OPEN_SOCKET)
			{	
//				DebugWrite("T_OPENCOMPLETE  TCP_STATE_OPEN_SOCKET");
				//dprintf(" TCP_STATE_OPEN_SOCKET\n");
			
				theErr = result;
				if(!theErr)
				{
					// save TCP provider endpoint ref
					mRef = (EndpointRef) cookie;
					mSocketOpen = TRUE;
					theErr = do_bind();
				}
				else
					theErr = HXR_SOCKET_CREATE;
			}
			else if (mState == TCP_STATE_OPEN_LISTEN)
			{
				//dprintf(" TCP_STATE_OPEN_LISTEN\n");
				theErr = result;
				if ( !theErr )
				{
				    mRef = (EndpointRef) cookie;
				    mSocketOpen = TRUE;
				    mCode = code;
				    mComplete = true;
				}
				else
					theErr = HXR_SOCKET_CREATE;
			}
			else if (mState == TCP_STATE_OPEN_ACCEPT)
			{
				//dprintf(" TCP_STATE_OPEN_ACCEPT\n");
				theErr = result;
				if ( !theErr )
				{
				    mRef = (EndpointRef) cookie;
				    mSocketOpen = TRUE;
				    mCode = code;
				    mState = TCP_STATE_READY;
				    mComplete = true;
				}
				else
					theErr = HXR_SOCKET_CREATE;
			}
			break;
		}
			
		case T_DNRSTRINGTOADDRCOMPLETE:
		case T_DNRADDRTONAMECOMPLETE:
		{

//			DebugWrite("T_DNRSTRINGTOADDRCOMPLETE");
			//dprintf("this:%X T_DNRSTRINGTOADDRCOMPLETE\n", this);

			theErr = result;
			if(!theErr)
			{
				// extract DNS result from InetHostInfo struct
				mRemoteHost = mHInfoOT.addrs[0];
				
				// close the DNS endpoint
//				close_resolver();
				
				// open a TCP socket
				// next message should be T_OPEN_COMPLETE
				theErr = open_socket();
 			}
			else
				theErr = HXR_BIND;
				
			break;
		}
		
		case T_BINDCOMPLETE:
		{
//			DebugWrite("T_BINDCOMPLETE");
			//dprintf("this:%X T_BINDCOMPLETE ", this); 
			if ( mState == TCP_STATE_BIND_LISTEN )
			{
				//dprintf(" - Listen\n");
				theErr = result;
				if ( !theErr )
				{
					mCode = code;
					mComplete = true;
					
				}
				else
				{
					theErr = HXR_BIND;
				}
				
			}
			else
			{
				//dprintf(" - Regular\n");
				theErr = result;
				if(!theErr)
				{
					mComplete = true;
					
					// get inet address
					InetAddress *inetAddr = (InetAddress*)mBindRet.addr.buf;
		
					// save local port we are bound to
					mLocalPort = inetAddr->fPort;

					// now connect to the remote host
					theErr = do_connect();
				}
				else
					theErr = HXR_BIND;
			}
					
			break;
		}

		case T_CONNECT:
//			DebugWrite("T_CONNECT");
			//dprintf("this:%X T_CONNECT\n", this);

			theErr = result;
			if(!theErr)
				theErr = ::OTRcvConnect(mRef, nil);
				
			if(!theErr)
			{
				mConnectionOpen = TRUE;
				mWriteReady = TRUE;
				mCallBack->Func(CONNECT_NOTIFICATION); //z
			}
			else
				theErr = HXR_SERVER_DISCONNECTED;
				
			break;

		case T_DISCONNECT:
//			DebugWrite("T_DISCONNECT");
			//dprintf("this:%X T_DISCONNECT\n", this);

			/* Other side has aborted. */
			mCode = code;
			mOtherSideHasClosed = true;
			mComplete = true;
			mConnectionOpen = FALSE;
			mWeHaveClosed = TRUE; //cz
			mStartedReceivingData = FALSE;
			mWriteReady = FALSE;
			::OTRcvDisconnect(mRef, NULL);
			if (mCallBack) mCallBack->Func(CONNECT_NOTIFICATION, FALSE); // rml cr zach, rahul
			break;
			
		case T_ORDREL:
//			DebugWrite("T_ORDREL");
			//dprintf("this:%X T_ORDREL\n", this);
			
			/* Other side has closed. Close our side if necessary. */
			mCode = code;
			mOtherSideHasClosed = true;
			mComplete = true;
			mConnectionOpen = FALSE;
			mStartedReceivingData = FALSE;
			mWriteReady = FALSE;
			::OTRcvOrderlyDisconnect(mRef);
			if (!mWeHaveClosed) 
			{
				::OTSndOrderlyDisconnect(mRef);
				mWeHaveClosed = true;
			}
			if (mClosing) mRelease = true;
			break;
			
		case T_DATA:
//			DebugWrite("T_DATA");		
			//dprintf("this:%X T_DATA\n", this);
			mStartedReceivingData = TRUE;
			if (mClosing) 
			{
				/* Consume and discard response to "QUIT" comand. */
				do 
				{
					result = ::OTRcv(mRef, mBuf, kBufSize, nil);
				} while (result >= 0);
			}
			else if ( mState == TCP_STATE_ACCEPT_PENDING )
			{
				//dprintf("TCP_STAT_ACCEPT_PENDING - hold data.\n");
				mDataReady = TRUE;
			}
			else
			{
				mDataArrived = TRUE;
				if(mCallBack) 
//					mCallBack->callback_task(HX_TCP_CALLBACK);
					mCallBack->Func(READ_NOTIFICATION);
			}
			break;

		case T_DISCONNECTCOMPLETE:
		case T_PASSCON:
			//dprintf("this:%X T_PASSCON ", this);
//			DebugWrite("T_DISCONNECTCOMPLETE");
			if ( mState == TCP_STATE_ACCEPT_PENDING )
			{
				//dprintf("TCP_STATE_ACCEPT_PENDING\n");
				mConnectionOpen = TRUE;
				mWriteReady = TRUE;
				mOtherSideHasClosed = false;
				mState = TCP_STATE_READY;
				if ( mDataReady )
				{
					//dprintf("Data is waiting so give notification\n");
					mDataArrived = TRUE;
					if ( mCallBack )
						mCallBack->Func(READ_NOTIFICATION);
				}
			}
			else
			{
				//dprintf("Regular\n");
				mComplete = true;
				mCode = code;
				mResult = result;
				mCookie = cookie;
			}
			break;

			
		case T_GODATA:
//			DebugWrite("T_GODATA");		
			//dprintf("this:%X T_GODATA\n", this);		
			mDataFlowOn = FALSE;
			mWriteReady = TRUE;
			break;
		case T_LISTEN:
			//dprintf("this:%X T_LISTEN\n", this);
			::memset(&mNewAddr,0,sizeof(TCall));
			mCall.addr.buf = (UInt8 *)&mNewAddr;
			mCall.addr.maxlen = sizeof(InetAddress);
			mCall.addr.len = sizeof(InetAddress);
			//HX_ASSERT(mState == TCP_SOCKET_LISTEN);
			HX_ASSERT(mNewConnection);
			EndpointRef pRef;
#ifdef _CARBON
			mNewConnection->GetEndpoint((void*&)pRef);
#else
			mNewConnection->GetEndpoint((void*)pRef);
#endif
			if ( pRef )
			{
			    theErr = OTListen(mRef,&mCall);
			    if ( !theErr )
			    {
				if ( !theErr )
				{
				    theErr = OTAccept(mRef, pRef, &mCall);
				}
			    }
			}
			else
			{
				// some how we got messed up
				// not much we can do... we will
				// just ignor the listen request...
			}
			break;
		case T_ACCEPTCOMPLETE:
			{
				//dprintf("this:%X T_ACCEPTCOMPLETE\n", this);
				mCallBack->Func(ACCEPT_NOTIFICATION, 
						TRUE, mNewConnection);
				// it is the callback's job to call done...
				HX_RELEASE(mNewConnection);
				mNewConnection = conn::actual_new_socket(HX_TCP_SOCKET);
				mNewConnection->AddRef();
				// we are in deffered task time so this will not finish
				// until wait for event is called again...  therefore
				// we pass in false for wait.  We will wait at the
				// beginning to GetEndpoint() if it hasn't finished yet.
				HX_RESULT theErr = mNewConnection->SetupEndpoint(FALSE);
			}
			break;
		case kOTProviderIsClosed:
			{
				// This event is triggered by OpenTransport when the network is gone
				// i.e. network cable has been unpluged
				mCode = code;
				mResult = result;
				mOtherSideHasClosed = true;
				mComplete = true;
				mConnectionOpen = FALSE;
				mWeHaveClosed = TRUE;
				mStartedReceivingData = FALSE;
				mWriteReady = FALSE;
				::OTRcvDisconnect(mRef, NULL);
				if (mCallBack) mCallBack->Func(CONNECT_NOTIFICATION, FALSE);
			}
			break;
		default:
			//dprintf("this:%X Uncaugt message - %X\n", this, code);
			break;
	}
	
	mAsyncError = theErr;
}

HX_RESULT OT_TCP::SetupEndpoint(BOOL bWait)
{
	//dprintf("this:%X OT_TCP::SetupEndpoint\n", this);
	// Open TCP endpoint
	mState = TCP_STATE_OPEN_ACCEPT;
	mComplete = false;
	mConnectionOpen = FALSE;
	mDataFlowOn = FALSE;
	mDataArrived = FALSE;
	mDataReady = FALSE;
	mAsyncError = HXR_OK;

#ifdef USE_DEFERRED_IMPL	
	HX_RESULT theErr = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName), 0,NULL, UDPTCPNotifyProc, this);
#else
#ifdef _CARBON
	HX_RESULT theErr = ::OTAsyncOpenEndpointInContext(OTCreateConfiguration(kTCPName),
			0,NULL, (OTNotifyUPP)TCPNotifyProc, this, NULL);
#else
	HX_RESULT theErr = ::OTAsyncOpenEndpoint(OTCreateConfiguration(kTCPName),
			0,NULL, TCPNotifyProc, this);
#endif
#endif
	if ( theErr )
	{
		mLastError = theErr;
		theErr = HXR_SOCKET_CREATE;
	}
	// wait for open completion.. if we were called from deffered task time
	// or Interupt time we don't want to wait though...  Because the creation
	// of the end point will not finish until control is passed back to the
	// application.
	if( bWait )
	{
		if ( !theErr)
		{
			theErr = OTWait();
			if(theErr == kOTNoDataErr) theErr = HXR_OK;
			
			if(theErr || mCode != T_OPENCOMPLETE) 
			{
				theErr = theErr ? theErr : HXR_SOCKET_CREATE;
				mLastError = theErr;
				theErr = HXR_SOCKET_CREATE;
			}
		}
	}
	return theErr;
}

HX_RESULT OT_TCP::GetEndpoint(REF(void*) pRef)
{
	////dprintf("this:%X OT_TCP::GetEndpoint\n", this);
	HX_RESULT theErr = HXR_OK;
	if ( mState == TCP_STATE_OPEN_ACCEPT )
	{
		theErr = OTWait();
		if(theErr == kOTNoDataErr) theErr = HXR_OK;
		if ( theErr || mCode != T_OPENCOMPLETE )
		{
			theErr = theErr ? theErr : HXR_SOCKET_CREATE;
			mLastError = theErr;
			return HXR_SOCKET_CREATE;
		}
	}
	if ( mRef )
	{
		mState = TCP_STATE_ACCEPT_PENDING;
		pRef = (void*)mRef;
		return HXR_OK;
	}
	else
	{
		return HXR_NOT_INITIALIZED;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -