/******************************************************************************* ** ** Dummy Ethernet Code for RPC ** ** This code is part of the RPC system from CERN DD/OC and collaborators. ** ** ** FUNCTION: ** ** This is the machine-dependent part of the code to allow the system to ** communicate over ethernet. This version is for test only. ** ** HISTORY: ** ** Sep 89 Written ** */ #include #define TS /* We want TS_layer visibility */ #define TS_INTERNALS /* and internal data structures */ #include "syspec.h" #include "rpcrts.h" /* RPC structures including TS layer */ #include "rpc_code.h" /*Coding conventions and trace */ /* Module Variables */ int eth_usage; /* Count of current usage of ethernet */ /* Procedure: Initialise the ethernet i/o ** --------- --------------------------- ** ** This routine is called once only for this process, to initialise ** any process-wide things. ** ** On exit, ** return gives the return status */ PUBLIC rpc_status rpc_eth_init() { eth_usage = 0; CTRACE(tfp, "rpc_eth_init() called.\n"); return RPC_S_NORMAL; } /* Procedure: Initialise the ethernet i/o for one channel ** --------- ------------------------------------------- ** ** On entry, ** psocket points to a socket descriptor which has been set up ** with the correct ethernet addreess, type fields and masks. ** On exit, ** return gives the return status */ PUBLIC rpc_status rpc_eth_open(psocket) socket_type psocket; { register socket_type soc = psocket; int eth_status; CTRACE(tfp, "rpc_th_open(%lx)\n", (long int)psocket); dump_socket(psocket); return RPC_S_NORMAL; } /* ** Procedure: DeInitialise the ethernet i/o for one channel ** --------- --------------------------------------------- ** ** This procedure in fact checks whether the very last open is being done, ** in which case it performs any global deinitialisation which may be required. ** ** On entry, ** psocket points to a socket descriptor. ** On exit, ** return gives the return status */ PUBLIC rpc_eth_close(soc) socket_type soc; { eth_usage = eth_usage - 1; CTRACE(tfp, "rpc_eth_close(%lx)\n", (long int)soc); return RPC_S_NORMAL; } /* Procedure: Send ethernet packet ** --------- -------------------- ** ** On entry, ** socket points to an initialised socket. ** ** buffer points to a packet. The destination field and protocol type ** in the packet header are correct. ** m_socket is valid ** m_index is the number of bytes (excluding the header) ** The source address is not yet filled in. ** bufsize gives the number of bytes to be transmitted, EXCLUDING the ** ethernet header. ** On exit, ** return Gives the status: if good, the packet has been sent. ** */ PUBLIC rpc_status rpc_eth_send(mes) rpc_message_pointer mes; { int bufsize = (int)mes->m_index; register socket_type soc = mes->m_socket; CTRACE(tfp, "rpc_eth_send(%lx)\n", (long int)mes); dump_message(mes); return RPC_S_NORMAL; } /* Wait for ethernet message rpc_eth_receive() ** ------------------------- ** ** This procedure receives one ethernet message on the given socket. ** The packets are filtered by source address and protocol type according ** to the way the socket has been set up (wildcard or not). ** ** On entry, ** ** ppmessage points to a pointer to a suitable message buffer with ** the following fields set up: ** ** m_socket Pointer to socket descriptor ** ** timeout may be -1 for infinite timeout, or 0 for poll. ** else units of microseconds. ** ** On return, ** ** return returns error code or normal or timeout. ** *pmessage may have been changed, ie the message swapped for another. ** **pmessage has the header and data fields both filled in. ** m_index gives the number of data bytes in the message. */ PUBLIC rpc_status rpc_eth_receive(ppmessage, timeout) rpc_message_pointer *ppmessage; int timeout; { register rpc_message *mes = *ppmessage; register socket_type soc = mes->m_socket; CTRACE(tfp, "rpc_eth_receive(%lx->%lx, %x)\n", (long int)ppmessage, (long int)*ppmessage, timeout); dump_message(mes); #ifdef ZAPPED return (RPC_S_TIMEOUT); /* Simulate no response */ #else (*ppmessage)->body.rpc_b[1] = 2; /* Cheat a "reply" type */ return (RPC_S_NORMAL); /* Simulate the same message back */ #endif } /* Return the ethernet address of this host rpc_eth_my_address() ** ---------------------------------------- ** ** On entry, ** host points to a 6-byte buffer ** ** On exit, ** *host is filled in with the address in binary of the local ** ethernet adapter if good status. ** ** returns status if bad means *host is undefined but may be corrupted. */ #ifdef __STDC__ rpc_status rpc_eth_my_address( /* Return host address */ rpc_ethernet_address host) /* Buffer for host address */ #else rpc_status rpc_eth_my_address(host) /* Return host address */ rpc_ethernet_address host; /* Buffer for host address */ #endif { rpc_byte i; for (i=0; i<6; i++) host[i] = (i*34)+18; /* 123456789ABC */ return RPC_S_NORMAL; } #ifdef AST /* Set up handler for next message to arrive rpc_eth_when_receive() ** ----------------------------------------- ** ** (Only if ASTs supported) ** ** On entry, ** pmessage points to an available message buffer, fields as follows: ** m_index maximum length to be read ** m_status (undefined) ** m_next (undefined) ** m_socket points to valid socket descriptor, includes fields ** soc_user_ast address of AST completion routine */ PUBLIC rpc_status eth_when_receive(pmessage) rpc_message_pointer pmessage; { register struct socket_struct *soc = pmessage->m_socket; CTRACE(tfp, "rpc_eth_when_receive(%lx)\n", (long int)pmessage); return RPC_S_NORMAL; } #endif /* AST */