void
OTIPEnumerator::HandleLookErr(void)
{
	DEBUG_ENTRY_EXIT("IPEnumerator::HandleLookErr");

OTResult	result;
OSStatus	status;
TUDErr		udErr;
InetAddress	addr;
	
	udErr.addr.buf = (NMUInt8 *) &addr;
	udErr.addr.len = udErr.addr.maxlen = sizeof(InetAddress);
	udErr.opt.maxlen = 0;
	
	
	result = OTLook(mEP);
	DEBUG_PRINT("OTLook returned %ld", result);

	switch (result)
	{
		case T_DATA:
			ReceiveDatagram();
			break;
			
		case T_UDERR:
			status = OTRcvUDErr(mEP, &udErr);
			DEBUG_PRINT("OTRcvUDErr returned %ld", status);
			break;

		default:
			DEBUG_PRINT("Unhandled look error!");
			break;
	}
}
Example #2
0
int SDLNet_CheckSockets(SDLNet_SocketSet set, Uint32 timeout)
{
Uint32	stop;
int 	numReady;

	/* Loop, polling the network devices */
	
	stop = SDL_GetTicks() + timeout;
	
	do 
	{
	OTResult status;
	size_t	numBytes;
	int 	i;
		
		numReady = 0;
	
		for (i = set->numsockets-1;i >= 0;--i) 
		{
			status = OTLook( set->sockets[i]->channel );
			if( status > 0 )
			{
				switch( status )
				{
					case T_UDERR:
						OTRcvUDErr( set->sockets[i]->channel , nil);
						break;
					case T_DISCONNECT:
						OTRcvDisconnect( set->sockets[i]->channel, nil );
						break;
					case T_ORDREL:
						OTRcvOrderlyDisconnect(set->sockets[i]->channel );
						break;
					case T_CONNECT:
						OTRcvConnect( set->sockets[i]->channel, nil );
						break;
					
				
					default:
						set->sockets[i]->ready = 1;
						++numReady;
				}
			}
			else if( OTCountDataBytes(set->sockets[i]->channel, &numBytes ) != kOTNoDataErr )
			{
				set->sockets[i]->ready = 1;
				++numReady;
			}
			else
				set->sockets[i]->ready = 0;
		}
		
	} while (!numReady && (SDL_GetTicks() < stop));

	return(numReady);
}
Example #3
0
// Notification routine
// Async callback routine.
// A5 is OK. Cannot allocate memory here
pascal void  NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
{
	PRThread * thread = (PRThread *) contextPtr;
    _PRCPU *cpu = _PR_MD_CURRENT_CPU();	
	
	switch (code)
	{
// Async Completion Event
		case T_OPENCOMPLETE:
		case T_BINDCOMPLETE:
		case T_UNBINDCOMPLETE:
		case T_GETPROTADDRCOMPLETE:
		case T_ACCEPTCOMPLETE:
// Connect callback
		case T_CONNECT:
// Standard or expedited data is available
		case T_DATA:
		case T_EXDATA:
// Standard or expedited data Flow control lifted
		case T_GODATA:
		case T_GOEXDATA:
// Asynchronous Listen Event
		case T_LISTEN:
// DNR String To Address Complete Event
		case T_DNRSTRINGTOADDRCOMPLETE:
// Option Management Request Complete Event
		case T_OPTMGMTCOMPLETE:
			thread->md.osErrCode = result;
			thread->md.cookie = cookie;
		    if (_PR_MD_GET_INTSOFF()) {
		        cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
		        thread->md.notifyPending = PR_TRUE;
				return;
		    }
			DoneWaitingOnThisThread(thread);
			break;

// T_ORDREL orderly release is available;  nothing to do
		case T_ORDREL:
			break;

// T_PASSCON; nothing to do
		case T_PASSCON:
			break;

// T_DISCONNECT; disconnect is available; nothing to do
		case T_DISCONNECT:
			break;

// UDP Send error; clear the error
		case T_UDERR:
			(void) OTRcvUDErr((EndpointRef) cookie, NULL);
		default:
			PR_ASSERT(0);
	}
}
Example #4
0
// This function is taken from GUSI interface.
// ( 01/02/19 masahiro minami<*****@*****.**> )
static void AsyncTCPPopEvent( TCPsocket sock )
{
	// Make sure OT calls are not interrupted
	// Not sure if we really need this.
	OTEnterNotifier( sock->channel );
	
	sock->event |= (sock->curEvent = sock->newEvent );
	sock->completion |= ( sock->curCompletion = sock->newCompletion );
	sock->newEvent = sock->newCompletion = 0;
	
	OTLeaveNotifier( sock->channel );
	
	if( sock->curEvent & T_UDERR)
	{
		// We just clear the error.
		// Should we feed this back to users ?
		// (TODO )
		OTRcvUDErr( sock->channel, NULL );
		
#ifdef DEBUG_NET
		printf("AsyncTCPPopEvent  T_UDERR recognized");
#endif
	}
	
	// Remote is disconnecting...
	if( sock->curEvent & ( T_DISCONNECT | T_ORDREL ))
	{
		sock->readShutdown = true;
	}
	
	if( sock->curEvent &T_CONNECT )
	{
		// Ignore the info of remote (second parameter).
		// Shoule we care ?
		// (TODO)
		OTRcvConnect( sock->channel, NULL );
		sock->connected = 1;
	}
	
	if( sock->curEvent & T_ORDREL )
	{
		OTRcvOrderlyDisconnect( sock->channel );
	}
	
	if( sock->curEvent & T_DISCONNECT )
	{
		OTRcvDisconnect( sock->channel, NULL );
	}
	
	// Do we need to ?
	// (masahiro minami<*****@*****.**>)
	//YieldToAnyThread();
}
Example #5
0
void PostUDERR(char *source, EndpointRef ep) {
	OSStatus	err;
	TUDErr errBlock;
	struct InetAddress addr;
#define OPTIONS_LENGTH 2048
	unsigned char RoomForStupidOptions[OPTIONS_LENGTH];
	
	errBlock.addr.buf = (void *) &addr;
	errBlock.addr.maxlen = sizeof(addr);
#ifdef IGNORE_OPTIONS
	errBlock.opt.len = 0;
	errBlock.opt.maxlen = 0;
	errBlock.opt.buf = 0;
#else
	errBlock.opt.len = 0;
	errBlock.opt.maxlen = OPTIONS_LENGTH;
	errBlock.opt.buf = RoomForStupidOptions;
#endif
		
	err = OTRcvUDErr(ep, &errBlock);
	post("OTUDP: %s  \"protocol-dependent\" error code %ld", source, errBlock.error);
	{
		char hostNameString[255];
		OTInetHostToString(addr.fHost, hostNameString);
		post(" Addr. assoc w/ error is %s, port %d.", hostNameString, addr.fPort);
	}

	if (errBlock.error == 49) {
		post("Error 49 seems to mean that you're sending to a machine that's listening to");
		post("UDP but not on the port you're sending to.");
	}


	if (err == kOTNoError ) {
		// No further error; don't worry about it
	} else if (err == kOTLookErr) {
		OTResult r = OTLook(ep);
		post("Got kOTLookErr; OTLook returned %d", r);
	} else if (err == kOTFlowErr) {
		post("Flow control error.");
	} else if (err == kOTBufferOverflowErr) {
	    post("Lame Open Transport says it doesn't have enough memory0 to tell me what my problem is.");
	} else {	
		post("OTRcvUDErr returned %ld", err);
	}
}
Example #6
0
pascal void OTUDPNotifier(void* vobj, OTEventCode code, OTResult result, void* cookie) {
	OTUDP *x = (OTUDP *) vobj;
/*	long oldA5; */
	
	// Maybe want to call OTEnterNotifier here...
	
/*	oldA5 = SetA5(x->o_a5); */

	numTimesNotifierCalled++;
	
	if (gHandlingSomethingAlready) {
		numTimesGaveUpForReentrancy++;
		goto done;
	}
	gHandlingSomethingAlready = 1;
	
#ifdef DEBUG
	post("*** OTUDPNotifier(code %ld, result %ld)", (long) code, (long) result);
#endif
	
	if (code == T_OPENCOMPLETE) {
		if (result != noErr) {
			error("OTUDPNotifier got a T_OPENCOMPLETE code with error %ld", result);
		}
		
		// Even if we got an error, we'll bind the endpoint.  
		x->o_udp_ep = (EndpointRef) cookie;
		BindTheEndpoint(x);
		// This is asynchronous; now we expect the notifier to be called with 
		// a T_BINDCOMPLETE message.

	} else if (code == T_BINDCOMPLETE) {
		// See what address we actually got
		
		if (x->o_writer) {
			// We let OT pick an address for us, so look up the port just in case
			// we ever care to know what our return address port number is
			x->o_receiveInetPort = x->o_addrWeActuallyGot.fPort;
		} else {
			// We asked OT for a particular port, but didn't necessarily get it
			if (x->o_receiveInetPort != x->o_addrWeActuallyGot.fPort) {
				error("¥ otudp: Tried to bind to port %ld, but got %ld instead!!",
						   x->o_receiveInetPort, x->o_addrWeActuallyGot.fPort);
				x->o_receiveInetPort = x->o_addrWeActuallyGot.fPort;
			} else {
#ifdef DEBUG
				post("*** successfully bound to port %ld", (long) x->o_addrWeActuallyGot.fPort);
#endif
			}
		}
		
		// Now the endpoint has been bound, so we're ready to go
		x->o_ready = 1;
	} else if (code == T_UNBINDCOMPLETE) {
		// Only otudp_changeHost and otudp_changeReceivePort unbind the port, so now 
		// it's time to rebind with the new host info
		BindTheEndpoint(x);		
	} else if (code == T_DATA) {
		otudp_read(x);
	} else if (code == T_UDERR) {
		if (x->o_errorreporting) {
			PostUDERR("OTUDPNotifier was called for a T_UDERR code", x->o_udp_ep);
		} else {
			/* We still have to receive the error to clear the condition */
			OTRcvUDErr(x->o_udp_ep, 0);
		}		
	} else {
	 	if (x->o_errorreporting) {
			error("OTUDP: Unrecognized OTEventCode %ld in event handler.  Oh well.", (long) code);
		}
	}

done:
	gHandlingSomethingAlready = 0;
	/* SetA5(oldA5); */
}
Example #7
0
pascal void OTTCPNotifier(void* vobj, OTEventCode code, OTResult result, void* cookie) {
	OTTCP *x = (OTTCP *) vobj;
	long oldA5;
	OSStatus s;
		
	EnterCallback();
	oldA5 = SetA5(x->o_a5);

	post("*** OTTCPNotifier(code %x, result %ld)", (long) code, (long) result);
	
	if (code == T_OPENCOMPLETE) {
		if (result != noErr) {
			post("OTTCPNotifier got a T_OPENCOMPLETE code with error %ld", result);
		}

		// Even if we got an error, we'll use the endpoint.  
		x->o_tcp_ep = (EndpointRef) cookie;
		
		if (x->o_inetHostName != 0) {
			BindTheEndpoint(x);
			// Now we expect a T_BINDCOMPLETE message.
		}
		
	} else if (code == T_BINDCOMPLETE) {
		TCall sndCall;
		InetAddress inAddr;
		
		// See what ephemeral port number OT gave us
		x->o_receiveInetPort = x->o_addrWeActuallyGot.fPort;
		
		// Now the endpoint has been bound; next trick is connecting
		OTInitInetAddress(&inAddr, x->o_inetPort, x->o_inetHost);
		OTMemzero(&sndCall, sizeof(TCall));
		sndCall.addr.buf = (void *) &inAddr;
		sndCall.addr.len = sizeof(InetAddress);

		post("** About to OTConnect");
		s = OTConnect(x->o_tcp_ep, &sndCall, NULL);
		if (s == kOTNoDataErr) {
			// No problem; that means connection is in progress
			post("** OTConnect returned kOTNoDataErr - good");
		} else {
			post("е OTTCP: error: OTConnect returned %ld; not connecting.", s);
		}
		// Now we expect T_CONNECT
		
	} else if (code == T_CONNECT) {
		if (result == kOTBadAddressErr) {
			post("е OTTCP: error: bad address.  Disconnecting");
			x->o_inetHost = 0;
			change_connection(x);
		} else {
			post("** Got T_CONNECT");
			post("** Result passed to notifier: %ld", (long) result);
			post("** Endpoint state before OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep));
			// We could pass in buffers to find out the actual address we connected to, etc.
			s = OTRcvConnect(x->o_tcp_ep, nil);
			if (s != kOTNoError) {
				post("е OTTCP: error: RcvConnect returned %ld", s);
			}
			post("** Endpoint state after OTRcvConnect: %ld", (long) OTGetEndpointState(x->o_tcp_ep));
			ChangeState(x, NO_REQUEST);
			x->o_connectionSymbol = ps_connected;
			clock_delay(x->o_connectedclock, 0);
		}
	} else if (code == T_UNBINDCOMPLETE) {
		// If we have a new inetHost, try to bind it
		if (x->o_inetHost != 0) {
			BindTheEndpoint(x);
			// Now we expect T_BINDCOMPLETE
		} else {
			// No inetHost, so we're disonnected
			x->o_connectionSymbol = ps_disconnected;
			clock_delay(x->o_connectedclock, 0);
		}
	} else if (code == T_DISCONNECTCOMPLETE) {
		// We always want to rebind when we reconnect, so after disconnecting we unbind
		s = OTUnbind(x->o_tcp_ep);
		if (s != kOTNoError) {
			post("OTTCP: warning: OTUnbind returned %ld", s);
		}		
	} else if (code == T_DATA) {
		ottcp_handleIncomingData(x);
	} else if (code == T_UDERR) {
		if (x->o_errorreporting) {
			PostUDERR("OTTCPNotifier was called for a T_UDERR code", x->o_tcp_ep);
		} else {
			/* We still have to receive the error to clear the condition */
			OTRcvUDErr(x->o_tcp_ep, 0);
		}
	} else if (code == T_GODATA) {
		// Flow control restriction has lifted; now it's OK to send more data.
		do_write(x, 0, 0);
	} else if (code == T_DISCONNECT) {
		// The other dude wants to disconnect
		post("OTTCP: peer wants to disconnect");
		s = OTRcvDisconnect(x->o_tcp_ep, NULL);
		if (s == kOTNoError) {
			x->o_inetHost = 0;
			change_connection(x);
		} else if (s == kOTNoDisconnectErr) {
			// false alarm
		} else {
			post("е OTTCP: error: OTRcvDisconnect returned %ld", s);
		}
	} else if (code == T_ORDREL) {
		post("*** Got T_ORDREL");
		s = OTRcvOrderlyDisconnect(x->o_tcp_ep);
		if (s == kOTNoReleaseErr) {
			post("...false alarm!");
		} else if (s == kOTNoError) {
			x->o_inetHost = 0;
			change_connection(x);
		} else {
			post("е OTTCP: error: OTRcvOrderlyDisconnect returned %ld", s);
		}
	} else {
	 	if (x->o_errorreporting) {
			post("OTTCP: Unrecognized OTEventCode %ld in event handler.  Oh well.", (long) code);
		}
	}

done:
	SetA5(oldA5);
	ExitCallback();
}