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; } }
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); }
// 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); } }
// 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(); }
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); } }
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); */ }
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(); }