/* ********************************************************************************************************* * uC/TCP-IP * The Embedded TCP/IP Suite * * (c) Copyright 2003-2007; Micrium, Inc.; Weston, FL * * All rights reserved. Protected by international copyright laws. * * uC/TCP-IP is provided in source form for FREE evaluation, for educational * use or peaceful research. If you plan on using uC/TCP-IP in a commercial * product you need to contact Micrium to properly license its use in your * product. We provide ALL the source code for your convenience and to help * you experience uC/TCP-IP. The fact that the source code is provided does * NOT mean that you can use it without paying a licensing fee. * * Knowledge of the source code may NOT be used to develop a similar product. * * Please help us continue to provide the Embedded community with the finest * software available. Your honesty is greatly appreciated. ********************************************************************************************************* */ /* ********************************************************************************************************* * * NETWORK SOCKET LAYER * * Filename : net_sock.c * Version : V1.89 * Programmer(s) : ITJ ********************************************************************************************************* * Note(s) : (1) Supports BSD 4.x Socket Layer with the following restrictions/constraints : * * (a) ONLY supports a single address family from the following families : * (1) IPv4 (AF_INET) * * (b) ONLY supports the following socket types : * (1) Datagram (SOCK_DGRAM) * (2) Stream (SOCK_STREAM) * * (c) ONLY supports a single protocol family from the following families : * (1) IPv4 (PF_INET) * (A) ONLY supports the following protocols : * (1) UDP (IPPROTO_UDP) * (2) TCP (IPPROTO_TCP) * * (d) ONLY supports the following socket options : * (1) Global options * #### ( ) * (2) Socket options * #### ( ) * ********************************************************************************************************* * Notice(s) : (1) The Institute of Electrical and Electronics Engineers and The Open Group, have given * us permission to reprint portions of their documentation. Portions of this text are * reprinted and reproduced in electronic form from the IEEE Std 1003.1, 2004 Edition, * Standard for Information Technology -- Portable Operating System Interface (POSIX), * The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute * of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any * discrepancy between these versions and the original IEEE and The Open Group Standard, * the original IEEE and The Open Group Standard is the referee document. The original * Standard can be obtained online at http://www.opengroup.org/unix/online.html. ********************************************************************************************************* */ /* ********************************************************************************************************* * INCLUDE FILES ********************************************************************************************************* */ #define NET_SOCK_MODULE #include /* ********************************************************************************************************* * MODULE * * Note(s) : (1) See 'net_sock.h MODULE'. ********************************************************************************************************* */ #ifdef NET_SOCK_MODULE_PRESENT /*$PAGE*/ /* ********************************************************************************************************* * LOCAL DEFINES ********************************************************************************************************* */ /* ********************************************************************************************************* * LOCAL CONSTANTS ********************************************************************************************************* */ /* ********************************************************************************************************* * LOCAL DATA TYPES ********************************************************************************************************* */ /* ********************************************************************************************************* * LOCAL TABLES ********************************************************************************************************* */ /* ********************************************************************************************************* * LOCAL GLOBAL VARIABLES ********************************************************************************************************* */ /*$PAGE*/ /* ********************************************************************************************************* * LOCAL FUNCTION PROTOTYPES ********************************************************************************************************* */ /* ----------- RX FNCTS ----------- */ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) static void NetSock_RxPktValidateBuf (NET_BUF_HDR *pbuf_hdr, NET_ERR *perr); #endif static void NetSock_RxPktDemux (NET_BUF *pbuf, NET_BUF_HDR *pbuf_hdr, NET_ERR *perr); static void NetSock_RxPktDiscard (NET_BUF *pbuf, NET_ERR *perr); /* ------ SOCK STATUS FNCTS ------- */ #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) static CPU_BOOLEAN NetSock_IsValidAddrLocal (NET_SOCK_ADDR *paddr, NET_SOCK_ADDR_LEN addr_len, NET_ERR *perr); static CPU_BOOLEAN NetSock_IsValidAddrRemote (NET_SOCK_ADDR *paddr, NET_SOCK_ADDR_LEN addr_len, NET_SOCK *psock, NET_ERR *perr); #endif /* ------ SOCK HANDLER FNCTS ------ */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_SOCK_RTN_CODE NetSock_CloseHandlerStream (NET_SOCK_ID sock_id, NET_SOCK *psock, NET_ERR *perr); #endif static NET_SOCK_RTN_CODE NetSock_BindHandler (NET_SOCK_ID sock_id, NET_SOCK_ADDR *paddr_local, NET_SOCK_ADDR_LEN addr_len, CPU_BOOLEAN addr_random_reqd, NET_ERR *perr); static NET_SOCK_RTN_CODE NetSock_ConnHandlerDatagram (NET_SOCK_ID sock_id, NET_SOCK *psock, NET_SOCK_ADDR *paddr_remote, NET_ERR *perr); #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_SOCK_RTN_CODE NetSock_ConnHandlerStream (NET_SOCK_ID sock_id, NET_SOCK *psock, NET_SOCK_ADDR *paddr_remote, NET_ERR *perr); #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) static void NetSock_ConnHandlerAddrRemoteValidate(NET_SOCK *psock, NET_SOCK_ADDR *paddr_remote, NET_ERR *perr); #endif static void NetSock_ConnHandlerAddrRemoteSet (NET_SOCK *psock, NET_SOCK_ADDR *paddr_remote, CPU_BOOLEAN addr_over_wr, NET_ERR *perr); /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static void NetSock_ConnAcceptQ_Init (NET_SOCK *psock, NET_SOCK_Q_SIZE sock_q_size); static void NetSock_ConnAcceptQ_Clr (NET_SOCK *psock); static CPU_BOOLEAN NetSock_ConnAcceptQ_IsAvail (NET_SOCK *psock, NET_ERR *perr); static void NetSock_ConnAcceptQ_ConnID_Add (NET_SOCK *psock, NET_CONN_ID conn_id, NET_ERR *perr); static NET_CONN_ID NetSock_ConnAcceptQ_ConnID_Get (NET_SOCK *psock, NET_ERR *perr); static CPU_BOOLEAN NetSock_ConnAcceptQ_ConnID_Srch (NET_SOCK *psock, NET_CONN_ID conn_id, NET_SOCK_Q_SIZE *pconn_ix, NET_SOCK_Q_SIZE *pconn_nbr); static CPU_BOOLEAN NetSock_ConnAcceptQ_ConnID_Remove (NET_SOCK *psock, NET_CONN_ID conn_id); #endif static NET_SOCK_RTN_CODE NetSock_RxDataHandler (NET_SOCK_ID sock_id, void *pdata_buf, CPU_INT16S data_buf_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN *paddr_len, void *pip_opts_buf, CPU_INT08U ip_opts_buf_len, CPU_INT08U *pip_opts_len, NET_ERR *perr); static NET_SOCK_RTN_CODE NetSock_RxDataHandlerDatagram (NET_SOCK_ID sock_id, NET_SOCK *psock, void *pdata_buf, CPU_INT16S data_buf_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN *paddr_len, void *pip_opts_buf, CPU_INT08U ip_opts_buf_len, CPU_INT08U *pip_opts_len, NET_ERR *perr); #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_SOCK_RTN_CODE NetSock_RxDataHandlerStream (NET_SOCK_ID sock_id, NET_SOCK *psock, void *pdata_buf, CPU_INT16S data_buf_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN *paddr_len, NET_ERR *perr); #endif static NET_SOCK_RTN_CODE NetSock_TxDataHandler (NET_SOCK_ID sock_id, void *p_data, CPU_INT16S data_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN addr_len, NET_ERR *perr); static NET_SOCK_RTN_CODE NetSock_TxDataHandlerDatagram (NET_SOCK_ID sock_id, NET_SOCK *psock, void *p_data, CPU_INT16S data_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_ERR *perr); #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_SOCK_RTN_CODE NetSock_TxDataHandlerStream (NET_SOCK_ID sock_id, NET_SOCK *psock, void *p_data, CPU_INT16S data_len, CPU_INT16S flags, NET_ERR *perr); #endif /*$PAGE*/ /* ---------- SOCK FNCTS ---------- */ static NET_SOCK *NetSock_Get (NET_ERR *perr); #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_CONN_ID NetSock_GetConnTransport (NET_SOCK *psock, NET_ERR *perr); #endif static void NetSock_CloseHandler (NET_SOCK *psock, CPU_BOOLEAN close_conn, CPU_BOOLEAN close_conn_transport); static void NetSock_CloseSock (NET_SOCK *psock, CPU_BOOLEAN close_conn, CPU_BOOLEAN close_conn_transport); static void NetSock_CloseSockHandler (NET_SOCK *psock, CPU_BOOLEAN close_conn, CPU_BOOLEAN close_conn_transport, NET_ERR *perr); static void NetSock_CloseSockFromClose (NET_SOCK *psock); static void NetSock_CloseConn (NET_CONN_ID conn_id); static void NetSock_CloseConnFree (NET_CONN_ID conn_id); static void NetSock_Free (NET_SOCK *psock); static void NetSock_FreeHandler (NET_SOCK *psock, NET_ERR *perr); static void NetSock_FreeAddr (NET_SOCK *psock); static void NetSock_FreeBufQ (NET_BUF **pbuf_q_head, NET_BUF **pbuf_q_tail); static void NetSock_Clr (NET_SOCK *psock); #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static void NetSock_Copy (NET_SOCK *psock_dest, NET_SOCK *psock_src); #endif static void NetSock_Discard (NET_SOCK *psock); /* ----- RANDOM PORT Q FNCTS ------ */ static NET_PORT_NBR NetSock_RandomPortNbrGet (NET_ERR *perr); static void NetSock_RandomPortNbrFree (NET_PORT_NBR port_nbr, NET_ERR *perr); static CPU_BOOLEAN NetSock_RandomPortNbrChkRange (NET_PORT_NBR port_nbr); #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) static CPU_BOOLEAN NetSock_RandomPortNbrSrch (NET_PORT_NBR port_nbr); #endif /* ********************************************************************************************************* * LOCAL CONFIGURATION ERRORS ********************************************************************************************************* */ /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Init() * * Description : (1) Initialize Network Socket Layer : * * (a) Perform Socket/OS initialization * (b) Initialize socket pool * (c) Initialize socket table * (d) Initialize random port number queue * (e) Initialize socket statistics & error counters * * * Argument(s) : perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket layer successfully initialized. * * ----- RETURNED BY NetOS_Sock_Init() : ----- * NET_OS_ERR_INIT_SOCK_RX_Q Socket receive queue(s) * NOT successfully initialized. * NET_OS_ERR_INIT_SOCK_RX_Q_TIMEOUT Socket receive queue timeout(s) * NOT successfully configured. * NET_OS_ERR_INIT_SOCK_CONN Socket connection request signal(s) * NOT successfully initialized. * NET_OS_ERR_INIT_SOCK_CONN_TIMEOUT Socket connection request signal timeout(s) * NOT successfully configured. * NET_OS_ERR_INIT_SOCK_ACCEPT Socket connection accept signal(s) * NOT successfully initialized. * NET_OS_ERR_INIT_SOCK_ACCEPT_TIMEOUT Socket connection accept signal timeout(s) * NOT successfully configured. * NET_OS_ERR_INIT_SOCK_CLOSE Socket connection close signal(s) * NOT successfully initialized. * NET_OS_ERR_INIT_SOCK_CLOSE_TIMEOUT Socket connection close signal timeout(s) * NOT successfully configured. * * Return(s) : none. * * Caller(s) : Net_Init(). * * This function is an INTERNAL network protocol suite function & MUST NOT be called by * application function(s). * * Note(s) : (2) Socket pool MUST be initialized PRIOR to initializing the pool with pointers to sockets. ********************************************************************************************************* */ /*$PAGE*/ void NetSock_Init (NET_ERR *perr) { NET_SOCK *psock; NET_PORT_NBR *pport_nbr_q; NET_PORT_NBR port_nbr_q_nbr; NET_SOCK_QTY i; NET_PORT_NBR_QTY j; NET_ERR stat_err; /* --------------- PERFORM SOCK/OS INIT --------------- */ NetOS_Sock_Init(perr); /* Create sock obj(s). */ if (*perr != NET_OS_ERR_NONE) { return; } /* --------------- INIT SOCK POOL/STATS --------------- */ NetSock_PoolPtr = (NET_SOCK *)0; /* Init-clr sock pool (see Note #2). */ NetStat_PoolInit((NET_STAT_POOL *)&NetSock_PoolStat, (NET_STAT_POOL_QTY) NET_SOCK_CFG_NBR_SOCK, (NET_ERR *)&stat_err); /* ------------------ INIT SOCK TBL ------------------- */ psock = &NetSock_Tbl[0]; for (i = 0; i < NET_SOCK_CFG_NBR_SOCK; i++) { psock->Type = NET_SOCK_TYPE_SOCK; /* Init each sock type/id--NEVER modify. */ psock->ID = (NET_SOCK_ID)i; psock->State = NET_SOCK_STATE_FREE; /* Init each sock as free/NOT used. */ psock->Flags = NET_SOCK_FLAG_NONE; #if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED) NetSock_Clr(psock); #endif psock->NextSockPtr = (void *)NetSock_PoolPtr; /* Free each sock to sock pool (see Note #2). */ NetSock_PoolPtr = psock; psock++; } /* -------------- INIT RANDOM PORT NBR Q -------------- */ pport_nbr_q = &NetSock_RandomPortNbrQ[0]; port_nbr_q_nbr = NET_SOCK_CFG_PORT_NBR_RANDOM_BASE; for (j = 0; j < NET_SOCK_PORT_NBR_RANDOM_NBR; j++) { *pport_nbr_q = port_nbr_q_nbr; port_nbr_q_nbr++; pport_nbr_q++; } NetSock_RandomPortNbrQ_HeadIx = 0; NetSock_RandomPortNbrQ_TailIx = 0; NetSock_RandomPortNbrQ_NbrUsed = 0; /*$PAGE*/ /* ------------ INIT SOCK STAT & ERR CTRS ------------- */ #if (NET_CTR_CFG_STAT_EN == DEF_ENABLED) NetSock_StatRxPktCtr = 0; NetSock_StatRxPktProcessedCtr = 0; #endif #if (NET_CTR_CFG_ERR_EN == DEF_ENABLED) NetSock_ErrNullPtrCtr = 0; NetSock_ErrNullSizeCtr = 0; NetSock_ErrNoneAvailCtr = 0; NetSock_ErrNotUsedCtr = 0; NetSock_ErrCloseCtr = 0; NetSock_ErrInvalidFamilyCtr = 0; NetSock_ErrInvalidProtocolCtr = 0; NetSock_ErrInvalidSockTypeCtr = 0; NetSock_ErrInvalidSockCtr = 0; NetSock_ErrInvalidFlagsCtr = 0; NetSock_ErrInvalidOpCtr = 0; NetSock_ErrInvalidStateCtr = 0; NetSock_ErrInvalidAddrCtr = 0; NetSock_ErrInvalidAddrLenCtr = 0; NetSock_ErrInvalidAddrInUseCtr = 0; NetSock_ErrInvalidPortNbrCtr = 0; NetSock_ErrInvalidConnInUseCtr = 0; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) NetSock_ErrConnAcceptQ_NoneAvailCtr = 0; #endif NetSock_ErrRandomPortNbrNoneAvailCtr = 0; NetSock_ErrRxDestCtr = 0; NetSock_ErrRxPktDiscardedCtr = 0; #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) NetSock_ErrTxInvalidSizeCtr = 0; #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) NetSock_ErrInvalidTypeCtr = 0; NetSock_ErrInvalidConnCtr = 0; NetSock_ErrRxInvalidBufIxCtr = 0; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) NetSock_ErrConnAcceptQ_MaxCtr = 0; #endif NetSock_ErrRandomPortNbrQ_UsedCtr = 0; NetSock_ErrRandomPortNbrQ_NbrInQ_Ctr = 0; #endif #endif *perr = NET_SOCK_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Rx() * * Description : (1) Process received socket data & forward to application : * * (a) Demultiplex data to connection * (b) Update receive statistics * * * Argument(s) : pbuf Pointer to network buffer that received socket data. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket data successfully received & processed. * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * * ----- RETURNED BY NetSock_RxPktDemux() : ----- * NET_ERR_RX_DEST Invalid destination; no socket connection * available for received packet. * * ---- RETURNED BY NetSock_RxPktDiscard() : ---- * NET_ERR_RX Receive error; packet discarded. * * Return(s) : none. * * Caller(s) : NetUDP_RxPktDemuxDatagram(). * * This function is an INTERNAL network protocol suite function & MUST NOT be called by * application function(s). * * Note(s) : (2) NetSock_Rx() blocked until network initialization completes. * * (3) Since RFC #792, Section 'Destination Unreachable Message : Description' states * that "if, in the destination host, the IP module cannot deliver the datagram * because the indicated ... process port is not active, the destination host may * send a destination unreachable message to the source host"; the network buffer * MUST NOT be freed by the socket layer but must be returned to the transport or * internet layer(s) to send an appropriate ICMP error message. * * See also 'net_udp.c NetUDP_Rx() Note #5'. * * (4) Network buffer freed by lower layer (see Note #3); only increment error counter. ********************************************************************************************************* */ /*$PAGE*/ void NetSock_Rx (NET_BUF *pbuf, NET_ERR *perr) { #if (((NET_CTR_CFG_ERR_EN == DEF_ENABLED) || \ (NET_CTR_CFG_STAT_EN == DEF_ENABLED)) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_BUF_HDR *pbuf_hdr; #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit rx (see Note #2). */ *perr = NET_ERR_INIT_INCOMPLETE; return; } #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------------- VALIDATE PTR ------------------- */ if (pbuf == (NET_BUF *)0) { NetSock_RxPktDiscard(pbuf, perr); NET_CTR_ERR_INC(NetSock_ErrNullPtrCtr); return; } #endif NET_CTR_STAT_INC(NetSock_StatRxPktCtr); /* ---------------- VALIDATE SOCK PKT ----------------- */ pbuf_hdr = &pbuf->Hdr; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) NetSock_RxPktValidateBuf(pbuf_hdr, perr); /* Validate rx'd buf. */ switch (*perr) { case NET_SOCK_ERR_NONE: break; case NET_ERR_INVALID_PROTOCOL: case NET_BUF_ERR_INVALID_IX: default: NetSock_RxPktDiscard(pbuf, perr); return; /* Prevent 'break NOT reachable' compiler warning. */ } #endif /* --------- DEMUX SOCK PKT / UPDATE RX STATS --------- */ NetSock_RxPktDemux(pbuf, pbuf_hdr, perr); switch (*perr) { case NET_SOCK_ERR_NONE: NET_CTR_STAT_INC(NetSock_StatRxPktProcessedCtr); break; case NET_ERR_RX_DEST: /* See Note #3. */ NET_CTR_ERR_INC(NetSock_ErrRxPktDiscardedCtr); /* See Note #4. */ return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_ERR_INIT_INCOMPLETE: case NET_SOCK_ERR_NOT_USED: case NET_SOCK_ERR_CLOSED: case NET_SOCK_ERR_INVALID_SOCK: case NET_SOCK_ERR_INVALID_FAMILY: case NET_SOCK_ERR_INVALID_PROTOCOL: case NET_SOCK_ERR_INVALID_OP: case NET_SOCK_ERR_RX_Q_FULL: case NET_SOCK_ERR_RX_Q_SIGNAL: case NET_CONN_ERR_INVALID_CONN: case NET_CONN_ERR_NOT_USED: case NET_CONN_ERR_CONN_NONE: default: NetSock_RxPktDiscard(pbuf, perr); return; /* Prevent 'break NOT reachable' compiler warning. */ } } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Open() * * Description : (1) Open a socket : * * (a) Acquire network lock * (b) Validate socket arguments : * (1) Socket protocol family See 'net_sock.c Note #1a' * (2) Socket protocol See 'net_sock.c Note #1b' * (3) Socket type See 'net_sock.c Note #1c' * * (c) Get socket from socket pool * (d) Initialize socket * (e) Release network lock * (f) Return socket descriptor/handle identifier * OR * NET_SOCK_BSD_ERR_OPEN & error code, on failure * * * Argument(s) : protocol_family Socket protocol family (see Note #1b1). * * sock_type Socket type (see Note #1b2). * * protocol Socket protocol (see Note #1b3). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully opened. * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * * --- RETURNED BY NetSock_Get() : ---- * NET_SOCK_ERR_NONE_AVAIL NO available sockets to allocate. * * ---- RETURNED BY NetOS_Lock() : ---- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Socket descriptor/handle identifier, if NO errors. * * NET_SOCK_BSD_ERR_OPEN, otherwise. * * Caller(s) : socket(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_Open() blocked until network initialization completes. ********************************************************************************************************* */ NET_SOCK_ID NetSock_Open (CPU_INT16S protocol_family, CPU_INT16S sock_type, CPU_INT16S protocol, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_SOCK_ID sock_id; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (NET_SOCK_BSD_ERR_OPEN); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit (see Note #2). */ NetOS_Unlock(); *perr = NET_ERR_INIT_INCOMPLETE; return (NET_SOCK_BSD_ERR_OPEN); } #endif /*$PAGE*/ /* ---------------- VALIDATE SOCK ARGS ---------------- */ switch (protocol_family) { #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) case NET_SOCK_FAMILY_IP_V4: switch (sock_type) { case NET_SOCK_TYPE_DATAGRAM: switch (protocol) { case NET_SOCK_PROTOCOL_UDP: break; case NET_SOCK_PROTOCOL_DFLT: protocol = NET_SOCK_PROTOCOL_UDP; break; default: NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return (NET_SOCK_BSD_ERR_OPEN); /* Prevent 'break NOT reachable' compiler warning. */ } break; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: switch (protocol) { #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: break; case NET_SOCK_PROTOCOL_DFLT: protocol = NET_SOCK_PROTOCOL_TCP; break; #endif default: NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return (NET_SOCK_BSD_ERR_OPEN); /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_TYPE_NONE: default: NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_SOCK_BSD_ERR_OPEN); /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_FAMILY_NONE: default: NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_SOCK_BSD_ERR_OPEN); /* Prevent 'break NOT reachable' compiler warning. */ } /* --------------------- GET SOCK --------------------- */ psock = NetSock_Get(perr); if (psock == (NET_SOCK *)0) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_OPEN); /* Rtn err from NetSock_Get(). */ } /* -------------------- INIT SOCK --------------------- */ psock->Family = protocol_family; psock->Protocol = protocol; psock->SockType = sock_type; sock_id = psock->ID; /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); *perr = NET_SOCK_ERR_NONE; return (sock_id); /* ------------------- RTN SOCK ID -------------------- */ } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Close() * * Description : (1) Close a socket : * * (a) Acquire network lock * (b) Validate socket * (1) Validate socket used * (2) Validate socket connection state * (c) Close socket * (d) Release network lock * * (2) Once an application closes its socket, NO further operations on the socket are allowed * & the application MUST NOT continue to access the socket. * * #### Continued access to the closed socket by the application layer will likely corrupt * the network socket layer. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to close. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully closed. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * * ------- RETURNED BY NetSock_IsUsed() : ------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * * - RETURNED BY NetSock_CloseHandlerStream() : - * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_CONN_CLOSE_IN_PROGRESS Socket close already in progress. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT Socket connection close NOT signaled by * timeout. * * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * * --------- RETURNED BY NetOS_Lock() : --------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : NET_SOCK_BSD_ERR_NONE, if NO errors (see Note #4). * * NET_SOCK_BSD_ERR_CLOSE, otherwise. * * Caller(s) : close(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (3) NetSock_Close() blocked until network initialization completes. * * See 'NetSock_IsUsed() Note #1'. * * (4) NO BSD socket error is returned for any internal error while closing the socket. * * (5) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ NET_SOCK_RTN_CODE NetSock_Close (NET_SOCK_ID sock_id, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_SOCK_RTN_CODE rtn_code; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (NET_SOCK_BSD_ERR_CLOSE); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_CLOSE); } #endif psock = &NetSock_Tbl[sock_id]; /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_CLOSE); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: /* If CLOSED from init open ... */ case NET_SOCK_STATE_CLOSED_FAULT: /* ... OR internal fault(s), ... */ NetSock_Free(psock); /* ... sock need ONLY be freed. */ NetOS_Unlock(); *perr = NET_SOCK_ERR_CLOSED; /* Rtn net sock err but rtn NO BSD err (see Note #4). */ return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: break; case NET_SOCK_STATE_NONE: default: NetSock_CloseSockFromClose(psock); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_STATE; /* Rtn net sock err but rtn NO BSD err (see Note #4). */ return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* -------------------- CLOSE SOCK -------------------- */ switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: NetSock_CloseHandler(psock, DEF_YES, DEF_YES); rtn_code = NET_SOCK_BSD_ERR_NONE; break; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: rtn_code = NetSock_CloseHandlerStream(sock_id, psock, perr); break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #5. */ NetSock_CloseSockFromClose(psock); NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; /* Rtn net sock err but rtn NO BSD err (see Note #4). */ return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ } /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); *perr = NET_SOCK_ERR_NONE; return (rtn_code); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CloseFromConn() * * Description : Close a socket via a network connection. * * (1) When a network connection closes a socket, the socket : * * (a) (1) Closes NO other network connection(s), * (2) MUST NOT recursively re-close other network connection(s); * * (b) SHOULD clear network connection(s)' handle identifiers. * * See also 'NetSock_CloseSockHandler() Note #2a', * 'net_tcp.c NetTCP_ConnCloseFromConn() Note #1', * & 'net_conn.c NetConn_CloseFromApp() Note #1b'. * * (2) Closes socket but does NOT free the socket since NO mechanism or API exists to close * an application's reference to the socket. * * See also 'NetSock_CloseSock() Note #2b'. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to close. * * Return(s) : none. * * Caller(s) : NetConn_CloseApp(). * * This function is an INTERNAL network protocol suite function & MUST NOT be called by * application function(s). * * Note(s) : none. ********************************************************************************************************* */ /*$PAGE*/ void NetSock_CloseFromConn (NET_SOCK_ID sock_id) { #if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) NET_ERR err; #endif NET_SOCK *psock; /* ------------------ VALIDATE SOCK ------------------- */ if (sock_id == NET_SOCK_ID_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, &err); if (err != NET_SOCK_ERR_NONE) { return; } #endif psock = &NetSock_Tbl[sock_id]; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: default: break; } #endif /* -------------------- CLOSE SOCK -------------------- */ NetSock_CloseSock((NET_SOCK *)psock, (CPU_BOOLEAN)DEF_YES, /* See Note #1b. */ (CPU_BOOLEAN)DEF_NO); /* See Note #1a. */ } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_FreeConnFromSock() * * Description : (1) Free/de-reference network connection from socket : * * (a) Remove connection handle identifier from socket's connection accept queue * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to free network connection. * * conn_id Handle identifier of network connection. * * Return(s) : none. * * Caller(s) : NetSock_CloseConnFree(), * NetConn_CloseApp(). * * This function is an INTERNAL network protocol suite function & MUST NOT be called by * application function(s). * * Note(s) : (2) (a) When a network connection is fully connected/established, it is queued to an * application connection as a cloned network connection until the connection is * accepted & a new application connection is created. * * See also 'net_tcp.c NetTCP_RxPktConnHandlerListen() Note #5a2A1'. * * (b) Therefore, network connections need only be de-referenced from cloned socket * application connections. ********************************************************************************************************* */ /*$PAGE*/ void NetSock_FreeConnFromSock (NET_SOCK_ID sock_id, NET_CONN_ID conn_id) { #if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) NET_ERR err; #endif NET_SOCK *psock; /* ------------------ VALIDATE SOCK ------------------- */ if (sock_id == NET_SOCK_ID_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, &err); if (err != NET_SOCK_ERR_NONE) { return; } #endif psock = &NetSock_Tbl[sock_id]; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: default: break; } #endif /* --------------- FREE/DE-REF CONN ID ---------------- */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) NetSock_ConnAcceptQ_ConnID_Remove(psock, conn_id); #endif (void)&psock; /* Prevent possible compiler warnings. */ (void)&conn_id; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Bind() * * Description : (1) Bind a socket to a local address : * * (a) Acquire network lock * (b) Validate socket used * (c) Bind socket to a local address * (d) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to bind to a local address. * * paddr_local Pointer to socket address structure (see Note #3). * * addr_len Length of socket address structure (in octets). * * perr Pointer to variable that will receive the return error code from this function : * * ----- RETURNED BY NetSock_IsUsed() : ------ * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * --- RETURNED BY NetSock_BindHandler() : --- * NET_SOCK_ERR_NONE Socket successfully bound to local address. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_ADDR Invalid local address. * NET_SOCK_ERR_ADDR_IN_USE Local address already in use. * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_NONE_AVAIL NO available connections to allocate. * NET_CONN_ERR_NOT_USED Network connection(s) NOT currently used. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_INVALID_FAMILY Invalid network connection family. * NET_CONN_ERR_INVALID_TYPE Invalid network connection type. * NET_CONN_ERR_INVALID_LIST_IX Invalid network connection list index. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * ------- RETURNED BY NetOS_Lock() : -------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : NET_SOCK_BSD_ERR_NONE, if NO errors. * * NET_SOCK_BSD_ERR_BIND, otherwise. * * Caller(s) : bind(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_Bind() blocked until network initialization completes. * * See 'NetSock_IsUsed() Note #1'. * * (3) (a) Socket address structure 'Family' member MUST be configured in host-order & MUST * NOT be converted to/from network-order. * * (b) Socket address structure addresses MUST be configured/converted from host-order * to network-order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. ********************************************************************************************************* */ /*$PAGE*/ NET_SOCK_RTN_CODE NetSock_Bind (NET_SOCK_ID sock_id, NET_SOCK_ADDR *paddr_local, NET_SOCK_ADDR_LEN addr_len, NET_ERR *perr) { NET_SOCK_RTN_CODE rtn_code; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (NET_SOCK_BSD_ERR_BIND); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_BIND); } #endif /* -------------------- BIND SOCK --------------------- */ rtn_code = NetSock_BindHandler((NET_SOCK_ID )sock_id, (NET_SOCK_ADDR *)paddr_local, (NET_SOCK_ADDR_LEN)addr_len, (CPU_BOOLEAN )DEF_NO, (NET_ERR *)perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); return (rtn_code); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Conn() * * Description : (1) Connect a socket to a remote host : * * (a) Acquire network lock * (b) Validate socket used * (c) Validate remote host address * (d) Handle socket connection by socket type * (e) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to connect. * * paddr_remote Pointer to socket address structure (see Note #3). * * addr_len Length of socket address structure (in octets). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully connected to remote address. * NET_SOCK_ERR_INVALID_ADDR Invalid remote address. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * * --------- RETURNED BY NetSock_IsUsed() : --------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * -- RETURNED BY NetSock_ConnHandlerDatagram() : --- * --- RETURNED BY NetSock_ConnHandlerStream() : ---- * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address structure length. * NET_SOCK_ERR_ADDR_IN_USE Socket address already in use. * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * NET_SOCK_ERR_CONN_IN_USE Socket connection already in use. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_NONE_AVAIL NO available connections to allocate. * NET_CONN_ERR_NOT_USED Network connection(s) NOT currently used. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_INVALID_FAMILY Invalid network connection family. * NET_CONN_ERR_INVALID_TYPE Invalid network connection type. * NET_CONN_ERR_INVALID_LIST_IX Invalid network connection list index. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * --- RETURNED BY NetSock_ConnHandlerStream() : ---- * NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT Socket connection request NOT signaled by timeout. * * ----------- RETURNED BY NetOS_Lock() : ----------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : NET_SOCK_BSD_ERR_NONE, if NO errors. * * NET_SOCK_BSD_ERR_CONN, otherwise. * * Caller(s) : connect(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_Conn() blocked until network initialization completes. * * See 'NetSock_IsUsed() Note #1'. * * (3) (a) Socket address structure 'Family' member MUST be configured in host-order & MUST * NOT be converted to/from network-order. * * (b) Socket address structure addresses MUST be configured/converted from host-order * to network-order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (4) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ NET_SOCK_RTN_CODE NetSock_Conn (NET_SOCK_ID sock_id, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN addr_len, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) CPU_BOOLEAN valid; #endif NET_SOCK *psock; NET_SOCK_RTN_CODE rtn_code; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (NET_SOCK_BSD_ERR_CONN); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_CONN); } #endif psock = &NetSock_Tbl[sock_id]; #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* --------------- VALIDATE REMOTE ADDR --------------- */ valid = NetSock_IsValidAddrRemote(paddr_remote, addr_len, psock, perr); if (valid != DEF_YES) { NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_ADDR; return (NET_SOCK_BSD_ERR_CONN); } #endif /* -------------------- CONN SOCK --------------------- */ switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: rtn_code = NetSock_ConnHandlerDatagram(sock_id, psock, paddr_remote, perr); break; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: rtn_code = NetSock_ConnHandlerStream(sock_id, psock, paddr_remote, perr); break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #4. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ } /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); return (rtn_code); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnSignalReq() * * Description : Signal socket that connection request complete; socket now connected. * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to signal connection request. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket connection successfully signaled. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * * ------ RETURNED BY NetSock_IsUsed() : ------ * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * * - RETURNED BY NetOS_Sock_ConnReqSignal() : - * NET_SOCK_ERR_CONN_SIGNAL_FAULT Socket connection request signal fault. * * Return(s) : none. * * Caller(s) : NetTCP_RxPktConnHandlerSignalConn(). * * This function is an INTERNAL network protocol suite function & MUST NOT be called by * application function(s). * * Note(s) : (1) See 'NetSock_ConnHandlerStream() Note #2c3'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) void NetSock_ConnSignalReq (NET_SOCK_ID sock_id, NET_ERR *perr) { #if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; CPU_BOOLEAN block; /*$PAGE*/ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { return; } #endif psock = &NetSock_Tbl[sock_id]; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK TYPE ---------------- */ if (psock->SockType != NET_SOCK_TYPE_STREAM) { NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); *perr = NET_SOCK_ERR_INVALID_TYPE; return; } /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: /* See Note #1. */ case NET_SOCK_STATE_CONN_IN_PROGRESS: break; case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_DONE: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return; /* Prevent 'break NOT reachable' compiler warning. */ } #endif /* ----------------- SIGNAL SOCK CONN ----------------- */ #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_BLOCK) block = DEF_YES; #elif (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_NO_BLOCK) block = DEF_NO; #else block = DEF_YES; #endif if (block != DEF_NO) { /* If blocking sock conn, ... */ NetOS_Sock_ConnReqSignal(sock_id, perr); /* ... signal sock conn req. */ if (*perr != NET_SOCK_ERR_NONE) { return; } } else { /* Else update sock state as conn done. */ psock->State = NET_SOCK_STATE_CONN_DONE; } *perr = NET_SOCK_ERR_NONE; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnSignalAccept() * * Description : Signal socket that connection request received; socket accept now available. * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to signal connection accept. * * conn_id Handle identifier of network connection. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket connection successfully signaled. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * * --------- RETURNED BY NetSock_IsUsed() : --------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * * - RETURNED BY NetSock_ConnAcceptQ_ConnID_Add() : - * NET_SOCK_ERR_CONN_ACCEPT_Q_MAX Socket maximum connection accept limit exceeded. * NET_SOCK_ERR_CONN_ACCEPT_Q_DUP Connection handle identifier already in socket * connection accept queue. * * - RETURNED BY NetOS_Sock_ConnAcceptQ_Signal() : -- * NET_SOCK_ERR_CONN_SIGNAL_FAULT Socket connection accept queue signal fault. * * Return(s) : none. * * Caller(s) : NetTCP_RxPktConnHandlerSignalConn(). * * This function is an INTERNAL network protocol suite function & MUST NOT be called by * application function(s). * * Note(s) : (1) On any faults, network connection NOT freed/closed; caller function(s) SHOULD handle * fault condition(s). ********************************************************************************************************* */ /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) void NetSock_ConnSignalAccept (NET_SOCK_ID sock_id, NET_CONN_ID conn_id, NET_ERR *perr) { #if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { return; } #endif psock = &NetSock_Tbl[sock_id]; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK TYPE ---------------- */ if (psock->SockType != NET_SOCK_TYPE_STREAM) { NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); *perr = NET_SOCK_ERR_INVALID_TYPE; return; } /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_LISTEN: break; case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return; /* Prevent 'break NOT reachable' compiler warning. */ } #endif /* --------- QUEUE & SIGNAL SOCK ACCEPT CONN ---------- */ NetSock_ConnAcceptQ_ConnID_Add(psock, conn_id, perr); /* Add conn id to sock accept Q. */ if (*perr != NET_SOCK_ERR_NONE) { return; } NetOS_Sock_ConnAcceptQ_Signal(sock_id, perr); /* Signal sock accept Q. */ if (*perr != NET_SOCK_ERR_NONE) { NetSock_ConnAcceptQ_Clr(psock); return; } *perr = NET_SOCK_ERR_NONE; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnSignalClose() * * Description : Signal socket that connection close complete; socket connection now closed. * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to signal connection close. * * data_avail Indicate whether application data is still available for the socket connection : * * DEF_YES Application data is available for the * closing socket connection. * DEF_NO Application data is NOT available for the * closing socket connection. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket connection successfully signaled. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * * ------- RETURNED BY NetSock_IsUsed() : ------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * * - RETURNED BY NetOS_Sock_ConnCloseSignal() : - * NET_SOCK_ERR_CONN_SIGNAL_FAULT Socket connection close signal fault. * * Return(s) : none. * * Caller(s) : NetTCP_RxPktConnHandlerSignalClose(). * * This function is an INTERNAL network protocol suite function & MUST NOT be called by * application function(s). * * Note(s) : (1) NetSock_ConnSignalClose() blocked until network initialization completes. * * (2) Once a socket connection has been signaled of its close : * * (a) Close socket connection * (b) Close socket connection's reference to network connection * (c) Do NOT close transport connection(s); transport layer responsible for closing its * remaining connection(s) * * See also 'NetSock_CloseHandlerStream() Note #2b'. * * (3) (a) #### Since sockets that have already closed are NOT to be accessed (see 'NetSock_Close() * Note #2'), non-blocking socket close may NOT require close completion. * * (b) #### 'data_avail' may NOT be necessary (remove if unnecessary). * * See Note 'NetSock_Close() Note #2'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) void NetSock_ConnSignalClose (NET_SOCK_ID sock_id, CPU_BOOLEAN data_avail, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif CPU_BOOLEAN block; NET_SOCK *psock; /* ------------------ VALIDATE SOCK ------------------- */ if (sock_id == NET_SOCK_ID_NONE) { *perr = NET_SOCK_ERR_NONE; return; } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { return; } #endif psock = &NetSock_Tbl[sock_id]; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK TYPE ---------------- */ if (psock->SockType != NET_SOCK_TYPE_STREAM) { NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); *perr = NET_SOCK_ERR_INVALID_TYPE; return; } #endif /*$PAGE*/ /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: *perr = NET_SOCK_ERR_NOT_USED; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: break; case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return; /* Prevent 'break NOT reachable' compiler warning. */ } /* ----------------- SIGNAL SOCK CONN ----------------- */ #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_BLOCK) block = DEF_YES; #elif (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_NO_BLOCK) block = DEF_NO; #else block = DEF_YES; #endif if (block != DEF_NO) { /* If blocking sock conn, ... */ if (data_avail != DEF_YES) { psock->State = NET_SOCK_STATE_CLOSED; } else { psock->State = NET_SOCK_STATE_CLOSING_DATA_AVAIL; } NetOS_Sock_ConnCloseSignal(sock_id, perr); /* ... signal sock conn close. */ if (*perr != NET_SOCK_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) } else { /* Else complete sock close (see Note #3a). */ if (data_avail != DEF_YES) { NetSock_CloseHandler((NET_SOCK *)psock, /* See Note #2a. */ (CPU_BOOLEAN)DEF_YES, /* See Note #2b. */ (CPU_BOOLEAN)DEF_NO); /* See Note #2c. */ } else { psock->State = NET_SOCK_STATE_CLOSING_DATA_AVAIL; } #endif } *perr = NET_SOCK_ERR_NONE; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Listen() * * Description : (1) Set socket to listen for connection requests : * * (a) Acquire network lock * (b) Validate socket : * (1) Validate socket used * (2) Validate socket type * (3) Validate socket connection state * (c) Configure transport connection * (d) Update socket connection state * (e) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to listen. * * sock_q_size Maximum number of connection requests to accept & queue on listen socket. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully set to listen. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_CONN_FAIL Socket connection configuration failed. * * ------ RETURNED BY NetSock_IsUsed() : ------ * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * * - RETURNED BY NetSock_GetConnTransport() : - * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * -------- RETURNED BY NetOS_Lock() : -------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : NET_SOCK_BSD_ERR_NONE, if NO errors. * * NET_SOCK_BSD_ERR_LISTEN, otherwise. * * Caller(s) : listen(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_Listen() blocked until network initialization completes. * * See 'NetSock_IsUsed() Note #1'. * * (3) Socket listen operation valid for stream-type sockets only. * * (4) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. * * (5) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. * * (6) On ANY errors after the transport connection is allocated, the transport connection * MUST be freed. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) NET_SOCK_RTN_CODE NetSock_Listen (NET_SOCK_ID sock_id, NET_SOCK_Q_SIZE sock_q_size, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_CONN_ID conn_id_transport; NET_ERR err; /*$PAGE*/ /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (NET_SOCK_BSD_ERR_LISTEN); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_LISTEN); } #endif psock = &NetSock_Tbl[sock_id]; /* ---------------- VALIDATE SOCK TYPE ---------------- */ switch (psock->SockType) { /* Validate sock for stream type(s) [see Note #3]. */ case NET_SOCK_TYPE_DATAGRAM: NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_SOCK_BSD_ERR_LISTEN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_TYPE_STREAM: break; case NET_SOCK_TYPE_NONE: default: /* See Note #4. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_SOCK_BSD_ERR_LISTEN); /* Prevent 'break NOT reachable' compiler warning. */ } /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_LISTEN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_BOUND: break; case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_LISTEN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_OP; return (NET_SOCK_BSD_ERR_LISTEN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_LISTEN); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* ---------------- CFG TRANSPORT CONN ---------------- */ /* Get transport conn. */ conn_id_transport = NetSock_GetConnTransport(psock, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_LISTEN); } /* Cfg transport to LISTEN. */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT NetTCP_ConnSetStateListen((NET_TCP_CONN_ID) conn_id_transport, (NET_ERR *)&err); if (err != NET_TCP_ERR_NONE) { /* If any errs, free transport conn (see Note #6). */ NetTCP_ConnFree((NET_TCP_CONN_ID)conn_id_transport); *perr = NET_SOCK_ERR_CONN_FAIL; } else { *perr = NET_SOCK_ERR_NONE; } #else (void)&conn_id_transport; /* Prevent compiler warnings. */ (void)&err; *perr = NET_SOCK_ERR_CONN_FAIL; #endif #else /* See Note #5. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_SOCK_BSD_ERR_LISTEN); #endif if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_LISTEN); } /* -------------- UPDATE SOCK CONN STATE -------------- */ NetSock_ConnAcceptQ_Init(psock, sock_q_size); /* Init listen sock conn accept Q. */ psock->State = NET_SOCK_STATE_LISTEN; /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); *perr = NET_SOCK_ERR_NONE; return (NET_SOCK_BSD_ERR_NONE); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ListenQ_IsAvail() * * Description : Check if socket's listen queue is available to queue a new connection. * * (1) Socket connection accept queue synonymous with socket listen queue. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to check listen queue. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket listen queue successfully checked; * check return value for socket listen * queue availablity. * * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * * ---- RETURNED BY NetSock_IsUsed() : ----- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * * Return(s) : DEF_YES, if socket listen queue is available to queue a new connection. * * DEF_NO, otherwise. * * Caller(s) : NetTCP_RxPktConnHandlerListenQ_IsAvail(). * * This function is an INTERNAL network protocol suite function & SHOULD NOT be called by * application function(s). * * Note(s) : (2) (a) Stevens, TCP/IP Illustrated, Volume 1, 8th Printing, Section 18.11, Pages 257-258 states * that : * * (1) "Each listening end point has a fixed length queue of connections that have been * accepted [i.e. connected] ... but not yet accepted by the application." * * (2) "The application specifies a limit to this queue, commonly called the backlog" : * * (A) "This backlog must be between 0 and 5, inclusive." * (B) "(Most applications specify the maximum value of 5.)" * * (b) Wright/Stevens, TCP/IP Illustrated, Volume 2, 3rd Printing, Section 15.9, Page 455 * reiterates that : * * (2) A "listen ... socket ... specifies a limit on the number of connections that can * be queued on the socket," ... * * (5) "after which the socket layer refuses to queue additional connection requests." * * See also 'net_tcp.c NetTCP_RxPktConnHandlerListenQ_IsAvail() Note #1'. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) CPU_BOOLEAN NetSock_ListenQ_IsAvail (NET_SOCK_ID sock_id, NET_ERR *perr) { #if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; CPU_BOOLEAN q_avail; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { return (DEF_NO); } #endif psock = &NetSock_Tbl[sock_id]; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK TYPE ---------------- */ if (psock->SockType != NET_SOCK_TYPE_STREAM) { NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); *perr = NET_SOCK_ERR_INVALID_TYPE; return (DEF_NO); } /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_LISTEN: break; case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ } #endif /* ------------- CHK SOCK LISTEN Q AVAIL -------------- */ q_avail = NetSock_ConnAcceptQ_IsAvail(psock, perr); /* Chk if listen Q avail for new conns (see Note #2). */ return (q_avail); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Accept() * * Description : (1) Return a new socket accepted from a listen socket : * * (a) Validate address pointers * (b) Acquire network lock * (c) Validate listen socket : * (1) Validate listen socket used * (2) Validate listen socket type * (3) Validate listen socket connection state * (d) Wait on listen socket's connection accept queue * (e) Configure accept socket : * (1) Get accept socket from socket pool * (2) Copy accept socket from listen socket * (3) Update network connection's application layer handle identifier * as accept socket's handle identifier * (4) Update transport connection, if necessary * (5) Update accept socket connection state * (f) Return accept socket connection's remote address * (g) Release network lock * (h) Return socket descriptor/handle identifier of new accept socket * OR * NET_SOCK_BSD_ERR_ACCEPT & error code, on failure * * * Argument(s) : sock_id Socket descriptor/handle identifier of listen socket. * * paddr_remote Pointer to an address buffer that will receive the socket address structure * of the accepted socket's remote address (see Note #3). * * paddr_len Pointer to a variable to ... : * * (a) Pass the size of the address buffer pointed to by 'paddr_remote'. * (b) (1) Return the actual size of socket address structure with the * accepted socket's remote address, if NO errors; * (2) Return 0, otherwise. * * See also Note #4. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully set to listen. * NET_SOCK_ERR_NULL_PTR Argument 'paddr_remote'/'paddr_len' passed * a NULL pointer. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_CONN_ACCEPT_Q_NONE_AVAIL Accept connection handle identifier * NOT available. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * * ------- RETURNED BY NetSock_IsUsed() : -------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * * --------- RETURNED BY NetSock_Get() : --------- * NET_SOCK_ERR_NONE_AVAIL NO available sockets to allocate. * * - RETURNED BY NetOS_Sock_ConnAcceptQ_Wait() : - * NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT Socket connection accept queue still empty * by timeout. * * --------- RETURNED BY NetOS_Lock() : ---------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Socket descriptor/handle identifier of new accepted socket, if NO errors. * * NET_SOCK_BSD_ERR_ACCEPT, otherwise. * * Caller(s) : accept(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). *$PAGE* * Note(s) : (2) NetSock_Accept() blocked until network initialization completes. * * See 'NetSock_IsUsed() Note #1'. * * (3) (a) Socket address structure 'Family' member returned in host-order & SHOULD NOT be * converted to network-order. * * (b) Socket address structure addresses MUST be converted from host-order to network- * order. * * See also Note #10. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (4) (a) Since 'paddr_len' parameter is both an input & output parameter (see 'Argument(s) : * paddr_len'), ... * * (1) its input value SHOULD be validated prior to use; ... * (2) while its output value MUST be initially configured to return a default error * value in case of any function exit due to error/fault conditions (see also * Note #5). * * (b) In the case that the 'paddr_len' parameter is passed a null pointer, ... * * (1) NO input value is validated or used. * * (5) Pointers to variables that return length or size values MUST be initialized to return * zero PRIOR to all other validation or function handling in case of any error(s). * * (6) Socket accept operation valid for stream-type sockets only. * * (7) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. * * (8) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be compiled/linked * since 'net_sock.h' ensures that the family type configuration constant (NET_SOCK_CFG_FAMILY) * is configured with an appropriate family type value (see 'net_sock.h CONFIGURATION ERRORS'). * The 'else'-conditional code is included for completeness & as an extra precaution in case * 'net_sock.h' is incorrectly modified. * * (9) On ANY errors, network resources MUST be appropriately freed : * * (a) PRIOR to network connection handle identifier dequeued from listen socket's * connection accept queue, only the listen socket need be freed for certain * errors; NO network resources need be freed. * * (b) After network connection handle identifier dequeued from listen socket's * connection accept queue, free network connection. * * (c) After new accept socket allocated, free network connection & new socket. * (1) Socket close handler frees network connection (see 'NetSock_CloseSockHandler() * Note #2'). * * (10) (a) Socket connection addresses are maintained in network-order. * * (b) Since the port number & address are copied from a network-order multi-octet array * into local variables & then into a network-order socket address structure, they do * NOT need to be converted from host-order to network-order. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) NET_SOCK_ID NetSock_Accept (NET_SOCK_ID sock_id, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN *paddr_len, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_SOCK_ADDR_IP *paddr_ip; NET_IP_ADDR remote_addr; #endif NET_PORT_NBR remote_port; CPU_INT08U addr_remote[NET_SOCK_CFG_ADDR_LEN]; NET_SOCK_ADDR_LEN addr_len; NET_SOCK *psock_listen; NET_SOCK *psock_accept; NET_SOCK_ID sock_id_accept; NET_CONN_ID conn_id_accept; CPU_BOOLEAN block; NET_ERR err; /*$PAGE*/ /* ---------------- VALIDATE ADDR PTRS ---------------- */ #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) if (paddr_len == (NET_SOCK_ADDR_LEN *)0) { /* See Note #4b. */ NET_CTR_ERR_INC(NetSock_ErrNullPtrCtr); *perr = NET_SOCK_ERR_NULL_PTR; return (NET_SOCK_BSD_ERR_ACCEPT); } addr_len = *paddr_len; /* Validate initial val (see Note #4a1). */ #endif *paddr_len = 0; /* Init len for err (see Note #4a2). */ #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) if (addr_len < NET_SOCK_ADDR_SIZE) { NET_CTR_ERR_INC(NetSock_ErrInvalidAddrLenCtr); *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return (NET_SOCK_BSD_ERR_ACCEPT); } if (paddr_remote == (NET_SOCK_ADDR *)0) { NET_CTR_ERR_INC(NetSock_ErrNullPtrCtr); *perr = NET_SOCK_ERR_NULL_PTR; return (NET_SOCK_BSD_ERR_ACCEPT); } #endif /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (NET_SOCK_BSD_ERR_ACCEPT); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ------------ VALIDATE LISTEN SOCK USED ------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_ACCEPT); } #endif psock_listen = &NetSock_Tbl[sock_id]; /* ------------ VALIDATE LISTEN SOCK TYPE ------------- */ switch (psock_listen->SockType) { /* Validate sock for stream type(s) [see Note #6]. */ case NET_SOCK_TYPE_DATAGRAM: NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_SOCK_BSD_ERR_ACCEPT); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_TYPE_STREAM: break; case NET_SOCK_TYPE_NONE: default: /* See Note #7. */ NetSock_CloseSock(psock_listen, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_SOCK_BSD_ERR_ACCEPT); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* --------- VALIDATE LISTEN SOCK CONN STATE ---------- */ switch (psock_listen->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_ACCEPT); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_LISTEN: break; case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_ACCEPT); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_OP; return (NET_SOCK_BSD_ERR_ACCEPT); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock_listen, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_ACCEPT); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* ----------- WAIT ON LISTEN SOCK ACCEPT Q ----------- */ #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_BLOCK) block = DEF_YES; #elif (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_NO_BLOCK) block = DEF_NO; #else block = DEF_YES; #endif if (block != DEF_YES) { /* If non-blocking sock rx ... */ if (psock_listen->ConnAcceptQ_SizeCur < 1) { /* ... & no conn req's q'd, ... */ NetOS_Unlock(); *perr = NET_SOCK_ERR_CONN_ACCEPT_Q_NONE_AVAIL; /* ... rtn conn accept Q empty err. */ return (NET_SOCK_BSD_ERR_ACCEPT); } } NetOS_Unlock(); NetOS_Sock_ConnAcceptQ_Wait(sock_id, perr); NetOS_Lock(&err); if ( err != NET_OS_ERR_NONE) { *perr = err; /* Rtn err from NetOS_Lock(). */ return (NET_SOCK_BSD_ERR_ACCEPT); } switch (*perr) { case NET_SOCK_ERR_NONE: break; case NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT: NetOS_Unlock(); /* Rtn err from NetOS_Sock_ConnAcceptQ_Wait(). */ return (NET_SOCK_BSD_ERR_ACCEPT); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_ERR_CONN_SIGNAL_ABORT: case NET_SOCK_ERR_CONN_SIGNAL_FAULT: default: NetOS_Unlock(); *perr = NET_SOCK_ERR_FAULT; return (NET_SOCK_BSD_ERR_ACCEPT); /* Prevent 'break NOT reachable' compiler warning. */ } /* Get conn id from sock conn accept Q. */ conn_id_accept = NetSock_ConnAcceptQ_ConnID_Get(psock_listen, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_ACCEPT); } /* Validate transport conn. */ (void)NetConn_ID_TransportGet(conn_id_accept, &err); if (err != NET_CONN_ERR_NONE) { /* See Note #9c. */ NetOS_Unlock(); *perr = NET_SOCK_ERR_CONN_FAIL; return (NET_SOCK_BSD_ERR_ACCEPT); } /* --------------- CFG NEW ACCEPT SOCK ---------------- */ psock_accept = NetSock_Get(perr); if (psock_accept == (NET_SOCK *)0) { /* See Note #9b. */ NetSock_CloseConn(conn_id_accept); NetOS_Unlock(); return (NET_SOCK_BSD_ERR_ACCEPT); /* Rtn err from NetSock_Get(). */ } /* Copy listen sock into new accept sock. */ NetSock_Copy(psock_accept, psock_listen); /* Set new conn & app id's. */ psock_accept->ID_Conn = conn_id_accept; sock_id_accept = psock_accept->ID; NetConn_ID_AppSet((NET_CONN_ID) conn_id_accept, (NET_CONN_ID) sock_id_accept, (NET_ERR *)&err); if (err != NET_CONN_ERR_NONE) { /* See Note #9c. */ NetSock_CloseHandler(psock_accept, DEF_YES, DEF_YES); NetOS_Unlock(); *perr = NET_SOCK_ERR_CONN_FAIL; return (NET_SOCK_BSD_ERR_ACCEPT); } /* Update accept sock conn state. */ psock_accept->State = NET_SOCK_STATE_CONN; /*$PAGE*/ /* ---------- RTN ACCEPT CONN'S REMOTE ADDR ----------- */ /* Get conn's remote addr. */ addr_len = sizeof(addr_remote); NetConn_AddrRemoteGet((NET_CONN_ID ) conn_id_accept, (CPU_INT08U *)&addr_remote[0], (NET_CONN_ADDR_LEN *)&addr_len, (NET_ERR *)&err); if (err != NET_CONN_ERR_NONE) { /* See Note #9c. */ NetSock_CloseHandler(psock_accept, DEF_YES, DEF_YES); NetOS_Unlock(); *perr = NET_SOCK_ERR_CONN_FAIL; return (NET_SOCK_BSD_ERR_ACCEPT); } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) if (addr_len != NET_SOCK_CFG_ADDR_LEN) { /* See Note #9c. */ NetSock_CloseHandler(psock_accept, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return (NET_SOCK_BSD_ERR_ACCEPT); } #endif /* Cfg & rtn sock conn's remote addr. */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) Mem_Copy((void *)&remote_port, (void *)&addr_remote[NET_SOCK_ADDR_IP_IX_PORT], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&remote_addr, (void *)&addr_remote[NET_SOCK_ADDR_IP_IX_ADDR], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); paddr_ip = (NET_SOCK_ADDR_IP *)paddr_remote; /* Cfg remote addr struct (see Note #3). */ NET_UTIL_VAL_SET_HOST_16(&paddr_ip->Family, NET_SOCK_ADDR_FAMILY_IP_V4); NET_UTIL_VAL_COPY_16(&paddr_ip->Port, &remote_port); /* Copy preserves net-order (see Note #10b). */ NET_UTIL_VAL_COPY_32(&paddr_ip->Addr, &remote_addr); /* Copy preserves net-order (see Note #10b). */ Mem_Clr((void *) &paddr_ip->Unused[0], (CPU_SIZE_T) NET_SOCK_ADDR_IP_NBR_OCTETS_UNUSED); *paddr_len = NET_SOCK_ADDR_IP_SIZE; #else /* See Notes #8 & #9c. */ NetSock_CloseHandler(psock_accept, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_SOCK_BSD_ERR_ACCEPT); #endif /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); *perr = NET_SOCK_ERR_NONE; return (sock_id_accept); /* ----------------- RTN NEW SOCK ID ------------------ */ } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RxDataFrom() * * Description : (1) Receive data from a socket : * * (a) Validate receive address buffer See Notes #5 & 6 * (b) Validate & receive socket data * * See also 'NetSock_RxDataHandler() Note #1'. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to receive data. * * pdata_buf Pointer to an application data buffer that will receive the socket's received * data. * * data_buf_len Size of the application data buffer (in octets) [see Note #3]. * * flags Flags to select receive options (see Note #4); bit-field flags logically OR'd : * * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_RX_DATA_PEEK Receive socket data without consuming * the socket data; i.e. socket data * NOT removed from application receive * queue(s). * NET_SOCK_FLAG_RX_NO_BLOCK Receive socket data without blocking. * * paddr_remote Pointer to an address buffer that will receive the socket address structure * with the received data's remote address (see Note #5), if NO errors. * * paddr_len Pointer to a variable to ... : * * (a) Pass the size of the address buffer pointed to by 'paddr_remote'. * (b) (1) Return the actual size of socket address structure with the * received data's remote address, if NO errors; * (2) Return 0, otherwise. * * See also Note #6. * * pip_opts_buf Pointer to buffer to receive possible IP options (see Note #7a), if NO errors. * * ip_opts_buf_len Size of IP options receive buffer (in octets) [see Note #7b]. * * pip_opts_len Pointer to variable that will receive the return size of any received IP options, * if NO errors. * * perr Pointer to variable that will receive the return error code from this function : * * * ---- RETURNED BY NetSock_RxDataHandler() : ---- * NET_SOCK_ERR_NONE Socket data successfully received; check return * value for number of data octets received. * * NET_SOCK_ERR_INVALID_DATA_SIZE Socket data receive buffer insufficient size; * some, but not all, socket data deframed * into receive buffer (see Note #3a2). * * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_NULL_PTR Argument 'paddr_len'/'paddr_remote'/ * 'pdata_buf' passed a NULL pointer. * NET_SOCK_ERR_NULL_SIZE Argument 'data_buf_len' passed a NULL size. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol/address family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_FLAG Invalid socket flags. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address length. * * NET_SOCK_ERR_RX_Q_EMPTY Socket receive queue empty. * NET_SOCK_ERR_RX_Q_CLOSED Socket receive queue closed. * * NET_ERR_RX Receive error. * * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * * NET_OS_ERR_LOCK Network access NOT acquired. *$PAGE* * Return(s) : Number of positive data octets received, if NO errors (see Note #8a). * * NET_SOCK_BSD_RTN_CODE_CONN_CLOSED, if socket connection closed (see Note #8b). * * NET_SOCK_BSD_ERR_RX, otherwise (see Note #8c1). * * Caller(s) : recvfrom(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_RxDataFrom() blocked until network initialization completes. * * See 'NetSock_IsUsed() Note #1'. * * (3) (a) (1) (A) Datagram-type sockets transmit & receive all data atomically -- i.e. every * single, complete datagram transmitted MUST be received as a single, complete * datagram. * * (B) IEEE Std 1003.1, 2004 Edition, Section 'recvfrom() : DESCRIPTION' summarizes * that "for message-based sockets, such as ... SOCK_DGRAM ... the entire message * shall be read in a single operation. If a message is too long to fit in the * supplied buffer, and MSG_PEEK is not set in the flags argument, the excess * bytes shall be discarded". * * (2) Thus, if the socket's type is datagram & the receive data buffer size is * NOT large enough for the received data, the receive data buffer is maximally * filled with receive data but the remaining data octets are discarded & * NET_SOCK_ERR_INVALID_DATA_SIZE error is returned. * * (b) (1) (A) (1) Stream-type sockets transmit & receive all data octets in one or more * non-distinct packets. In other words, the application data is NOT * bounded by any specific packet(s); rather, it is contiguous & sequenced * from one packet to the next. * * (2) IEEE Std 1003.1, 2004 Edition, Section 'recv() : DESCRIPTION' summarizes * that "for stream-based sockets, such as SOCK_STREAM, message boundaries * shall be ignored. In this case, data shall be returned to the user as * soon as it becomes available, and no data shall be discarded". * * (B) Thus, if the socket's type is stream & the receive data buffer size is NOT * large enough for the received data, the receive data buffer is maximally * filled with receive data & the remaining data octets remain queued for * later application-socket receives. * * (2) Thus, it is typical -- but NOT absolutely required -- that a single application * task ONLY receive or request to receive data from a stream-type socket. * * See also 'NetSock_RxDataHandler() Note #2'. * * (4) #### Only some socket receive flag options are implemented. If other flag options are * requested, NetSock_RxData() handler function(s) abort & return appropriate error codes * so that requested flag options are NOT silently ignored. * * (5) (a) Socket address structure 'Family' member returned in host-order & SHOULD NOT be * converted to network-order. * * (b) Socket address structure addresses MUST be converted from host-order to network- * order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (6) (a) Since 'paddr_len' parameter is both an input & output parameter (see 'Argument(s) : * paddr_len'), ... * * (1) its input value, prior to use, SHOULD be ... * (A) saved, & ... * (B) validated; ... * * (2) while its output value MUST be initially configured to return a default error * value in case of any function exit due to error/fault conditions (see also * Note #9). * * (b) In the case that the 'paddr_len' parameter is passed a null pointer, ... * * (1) NO input value is saved, ... * (2) NO input value is validated or used. * * (7) (a) If ... * * (1) NO IP options were received * OR * (2) NO IP options receive buffer is provided * OR * (3) IP options receive buffer NOT large enough for the received IP options * * ... then NO IP options are returned & any received IP options are silently discarded. * * (b) The IP options receive buffer size SHOULD be large enough to receive the maximum * IP options size, NET_IP_HDR_OPT_SIZE_MAX. * * (c) #### Received IP options should be provided/decoded via appropriate IP layer API. * * See also Note #10. *$PAGE* * (8) IEEE Std 1003.1, 2004 Edition, Section 'recvfrom() : RETURN VALUE' states that : * * (a) "Upon successful completion, recvfrom() shall return the length of the message in * bytes." * * (b) "If no messages are available to be received and the peer has performed an orderly * shutdown, recvfrom() shall return 0." * * (c) (1) "Otherwise, [-1 shall be returned]" ... * (2) "and 'errno' set to indicate the error." * * See also 'NetSock_RxDataHandler() Note #7'. * * (9) Pointers to variables that return length or size values MUST be initialized to return * zero PRIOR to all other validation or function handling in case of any error(s). * * (10) #### IP options arguments may NOT be necessary (remove if unnecessary). ********************************************************************************************************* */ NET_SOCK_RTN_CODE NetSock_RxDataFrom (NET_SOCK_ID sock_id, void *pdata_buf, CPU_INT16S data_buf_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN *paddr_len, void *pip_opts_buf, CPU_INT08U ip_opts_buf_len, CPU_INT08U *pip_opts_len, NET_ERR *perr) { #if ((NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) NET_SOCK_ADDR_LEN addr_len; #endif NET_SOCK_RTN_CODE rtn_code; /* Init len for err (see Note #9). */ if (pip_opts_len != (CPU_INT08U *)0) { *pip_opts_len = 0; } /* --------------- VALIDATE RX ADDR BUF --------------- */ #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) if (paddr_len == (NET_SOCK_ADDR_LEN *)0) { /* See Note #6b. */ NET_CTR_ERR_INC(NetSock_ErrNullPtrCtr); *perr = NET_SOCK_ERR_NULL_PTR; return (NET_SOCK_BSD_ERR_RX); } addr_len = *paddr_len; /* Save initial addr len (see Note #6a1A). */ #endif *paddr_len = 0; /* Cfg dflt addr len for err (see Note #6a2). */ #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) if (addr_len < NET_SOCK_ADDR_SIZE) { /* Validate initial addr len (see Note #6a1B). */ NET_CTR_ERR_INC(NetSock_ErrInvalidAddrLenCtr); *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return (NET_SOCK_BSD_ERR_RX); } if (paddr_remote == (NET_SOCK_ADDR *)0) { NET_CTR_ERR_INC(NetSock_ErrNullPtrCtr); *perr = NET_SOCK_ERR_NULL_PTR; return (NET_SOCK_BSD_ERR_RX); } #endif /* -------------- VALIDATE/RX SOCK DATA --------------- */ rtn_code = NetSock_RxDataHandler((NET_SOCK_ID )sock_id, (void *)pdata_buf, (CPU_INT16S )data_buf_len, (CPU_INT16S )flags, (NET_SOCK_ADDR *)paddr_remote, (NET_SOCK_ADDR_LEN *)paddr_len, (void *)pip_opts_buf, (CPU_INT08U )ip_opts_buf_len, (CPU_INT08U *)pip_opts_len, (NET_ERR *)perr); return (rtn_code); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RxData() * * Description : (1) Receive data from a socket : * * (a) Validate & receive socket data * * See also 'NetSock_RxDataHandler() Note #1'. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to receive data. * * pdata_buf Pointer to an application data buffer that will receive the socket's received * data. * * data_buf_len Size of the application data buffer (in octets) [see Note #3]. * * flags Flags to select receive options (see Note #4); bit-field flags logically OR'd : * * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_RX_DATA_PEEK Receive socket data without consuming * the socket data; i.e. socket data * NOT removed from application receive * queue(s). * NET_SOCK_FLAG_RX_NO_BLOCK Receive socket data without blocking. * * perr Pointer to variable that will receive the return error code from this function : * * ---- RETURNED BY NetSock_RxDataHandler() : ---- * NET_SOCK_ERR_NONE Socket data successfully received; check return * value for number of data octets received. * * NET_SOCK_ERR_INVALID_DATA_SIZE Socket data receive buffer insufficient size; * some, but not all, socket data deframed * into receive buffer (see Note #3a2). * * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_NULL_PTR Argument 'pdata_buf' passed a NULL pointer. * NET_SOCK_ERR_NULL_SIZE Argument 'data_buf_len' passed a NULL size. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol/address family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_FLAG Invalid socket flags. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address length. * * NET_SOCK_ERR_RX_Q_EMPTY Socket receive queue empty. * NET_SOCK_ERR_RX_Q_CLOSED Socket receive queue closed. * * NET_ERR_RX Receive error. * * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Number of positive data octets received, if NO errors (see Note #5a). * * NET_SOCK_BSD_RTN_CODE_CONN_CLOSED, if socket connection closed (see Note #5b). * * NET_SOCK_BSD_ERR_RX, otherwise (see Note #5c1). * * Caller(s) : recv(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). *$PAGE* * Note(s) : (2) NetSock_RxData() blocked until network initialization completes. * * See 'NetSock_IsUsed() Note #1'. * * (3) (a) (1) (A) Datagram-type sockets transmit & receive all data atomically -- i.e. every * single, complete datagram transmitted MUST be received as a single, complete * datagram. * * (B) IEEE Std 1003.1, 2004 Edition, Section 'recv() : DESCRIPTION' summarizes * that "for message-based sockets, such as SOCK_DGRAM ... the entire message * shall be read in a single operation. If a message is too long to fit in * the supplied buffer, and MSG_PEEK is not set in the flags argument, the * excess bytes shall be discarded". * * (2) Thus, if the socket's type is datagram & the receive data buffer size is * NOT large enough for the received data, the receive data buffer is maximally * filled with receive data but the remaining data octets are discarded & * NET_SOCK_ERR_INVALID_DATA_SIZE error is returned. * * (b) (1) (A) (1) Stream-type sockets transmit & receive all data octets in one or more * non-distinct packets. In other words, the application data is NOT * bounded by any specific packet(s); rather, it is contiguous & sequenced * from one packet to the next. * * (2) IEEE Std 1003.1, 2004 Edition, Section 'recv() : DESCRIPTION' summarizes * that "for stream-based sockets, such as SOCK_STREAM, message boundaries * shall be ignored. In this case, data shall be returned to the user as * soon as it becomes available, and no data shall be discarded". * * (B) Thus, if the socket's type is stream & the receive data buffer size is NOT * large enough for the received data, the receive data buffer is maximally * filled with receive data & the remaining data octets remain queued for * later application-socket receives. * * (2) Thus, it is typical -- but NOT absolutely required -- that a single application * task ONLY receive or request to receive data from a stream-type socket. * * See also 'NetSock_RxDataHandler() Note #2'. * * (4) #### Only some socket receive flag options are implemented. If other flag options are * requested, NetSock_RxData() handler function(s) abort & return appropriate error codes * so that requested flag options are NOT silently ignored. * * (5) IEEE Std 1003.1, 2004 Edition, Section 'recv() : RETURN VALUE' states that : * * (a) "Upon successful completion, recv() shall return the length of the message in bytes." * * (b) "If no messages are available to be received and the peer has performed an orderly * shutdown, recv() shall return 0." * * (c) (1) "Otherwise, -1 shall be returned" ... * (2) "and 'errno' set to indicate the error." * * See also 'NetSock_RxDataHandler() Note #7'. ********************************************************************************************************* */ NET_SOCK_RTN_CODE NetSock_RxData (NET_SOCK_ID sock_id, void *pdata_buf, CPU_INT16S data_buf_len, CPU_INT16S flags, NET_ERR *perr) { NET_SOCK_RTN_CODE rtn_code; /* -------------- VALIDATE/RX SOCK DATA --------------- */ rtn_code = NetSock_RxDataHandler((NET_SOCK_ID )sock_id, (void *)pdata_buf, (CPU_INT16S )data_buf_len, (CPU_INT16S )flags, (NET_SOCK_ADDR *)0, (NET_SOCK_ADDR_LEN *)0, (void *)0, (CPU_INT08U )0, (CPU_INT08U *)0, (NET_ERR *)perr); return (rtn_code); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_TxDataTo() * * Description : (1) Transmit data through a socket : * * (a) Validate & transmit application data * * See also 'NetSock_TxDataHandler() Note #1'. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to transmit data. * * p_data Pointer to application data to transmit. * * data_len Length of application data to transmit (in octets) [see Note #3]. * * flags Flags to select transmit options (see Note #4); bit-field flags logically OR'd : * * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_TX_NO_BLOCK Transmit socket data without blocking. * * paddr_remote Pointer to destination address buffer (see Note #5). * * addr_len Length of destination address buffer (in octets). * * perr Pointer to variable that will receive the return error code from this function : * * ----- RETURNED BY NetSock_TxDataHandler() : ------- * NET_SOCK_ERR_NONE Socket data successfully transmitted &/or prepared * for transmission; check return value for number * of data octets transmitted (see Note #6a1). * * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_NULL_PTR Argument 'p_data' passed a NULL pointer. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol/address family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_FLAG Invalid socket flags. * NET_SOCK_ERR_INVALID_DATA_SIZE Invalid data size (see Notes #3b & #3a1B2). * * NET_SOCK_ERR_INVALID_CONN Invalid socket connection. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address structure length. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_INVALID_PORT_NBR Invalid socket port number. * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * NET_SOCK_ERR_ADDR_IN_USE Socket address already in use. * * NET_ERR_TX Transitory transmit error. * * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_INVALID_FAMILY Invalid network connection family. * NET_CONN_ERR_INVALID_TYPE Invalid network connection type. * NET_CONN_ERR_INVALID_LIST_IX Invalid network connection list index. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_NONE_AVAIL NO available connections to allocate. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Number of positive data octets transmitted, if NO errors (see Note #6a1). * * NET_SOCK_BSD_RTN_CODE_CONN_CLOSED, if socket connection closed (see Note #6b). * * NET_SOCK_BSD_ERR_TX, otherwise (see Note #6a2A). * * Caller(s) : sendto(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). *$PAGE* * Note(s) : (2) NetSock_TxDataTo() blocked until network initialization completes. * * See 'NetSock_IsUsed() Note #1'. * * (3) (a) (1) (A) Datagram-type sockets transmit & receive all data atomically -- i.e. every * single, complete datagram transmitted MUST be received as a single, complete * datagram. Thus, each call to transmit data MUST be transmitted in a single, * complete datagram. * * (B) (1) IEEE Std 1003.1, 2004 Edition, Section 'send() : DESCRIPTION' states * that "if the message is too long to pass through the underlying protocol, * send() shall fail and no data shall be transmitted". * * (2) Since IP transmit fragmentation is NOT currently supported (see 'net_ip.h * Note #1e'), if the socket's type is datagram & the requested transmit * data length is greater than the socket/transport layer MTU, then NO data * is transmitted & NET_SOCK_ERR_INVALID_DATA_SIZE error is returned. * * (2) (A) (1) Stream-type sockets transmit & receive all data octets in one or more * non-distinct packets. In other words, the application data is NOT * bounded by any specific packet(s); rather, it is contiguous & sequenced * from one packet to the next. * * (2) Thus, if the socket's type is stream & the socket's transmit data queue(s) * are NOT large enough for the transmitted data, the transmit data queue(s) * are maximally filled with transmit data & the remaining data octets are * discarded but may be re-transmitted by later application-socket transmits. * * (3) Therefore, NO stream-type socket transmit data length should be "too long * to pass through the underlying protocol" & cause the socket transmit to * "fail ... [with] no data ... transmitted" (see Note #3a1B1). * * (B) Thus, it is typical -- but NOT absolutely required -- that a single application * task ONLY transmit or request to transmit data to a stream-type socket. * * (b) 'data_len' of 0 octets NOT allowed. * * See also 'NetSock_TxDataHandler() Note #2'. * * (4) #### Only some socket transmit flag options are implemented. If other flag options are * requested, NetSock_TxData() handler function(s) abort & return appropriate error codes * so that requested flag options are NOT silently ignored. * * (5) (a) Socket address structure 'Family' member MUST be configured in host-order & MUST * NOT be converted to/from network-order. * * (b) Socket address structure addresses MUST be configured/converted from host-order * to network-order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (6) (a) IEEE Std 1003.1, 2004 Edition, Section 'sendto() : RETURN VALUE' states that : * * (1) "Upon successful completion, sendto() shall return the number of bytes sent." * * (A) Section 'sendto() : DESCRIPTION' elaborates that "successful completion * of a call to sendto() does not guarantee delivery of the message". * * (B) Thus, applications SHOULD verify the actual returned number of data * octets transmitted &/or prepared for transmission. * * (2) (A) "Otherwise, -1 shall be returned" ... * (1) Section 'sendto() : DESCRIPTION' elaborates that "a return value of * -1 indicates only locally-detected errors". * * (B) "and 'errno' set to indicate the error." * * (b) ???? Although NO socket send() specification states to return '0' when the socket's * connection is closed, it seems reasonable to return '0' since it is possible for the * socket connection to be close()'d or shutdown() by the remote host. * * See also 'NetSock_TxDataHandler() Note #5'. ********************************************************************************************************** */ /*$PAGE*/ NET_SOCK_RTN_CODE NetSock_TxDataTo (NET_SOCK_ID sock_id, void *p_data, CPU_INT16S data_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN addr_len, NET_ERR *perr) { NET_SOCK_RTN_CODE rtn_code; /* --------------- VALIDATE/TX APP DATA --------------- */ rtn_code = NetSock_TxDataHandler((NET_SOCK_ID )sock_id, (void *)p_data, (CPU_INT16S )data_len, (CPU_INT16S )flags, (NET_SOCK_ADDR *)paddr_remote, (NET_SOCK_ADDR_LEN )addr_len, (NET_ERR *)perr); return (rtn_code); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_TxData() * * Description : (1) Transmit data through a socket : * * (a) Validate & transmit application data * * See also 'NetSock_TxDataHandler() Note #1'. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to transmit data. * * p_data Pointer to application data to transmit. * * data_len Length of application data to transmit (in octets) [see Note #3]. * * flags Flags to select transmit options (see Note #4); bit-field flags logically OR'd : * * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_TX_NO_BLOCK Transmit socket data without blocking. * * perr Pointer to variable that will receive the return error code from this function : * * ----- RETURNED BY NetSock_TxDataHandler() : ------- * NET_SOCK_ERR_NONE Socket data successfully transmitted &/or prepared * for transmission; check return value for number * of data octets transmitted (see Note #5a1). * * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_NULL_PTR Argument 'p_data' passed a NULL pointer. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol/address family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_FLAG Invalid socket flags. * NET_SOCK_ERR_INVALID_DATA_SIZE Invalid data size (see Notes #3b & #3a1B2). * * NET_SOCK_ERR_INVALID_CONN Invalid socket connection. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address structure length. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_INVALID_PORT_NBR Invalid socket port number. * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * NET_SOCK_ERR_ADDR_IN_USE Socket address already in use. * * NET_ERR_TX Transitory transmit error. * * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_INVALID_FAMILY Invalid network connection family. * NET_CONN_ERR_INVALID_TYPE Invalid network connection type. * NET_CONN_ERR_INVALID_LIST_IX Invalid network connection list index. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_NONE_AVAIL NO available connections to allocate. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Number of positive data octets transmitted, if NO errors (see Note #5a1). * * NET_SOCK_BSD_RTN_CODE_CONN_CLOSED, if socket connection closed (see Note #5b). * * NET_SOCK_BSD_ERR_TX, otherwise (see Note #5a2A). * * Caller(s) : send(). * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). *$PAGE* * Note(s) : (2) NetSock_TxData() blocked until network initialization completes. * * See 'NetSock_IsUsed() Note #1'. * * (3) (a) (1) (A) Datagram-type sockets transmit & receive all data atomically -- i.e. every * single, complete datagram transmitted MUST be received as a single, complete * datagram. Thus, each call to transmit data MUST be transmitted in a single, * complete datagram. * * (B) (1) IEEE Std 1003.1, 2004 Edition, Section 'send() : DESCRIPTION' states * that "if the message is too long to pass through the underlying protocol, * send() shall fail and no data shall be transmitted". * * (2) Since IP transmit fragmentation is NOT currently supported (see 'net_ip.h * Note #1e'), if the socket's type is datagram & the requested transmit * data length is greater than the socket/transport layer MTU, then NO data * is transmitted & NET_SOCK_ERR_INVALID_DATA_SIZE error is returned. * * (2) (A) (1) Stream-type sockets transmit & receive all data octets in one or more * non-distinct packets. In other words, the application data is NOT * bounded by any specific packet(s); rather, it is contiguous & sequenced * from one packet to the next. * * (2) Thus, if the socket's type is stream & the socket's transmit data queue(s) * are NOT large enough for the transmitted data, the transmit data queue(s) * are maximally filled with transmit data & the remaining data octets are * discarded but may be re-transmitted by later application-socket transmits. * * (3) Therefore, NO stream-type socket transmit data length should be "too long * to pass through the underlying protocol" & cause the socket transmit to * "fail ... [with] no data ... transmitted" (see Note #3a1B1). * * (B) Thus, it is typical -- but NOT absolutely required -- that a single application * task ONLY transmit or request to transmit data to a stream-type socket. * * (b) 'data_len' of 0 octets NOT allowed. * * See also 'NetSock_TxDataHandler() Note #2'. * * (4) #### Only some socket transmit flag options are implemented. If other flag options are * requested, NetSock_TxData() handler function(s) abort & return appropriate error codes * so that requested flag options are NOT silently ignored. * * (5) (a) IEEE Std 1003.1, 2004 Edition, Section 'send() : RETURN VALUE' states that : * * (1) "Upon successful completion, send() shall return the number of bytes sent." * * (A) Section 'send() : DESCRIPTION' elaborates that "successful completion * of a call to sendto() does not guarantee delivery of the message". * * (B) Thus, applications SHOULD verify the actual returned number of data * octets transmitted &/or prepared for transmission. * * (2) (A) "Otherwise, -1 shall be returned" ... * (1) Section 'send() : DESCRIPTION' elaborates that "a return value of * -1 indicates only locally-detected errors". * * (B) "and 'errno' set to indicate the error." * * (b) ???? Although NO socket send() specification states to return '0' when the socket's * connection is closed, it seems reasonable to return '0' since it is possible for the * socket connection to be close()'d or shutdown() by the remote host. * * See also 'NetSock_TxDataHandler() Note #5'. ********************************************************************************************************** */ NET_SOCK_RTN_CODE NetSock_TxData (NET_SOCK_ID sock_id, void *p_data, CPU_INT16S data_len, CPU_INT16S flags, NET_ERR *perr) { NET_SOCK_RTN_CODE rtn_code; /* --------------- VALIDATE/TX APP DATA --------------- */ rtn_code = NetSock_TxDataHandler((NET_SOCK_ID )sock_id, (void *)p_data, (CPU_INT16S )data_len, (CPU_INT16S )flags, (NET_SOCK_ADDR *)0, (NET_SOCK_ADDR_LEN )0, (NET_ERR *)perr); return (rtn_code); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutRxQ_Dflt() * * Description : (1) Set socket receive queue configured-default timeout value : * * (a) Acquire network lock See Note #2 * (b) Validate socket used * (c) Configure socket receive queue default timeout * (d) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set receive queue configured- * default timeout. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * * - RETURNED BY NetOS_Sock_RxQ_TimeoutDflt() : - * - RETURNED BY NetOS_TCP_RxQ_TimeoutDflt() : -- * NET_SOCK_ERR_NONE Socket receive queue configured-default * timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * ------- RETURNED BY NetSock_IsUsed() : ------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ----- RETURNED BY NetTCP_ConnIsUsed() : ------ * NET_TCP_ERR_INVALID_CONN Invalid TCP connection number. * NET_TCP_ERR_CONN_NOT_USED TCP connection NOT currently used. * * -- RETURNED BY NetConn_ID_TransportGet() : --- * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * --------- RETURNED BY NetOS_Lock() : --------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_CfgTimeoutRxQ_Dflt() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_RxQ_TimeoutDflt() Note #2' * & 'net_os.c NetOS_TCP_RxQ_TimeoutDflt() Note #1'. * * (3) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'Protocol' is incorrectly modified. * * (4) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ void NetSock_CfgTimeoutRxQ_Dflt (NET_SOCK_ID sock_id, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; NET_ERR err; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* ------------ CFG SOCK RX Q DFLT TIMEOUT ------------ */ psock = &NetSock_Tbl[sock_id]; switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: NetOS_Sock_RxQ_TimeoutDflt(sock_id, perr); break; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: switch (psock->Protocol) { #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: conn_id = psock->ID_Conn; conn_id_transport = NetConn_ID_TransportGet(conn_id, perr); if (*perr != NET_CONN_ERR_NONE) { NetOS_Unlock(); return; } (void)NetTCP_ConnIsUsed((NET_TCP_CONN_ID)conn_id_transport, (NET_ERR *)perr); if (*perr != NET_TCP_ERR_NONE) { NetOS_Unlock(); return; } NetOS_TCP_RxQ_TimeoutDflt((NET_TCP_CONN_ID) conn_id_transport, (NET_ERR *)&err); *perr = (err == NET_TCP_ERR_NONE) ? NET_SOCK_ERR_NONE : err; break; #endif #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Note #3. */ NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return; /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #4. */ NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return; /* Prevent 'break NOT reachable' compiler warning. */ } (void)&conn_id; /* Prevent possible compiler warnings. */ (void)&conn_id_transport; (void)&err; /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutRxQ_Set() * * Description : (1) Set socket receive queue timeout value : * * (a) Acquire network lock See Note #2 * (b) Validate socket used * (c) Configure socket receive queue timeout * (d) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set receive queue timeout. * * timeout_ms Timeout value : * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value desired. * * In number of milliseconds, otherwise. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * * -- RETURNED BY NetOS_Sock_RxQ_TimeoutSet() : - * -- RETURNED BY NetOS_TCP_RxQ_TimeoutSet() : -- * NET_SOCK_ERR_NONE Socket receive queue timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * ------- RETURNED BY NetSock_IsUsed() : ------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ----- RETURNED BY NetTCP_ConnIsUsed() : ------ * NET_TCP_ERR_INVALID_CONN Invalid TCP connection number. * NET_TCP_ERR_CONN_NOT_USED TCP connection NOT currently used. * * -- RETURNED BY NetConn_ID_TransportGet() : --- * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * --------- RETURNED BY NetOS_Lock() : --------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_CfgTimeoutRxQ_Set() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_RxQ_TimeoutSet() Note #2' * & 'net_os.c NetOS_TCP_RxQ_TimeoutSet() Note #1'. * * (3) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'Protocol' is incorrectly modified. * * (4) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ void NetSock_CfgTimeoutRxQ_Set (NET_SOCK_ID sock_id, CPU_INT32U timeout_ms, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; NET_ERR err; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* -------------- CFG SOCK RX Q TIMEOUT --------------- */ psock = &NetSock_Tbl[sock_id]; switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: NetOS_Sock_RxQ_TimeoutSet(sock_id, timeout_ms, perr); break; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: switch (psock->Protocol) { #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: conn_id = psock->ID_Conn; conn_id_transport = NetConn_ID_TransportGet(conn_id, perr); if (*perr != NET_CONN_ERR_NONE) { NetOS_Unlock(); return; } (void)NetTCP_ConnIsUsed((NET_TCP_CONN_ID)conn_id_transport, (NET_ERR *)perr); if (*perr != NET_TCP_ERR_NONE) { NetOS_Unlock(); return; } NetOS_TCP_RxQ_TimeoutSet((NET_TCP_CONN_ID) conn_id_transport, (CPU_INT32U ) timeout_ms, (NET_ERR *)&err); *perr = (err == NET_TCP_ERR_NONE) ? NET_SOCK_ERR_NONE : err; break; #endif #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Note #3. */ NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return; /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #4. */ NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return; /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ (void)&conn_id; /* Prevent possible compiler warnings. */ (void)&conn_id_transport; (void)&err; /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutRxQ_Get_ms() * * Description : (1) Get socket receive queue timeout value : * * (a) Acquire network lock See Note #3 * (b) Validate socket used * (c) Get socket receive queue timeout * (d) Release network lock * (e) Return socket receive queue timeout * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to get receive queue timeout. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * * -- RETURNED BY NetOS_Sock_RxQ_TimeoutGet_ms() : --- * -- RETURNED BY NetOS_TCP_RxQ_TimeoutGet_ms() : ---- * NET_SOCK_ERR_NONE Socket receive queue timeout successfully returned. * NET_OS_ERR_INVALID_TIME Invalid time value. * * --------- RETURNED BY NetSock_IsUsed() : ---------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * -------- RETURNED BY NetTCP_ConnIsUsed() : -------- * NET_TCP_ERR_INVALID_CONN Invalid TCP connection number. * NET_TCP_ERR_CONN_NOT_USED TCP connection NOT currently used. * * ----- RETURNED BY NetConn_ID_TransportGet() : ----- * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * ----------- RETURNED BY NetOS_Lock() : ------------ * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Socket receive queue network timeout value : * * 0, on any errors. * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value configured. * * In number of milliseconds, otherwise. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : none. * * Note(s) : (2) Despite inconsistency with other 'Get' status functions, * NetSock_CfgTimeoutRxQ_Get_ms() includes 'Cfg' for consistency with other * NetSock_CfgTimeout???() functions. * * (3) NetSock_CfgTimeoutRxQ_Get_ms() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_RxQ_TimeoutGet_ms() Note #2' * & 'net_os.c NetOS_TCP_RxQ_TimeoutGet_ms() Note #1'. * * (4) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'Protocol' is incorrectly modified. * * (5) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ CPU_INT32U NetSock_CfgTimeoutRxQ_Get_ms (NET_SOCK_ID sock_id, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; NET_ERR err; CPU_INT32U timeout_ms; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (0); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (0); } #endif /* -------------- GET SOCK RX Q TIMEOUT --------------- */ psock = &NetSock_Tbl[sock_id]; switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: timeout_ms = NetOS_Sock_RxQ_TimeoutGet_ms(sock_id, perr); break; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: switch (psock->Protocol) { #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: conn_id = psock->ID_Conn; conn_id_transport = NetConn_ID_TransportGet(conn_id, perr); if (*perr != NET_CONN_ERR_NONE) { NetOS_Unlock(); return (0); } (void)NetTCP_ConnIsUsed((NET_TCP_CONN_ID)conn_id_transport, (NET_ERR *)perr); if (*perr != NET_TCP_ERR_NONE) { NetOS_Unlock(); return (0); } timeout_ms = NetOS_TCP_RxQ_TimeoutGet_ms((NET_TCP_CONN_ID) conn_id_transport, (NET_ERR *)&err); *perr = (err == NET_TCP_ERR_NONE) ? NET_SOCK_ERR_NONE : err; break; #endif #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Note #4. */ NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return (0); /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #5. */ NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (0); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ (void)&conn_id; /* Prevent possible compiler warnings. */ (void)&conn_id_transport; (void)&err; /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); return (timeout_ms); /* -------------- RTN SOCK RX Q TIMEOUT --------------- */ } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutTxQ_Dflt() * * Description : (1) Set socket transmit queue configured-default timeout value : * * (a) Acquire network lock See Note #3 * (b) Validate socket used * (c) Configure socket transmit queue default timeout * (d) Release network lock * * (2) Socket transmit queues apply to the following socket type(s)/protocol(s) : * * (a) Stream * (1) TCP * * (b) #### Datagram sockets NOT blocked during transmit since socket receive/transmit * buffer queue sizes NOT yet implemented. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set transmit queue configured- * default timeout. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * * - RETURNED BY NetOS_TCP_TxQ_TimeoutDflt() : - * NET_SOCK_ERR_NONE Socket transmit queue configured-default * timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * ------ RETURNED BY NetSock_IsUsed() : ------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ----- RETURNED BY NetTCP_ConnIsUsed() : ----- * NET_TCP_ERR_INVALID_CONN Invalid TCP connection number. * NET_TCP_ERR_CONN_NOT_USED TCP connection NOT currently used. * * -- RETURNED BY NetConn_ID_TransportGet() : -- * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * -------- RETURNED BY NetOS_Lock() : --------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (3) NetSock_CfgTimeoutTxQ_Dflt() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_TCP_TxQ_TimeoutDflt() Note #1'. * * (4) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'Protocol' is incorrectly modified. * * (5) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ void NetSock_CfgTimeoutTxQ_Dflt (NET_SOCK_ID sock_id, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; NET_ERR err; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* ------------ CFG SOCK TX Q DFLT TIMEOUT ------------ */ psock = &NetSock_Tbl[sock_id]; switch (psock->SockType) { #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: switch (psock->Protocol) { #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: conn_id = psock->ID_Conn; conn_id_transport = NetConn_ID_TransportGet(conn_id, perr); if (*perr != NET_CONN_ERR_NONE) { NetOS_Unlock(); return; } (void)NetTCP_ConnIsUsed((NET_TCP_CONN_ID)conn_id_transport, (NET_ERR *)perr); if (*perr != NET_TCP_ERR_NONE) { NetOS_Unlock(); return; } NetOS_TCP_TxQ_TimeoutDflt((NET_TCP_CONN_ID) conn_id_transport, (NET_ERR *)&err); *perr = (err == NET_TCP_ERR_NONE) ? NET_SOCK_ERR_NONE : err; break; #endif #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Note #4. */ NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return; /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_TYPE_NONE: case NET_SOCK_TYPE_DATAGRAM: /* See Note #2b. */ default: /* See Note #5. */ NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return; /* Prevent 'break NOT reachable' compiler warning. */ } (void)&conn_id; /* Prevent possible compiler warnings. */ (void)&conn_id_transport; (void)&err; /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutTxQ_Set() * * Description : (1) Set socket transmit queue timeout value : * * (a) Acquire network lock See Note #3 * (b) Validate socket used * (c) Configure socket transmit queue timeout * (d) Release network lock * * (2) Socket transmit queues apply to the following socket type(s)/protocol(s) : * * (a) Stream * (1) TCP * * (b) #### Datagram sockets NOT blocked during transmit since socket receive/transmit * buffer queue sizes NOT yet implemented. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set transmit queue timeout. * * timeout_ms Timeout value : * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value desired. * * In number of milliseconds, otherwise. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * * -- RETURNED BY NetOS_TCP_TxQ_TimeoutSet() : --- * NET_SOCK_ERR_NONE Socket transmit queue timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * ------- RETURNED BY NetSock_IsUsed() : -------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ------ RETURNED BY NetTCP_ConnIsUsed() : ------ * NET_TCP_ERR_INVALID_CONN Invalid TCP connection number. * NET_TCP_ERR_CONN_NOT_USED TCP connection NOT currently used. * * --- RETURNED BY NetConn_ID_TransportGet() : --- * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * --------- RETURNED BY NetOS_Lock() : ---------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (3) NetSock_CfgTimeoutTxQ_Set() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_TCP_TxQ_TimeoutSet() Note #1'. * * (4) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'Protocol' is incorrectly modified. * * (5) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ void NetSock_CfgTimeoutTxQ_Set (NET_SOCK_ID sock_id, CPU_INT32U timeout_ms, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; NET_ERR err; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* -------------- CFG SOCK TX Q TIMEOUT --------------- */ psock = &NetSock_Tbl[sock_id]; switch (psock->SockType) { #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: switch (psock->Protocol) { #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: conn_id = psock->ID_Conn; conn_id_transport = NetConn_ID_TransportGet(conn_id, perr); if (*perr != NET_CONN_ERR_NONE) { NetOS_Unlock(); return; } (void)NetTCP_ConnIsUsed((NET_TCP_CONN_ID)conn_id_transport, (NET_ERR *)perr); if (*perr != NET_TCP_ERR_NONE) { NetOS_Unlock(); return; } NetOS_TCP_TxQ_TimeoutSet((NET_TCP_CONN_ID) conn_id_transport, (CPU_INT32U ) timeout_ms, (NET_ERR *)&err); *perr = (err == NET_TCP_ERR_NONE) ? NET_SOCK_ERR_NONE : err; break; #endif #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Note #4. */ NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return; /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_TYPE_NONE: case NET_SOCK_TYPE_DATAGRAM: /* See Note #2b. */ default: /* See Note #5. */ NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return; /* Prevent 'break NOT reachable' compiler warning. */ } (void)&conn_id; /* Prevent possible compiler warnings. */ (void)&conn_id_transport; (void)&err; /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutTxQ_Get_ms() * * Description : (1) Get socket transmit queue timeout value : * * (a) Acquire network lock See Note #4 * (b) Validate socket used * (c) Get socket transmit queue timeout * (d) Release network lock * (e) Return socket transmit queue timeout * * (2) Socket transmit queues apply to the following socket type(s)/protocol(s) : * * (a) Stream * (1) TCP * * (b) #### Datagram sockets NOT blocked during transmit since socket receive/transmit * buffer queue sizes NOT yet implemented. * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to get transmit queue timeout. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * * -- RETURNED BY NetOS_Sock_RxQ_TimeoutGet_ms() : --- * -- RETURNED BY NetOS_TCP_TxQ_TimeoutGet_ms() : ---- * NET_SOCK_ERR_NONE Socket transmit queue timeout successfully returned. * NET_OS_ERR_INVALID_TIME Invalid time value. * * --------- RETURNED BY NetSock_IsUsed() : ---------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * -------- RETURNED BY NetTCP_ConnIsUsed() : -------- * NET_TCP_ERR_INVALID_CONN Invalid TCP connection number. * NET_TCP_ERR_CONN_NOT_USED TCP connection NOT currently used. * * ----- RETURNED BY NetConn_ID_TransportGet() : ----- * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * ----------- RETURNED BY NetOS_Lock() : ------------ * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Socket transmit queue network timeout value : * * 0, on any errors. * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value configured. * * In number of milliseconds, otherwise. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : none. * * Note(s) : (3) Despite inconsistency with other 'Get' status functions, * NetSock_CfgTimeoutTxQ_Get_ms() includes 'Cfg' for consistency with other * NetSock_CfgTimeout???() functions. * * (4) NetSock_CfgTimeoutTxQ_Get_ms() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_TCP_TxQ_TimeoutGet_ms() Note #1'. * * (5) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'Protocol' is incorrectly modified. * * (6) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ CPU_INT32U NetSock_CfgTimeoutTxQ_Get_ms (NET_SOCK_ID sock_id, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; NET_ERR err; CPU_INT32U timeout_ms; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (0); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (0); } #endif /* -------------- GET SOCK TX Q TIMEOUT --------------- */ psock = &NetSock_Tbl[sock_id]; switch (psock->SockType) { #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: switch (psock->Protocol) { #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: conn_id = psock->ID_Conn; conn_id_transport = NetConn_ID_TransportGet(conn_id, perr); if (*perr != NET_CONN_ERR_NONE) { NetOS_Unlock(); return (0); } (void)NetTCP_ConnIsUsed((NET_TCP_CONN_ID)conn_id_transport, (NET_ERR *)perr); if (*perr != NET_TCP_ERR_NONE) { NetOS_Unlock(); return (0); } timeout_ms = NetOS_TCP_TxQ_TimeoutGet_ms((NET_TCP_CONN_ID) conn_id_transport, (NET_ERR *)&err); *perr = (err == NET_TCP_ERR_NONE) ? NET_SOCK_ERR_NONE : err; break; #endif #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Note #5. */ NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return (0); /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_TYPE_NONE: case NET_SOCK_TYPE_DATAGRAM: /* See Note #2b. */ default: /* See Note #6. */ NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (0); /* Prevent 'break NOT reachable' compiler warning. */ } (void)&conn_id; /* Prevent possible compiler warnings. */ (void)&conn_id_transport; (void)&err; /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); return (timeout_ms); /* -------------- RTN SOCK TX Q TIMEOUT --------------- */ } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutConnReqDflt() * * Description : (1) Set socket connection request configured-default timeout value : * * (a) Acquire network lock See Note #2 * (b) Validate socket used * (c) Configure socket connection request default timeout * (d) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set connection request * configured-default timeout. * * perr Pointer to variable that will receive the return error code from this function : * * - RETURNED BY NetOS_Sock_ConnReqTimeoutDflt() : - * NET_SOCK_ERR_NONE Socket connection request configured-default * timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * -------- RETURNED BY NetSock_IsUsed() : --------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ---------- RETURNED BY NetOS_Lock() : ----------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_CfgTimeoutConnReqDflt() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_ConnReqTimeoutDflt() Note #1'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) void NetSock_CfgTimeoutConnReqDflt (NET_SOCK_ID sock_id, NET_ERR *perr) { /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* ---------- CFG SOCK CONN REQ DFLT TIMEOUT ---------- */ NetOS_Sock_ConnReqTimeoutDflt(sock_id, perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutConnReqSet() * * Description : (1) Set socket connection request timeout value : * * (a) Acquire network lock See Note #2 * (b) Validate socket used * (c) Configure socket connection request timeout * (d) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set connection request timeout. * * timeout_ms Timeout value : * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value desired. * * In number of milliseconds, otherwise. * * perr Pointer to variable that will receive the return error code from this function : * * -- RETURNED BY NetOS_Sock_ConnReqTimeoutSet() : --- * NET_SOCK_ERR_NONE Socket connection request timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * --------- RETURNED BY NetSock_IsUsed() : ---------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ----------- RETURNED BY NetOS_Lock() : ------------ * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_CfgTimeoutConnReqSet() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_ConnReqTimeoutSet() Note #1'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) void NetSock_CfgTimeoutConnReqSet (NET_SOCK_ID sock_id, CPU_INT32U timeout_ms, NET_ERR *perr) { /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* ------------ CFG SOCK CONN REQ TIMEOUT ------------- */ NetOS_Sock_ConnReqTimeoutSet(sock_id, timeout_ms, perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutConnReqGet_ms() * * Description : (1) Get socket connection request timeout value : * * (a) Acquire network lock See Note #3 * (b) Validate socket used * (c) Get socket connection request timeout * (d) Release network lock * (e) Return socket connection request timeout * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to get connection request timeout. * * perr Pointer to variable that will receive the return error code from this function : * * - RETURNED BY NetOS_Sock_ConnReqTimeoutGet_ms() : - * NET_SOCK_ERR_NONE Socket connection request timeout successfully * returned. * * --------- RETURNED BY NetSock_IsUsed() : ---------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ----------- RETURNED BY NetOS_Lock() : ------------ * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Socket connection request network timeout value : * * 0, on any errors. * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value configured. * * In number of milliseconds, otherwise. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : none. * * Note(s) : (2) Despite inconsistency with other 'Get' status functions, * NetSock_CfgTimeoutConnReqGet_ms() includes 'Cfg' for consistency with other * NetSock_CfgTimeout???() functions. * * (3) NetSock_CfgTimeoutConnReqGet_ms() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_ConnReqTimeoutGet_ms() Note #1'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) CPU_INT32U NetSock_CfgTimeoutConnReqGet_ms (NET_SOCK_ID sock_id, NET_ERR *perr) { CPU_INT32U timeout_ms; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (0); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (0); } #endif /* ------------ GET SOCK CONN REQ TIMEOUT ------------- */ timeout_ms = NetOS_Sock_ConnReqTimeoutGet_ms(sock_id, perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); return (timeout_ms); /* ------------ RTN SOCK CONN REQ TIMEOUT ------------- */ } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutConnAcceptDflt() * * Description : (1) Set socket connection accept configured-default timeout value : * * (a) Acquire network lock See Note #2 * (b) Validate socket used * (c) Configure socket connection accept default timeout * (d) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set connection accept * configured-default timeout. * * perr Pointer to variable that will receive the return error code from this function : * * - RETURNED BY NetOS_Sock_ConnAcceptQ_TimeoutDflt() : - * NET_SOCK_ERR_NONE Socket connection accept configured-default * timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * ----------- RETURNED BY NetSock_IsUsed() : ----------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ------------- RETURNED BY NetOS_Lock() : ------------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_CfgTimeoutConnAcceptDflt() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_ConnAcceptQ_TimeoutDflt() Note #2'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) void NetSock_CfgTimeoutConnAcceptDflt (NET_SOCK_ID sock_id, NET_ERR *perr) { /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* --------- CFG SOCK CONN ACCEPT DFLT TIMEOUT -------- */ NetOS_Sock_ConnAcceptQ_TimeoutDflt(sock_id, perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutConnAcceptSet() * * Description : (1) Set socket connection accept timeout value : * * (a) Acquire network lock See Note #2 * (b) Validate socket used * (c) Configure socket connection accept timeout * (d) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set connection accept timeout. * * timeout_ms Timeout value : * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value desired. * * In number of milliseconds, otherwise. * * perr Pointer to variable that will receive the return error code from this function : * * - RETURNED BY NetOS_Sock_ConnAcceptQ_TimeoutSet() : - * NET_SOCK_ERR_NONE Socket connection accept timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * ---------- RETURNED BY NetSock_IsUsed() : ----------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ------------ RETURNED BY NetOS_Lock() : ------------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_CfgTimeoutConnAcceptSet() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_ConnAcceptQ_TimeoutSet() Note #2'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) void NetSock_CfgTimeoutConnAcceptSet (NET_SOCK_ID sock_id, CPU_INT32U timeout_ms, NET_ERR *perr) { /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* ----------- CFG SOCK CONN ACCEPT TIMEOUT ----------- */ NetOS_Sock_ConnAcceptQ_TimeoutSet(sock_id, timeout_ms, perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutConnAcceptGet_ms() * * Description : (1) Get socket connection accept timeout value : * * (a) Acquire network lock See Note #3 * (b) Validate socket used * (c) Get socket connection accept timeout * (d) Release network lock * (e) Return socket connection accept timeout * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to get connection accept timeout. * * perr Pointer to variable that will receive the return error code from this function : * * - RETURNED BY NetOS_Sock_ConnAcceptQ_TimeoutGet_ms() : - * NET_SOCK_ERR_NONE Socket connection accept timeout successfully * returned. * * ------------ RETURNED BY NetSock_IsUsed() : ------------ * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * -------------- RETURNED BY NetOS_Lock() : -------------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Socket connection accept network timeout value : * * 0, on any errors. * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value configured. * * In number of milliseconds, otherwise. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : none. * * Note(s) : (2) Despite inconsistency with other 'Get' status functions, * NetSock_CfgTimeoutConnAcceptGet_ms() includes 'Cfg' for consistency with other * NetSock_CfgTimeout???() functions. * * (3) NetSock_CfgTimeoutConnAcceptGet_ms() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_ConnAcceptQ_TimeoutGet_ms() Note #2'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) CPU_INT32U NetSock_CfgTimeoutConnAcceptGet_ms (NET_SOCK_ID sock_id, NET_ERR *perr) { CPU_INT32U timeout_ms; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (0); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (0); } #endif /* ----------- GET SOCK CONN ACCEPT TIMEOUT ----------- */ timeout_ms = NetOS_Sock_ConnAcceptQ_TimeoutGet_ms(sock_id, perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); return (timeout_ms); /* ----------- RTN SOCK CONN ACCEPT TIMEOUT ----------- */ } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutConnCloseDflt() * * Description : (1) Set socket connection close configured-default timeout value : * * (a) Acquire network lock See Note #2 * (b) Validate socket used * (c) Configure socket connection close default timeout * (d) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set connection close * configured-default timeout. * * perr Pointer to variable that will receive the return error code from this function : * * - RETURNED BY NetOS_Sock_ConnCloseTimeoutDflt() : - * NET_SOCK_ERR_NONE Socket connection close configured-default * timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * --------- RETURNED BY NetSock_IsUsed() : ---------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ----------- RETURNED BY NetOS_Lock() : ------------ * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_CfgTimeoutConnCloseDflt() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_ConnCloseTimeoutDflt() Note #1'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) void NetSock_CfgTimeoutConnCloseDflt (NET_SOCK_ID sock_id, NET_ERR *perr) { /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* --------- CFG SOCK CONN CLOSE DFLT TIMEOUT --------- */ NetOS_Sock_ConnCloseTimeoutDflt(sock_id, perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutConnCloseSet() * * Description : (1) Set socket connection close timeout value : * * (a) Acquire network lock See Note #2 * (b) Validate socket used * (c) Configure socket connection close timeout * (d) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to set connection close timeout. * * timeout_ms Timeout value : * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value desired. * * In number of milliseconds, otherwise. * * perr Pointer to variable that will receive the return error code from this function : * * - RETURNED BY NetOS_Sock_ConnCloseTimeoutSet() : - * NET_SOCK_ERR_NONE Socket connection close timeout successfully set. * NET_OS_ERR_INVALID_TIME Invalid time value. * * -------- RETURNED BY NetSock_IsUsed() : ---------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ---------- RETURNED BY NetOS_Lock() : ------------ * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (2) NetSock_CfgTimeoutConnCloseSet() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_ConnCloseTimeoutSet() Note #1'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) void NetSock_CfgTimeoutConnCloseSet (NET_SOCK_ID sock_id, CPU_INT32U timeout_ms, NET_ERR *perr) { /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return; } #endif /* ----------- CFG SOCK CONN CLOSE TIMEOUT ------------ */ NetOS_Sock_ConnCloseTimeoutSet(sock_id, timeout_ms, perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CfgTimeoutConnCloseGet_ms() * * Description : (1) Get socket connection close timeout value : * * (a) Acquire network lock See Note #3 * (b) Validate socket used * (c) Get socket connection close timeout * (d) Release network lock * (e) Return socket connection close timeout * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to get connection close timeout. * * perr Pointer to variable that will receive the return error code from this function : * * - RETURNED BY NetOS_Sock_ConnCloseTimeoutGet_ms() : - * NET_SOCK_ERR_NONE Socket connection close timeout successfully * returned. * * ---------- RETURNED BY NetSock_IsUsed() : ----------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * ------------ RETURNED BY NetOS_Lock() : ------------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Socket connection close network timeout value : * * 0, on any errors. * * NET_TMR_TIME_INFINITE, if infinite (i.e. NO timeout) value configured. * * In number of milliseconds, otherwise. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : none. * * Note(s) : (2) Despite inconsistency with other 'Get' status functions, * NetSock_CfgTimeoutConnCloseGet_ms() includes 'Cfg' for consistency with other * NetSock_CfgTimeout???() functions. * * (3) NetSock_CfgTimeoutConnCloseGet_ms() is called by application function(s) & ... : * * (a) MUST NOT be called with the global network lock already acquired; ... * (b) MUST block ALL other network protocol tasks by pending on & acquiring the global * network lock (see 'net.h Note #2'). * * This is required since an application's network protocol suite API function access is * asynchronous to other network protocol tasks. * * See also 'net_os.c NetOS_Sock_ConnCloseTimeoutGet_ms() Note #1'. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) CPU_INT32U NetSock_CfgTimeoutConnCloseGet_ms (NET_SOCK_ID sock_id, NET_ERR *perr) { CPU_INT32U timeout_ms; /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (0); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (0); } #endif /* ----------- GET SOCK CONN CLOSE TIMEOUT ------------ */ timeout_ms = NetOS_Sock_ConnCloseTimeoutGet_ms(sock_id, perr); /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); return (timeout_ms); /* ----------- RTN SOCK CONN CLOSE TIMEOUT ------------ */ } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_IsUsed() * * Description : Validate socket in use. * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to validate. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully validated as in use. * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * Return(s) : DEF_YES, socket valid & in use. * * DEF_NO, socket invalid or NOT in use. * * Caller(s) : various. * * This function is an INTERNAL network protocol suite function & SHOULD NOT be called by * application function(s). * * Note(s) : (1) NetSock_IsUsed() blocked until network initialization completes. * * (2) NetSock_IsUsed() MUST be called with the global network lock already acquired. ********************************************************************************************************* */ CPU_BOOLEAN NetSock_IsUsed (NET_SOCK_ID sock_id, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; CPU_BOOLEAN used; #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit (see Note #1). */ *perr = NET_ERR_INIT_INCOMPLETE; return (DEF_NO); } #endif /* ----------------- VALIDATE SOCK ID ----------------- */ if (sock_id < NET_SOCK_ID_MIN) { NET_CTR_ERR_INC(NetSock_ErrInvalidSockCtr); *perr = NET_SOCK_ERR_INVALID_SOCK; return (DEF_NO); } if (sock_id > NET_SOCK_ID_MAX) { NET_CTR_ERR_INC(NetSock_ErrInvalidSockCtr); *perr = NET_SOCK_ERR_INVALID_SOCK; return (DEF_NO); } /* ---------------- VALIDATE SOCK USED ---------------- */ psock = &NetSock_Tbl[sock_id]; used = DEF_BIT_IS_SET(psock->Flags, NET_SOCK_FLAG_USED); if (used != DEF_YES) { NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (DEF_NO); } *perr = NET_SOCK_ERR_NONE; return (DEF_YES); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_IsConn() * * Description : Validate socket in use & connected. * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to validate. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully checked; check return * value for socket connection status. * * ---- RETURNED BY NetSock_IsUsed() : ----- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * Return(s) : DEF_YES, socket valid & connected. * * DEF_NO, socket invalid or NOT connected. * * Caller(s) : various. * * This function is an INTERNAL network protocol suite function & SHOULD NOT be called by * application function(s). * * Note(s) : (1) NetSock_IsConn() MUST be called with the global network lock already acquired. * * (2) #### NetSock_IsConn() may NOT be necessary (remove if unnecessary). ********************************************************************************************************* */ CPU_BOOLEAN NetSock_IsConn (NET_SOCK_ID sock_id, NET_ERR *perr) { NET_SOCK *psock; CPU_BOOLEAN conn; /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { return (DEF_NO); } /* ------------ DETERMINE SOCK CONN STATUS ------------ */ psock = &NetSock_Tbl[sock_id]; switch (psock->State) { case NET_SOCK_STATE_CONN_DONE: conn = DEF_YES; break; case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_CLOSED_FAULT: case NET_SOCK_STATE_BOUND: default: conn = DEF_NO; break; } *perr = NET_SOCK_ERR_NONE; return (conn); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_PoolStatGet() * * Description : Get socket statistics pool. * * Argument(s) : none. * * Return(s) : Socket statistics pool, if NO errors. * * NULL statistics pool, otherwise. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : (1) NetSock_PoolStatGet() blocked until network initialization completes; return NULL * statistics pool. ********************************************************************************************************* */ NET_STAT_POOL NetSock_PoolStatGet (void) { #if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) NET_ERR err; #endif NET_STAT_POOL stat_pool; #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) if (Net_InitDone != DEF_YES) { /* If init NOT complete, ... */ NetStat_PoolClr(&stat_pool, &err); return (stat_pool); /* ... rtn NULL stat pool (see Note #1). */ } #endif CPU_CRITICAL_ENTER(); stat_pool = NetSock_PoolStat; CPU_CRITICAL_EXIT(); return (stat_pool); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_PoolStatResetMaxUsed() * * Description : Reset socket statistics pool's maximum number of entries used. * * Argument(s) : none. * * Return(s) : none. * * Caller(s) : Application. * * This function is a network protocol suite application interface (API) function & MAY be * called by application function(s). * * Note(s) : none. ********************************************************************************************************* */ void NetSock_PoolStatResetMaxUsed (void) { NET_ERR err; NetStat_PoolResetUsedMax(&NetSock_PoolStat, &err); } /*$PAGE*/ /* ********************************************************************************************************* ********************************************************************************************************* * LOCAL FUNCTIONS ********************************************************************************************************* ********************************************************************************************************* */ /* ********************************************************************************************************* * NetSock_RxPktValidateBuf() * * Description : Validate received buffer header as socket layer. * * Argument(s) : pbuf_hdr Pointer to network buffer header that received socket packet. * -------- Argument validated in NetSock_Rx(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Received buffer's socket/data header validated. * NET_ERR_INVALID_PROTOCOL Buffer's protocol type is NOT socket. * NET_BUF_ERR_INVALID_IX Invalid buffer index. * * Return(s) : none. * * Caller(s) : NetSock_Rx(). * * Note(s) : (1) Since lower network layers eventually demultiplex data to the application layer, the * socket layer must validate received packet's as application type, not socket type. ********************************************************************************************************* */ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) static void NetSock_RxPktValidateBuf (NET_BUF_HDR *pbuf_hdr, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif /* -------------- VALIDATE SOCK/DATA HDR -------------- */ if (pbuf_hdr->ProtocolHdrType != NET_PROTOCOL_TYPE_APP) { /* See Note #1. */ NET_CTR_ERR_INC(Net_ErrInvalidProtocolCtr); *perr = NET_ERR_INVALID_PROTOCOL; return; } if (pbuf_hdr->DataIx == NET_BUF_IX_NONE) { NET_CTR_ERR_INC(NetSock_ErrRxInvalidBufIxCtr); *perr = NET_BUF_ERR_INVALID_IX; return; } *perr = NET_SOCK_ERR_NONE; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RxPktDemux() * * Description : (1) Demultiplex received packet to appropriate socket : * * (a) Determine appropriate receive socket : * * (1) Packet's socket demultiplexed in previous transport layer. * * (2) Search connection lists for socket identifier whose local &/or remote addresses * are identical to the received packet's destination & source addresses. * * (b) Validate socket connection * (c) Demultiplex received packet to appropriate socket * * * Argument(s) : pbuf Pointer to network buffer that received socket data. * ---- Argument checked in NetSock_Rx(). * * pbuf_hdr Pointer to network buffer header. * -------- Argument validated in NetSock_Rx(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Received packet successfully demultiplexed * to appropriate socket. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_ERR_RX_DEST Invalid destination; no socket connection * available for received packet. * * ----- RETURNED BY NetConn_IsConn() : ----- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_CONN_NONE NO connection. * * -- RETURNED BY NetOS_Sock_RxQ_Signal() : - * NET_SOCK_ERR_RX_Q_FULL Socket receive queue full. * NET_SOCK_ERR_RX_Q_SIGNAL Socket receive queue signal failed. * * Return(s) : none. * * Caller(s) : NetSock_Rx(). * * Note(s) : (2) (a) Assumes packet buffer's internet protocol controls configured in previous layer(s). * * (b) Assumes packet's addresses & ports demultiplexed & decoded in previous layer(s). * * (3) (a) Since datagram-type sockets transmit & receive all data atomically, each datagram * socket receive MUST always receive exactly one datagram. Therefore, the socket * receive queue MUST be signaled for each datagram packet received. * * (b) Stream-type sockets transmit & receive all data octets in one or more non-distinct * packets. In other words, the application data is NOT bounded by any specific * packet(s); rather, it is contiguous & sequenced from one packet to the next. * * Therefore, the socket receive queue is signaled ONLY when data is received for a * connection where data was previously unavailable. * * (4) Default case already invalidated in earlier internet protocol layer function(s). * However, the default case is included as an extra precaution in case 'Protocol' * is incorrectly modified. * * (5) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. * * (6) Default case already invalidated in NetSock_Open(). However, the default case * is included as an extra precaution in case 'SockType' is incorrectly modified. * * (7) Socket connection addresses are maintained in network-order. * * (8) Some buffer controls were previously initialized in NetBuf_Get() when the packet * was received at the network interface layer. These buffer controls do NOT need * to be re-initialized but are shown for completeness. ********************************************************************************************************* */ /*$PAGE*/ static void NetSock_RxPktDemux (NET_BUF *pbuf, NET_BUF_HDR *pbuf_hdr, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) NET_ERR err; CPU_BOOLEAN used; CPU_BOOLEAN conn; #endif #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) CPU_BOOLEAN q_prevly_empty; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_IP_HDR *pip_hdr; NET_IP_ADDR addr_ip; #endif CPU_INT08U addr_local[NET_SOCK_CFG_ADDR_LEN]; CPU_INT08U addr_remote[NET_SOCK_CFG_ADDR_LEN]; NET_PORT_NBR port_nbr; NET_CONN_LIST_IX protocol_ix; NET_CONN_FAMILY family; NET_CONN_ID conn_id; NET_SOCK_ID sock_id; NET_SOCK *psock; NET_BUF *pbuf_tail; NET_BUF_HDR *pbuf_hdr_tail; sock_id = (NET_SOCK_ID)pbuf_hdr->Conn_ID_App; conn_id = (NET_CONN_ID)pbuf_hdr->Conn_ID; /* --------------- CHK PREV SOCK DEMUX ---------------- */ if (sock_id != (NET_SOCK_ID)NET_CONN_ID_NONE) { /* If sock id demux'd by prev layer (see Note #1a1), ...*/ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ... validate sock conn. */ NetConn_IsConn(conn_id, perr); switch (*perr) { case NET_CONN_ERR_CONN_HALF: conn = DEF_NO; break; case NET_CONN_ERR_CONN_FULL: conn = DEF_YES; break; case NET_CONN_ERR_INVALID_CONN: case NET_CONN_ERR_NOT_USED: case NET_CONN_ERR_CONN_NONE: default: /* Rtn err from NetConn_IsConn(). */ return; /* Prevent 'break NOT reachable' compiler warning. */ } #endif /*$PAGE*/ } else { /* ---- SRCH CONN LIST(S) FOR PKT/SOCK ADDR(S) ---- */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) family = NET_CONN_FAMILY_IP_V4_SOCK; pip_hdr = (NET_IP_HDR *)&pbuf->Data[pbuf_hdr->IP_HdrIx]; switch (pip_hdr->Protocol) { case NET_IP_HDR_PROTOCOL_UDP: protocol_ix = NET_CONN_LIST_IX_IP_V4_SOCK_UDP; break; #ifdef NET_TCP_MODULE_PRESENT case NET_IP_HDR_PROTOCOL_TCP: protocol_ix = NET_CONN_LIST_IX_IP_V4_SOCK_TCP; break; #endif default: /* See Note #4. */ NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return; /* Prevent 'break NOT reachable' compiler warning. */ } /* Cfg srch local addr as pkt dest addr. */ port_nbr = (NET_PORT_NBR)NET_UTIL_HOST_TO_NET_16(pbuf_hdr->TCP_UDP_PortDest); addr_ip = (NET_IP_ADDR )NET_UTIL_HOST_TO_NET_32(pbuf_hdr->IP_AddrDest); Mem_Copy((void *)&addr_local[NET_SOCK_ADDR_IP_IX_PORT], (void *)&port_nbr, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&addr_local[NET_SOCK_ADDR_IP_IX_ADDR], (void *)&addr_ip, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); /* Cfg srch remote addr as pkt src addr. */ port_nbr = (NET_PORT_NBR)NET_UTIL_HOST_TO_NET_16(pbuf_hdr->TCP_UDP_PortSrc); addr_ip = (NET_IP_ADDR )NET_UTIL_HOST_TO_NET_32(pbuf_hdr->IP_AddrSrc); Mem_Copy((void *)&addr_remote[NET_SOCK_ADDR_IP_IX_PORT], (void *)&port_nbr, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&addr_remote[NET_SOCK_ADDR_IP_IX_ADDR], (void *)&addr_ip, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); #else /* See Note #5. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return; #endif conn_id = NetConn_Srch((NET_CONN_FAMILY ) family, /* Srch for conn'd sock whose local/remote .. */ (NET_CONN_LIST_IX ) protocol_ix, /* .. addrs are identical to pkt dest/src addrs.*/ (NET_CONN_LIST_TYPE) NET_CONN_LIST_TYPE_ALL, (CPU_BOOLEAN ) DEF_YES, (CPU_INT08U *)&addr_local[0], (CPU_INT08U *)&addr_remote[0], (NET_CONN_ADDR_LEN ) NET_SOCK_CFG_ADDR_LEN, (NET_CONN_ID *) 0, (NET_CONN_ID *)&sock_id); if (conn_id == NET_CONN_ID_NONE) { /* If fully conn'd sock NOT found, ... */ conn_id = NetConn_Srch((NET_CONN_FAMILY ) family, /* ... srch for non-conn'd sock whose local ... */ (NET_CONN_LIST_IX ) protocol_ix, /* ... addr is identical to pkt dest addr. */ (NET_CONN_LIST_TYPE) NET_CONN_LIST_TYPE_ALL, (CPU_BOOLEAN ) DEF_NO, (CPU_INT08U *)&addr_local[0], (CPU_INT08U *) 0, (NET_CONN_ADDR_LEN ) NET_SOCK_CFG_ADDR_LEN, (NET_CONN_ID *) 0, (NET_CONN_ID *)&sock_id); if (conn_id == NET_CONN_ID_NONE) { /* If NO sock conn found, rtn dest err. */ NET_CTR_ERR_INC(NetSock_ErrRxDestCtr); *perr = NET_ERR_RX_DEST; return; } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) conn = DEF_NO; /* Validate half-conn. */ #endif } else { #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) conn = DEF_YES; /* Validate full-conn. */ #endif } } /*$PAGE*/ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ used = NetSock_IsUsed(sock_id, &err); if (used != DEF_YES) { NetSock_CloseConn(conn_id); NET_CTR_ERR_INC(NetSock_ErrInvalidSockCtr); *perr = NET_SOCK_ERR_INVALID_SOCK; return; } #endif psock = &NetSock_Tbl[sock_id]; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK CONN ---------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; break; case NET_SOCK_STATE_CLOSED: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; break; case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: if (conn != DEF_NO) { NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return; } break; case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: if (conn != DEF_YES) { NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return; } break; case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return; /* Prevent 'break NOT reachable' compiler warning. */ } #endif /*$PAGE*/ /* ---------------- DEMUX PKT TO SOCK ----------------- */ pbuf_tail = psock->RxQ_Tail; if (pbuf_tail != (NET_BUF *)0) { /* If sock rx Q NOT empty, insert pkt after tail. */ pbuf_hdr_tail = (NET_BUF_HDR *)&pbuf_tail->Hdr; pbuf_hdr_tail->NextPrimListPtr = (void *) pbuf; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) q_prevly_empty = DEF_NO; #endif } else { /* Else add first pkt to sock rx Q. */ psock->RxQ_Head = (NET_BUF *) pbuf; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) q_prevly_empty = DEF_YES; #endif } psock->RxQ_Tail = (NET_BUF *)pbuf; /* Insert pkt @ Q tail. */ pbuf_hdr->PrevPrimListPtr = (void *)pbuf_tail; #if 0 /* Init'd in NetBuf_Get() [see Note #8]. */ pbuf_hdr->NextPrimListPtr = (void *)0; #endif switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: NetOS_Sock_RxQ_Signal(sock_id, perr); /* Signal rx Q for each datagram pkt (see Note #3a). */ break; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: if (q_prevly_empty == DEF_YES) { /* If stream rx Q prev'ly empty, ... */ NetOS_Sock_RxQ_Signal(sock_id, perr); /* .. signal rx Q now non-empty (see Note #3b). */ } break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #6. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); *perr = NET_SOCK_ERR_INVALID_TYPE; return; /* Prevent 'break NOT reachable' compiler warning. */ } if (*perr != NET_SOCK_ERR_NONE) { /* If sock rx Q signal failed, unlink pkt from Q. */ pbuf_tail = (NET_BUF *)pbuf_hdr->PrevPrimListPtr; if (pbuf_tail != (NET_BUF *)0) { /* If sock rx Q NOT yet empty, unlink last pkt from Q. */ pbuf_hdr_tail = (NET_BUF_HDR *)&pbuf_tail->Hdr; pbuf_hdr_tail->NextPrimListPtr = (void *) 0; } else { /* Else unlink last pkt from Q. */ psock->RxQ_Head = (NET_BUF *) 0; } psock->RxQ_Tail = (NET_BUF *)pbuf_tail; /* Set new sock rx Q tail. */ pbuf_hdr->PrevPrimListPtr = (void *)0; return; /* Rtn err from NetOS_Sock_RxQ_Signal(). */ } *perr = NET_SOCK_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RxPktDiscard() * * Description : On any Socket Receive errors, discard socket packet(s) & buffer(s). * * Argument(s) : pbuf Pointer to network buffer. * * perr Pointer to variable that will receive the return error code from this function : * * NET_ERR_RX Receive error; packet discarded. * * Return(s) : none. * * Caller(s) : NetSock_Rx(), * NetSock_RxDataHandlerDatagram(). * * Note(s) : none. ********************************************************************************************************* */ static void NetSock_RxPktDiscard (NET_BUF *pbuf, NET_ERR *perr) { NET_CTR *pctr; #if (NET_CTR_CFG_ERR_EN == DEF_ENABLED) pctr = (NET_CTR *)&NetSock_ErrRxPktDiscardedCtr; #else pctr = (NET_CTR *) 0; #endif NetBuf_FreeBufQ_PrimList((NET_BUF *)pbuf, (NET_CTR *)pctr); *perr = NET_ERR_RX; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_IsValidAddrLocal() * * Description : (1) Validate a socket address as a local address : * * (a) Validate socket address family type * (b) Validate socket address * (c) Validate socket port number * * * Argument(s) : paddr Pointer to socket address structure (see Note #2). * * addr_len Length of socket address structure (in octets). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket address successfully validated. * NET_SOCK_ERR_NULL_PTR Argument 'paddr' passed a NULL pointer. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address structure length. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket address family. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_INVALID_PORT_NBR Invalid socket port number. * * Return(s) : DEF_YES, if a valid local socket address. * * DEF_NO, otherwise. * * Caller(s) : NetSock_BindHandler(). * * Note(s) : (2) (a) Socket address structure 'Family' member MUST be configured in host-order & * MUST NOT be converted to/from network-order. * * (b) Socket address structure addresses MUST be configured/converted from host- * order to network-order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (3) Socket connection addresses are maintained in network-order. * * (4) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) static CPU_BOOLEAN NetSock_IsValidAddrLocal (NET_SOCK_ADDR *paddr, NET_SOCK_ADDR_LEN addr_len, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_SOCK_ADDR_IP *paddr_ip; NET_IP_ADDR addr_ip; #endif NET_SOCK_FAMILY family; NET_PORT_NBR port_nbr; CPU_BOOLEAN port_nbr_random; /* ------------------- VALIDATE PTR ------------------- */ if (paddr == (NET_SOCK_ADDR *)0) { NET_CTR_ERR_INC(NetSock_ErrNullPtrCtr); *perr = NET_SOCK_ERR_NULL_PTR; return (DEF_NO); } /* ---------------- VALIDATE ADDR LEN ----------------- */ if (addr_len != NET_SOCK_ADDR_SIZE) { NET_CTR_ERR_INC(NetSock_ErrInvalidAddrLenCtr); *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return (DEF_NO); } /* ------------------ VALIDATE ADDR ------------------- */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) paddr_ip = (NET_SOCK_ADDR_IP *)paddr; /* Validate addr family (see Note #2a). */ family = NET_UTIL_VAL_GET_HOST_16(&paddr_ip->Family); if (family != NET_SOCK_ADDR_FAMILY_IP_V4) { NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (DEF_NO); } /* Validate addr (see Note #2b). */ addr_ip = NET_UTIL_VAL_GET_NET_32(&paddr_ip->Addr); if (addr_ip != NetIP_AddrThisHost) { /* If req'd addr NOT this host's IP addr ... */ if (addr_ip != NET_SOCK_ADDR_IP_WILD_CARD) { /* ... or wildcard addr, ... */ NET_CTR_ERR_INC(NetSock_ErrInvalidAddrCtr); *perr = NET_SOCK_ERR_INVALID_ADDR; /* ... rtn err. */ return (DEF_NO); } } /* Validate port nbr (see Note #2b). */ port_nbr = NET_UTIL_VAL_GET_NET_16(&paddr_ip->Port); if (port_nbr == NET_SOCK_PORT_NBR_RESERVED) { NET_CTR_ERR_INC(NetSock_ErrInvalidPortNbrCtr); *perr = NET_SOCK_ERR_INVALID_PORT_NBR; return (DEF_NO); } port_nbr_random = NetSock_RandomPortNbrChkRange(port_nbr); if (port_nbr_random != DEF_NO) { /* If port nbr in random port nbr Q, rtn err. */ NET_CTR_ERR_INC(NetSock_ErrInvalidPortNbrCtr); *perr = NET_SOCK_ERR_INVALID_PORT_NBR; return (DEF_NO); } #else /* See Note #4. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (DEF_NO); #endif *perr = NET_SOCK_ERR_NONE; return (DEF_YES); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_IsValidAddrRemote() * * Description : (1) Validate a socket address as an appopriate remote address : * * (a) Validate remote socket address : * * (1) Validate the following socket address fields : * * (A) Validate socket address family type * (B) Validate socket port number * * (2) Validation ignores the following socket address fields : * * (A) Address field(s) Addresses will be validated by other * network layers * * (b) Validate remote socket address to socket's connection address * * * Argument(s) : paddr Pointer to socket address structure (see Note #2). * * addr_len Length of socket address structure (in octets). * * psock Pointer to socket. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket address successfully validated. * NET_SOCK_ERR_NULL_PTR Argument 'paddr' passed a NULL pointer. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket address family. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_CONN Invalid socket connection. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address structure length. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_INVALID_PORT_NBR Invalid socket port number. * * Return(s) : DEF_YES, if a valid remote socket address. * * DEF_NO, otherwise. * * Caller(s) : NetSock_Conn(), * NetSock_TxDataHandler(). *$PAGE* * Note(s) : (2) (a) Socket address structure 'Family' member MUST be configured in host-order & MUST * NOT be converted to/from network-order. * * (b) Socket address structure addresses MUST be configured/converted from host-order * to network-order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (3) (a) Socket connection addresses are maintained in network-order. * * (b) However, since the port number & address are copied from a network-order socket * address structure into a multi-octet array, they do NOT need to be converted * from host-order to network-order. * * (4) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. * * (5) (a) For datagram-type sockets, the remote address is NOT required to be static -- * even if the socket is in a connected state. In other words, any datagram-type * socket may receive or transmit from or to different remote addresses on each * or any separate socket operation. * * (b) (1) For stream-type sockets, the remote address MUST be static. In other words, * a stream-type socket MUST be connected to & use the same remote address for * ALL socket operations. * * (2) However, if the socket is NOT yet connected; then any valid remote address * may be validated for the socket connection. * * (6) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************* */ #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) static CPU_BOOLEAN NetSock_IsValidAddrRemote (NET_SOCK_ADDR *paddr, NET_SOCK_ADDR_LEN addr_len, NET_SOCK *psock, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_SOCK_ADDR_IP *paddr_ip; #endif #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) NET_CONN_ID conn_id; CPU_INT08U addr[NET_SOCK_CFG_ADDR_LEN]; CPU_BOOLEAN cmp; #endif NET_SOCK_FAMILY family; NET_PORT_NBR port_nbr; NET_ERR err; /*$PAGE*/ /* ------------------- VALIDATE PTR ------------------- */ if (paddr == (NET_SOCK_ADDR *)0) { NET_CTR_ERR_INC(NetSock_ErrNullPtrCtr); *perr = NET_SOCK_ERR_NULL_PTR; return (DEF_NO); } /* ---------------- VALIDATE ADDR LEN ----------------- */ if (addr_len != NET_SOCK_ADDR_SIZE) { NET_CTR_ERR_INC(NetSock_ErrInvalidAddrLenCtr); *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return (DEF_NO); } /* ------------------ VALIDATE ADDR ------------------- */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) paddr_ip = (NET_SOCK_ADDR_IP *)paddr; /* Validate addr family (see Note #2a). */ family = NET_UTIL_VAL_GET_HOST_16(&paddr_ip->Family); if (family != NET_SOCK_ADDR_FAMILY_IP_V4) { NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (DEF_NO); } /* Validate port nbr (see Note #2b). */ port_nbr = NET_UTIL_VAL_GET_NET_16(&paddr_ip->Port); if (port_nbr == NET_SOCK_PORT_NBR_RESERVED) { NET_CTR_ERR_INC(NetSock_ErrInvalidPortNbrCtr); *perr = NET_SOCK_ERR_INVALID_PORT_NBR; return (DEF_NO); } #else /* See Note #4. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (DEF_NO); #endif /* ------------- VALIDATE SOCK CONN STATE ------------- */ if (psock != (NET_SOCK *)0) { /* If sock avail, chk conn status/addr. */ switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_CONN: /* Remote addr validation NOT req'd (see Note #5a). */ break; case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_CLOSED_FAULT: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ } break; /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: /* Remote addr validation NOT req'd (see Note #5b2). */ break; case NET_SOCK_STATE_CONN: /* Validate sock's conn remote addr (see Note #5b1). */ case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: conn_id = psock->ID_Conn; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) if (conn_id == NET_CONN_ID_NONE) { NET_CTR_ERR_INC(NetSock_ErrInvalidConnCtr); *perr = NET_SOCK_ERR_INVALID_CONN; return (DEF_NO); } #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) /* Cfg cmp addr in net-order (see Note #3). */ Mem_Copy((void *)&addr[NET_SOCK_ADDR_IP_IX_PORT], (void *)&paddr_ip->Port, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&addr[NET_SOCK_ADDR_IP_IX_ADDR], (void *)&paddr_ip->Addr, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); #else /* See Note #4. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (DEF_NO); #endif cmp = NetConn_AddrRemoteCmp((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr[0], (NET_CONN_ADDR_LEN) NET_SOCK_CFG_ADDR_LEN, (NET_ERR *)&err); if (cmp != DEF_YES) { /* If sock's remote addr does NOT cmp, rtn err. */ NET_CTR_ERR_INC(NetSock_ErrInvalidAddrCtr); *perr = NET_SOCK_ERR_INVALID_ADDR; return (DEF_NO); } break; case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #6. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); *perr = NET_SOCK_ERR_INVALID_TYPE; return (DEF_NO); /* Prevent 'break NOT reachable' compiler warning. */ } } *perr = NET_SOCK_ERR_NONE; return (DEF_YES); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CloseHandlerStream() * * Description : (1) Close a stream-type socket : * * (a) Validate socket connection state * (b) Request transport layer connection close * (c) Wait on transport layer connection close * (d) Close socket * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to close. * ------- Argument checked in NetSock_Close(). * * psock Pointer to socket. * ----- Argument validated in NetSock_Close(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully closed. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_CONN_CLOSE_IN_PROGRESS Socket close already in progress. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * * - RETURNED BY NetOS_Sock_ConnCloseWait() : - * NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT Socket connection close NOT signaled by * timeout. * * - RETURNED BY NetConn_ID_TransportGet() : -- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * -------- RETURNED BY NetOS_Lock() : -------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : NET_SOCK_BSD_ERR_NONE, if NO errors (see Note #3). * * NET_SOCK_BSD_ERR_CLOSE, otherwise. * * Caller(s) : NetSock_Close(). * * Note(s) : (2) Network resources MUST be appropriately closed : * * (a) For the following socket connection close conditions, close ALL socket connections : * * (1) Non-connected socket states * (2) On any socket fault(s) * (3) On any transport layer fault(s) * * (b) #### For connection-closing socket states : * * (1) Close socket connection * (2) Do NOT close socket connection's reference to network connection * (3) Do NOT close transport connection(s); transport layer responsible for * closing its remaining connection(s) * * (c) (1) For the following socket connection close conditions ... : * * (A) For non-blocking, connected socket states * (B) For connection-closed socket states * * (2) ... perform the following close actions : * * (A) Close socket connection * (B) Close socket connection's reference to network connection * (C) Do NOT close transport connection(s); transport layer responsible for * closing its remaining connection(s) * * (3) NO BSD socket error is returned for any internal error while closing the socket. * * (4) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be compiled/linked * since 'net_sock.h' ensures that the family type configuration constant (NET_SOCK_CFG_FAMILY) * is configured with an appropriate family type value (see 'net_sock.h CONFIGURATION ERRORS'). * The 'else'-conditional code is included for completeness & as an extra precaution in case * 'net_sock.h' is incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_SOCK_RTN_CODE NetSock_CloseHandlerStream (NET_SOCK_ID sock_id, NET_SOCK *psock, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; CPU_BOOLEAN block; NET_ERR err; /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_CLOSE); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: /* If already CLOSED from internal fault(s), ... */ NetSock_Free(psock); /* ... sock need ONLY be freed. */ *perr = NET_SOCK_ERR_CLOSED; /* Rtn net sock err but rtn NO BSD err. */ return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_BOUND: NetSock_CloseHandler(psock, DEF_YES, DEF_YES); /* See Note #2a1. */ *perr = NET_SOCK_ERR_NONE; return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: psock->State = NET_SOCK_STATE_CLOSE_IN_PROGRESS; break; case NET_SOCK_STATE_CLOSE_IN_PROGRESS: /* See Note #2b. */ case NET_SOCK_STATE_CLOSING_DATA_AVAIL: /* #### Net conn(s) prev'ly closed? (See Note #2b) */ NetSock_CloseHandler((NET_SOCK *)psock, /* See Note #2b1. */ (CPU_BOOLEAN)DEF_NO, /* See Note #2b2. */ (CPU_BOOLEAN)DEF_NO); /* See Note #2b3. */ *perr = NET_SOCK_ERR_CONN_CLOSE_IN_PROGRESS; /* #### Rtn net sock err ... */ /* ... but rtn NO BSD err (see Note #3). */ return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: default: /* See Note #2a2. */ NetSock_CloseSockFromClose(psock); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; /* Rtn net sock err but rtn NO BSD err (see Note #3). */ return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* ------------- REQ TRANSPORT CONN CLOSE ------------- */ conn_id = psock->ID_Conn; conn_id_transport = NetConn_ID_TransportGet(conn_id, perr); if (*perr != NET_CONN_ERR_NONE) { /* See Note #2a2. */ NetSock_CloseSockFromClose(psock); return (NET_SOCK_BSD_ERR_NONE); } #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT NetTCP_ConnReqClose((NET_TCP_CONN_ID) conn_id_transport, (CPU_INT08U ) NET_CONN_CLOSE_FULL, (NET_ERR *)&err); *perr = (err != NET_TCP_ERR_NONE) ? NET_SOCK_ERR_CONN_FAIL : NET_SOCK_ERR_NONE; #else (void)&conn_id_transport; /* Prevent compiler warning. */ *perr = NET_SOCK_ERR_CONN_FAIL; #endif #else /* See Notes #4 & #2a2. */ NetSock_CloseSockFromClose(psock); NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; /* Rtn net sock err ... */ return (NET_SOCK_BSD_ERR_NONE); /* ... but rtn NO BSD err (see Note #3). */ #endif if (*perr != NET_SOCK_ERR_NONE) { /* See Note #2a3. */ NetSock_CloseSockFromClose(psock); /* Rtn net sock err ... */ return (NET_SOCK_BSD_ERR_NONE); /* ... but rtn NO BSD err (see Note #3). */ } /* ----------- WAIT ON TRANSPORT CONN CLOSE ----------- */ #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_BLOCK) block = DEF_YES; #elif (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_NO_BLOCK) block = DEF_NO; #else block = DEF_YES; #endif if (block != DEF_YES) { /* If non-blocking sock conn, ... */ NetSock_CloseHandler((NET_SOCK *)psock, /* ... close sock (see Note #2c1A). */ (CPU_BOOLEAN)DEF_YES, /* See Note #2c2B. */ (CPU_BOOLEAN)DEF_NO); /* See Note #2c2C. */ *perr = NET_SOCK_ERR_NONE; return (NET_SOCK_BSD_ERR_NONE); } NetOS_Unlock(); NetOS_Sock_ConnCloseWait(sock_id, perr); NetOS_Lock(&err); if ( err != NET_OS_ERR_NONE) { /* See Note #2a2. */ NetSock_CloseSockFromClose(psock); *perr = err; /* Rtn err from NetOS_Lock() ... */ return (NET_SOCK_BSD_ERR_NONE); /* ... but rtn NO BSD err (see Note #3). */ } switch (*perr) { case NET_SOCK_ERR_NONE: break; case NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT: NetSock_CloseSockFromClose(psock); /* See Note #2a2. */ /* Rtn err from NetOS_Sock_ConnCloseWait() ... */ /* ... but rtn NO BSD err (see Note #3). */ return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_ERR_CONN_SIGNAL_ABORT: case NET_SOCK_ERR_CONN_SIGNAL_FAULT: default: NetSock_CloseSockFromClose(psock); /* See Note #2a2. */ *perr = NET_SOCK_ERR_FAULT; /* Rtn net sock err but rtn NO BSD err (see Note #3). */ return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ } /* -------------------- CLOSE SOCK -------------------- */ NetSock_CloseHandler((NET_SOCK *)psock, /* See Note #2c1B. */ (CPU_BOOLEAN)DEF_YES, /* See Note #2c2B. */ (CPU_BOOLEAN)DEF_NO); /* See Note #2c2C. */ *perr = NET_SOCK_ERR_NONE; return (NET_SOCK_BSD_ERR_NONE); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_BindHandler() * * Description : (1) Bind a local address to a socket : * * (a) Handle socket type connection * (b) Validate socket local address * (c) Search for other socket(s) with same local address See Note #8 * (d) Add local address into socket connection * (1) Get & configure socket connection, if necessary * (2) Set socket connection local address * (3) Add socket connection into connection list * (e) Update socket connection state * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to bind to a local address. * ------- Argument checked in NetSock_Bind(), * NetSock_ConnHandlerDatagram(), * NetSock_ConnHandlerStream(), * NetSock_TxDataHandlerDatagram(). * * paddr_local Pointer to socket address structure. * * addr_len Length of socket address structure (in octets). * * addr_random_reqd Indicate whether a random address is requested (see Note #4) : * * DEF_NO Random address NOT requested. * DEF_YES Random address is requested. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully bound to local address. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_ADDR Invalid local address. * NET_SOCK_ERR_ADDR_IN_USE Local address already in use (see Note #8). * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * * -- RETURNED BY NetConn_AddrRemoteGet() : --- * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * * - RETURNED BY NetSock_RandomPortNbrGet() : - * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * * ------- RETURNED BY NetConn_Get() : -------- * NET_CONN_ERR_NONE_AVAIL NO available connections to allocate. * NET_CONN_ERR_INVALID_FAMILY Invalid network connection family. * NET_CONN_ERR_INVALID_TYPE Invalid network connection type. * NET_CONN_ERR_INVALID_LIST_IX Invalid network connection list index. * * ---- RETURNED BY NetConn_ID_AppSet() : ----- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection(s) NOT currently used. * * --- RETURNED BY NetConn_AddrLocalSet() : --- * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * Return(s) : NET_SOCK_BSD_ERR_NONE, if NO errors. * * NET_SOCK_BSD_ERR_BIND, otherwise. * * Caller(s) : NetSock_Bind(), * NetSock_ConnHandlerDatagram(), * NetSock_ConnHandlerStream(), * NetSock_TxDataHandlerDatagram(). *$PAGE* * Note(s) : (2) (a) Socket connection addresses MUST be maintained in network-order. * * (b) However, since the port number & address are copied from a network-order socket address * structure into local variables & then into a multi-octet array, they do NOT need to be * converted from host-order to network-order. * * (3) (a) For datagram-type sockets, the local & remote addresses are NOT required to be static -- * even if the socket is in a "connected" state. In other words, any datagram-type socket * may bind to different local addresses on each or any separate socket operation. * * (b) For stream-type sockets, the local & remote addresses MUST be static. In other words, * a stream-type socket may bind only once to a single local address. * * (4) If a random local address is requested, ... * * (a) Configure the local address with ... * (1) A random port number obtained from the random port number queue; ... * (2) This host's protocol address. * * (b) And if no remote address is configured for the current socket state, configure the * connection list type as a server connection since the socket's only valid address * will be its local address & server connection lists are organized primarily by each * connections' local address (see 'net_conn.c NetConn_ListSrch() Note #1a1'). * * (5) Default case already invalidated in NetSock_Open(). However, the default case is included * as an extra precaution in case 'SockType' is incorrectly modified. * * (6) Default case already invalidated in NetSock_Open(). However, the default case is included * as an extra precaution in case 'Protocol' is incorrectly modified. * * (7) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be compiled/linked * since 'net_sock.h' ensures that the family type configuration constant (NET_SOCK_CFG_FAMILY) * is configured with an appropriate family type value (see 'net_sock.h CONFIGURATION ERRORS'). * The 'else'-conditional code is included for completeness & as an extra precaution in case * 'net_sock.h' is incorrectly modified. * * (8) (a) Multiple sockets with the same local address -- both address & port number -- is currently * NOT supported. In other words, the option for sockets to reuse of the same local address * is NOT supported even if the socket reuse option (SO_REUSEADDR) is enabled. * * (b) All sockets whether fully-connected or half-connected MUST be added into connection lists * in order to validate sockets for unique local addresses. * * See also 'net_sock.c Note #1d1' & 'NetSock_ConnHandlerAddrRemoteValidate() Note #5'. ********************************************************************************************************* */ static NET_SOCK_RTN_CODE NetSock_BindHandler (NET_SOCK_ID sock_id, NET_SOCK_ADDR *paddr_local, NET_SOCK_ADDR_LEN addr_len, CPU_BOOLEAN addr_random_reqd, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_SOCK_ADDR_IP *paddr_ip; NET_IP_ADDR addr_ip; #endif #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) CPU_BOOLEAN valid; #endif CPU_BOOLEAN conn_avail; CPU_BOOLEAN addr_remote_avail; CPU_BOOLEAN addr_over_wr; NET_PORT_NBR port_nbr; CPU_INT08U addr_local[NET_SOCK_CFG_ADDR_LEN]; CPU_INT08U addr_remote[NET_SOCK_CFG_ADDR_LEN]; NET_SOCK_ADDR_LEN addr_remote_len; CPU_INT08U *paddr_remote; NET_SOCK *psock; NET_SOCK_STATE sock_state; NET_CONN_FAMILY conn_family; NET_CONN_LIST_IX conn_protocol_ix; NET_CONN_LIST_TYPE conn_list_type; NET_CONN_ID conn_id; NET_CONN_ID conn_id_conn; NET_ERR err; /*$PAGE*/ /* ----------------- HANDLE SOCK TYPE ----------------- */ psock = &NetSock_Tbl[sock_id]; switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: /* See Note #3a. */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_BIND); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_BIND); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: conn_avail = DEF_NO; addr_over_wr = DEF_NO; addr_remote_avail = DEF_NO; paddr_remote = (CPU_INT08U *)0; /* Cfg conn's conn list type (see Note #4b). */ conn_list_type = NET_CONN_LIST_TYPE_SERVER; sock_state = NET_SOCK_STATE_BOUND; break; case NET_SOCK_STATE_BOUND: conn_avail = DEF_YES; addr_over_wr = DEF_YES; addr_remote_avail = DEF_NO; paddr_remote = (CPU_INT08U *)0; /* Cfg conn's conn list type (see Note #4b). */ conn_list_type = NET_CONN_LIST_TYPE_SERVER; sock_state = NET_SOCK_STATE_BOUND; break; case NET_SOCK_STATE_CONN: conn_avail = DEF_YES; addr_over_wr = DEF_YES; addr_remote_avail = DEF_YES; /* Get sock's remote addr. */ conn_id = psock->ID_Conn; addr_remote_len = sizeof(addr_remote); NetConn_AddrRemoteGet((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr_remote[0], (NET_CONN_ADDR_LEN *)&addr_remote_len, (NET_ERR *)&err); if (err != NET_CONN_ERR_NONE) { return (NET_SOCK_BSD_ERR_BIND); } paddr_remote = &addr_remote[0]; /* Get conn's conn list type. */ conn_list_type = NetConn_GetConnListType(conn_id, &err); if (err != NET_CONN_ERR_NONE) { return (NET_SOCK_BSD_ERR_BIND); } sock_state = NET_SOCK_STATE_CONN; break; case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_BIND); /* Prevent 'break NOT reachable' compiler warning. */ } break; /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: /* See Note #3b. */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_BIND); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_BIND); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: conn_avail = DEF_NO; addr_over_wr = DEF_NO; addr_remote_avail = DEF_NO; paddr_remote = (CPU_INT08U *)0; /* Cfg conn's conn list type (see Note #4b). */ conn_list_type = NET_CONN_LIST_TYPE_SERVER; sock_state = NET_SOCK_STATE_BOUND; break; case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return (NET_SOCK_BSD_ERR_BIND); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_BIND); /* Prevent 'break NOT reachable' compiler warning. */ } break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #5. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_SOCK_BSD_ERR_BIND); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* ------------- VALIDATE/CFG LOCAL ADDR -------------- */ if (addr_random_reqd != DEF_YES) { /* If random addr NOT req'd, validate local addr. */ #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) valid = NetSock_IsValidAddrLocal(paddr_local, addr_len, perr); if (valid != DEF_YES) { *perr = NET_SOCK_ERR_INVALID_ADDR; return (NET_SOCK_BSD_ERR_BIND); } #endif } else { /* Else get random port nbr (see Note #4a1). */ port_nbr = NetSock_RandomPortNbrGet(perr); if (*perr != NET_SOCK_ERR_NONE) { return (NET_SOCK_BSD_ERR_BIND); } } /* ------- SRCH FOR LOCAL ADDR IN CONN LIST(S) -------- */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) if (addr_random_reqd != DEF_YES) { /* If random addr NOT req'd, cfg req'd local addr. */ paddr_ip = (NET_SOCK_ADDR_IP *)paddr_local; NET_UTIL_VAL_COPY_16(&port_nbr, &paddr_ip->Port); /* Copy preserves net-order (see Note #2b). */ NET_UTIL_VAL_COPY_32(&addr_ip, &paddr_ip->Addr); /* Copy preserves net-order (see Note #2b). */ } else { /* Else cfg random port/this host's addr (see Note #4a).*/ port_nbr = NET_UTIL_HOST_TO_NET_16(port_nbr); addr_ip = NET_UTIL_HOST_TO_NET_32(NetIP_AddrThisHost); } /* Cfg local addr as net-order sock addr (see Note #2). */ Mem_Copy((void *)&addr_local[NET_SOCK_ADDR_IP_IX_PORT], (void *)&port_nbr, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&addr_local[NET_SOCK_ADDR_IP_IX_ADDR], (void *)&addr_ip, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); /* Cfg conn srch. */ conn_family = NET_CONN_FAMILY_IP_V4_SOCK; switch (psock->Protocol) { case NET_SOCK_PROTOCOL_UDP: conn_protocol_ix = NET_CONN_LIST_IX_IP_V4_SOCK_UDP; break; #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: conn_protocol_ix = NET_CONN_LIST_IX_IP_V4_SOCK_TCP; break; #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Note #6. */ NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return (NET_SOCK_BSD_ERR_BIND); /* Prevent 'break NOT reachable' compiler warning. */ } #else /* See Note #7. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_SOCK_BSD_ERR_BIND); #endif /* Srch for sock conn with identical local addr. */ conn_id_conn = NetConn_Srch((NET_CONN_FAMILY ) conn_family, (NET_CONN_LIST_IX ) conn_protocol_ix, (NET_CONN_LIST_TYPE) NET_CONN_LIST_TYPE_ALL, (CPU_BOOLEAN ) addr_remote_avail, (CPU_INT08U *)&addr_local[0], (CPU_INT08U *)paddr_remote, (NET_CONN_ADDR_LEN ) NET_SOCK_CFG_ADDR_LEN, (NET_CONN_ID *) 0, (NET_CONN_ID *) 0); if (conn_id_conn != NET_CONN_ID_NONE) { /* If local addr already conn'd, ... */ NET_CTR_ERR_INC(NetSock_ErrInvalidAddrInUseCtr); *perr = NET_SOCK_ERR_ADDR_IN_USE; /* ... rtn err (see Note #8). */ return (NET_SOCK_BSD_ERR_BIND); } /*$PAGE*/ /* ----------- ADD LOCAL ADDR TO SOCK CONN ------------ */ if (conn_avail != DEF_YES) { /* If NO conn prev'ly avail, get/cfg sock conn. */ conn_id = NetConn_Get(conn_family, conn_protocol_ix, perr); if (*perr != NET_CONN_ERR_NONE) { return (NET_SOCK_BSD_ERR_BIND); } psock->ID_Conn = conn_id; /* Set sock's conn id. */ NetConn_ID_AppSet((NET_CONN_ID)conn_id, (NET_CONN_ID)psock->ID, (NET_ERR *)perr); if (*perr != NET_CONN_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); return (NET_SOCK_BSD_ERR_BIND); } } else { /* Else get sock's conn id. */ conn_id = psock->ID_Conn; } /* Set sock's local addr. */ NetConn_AddrLocalSet((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr_local[0], (NET_CONN_ADDR_LEN) NET_SOCK_CFG_ADDR_LEN, (CPU_BOOLEAN ) addr_over_wr, (NET_ERR *) perr); if (*perr != NET_CONN_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); return (NET_SOCK_BSD_ERR_BIND); } if (conn_avail != DEF_NO) { /* If conn prev'ly avail, ... */ NetConn_ListUnlink(conn_id, &err); /* ... unlink conn from prev conn list. */ if (err != NET_CONN_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_CONN_FAIL; return (NET_SOCK_BSD_ERR_BIND); } } NetConn_ListAdd(conn_id, conn_list_type, &err); /* Add sock conn into conn list. */ if (err != NET_CONN_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_CONN_FAIL; return (NET_SOCK_BSD_ERR_BIND); } /* -------------- UPDATE SOCK CONN STATE -------------- */ psock->State = sock_state; *perr = NET_SOCK_ERR_NONE; return (NET_SOCK_BSD_ERR_NONE); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnHandlerDatagram() * * Description : (1) Connect a datagram-type socket to a remote address : * * (a) Validate socket connection state * (b) Validate remote address for socket connection * (c) Add remote address into socket connection * (1) Bind to local address, if necessary * (2) Set socket connection remote address * (3) Add socket connection into client connection list * (d) Update socket connection state * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to connect. * ------- Argument checked in NetSock_Conn(). * * psock Pointer to socket. * ----- Argument validated in NetSock_Conn(). * * paddr_remote Pointer to socket address structure. * ------------ Argument checked in NetSock_Conn(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully connected. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * * - RETURNED BY NetSock_ConnHandlerAddrRemoteValidate() : - * --- RETURNED BY NetSock_ConnHandlerAddrRemoteSet() : ---- * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address structure length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * NET_SOCK_ERR_CONN_IN_USE Socket connection already in use. * * ---------- RETURNED BY NetSock_BindHandler() : ---------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_ADDR_IN_USE Socket address already in use. * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_NONE_AVAIL NO available connections to allocate. * NET_CONN_ERR_NOT_USED Network connection(s) NOT currently used. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_INVALID_FAMILY Invalid network connection family. * NET_CONN_ERR_INVALID_TYPE Invalid network connection type. * NET_CONN_ERR_INVALID_LIST_IX Invalid network connection list index. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * Return(s) : NET_SOCK_BSD_ERR_NONE, if NO errors. * * NET_SOCK_BSD_ERR_CONN, otherwise. * * Caller(s) : NetSock_Conn(). * * Note(s) : (2) (a) For datagram-type sockets, the remote address does NOT require any connection. The * pseudo-connection provides a remote address to allow datagram-type sockets to use * stream-type sockets' send & receive functions -- NetSock_RxData() & NetSock_TxData(). * * (b) In addition, the remote address is NOT required to be static -- even if the socket * is in a "connected" state. In other words, any datagram-type socket may "connect" * to different remote addresses on each or any separate socket operation. ********************************************************************************************************* */ static NET_SOCK_RTN_CODE NetSock_ConnHandlerDatagram (NET_SOCK_ID sock_id, NET_SOCK *psock, NET_SOCK_ADDR *paddr_remote, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_CONN_ID conn_id; NET_ERR err; /*$PAGE*/ /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_CONN: /* See Note #2b. */ case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: break; case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------- VALIDATE SOCK CONN REMOTE ADDR ---------- */ NetSock_ConnHandlerAddrRemoteValidate(psock, paddr_remote, perr); if (*perr != NET_SOCK_ERR_NONE) { return (NET_SOCK_BSD_ERR_CONN); } #endif /* ----------- ADD REMOTE ADDR TO SOCK CONN ----------- */ if (psock->State == NET_SOCK_STATE_CLOSED) { /* If sock closed, bind to random local addr. */ (void)NetSock_BindHandler((NET_SOCK_ID )sock_id, (NET_SOCK_ADDR *)0, (NET_SOCK_ADDR_LEN)0, (CPU_BOOLEAN )DEF_YES, (NET_ERR *)perr); if (*perr != NET_SOCK_ERR_NONE) { return (NET_SOCK_BSD_ERR_CONN); } } /* Set sock's remote addr. */ NetSock_ConnHandlerAddrRemoteSet(psock, paddr_remote, DEF_YES, perr); if (*perr != NET_SOCK_ERR_NONE) { return (NET_SOCK_BSD_ERR_CONN); } /* Re-insert sock conn into client list. */ conn_id = psock->ID_Conn; NetConn_ListUnlink(conn_id, &err); /* Unlink sock conn from prev conn list. */ if (err != NET_CONN_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_CONN_FAIL; return (NET_SOCK_BSD_ERR_CONN); } NetConn_ListAdd(conn_id, NET_CONN_LIST_TYPE_CLIENT, &err); /* Add sock conn into client conn list. */ if (err != NET_CONN_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_CONN_FAIL; return (NET_SOCK_BSD_ERR_CONN); } /* -------------- UPDATE SOCK CONN STATE -------------- */ psock->State = NET_SOCK_STATE_CONN; *perr = NET_SOCK_ERR_NONE; return (NET_SOCK_BSD_ERR_NONE); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnHandlerStream() * * Description : (1) Connect a stream-type socket to a remote address : * * (a) Validate socket connection state * (b) Validate remote address for socket connection * (c) Prepare socket for remote connection * (1) Bind to local address, if necessary * (d) Configure socket transport connection * (e) Add remote address into socket connection * (1) Set socket connection remote address * (2) Add socket connection into client connection list * (f) Initiate transport layer connection * (1) Get transport connection * (2) Transmit transport connection request * (3) Wait on transport connection to connect * (g) Update socket connection state * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to connect. * ------- Argument checked in NetSock_Conn(). * * psock Pointer to socket. * ----- Argument validated in NetSock_Conn(). * * paddr_remote Pointer to socket address structure. * ------------ Argument checked in NetSock_Conn(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully connected. * NET_SOCK_ERR_CONN_IN_PROGRESS Socket connection in progress. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address length. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * * --------- RETURNED BY NetConn_AddrLocalGet() : ---------- * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection(s) NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * * - RETURNED BY NetSock_ConnHandlerAddrRemoteValidate() : - * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address structure length. * NET_SOCK_ERR_CONN_IN_USE Socket connection already in use. * * ---------- RETURNED BY NetSock_BindHandler() : ---------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_ADDR_IN_USE Socket address already in use. * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * NET_CONN_ERR_NONE_AVAIL NO available connections to allocate. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_INVALID_FAMILY Invalid network connection family. * NET_CONN_ERR_INVALID_TYPE Invalid network connection type. * NET_CONN_ERR_INVALID_LIST_IX Invalid network connection list index. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * -------- RETURNED BY NetOS_Sock_ConnReqWait() : --------- * NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT Socket connection request NOT signaled by timeout. * * -------------- RETURNED BY NetOS_Lock() : --------------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : NET_SOCK_BSD_ERR_NONE, if NO errors. * * NET_SOCK_BSD_ERR_CONN, otherwise. * * Caller(s) : NetSock_Conn(). *$PAGE* * Note(s) : (2) (a) For stream-type sockets, the remote address MUST be static. In other words, * a stream-type socket MUST be connected to & use the same remote address for * ALL socket operations. * * (b) In addition, the socket MUST be connected to the remote address PRIOR to any * data transmit or receive operation. * * (c) Stream-type sockets may connect to remote addresses from the following states : * * (1) CLOSED * (2) BOUND See Note #2d * (3) LISTEN See Note #2d * * (d) Stream-type sockets MUST be bound to a valid local address that is NOT a * protocol's wildcard address. * * (3) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. * * (4) #### IP layer parameters/options NOT yet implemented. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_SOCK_RTN_CODE NetSock_ConnHandlerStream (NET_SOCK_ID sock_id, NET_SOCK *psock, NET_SOCK_ADDR *paddr_remote, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_IP_ADDR addr_src; CPU_INT08U addr_local[NET_SOCK_CFG_ADDR_LEN]; NET_SOCK_ADDR_LEN addr_len; #endif NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; CPU_BOOLEAN block; NET_ERR err; /*$PAGE*/ /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: /* See Note #2c1. */ break; case NET_SOCK_STATE_BOUND: /* Chk valid local addr (see Note #2d). */ case NET_SOCK_STATE_LISTEN: #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) conn_id = psock->ID_Conn; addr_len = sizeof(addr_local); NetConn_AddrLocalGet((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr_local[0], (NET_CONN_ADDR_LEN *)&addr_len, (NET_ERR *) perr); if (*perr != NET_CONN_ERR_NONE) { return (NET_SOCK_BSD_ERR_CONN); } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) if (addr_len != NET_SOCK_CFG_ADDR_LEN) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return (NET_SOCK_BSD_ERR_CONN); } #endif Mem_Copy((void *)&addr_src, (void *)&addr_local[NET_SOCK_ADDR_IP_IX_ADDR], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); addr_src = NET_UTIL_NET_TO_HOST_32(addr_src); if (addr_src == NET_SOCK_ADDR_IP_WILD_CARD) { /* If wildcard addr, ... */ *perr = NET_SOCK_ERR_INVALID_ADDR; /* ... rtn invalid addr. */ return (NET_SOCK_BSD_ERR_CONN); } break; #else /* See Note #3. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ #endif case NET_SOCK_STATE_CONN_IN_PROGRESS: *perr = NET_SOCK_ERR_CONN_IN_PROGRESS; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CONN_DONE: psock->State = NET_SOCK_STATE_CONN; *perr = NET_SOCK_ERR_NONE; return (NET_SOCK_BSD_ERR_NONE); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------- VALIDATE SOCK CONN REMOTE ADDR ---------- */ NetSock_ConnHandlerAddrRemoteValidate(psock, paddr_remote, perr); if (*perr != NET_SOCK_ERR_NONE) { return (NET_SOCK_BSD_ERR_CONN); } #endif /* ----------- PREPARE SOCK FOR REMOTE CONN ----------- */ if (psock->State == NET_SOCK_STATE_CLOSED) { /* If sock closed, bind to random local addr. */ (void)NetSock_BindHandler((NET_SOCK_ID )sock_id, (NET_SOCK_ADDR *)0, (NET_SOCK_ADDR_LEN)0, (CPU_BOOLEAN )DEF_YES, (NET_ERR *)perr); if (*perr != NET_SOCK_ERR_NONE) { return (NET_SOCK_BSD_ERR_CONN); } } /* ----------- ADD REMOTE ADDR TO SOCK CONN ----------- */ /* Set sock's remote addr. */ NetSock_ConnHandlerAddrRemoteSet(psock, paddr_remote, DEF_NO, perr); if (*perr != NET_SOCK_ERR_NONE) { return (NET_SOCK_BSD_ERR_CONN); } /* Insert sock conn into client list. */ conn_id = psock->ID_Conn; NetConn_ListUnlink(conn_id, &err); /* Unlink sock conn from prev conn list. */ if (err != NET_CONN_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_CONN_FAIL; return (NET_SOCK_BSD_ERR_CONN); } NetConn_ListAdd(conn_id, NET_CONN_LIST_TYPE_CLIENT, &err); /* Add sock conn into client conn list. */ if (err != NET_CONN_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_CONN_FAIL; return (NET_SOCK_BSD_ERR_CONN); } /*$PAGE*/ /* ---------------- GET TRANSPORT CONN ---------------- */ conn_id_transport = NetSock_GetConnTransport(psock, perr); if (*perr != NET_SOCK_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); return (NET_SOCK_BSD_ERR_CONN); } /* --------------- INIT TRANSPORT CONN ---------------- */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT NetTCP_TxConnReq((NET_TCP_CONN_ID) conn_id_transport, (NET_IP_TOS ) NET_IP_TOS_DFLT, /* #### See Note #4. */ (NET_IP_TTL ) NET_IP_TTL_DFLT, (CPU_INT16U ) NET_IP_FLAG_NONE, (void *) 0, (NET_ERR *)&err); switch (err) { case NET_TCP_ERR_NONE: *perr = NET_SOCK_ERR_NONE; break; case NET_TCP_ERR_CONN_NOT_USED: case NET_TCP_ERR_CONN_FAULT: case NET_TCP_ERR_CONN_CLOSE: case NET_TCP_ERR_INVALID_CONN: case NET_TCP_ERR_INVALID_CONN_STATE: case NET_TCP_ERR_TX: *perr = NET_SOCK_ERR_FAULT; break; default: *perr = NET_ERR_TX; break; } #else (void)&conn_id_transport; /* Prevent compiler warning. */ *perr = NET_ERR_TX; #endif #else /* See Note #3. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_SOCK_BSD_ERR_CONN); #endif switch (*perr) { case NET_SOCK_ERR_NONE: case NET_ERR_TX: break; case NET_SOCK_ERR_FAULT: NetSock_CloseSock(psock, DEF_YES, DEF_YES); return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ default: return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* -------------- WAIT ON TRANSPORT CONN -------------- */ #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_BLOCK) block = DEF_YES; #elif (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_NO_BLOCK) block = DEF_NO; #else block = DEF_YES; #endif if (block != DEF_YES) { /* If non-blocking sock conn ... */ psock->State = NET_SOCK_STATE_CONN_IN_PROGRESS; *perr = NET_SOCK_ERR_CONN_IN_PROGRESS; /* ... rtn not-yet-conn'd err. */ return (NET_SOCK_BSD_ERR_CONN); } NetOS_Unlock(); NetOS_Sock_ConnReqWait(sock_id, perr); NetOS_Lock(&err); if ( err != NET_OS_ERR_NONE) { *perr = err; /* Rtn err from NetOS_Lock(). */ return (NET_SOCK_BSD_ERR_CONN); } switch (*perr) { case NET_SOCK_ERR_NONE: break; case NET_SOCK_ERR_CONN_SIGNAL_TIMEOUT: /* Rtn err from NetOS_Sock_ConnReqWait(). */ return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_ERR_CONN_SIGNAL_ABORT: case NET_SOCK_ERR_CONN_SIGNAL_FAULT: default: *perr = NET_SOCK_ERR_FAULT; return (NET_SOCK_BSD_ERR_CONN); /* Prevent 'break NOT reachable' compiler warning. */ } /* -------------- UPDATE SOCK CONN STATE -------------- */ psock->State = NET_SOCK_STATE_CONN; *perr = NET_SOCK_ERR_NONE; return (NET_SOCK_BSD_ERR_NONE); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnHandlerAddrRemoteValidate() * * Description : (1) Validate socket remote address : * * (a) Validate socket connection See Note #5c * (b) Search for other socket connection(s) with same * local/remote addresses See Note #5 * * * Argument(s) : psock Pointer to socket. * ----- Argument validated in NetSock_Conn(). * * paddr_remote Pointer to socket address structure. * ------------ Argument checked in NetSock_Conn(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket remote address validated. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address structure length. * NET_SOCK_ERR_CONN_IN_USE Socket connection already in use. * * - RETURNED BY NetConn_AddrLocalGet() : - * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * * Return(s) : none. * * Caller(s) : NetSock_ConnHandlerDatagram(), * NetSock_ConnHandlerStream(). * * Note(s) : (2) (a) Socket connection addresses MUST be maintained in network-order. * * (b) However, since the port number & address are copied from a network-order socket * address structure into local variables & then into a multi-octet array, they do * NOT need to be converted from host-order to network-order. * * (3) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. * * (4) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'Protocol' is incorrectly modified. * * (5) (a) Multiple connections with the same local & remote address -- both addresses & port * numbers -- is NOT currently supported. * * (b) However, since multiple sockets with the same local address -- both address & port * number -- is NOT currently supported, it is NOT necessary to search the connection * lists since NO other connection with the same local address exists. * * (c) Furthermore, any socket NOT yet connected to a local address WILL be assigned a * unique, random local address & will therefore NOT conflict with any other socket * addresses or connections. * * See also 'net_sock.c Note #1d1' & 'NetSock_BindHandler() Note #8'. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* See Note #5b. */ static void NetSock_ConnHandlerAddrRemoteValidate (NET_SOCK *psock, NET_SOCK_ADDR *paddr_remote, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_SOCK_ADDR_IP *paddr_ip; NET_IP_ADDR addr_ip; #endif CPU_INT08U addr_remote[NET_SOCK_CFG_ADDR_LEN]; CPU_INT08U addr_local[NET_SOCK_CFG_ADDR_LEN]; NET_SOCK_ADDR_LEN addr_local_len; NET_PORT_NBR port_nbr; NET_CONN_ID conn_id; NET_CONN_ID conn_id_conn; NET_CONN_FAMILY conn_family; NET_CONN_LIST_IX conn_protocol_ix; /* ---------------- VALIDATE SOCK CONN ---------------- */ conn_id = psock->ID_Conn; if (conn_id == NET_CONN_ID_NONE) { /* If NO sock conn, rtn no err (see Note #5c). */ *perr = NET_SOCK_ERR_NONE; return; } /* --------------- CFG SOCK REMOTE ADDR --------------- */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) /* Cfg remote addr as net-order sock addr (see Note #2).*/ paddr_ip = (NET_SOCK_ADDR_IP *)paddr_remote; NET_UTIL_VAL_COPY_16(&port_nbr, &paddr_ip->Port); /* Copy preserves net-order (see Note #2b). */ NET_UTIL_VAL_COPY_32(&addr_ip, &paddr_ip->Addr); /* Copy preserves net-order (see Note #2b). */ Mem_Copy((void *)&addr_remote[NET_SOCK_ADDR_IP_IX_PORT], (void *)&port_nbr, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&addr_remote[NET_SOCK_ADDR_IP_IX_ADDR], (void *)&addr_ip, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); #else /* See Note #3. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return; #endif /*$PAGE*/ /* ---- SRCH FOR LOCAL/REMOTE CONN IN CONN LIST(S) ---- */ /* Get local addr from sock conn. */ addr_local_len = sizeof(addr_local); NetConn_AddrLocalGet((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr_local[0], (NET_CONN_ADDR_LEN *)&addr_local_len, (NET_ERR *) perr); if (*perr != NET_CONN_ERR_NONE) { return; } if (addr_local_len != NET_SOCK_CFG_ADDR_LEN) { *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return; } /* Cfg conn srch. */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) conn_family = NET_CONN_FAMILY_IP_V4_SOCK; switch (psock->Protocol) { case NET_SOCK_PROTOCOL_UDP: conn_protocol_ix = NET_CONN_LIST_IX_IP_V4_SOCK_UDP; break; #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: conn_protocol_ix = NET_CONN_LIST_IX_IP_V4_SOCK_TCP; break; #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Note #4. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return; /* Prevent 'break NOT reachable' compiler warning. */ } #else /* See Note #3. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return; #endif /* Srch for sock conn with identical local/remote addrs.*/ conn_id_conn = NetConn_Srch((NET_CONN_FAMILY ) conn_family, (NET_CONN_LIST_IX ) conn_protocol_ix, (NET_CONN_LIST_TYPE) NET_CONN_LIST_TYPE_ALL, (CPU_BOOLEAN ) DEF_YES, (CPU_INT08U *)&addr_local[0], (CPU_INT08U *)&addr_remote[0], (NET_CONN_ADDR_LEN ) NET_SOCK_CFG_ADDR_LEN, (NET_CONN_ID *) 0, (NET_CONN_ID *) 0); if (conn_id_conn != NET_CONN_ID_NONE) { /* If local/remote addrs already conn'd, ... */ NET_CTR_ERR_INC(NetSock_ErrInvalidConnInUseCtr); *perr = NET_SOCK_ERR_CONN_IN_USE; /* ... rtn err (see Note #5). */ return; } *perr = NET_SOCK_ERR_NONE; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnHandlerAddrRemoteSet() * * Description : Set socket remote address. * * Argument(s) : psock Pointer to socket. * ----- Argument validated in NetSock_Conn(). * * paddr_remote Pointer to socket address structure. * ------------ Argument checked in NetSock_ConnHandlerAddrRemoteValidate(). * * addr_over_wr Allow remote address overwrite : * ------------ * DEF_NO Do NOT overwrite remote address. * DEF_YES Overwrite remote address. * * Argument validated in NetSock_ConnHandlerDatagram(), * NetSock_ConnHandlerStream(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket remote address successfully set. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * * - RETURNED BY NetConn_AddrRemoteSet() : - * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * Return(s) : none. * * Caller(s) : NetSock_ConnHandlerDatagram(), * NetSock_ConnHandlerStream(). * * Note(s) : (1) (a) Socket connection addresses MUST be maintained in network-order. * * (b) However, since the port number & address are copied from a network-order socket * address structure into local variables & then into a multi-octet array, they do * NOT need to be converted from host-order to network-order. * * (2) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. ********************************************************************************************************* */ /*$PAGE*/ static void NetSock_ConnHandlerAddrRemoteSet (NET_SOCK *psock, NET_SOCK_ADDR *paddr_remote, CPU_BOOLEAN addr_over_wr, NET_ERR *perr) { #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_SOCK_ADDR_IP *paddr_ip; NET_IP_ADDR addr_ip; #else #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #endif CPU_INT08U addr_remote[NET_SOCK_CFG_ADDR_LEN]; NET_PORT_NBR port_nbr; NET_CONN_ID conn_id; /* --------------- CFG SOCK REMOTE ADDR --------------- */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) /* Cfg remote addr as net-order sock addr (see Note #1).*/ paddr_ip = (NET_SOCK_ADDR_IP *)paddr_remote; NET_UTIL_VAL_COPY_16(&port_nbr, &paddr_ip->Port); /* Copy preserves net-order (see Note #1b). */ NET_UTIL_VAL_COPY_32(&addr_ip, &paddr_ip->Addr); /* Copy preserves net-order (see Note #1b). */ Mem_Copy((void *)&addr_remote[NET_SOCK_ADDR_IP_IX_PORT], (void *)&port_nbr, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&addr_remote[NET_SOCK_ADDR_IP_IX_ADDR], (void *)&addr_ip, (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); #else /* See Note #2. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return; #endif /* --------------- SET SOCK REMOTE ADDR --------------- */ conn_id = psock->ID_Conn; NetConn_AddrRemoteSet((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr_remote[0], (NET_CONN_ADDR_LEN) NET_SOCK_CFG_ADDR_LEN, (CPU_BOOLEAN ) addr_over_wr, (NET_ERR *) perr); if (*perr != NET_CONN_ERR_NONE) { NetSock_CloseSock(psock, DEF_YES, DEF_YES); return; } *perr = NET_SOCK_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnAcceptQ_Init() * * Description : Initialize a stream-type socket's connection accept queue. * * Argument(s) : psock Pointer to socket. * ----- Argument validated in NetSock_Listen(). * * sock_q_size Maximum number of connection requests to accept & queue on listen socket. * * NET_SOCK_Q_SIZE_NONE NO custom configuration for socket's * connection accept queue maximum * size; configure to default maximum : * NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX. * * <= NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX Custom configure socket's connection * accept queue maximum size. * * Return(s) : none. * * Caller(s) : NetSock_Listen(). * * Note(s) : (1) Some socket controls were previously initialized in NetSock_Clr() when the socket * was allocated. These socket controls do NOT need to be re-initialized but are * shown for completeness. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static void NetSock_ConnAcceptQ_Init (NET_SOCK *psock, NET_SOCK_Q_SIZE sock_q_size) { NET_SOCK_Q_SIZE accept_q_size; if (sock_q_size != NET_SOCK_Q_SIZE_NONE) { /* If conn accept Q size cfg'd, .. */ if (sock_q_size > 0) { /* .. lim conn accept Q size; .. */ accept_q_size = (sock_q_size > NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX) ? NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX : sock_q_size; } else { accept_q_size = NET_SOCK_Q_SIZE_MIN; } } else { /* .. else cfg to dflt max size. */ accept_q_size = NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX; } psock->ConnAcceptQ_SizeMax = accept_q_size; /* Cfg listen sock conn accept Q max size. */ /* Init conn accept Q ctrls. */ #if 0 /* Init'd in NetSock_Clr() [see Note #1]. */ psock->ConnAcceptQ_SizeCur = 0; psock->ConnAcceptQ_HeadIx = 0; psock->ConnAcceptQ_TailIx = 0; #endif } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnAcceptQ_Clr() * * Description : Clear a stream-type socket's connection accept queue. * * Argument(s) : psock Pointer to socket. * ----- Argument validated in NetSock_ConnSignalAccept(), * NetSock_FreeHandler(). * * Return(s) : none. * * Caller(s) : NetSock_ConnSignalAccept(), * NetSock_FreeHandler(). * * Note(s) : none. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static void NetSock_ConnAcceptQ_Clr (NET_SOCK *psock) { CPU_BOOLEAN done; NET_CONN_ID conn_id; NET_ERR err; /* -------------- VALIDATE SOCK TYPE -------------- */ if (psock->SockType != NET_SOCK_TYPE_STREAM) { return; } /* -------------- CLR CONN ACCEPT Q --------------- */ done = DEF_NO; while (done == DEF_NO) { /* Clr sock's conn accept Q ... */ if (psock->ConnAcceptQ_SizeCur > 0) { /* ... while non-empty. */ conn_id = NetSock_ConnAcceptQ_ConnID_Get(psock, &err); if (err == NET_SOCK_ERR_NONE) { NetConn_CloseFromApp(conn_id, DEF_YES); } else { done = DEF_YES; } } else { done = DEF_YES; } } /* Clr sock's conn accept Q ix's. */ psock->ConnAcceptQ_HeadIx = 0; psock->ConnAcceptQ_TailIx = 0; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnAcceptQ_IsAvail() * * Description : Check if socket's connection accept queue is available to queue a new connection. * * Argument(s) : psock Pointer to socket. * ----- Argument validated in NetSock_ListenQ_IsAvail(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket connection accept queue successfully * checked; check return value for socket * connection accept queue availablity. * * NET_SOCK_ERR_INVALID_TYPE Invalid socket type; i.e. NOT stream-type. * * Return(s) : DEF_YES, if socket connection accept queue is available to queue a new connection. * * DEF_NO, otherwise. * * Caller(s) : NetSock_ListenQ_IsAvail(). * * Note(s) : none. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static CPU_BOOLEAN NetSock_ConnAcceptQ_IsAvail (NET_SOCK *psock, NET_ERR *perr) { CPU_BOOLEAN q_avail; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* -------------- VALIDATE SOCK TYPE -------------- */ if (psock->SockType != NET_SOCK_TYPE_STREAM) { *perr = NET_SOCK_ERR_INVALID_TYPE; return (DEF_NO); } #endif /* --------- CHK SOCK CONN ACCEPT Q AVAIL --------- */ q_avail = (psock->ConnAcceptQ_SizeCur >= psock->ConnAcceptQ_SizeMax) ? DEF_NO : DEF_YES; *perr = NET_SOCK_ERR_NONE; return (q_avail); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnAcceptQ_ConnID_Add() * * Description : Add a connection handle identifier into a stream-type socket's connection accept queue. * * (1) A stream-type socket's connection accept queue is a FIFO Q implemented as a circular * ring array : * * (a) Sockets' 'ConnAcceptQ_HeadIx' points to the next available connection handle * identifier to accept. * * (b) Sockets' 'ConnAcceptQ_TailIx' points to the next available queue entry to insert * a connection handle identifier. * * (c) Sockets' 'ConnAcceptQ_HeadIx'/'ConnAcceptQ_TailIx' advance : * * (1) By increment; * (2) Reset to minimum index value when maximum index value reached. * * (A) Although a specific maximum array-size/index-value is configured for * each socket connection accept queue ('ConnAcceptQ_SizeMax'), the global * maximum array-size/index-value ('NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX') * is used as the maximum index value. Although this uses the entire * queue array (not just a subset) for adding & removing connection handle * identifiers, it eliminates the need to redundantly validate the socket's * configured connection accept queue maximum array-size/index-value. * * * Index to next available Index to next available entry * connection handle identifier to insert accept connection * in accept queue handle identifier * (see Note #1a) (see Note #1b) * * | | * | | * v v * ------------------------------------------------------------- * | | | | | | | | | | | * | | | | | | | | | | | * | | | | | | | | | | | * ------------------------------------------------------------- * * ----------> * FIFO indices advance by * increment (see Note #1c1) * * | | * |<----------------- Circular Ring FIFO Q ------------------>| * | (see Note #1) | * * * Argument(s) : psock Pointer to socket. * ----- Argument validated in NetSock_ConnSignalAccept(). * * conn_id Handle identifier of network connection to insert into connection accept queue. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Accept connection handle identifier * successfully added. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type; i.e. NOT stream-type. * NET_SOCK_ERR_CONN_ACCEPT_Q_DUP Connection handle identifier already in socket * connection accept queue. * NET_SOCK_ERR_CONN_ACCEPT_Q_MAX Maximum or invalid number queue entries used. * * Return(s) : none. * * Caller(s) : NetSock_ConnSignalAccept(). * * Note(s) : none. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static void NetSock_ConnAcceptQ_ConnID_Add (NET_SOCK *psock, NET_CONN_ID conn_id, NET_ERR *perr) { #if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) CPU_BOOLEAN found; #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------- VALIDATE SOCK TYPE ---------- */ if (psock->SockType != NET_SOCK_TYPE_STREAM) { *perr = NET_SOCK_ERR_INVALID_TYPE; return; } /* ----------- VALIDATE CONN ID ----------- */ found = NetSock_ConnAcceptQ_ConnID_Srch((NET_SOCK *)psock, (NET_CONN_ID )conn_id, (NET_SOCK_Q_SIZE *)0, (NET_SOCK_Q_SIZE *)0); if (found != DEF_NO) { *perr = NET_SOCK_ERR_CONN_ACCEPT_Q_DUP; return; } #endif /* ---------- VALIDATE NBR USED ----------- */ /* Chk sock max conn accept Q lim. */ if (psock->ConnAcceptQ_SizeCur >= psock->ConnAcceptQ_SizeMax) { *perr = NET_SOCK_ERR_CONN_ACCEPT_Q_MAX; return; } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) if (psock->ConnAcceptQ_SizeCur >= NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX) { NET_CTR_ERR_INC(NetSock_ErrConnAcceptQ_MaxCtr); *perr = NET_SOCK_ERR_CONN_ACCEPT_Q_MAX; return; } #endif /* ---- ADD CONN ID INTO CONN ACCEPT Q ---- */ psock->ConnAcceptQ[psock->ConnAcceptQ_TailIx] = conn_id; /* Add conn id @ tail ix (see Note #1b). */ psock->ConnAcceptQ_TailIx++; /* Inc tail ix to next avail Q entry. */ if (psock->ConnAcceptQ_TailIx >= NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX) { /* If tail ix > max ix, ... */ psock->ConnAcceptQ_TailIx = 0; /* ... reset to min ix (see Note #1c2). */ } psock->ConnAcceptQ_SizeCur++; *perr = NET_SOCK_ERR_NONE; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnAcceptQ_ConnID_Get() * * Description : Get a connection handle identifier from a stream-type socket's connection accept queue. * * (1) A stream-type socket's connection accept queue is a FIFO Q implemented as a circular * ring array : * * (a) Sockets' 'ConnAcceptQ_HeadIx' points to the next available connection handle * identifier to accept. * * See also 'NetSock_ConnAcceptQ_ConnID_Add() Note #1'. * * * Argument(s) : psock Pointer to socket. * ----- Argument validated in NetSock_Accept(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Accept connection handle identifier * successfully retrieved. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type; i.e. NOT stream-type. * NET_SOCK_ERR_CONN_ACCEPT_Q_NONE_AVAIL Accept connection handle identifier NOT * available. * * Return(s) : Accept connection handle identifier, if NO errors. * * NET_CONN_ID_NONE, otherwise. * * Caller(s) : NetSock_Accept(). * * Note(s) : none. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_CONN_ID NetSock_ConnAcceptQ_ConnID_Get (NET_SOCK *psock, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_CONN_ID conn_id; /* ---------- VALIDATE SOCK TYPE ---------- */ if (psock->SockType != NET_SOCK_TYPE_STREAM) { *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_CONN_ID_NONE); } /* ---------- VALIDATE NBR USED ----------- */ if (psock->ConnAcceptQ_SizeCur < 1) { NET_CTR_ERR_INC(NetSock_ErrConnAcceptQ_NoneAvailCtr); *perr = NET_SOCK_ERR_CONN_ACCEPT_Q_NONE_AVAIL; return (NET_CONN_ID_NONE); } /* ---- GET CONN ID FROM CONN ACCEPT Q ---- */ /* Get conn id @ head ix (see Note #1a). */ conn_id = psock->ConnAcceptQ[psock->ConnAcceptQ_HeadIx]; #if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED) psock->ConnAcceptQ[psock->ConnAcceptQ_HeadIx] = NET_CONN_ID_NONE; #endif psock->ConnAcceptQ_HeadIx++; /* Inc head ix to next avail Q conn id. */ if (psock->ConnAcceptQ_HeadIx >= NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX) { /* If head ix > max ix, ... */ psock->ConnAcceptQ_HeadIx = 0; /* ... reset to min ix. */ } psock->ConnAcceptQ_SizeCur--; *perr = NET_SOCK_ERR_NONE; return (conn_id); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnAcceptQ_ConnID_Srch() * * Description : Saerch for a connection handle identifier in a stream-type socket's connection accept queue. * * Argument(s) : psock Pointer to socket. * ----- Argument validated in NetSock_ConnAcceptQ_ConnID_Add(), * NetSock_ConnAcceptQ_ConnID_Remove(). * * conn_id Handle identifier of network connection to search for in connection accept queue. * * pconn_ix Pointer to a variable to ... : * * (a) Return the connection accept queue array index of the network connection * handle identifier, if found; * (b) Return NET_SOCK_Q_IX_NONE, otherwise. * * pconn_nbr Pointer to a variable to ... : * * (a) Return the number of connection accept queue handle identifiers ahead * of the desired network connection handle identifier, if found; * (b) Return 0, otherwise. * * Return(s) : DEF_YES, connection handle identifier found in socket's connection accept queue. * * DEF_NO, otherwise. * * Caller(s) : NetSock_ConnAcceptQ_ConnID_Add(), * NetSock_ConnAcceptQ_ConnID_Remove(). * * Note(s) : (1) Pointer to variables that return values MUST be initialized PRIOR to all other validation * or function handling in case of any error(s). * * (2) Assumes queue indices valid. * * (3) If ALL connection handle identifiers in queue searched & queue tail index NOT found, * tail index MUST be invalid -- outside the range of table indices. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static CPU_BOOLEAN NetSock_ConnAcceptQ_ConnID_Srch (NET_SOCK *psock, NET_CONN_ID conn_id, NET_SOCK_Q_SIZE *pconn_ix, NET_SOCK_Q_SIZE *pconn_nbr) { CPU_BOOLEAN found; CPU_BOOLEAN done; NET_SOCK_Q_SIZE ix_cur; NET_SOCK_Q_SIZE nbr; /* Init rtn vals for err (see Note #1). */ if (pconn_ix != (NET_SOCK_Q_SIZE *)0) { *pconn_ix = NET_SOCK_Q_IX_NONE; } if (pconn_nbr != (NET_SOCK_Q_SIZE *)0) { *pconn_nbr = 0; } /* ----- VALIDATE CONN ACCEPT Q SIZE ------ */ if (psock->ConnAcceptQ_SizeCur < 1) { return (DEF_NO); } /* ---- SRCH CONN ID IN CONN ACCEPT Q ----- */ found = DEF_NO; done = DEF_NO; ix_cur = psock->ConnAcceptQ_HeadIx; nbr = 0; while (done == DEF_NO) { /* Srch sock conn accept Q for conn id. */ if (ix_cur == psock->ConnAcceptQ_TailIx) { /* If ix @ tail, conn id NOT found. */ done = DEF_YES; } else { found = (psock->ConnAcceptQ[ix_cur] == conn_id) ? DEF_YES : DEF_NO; if (found == DEF_YES) { /* If conn id found, ... */ done = DEF_YES; /* ... abort successful srch. */ } else { nbr++; if (nbr >= psock->ConnAcceptQ_SizeCur) { /* If nbr srch'd > nbr of Q's conn id's, .. */ done = DEF_YES; /* .. abort srch; Q corrupted (see Note #3).*/ } else { ix_cur++; if (ix_cur >= NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX) { /* If ix > max ix, ... */ ix_cur = 0; /* ... reset to min ix. */ } } } } } /* -------- RTN SRCH CONN ID FOUND -------- */ if (found == DEF_YES) { /* If srch conn id found, ... */ if (pconn_ix != (NET_SOCK_Q_SIZE *)0) { *pconn_ix = ix_cur; /* ... rtn conn id ix. */ } if (pconn_nbr != (NET_SOCK_Q_SIZE *)0) { *pconn_nbr = nbr; } } return (found); /* Rtn srch conn id found status. */ } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_ConnAcceptQ_ConnID_Remove() * * Description : Remove a connection handle identifier from a stream-type socket's connection accept queue. * * Argument(s) : psock Pointer to socket. * ----- Argument validated in NetSock_FreeConnFromSock(). * * conn_id Handle identifier of network connection to remove from connection accept queue. * * Return(s) : DEF_YES, connection handle identifier found & successfully removed from socket's connection * accept queue. * * DEF_NO, otherwise. * * Caller(s) : NetSock_FreeConnFromSock(). * * Note(s) : (1) Assumes queue indices valid. * * (2) If ALL connection handle identifiers in queue searched & queue tail index NOT found, * tail index MUST be invalid -- outside the range of table indices. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static CPU_BOOLEAN NetSock_ConnAcceptQ_ConnID_Remove (NET_SOCK *psock, NET_CONN_ID conn_id) { CPU_BOOLEAN found; NET_SOCK_Q_SIZE ix_id; NET_SOCK_Q_SIZE ix_next; NET_SOCK_Q_SIZE nbr; /* ---------- VALIDATE SOCK TYPE ---------- */ if (psock->SockType != NET_SOCK_TYPE_STREAM) { return (DEF_NO); } /* ----- VALIDATE CONN ACCEPT Q SIZE ------ */ if (psock->ConnAcceptQ_SizeCur < 1) { return (DEF_NO); } /* ---- SRCH CONN ID IN CONN ACCEPT Q ----- */ found = NetSock_ConnAcceptQ_ConnID_Srch(psock, conn_id, &ix_id, &nbr); if (found != DEF_YES) { /* If conn id NOT found, exit remove. */ return (DEF_NO); } /* -- REMOVE CONN ID FROM CONN ACCEPT Q --- */ psock->ConnAcceptQ_SizeCur--; /* Dec conn accept Q cur size. */ ix_next = ix_id; while (nbr < psock->ConnAcceptQ_SizeCur) { /* Shift ALL rem'ing conn id's following ...*/ /* ... removed conn id. */ ix_next++; if (ix_next >= NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX) { /* If next ix > max ix, ... */ ix_next = 0; /* ... reset to min ix. */ } psock->ConnAcceptQ[ix_id] = psock->ConnAcceptQ[ix_next]; /* Shift conn id @ next ix to cur ix. */ ix_id++; if (ix_id >= NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX) { /* If cur ix > max ix, ... */ ix_id = 0; /* ... reset to min ix. */ } nbr++; } #if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED) psock->ConnAcceptQ[ix_id] = NET_CONN_ID_NONE; #endif if (psock->ConnAcceptQ_TailIx == 0) { /* If tail ix @ min ix, ... */ psock->ConnAcceptQ_TailIx = NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX; /* ... reset to max ix. */ } psock->ConnAcceptQ_TailIx--; /* Dec tail ix. */ return (DEF_YES); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RxDataHandler() * * Description : (1) Receive data from a socket : * * (a) Validate receive data buffer See Note #2 * (b) Validate receive flags See Note #3 * (c) Acquire network lock * (d) Validate socket used * (e) Receive socket data * (f) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to receive data. * * pdata_buf Pointer to an application data buffer that will receive the socket's received * data. * * data_buf_len Size of the application data buffer (in octets) [see Note #2]. * * flags Flags to select receive options (see Note #3); bit-field flags logically OR'd : * * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_RX_DATA_PEEK Receive socket data without consuming * the socket data; i.e. socket data * NOT removed from application receive * queue(s). * NET_SOCK_FLAG_RX_NO_BLOCK Receive socket data without blocking. * * paddr_remote Pointer to an address buffer that will receive the socket address structure * with the received data's remote address (see Note #4), if NO errors. * * paddr_len Pointer to a variable, if available, to ... : * * (a) Pass the size of the address buffer pointed to by 'paddr_remote'. * (b) (1) Return the actual size of socket address structure with the * received data's remote address, if NO errors; * (2) Return 0, otherwise. * * See also Note #5. * * pip_opts_buf Pointer to buffer to receive possible IP options (see Note #6a), if NO errors. * * ip_opts_buf_len Size of IP options receive buffer (in octets) [see Note #6b]. * * pip_opts_len Pointer to variable that will receive the return size of any received IP options, * if NO errors. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NULL_PTR Argument 'pdata_buf' passed a NULL pointer. * NET_SOCK_ERR_NULL_SIZE Argument 'data_buf_len' passed a NULL size. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_FLAG Invalid socket flags. * * -------- RETURNED BY NetSock_IsUsed() : --------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * - RETURNED BY NetSock_RxDataHandlerDatagram() : - * -- RETURNED BY NetSock_RxDataHandlerStream() : -- * NET_SOCK_ERR_NONE Socket data successfully received; check return * value for number of data octets received. * * NET_SOCK_ERR_RX_Q_EMPTY Socket receive queue empty. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_ERR_RX Receive error. * * - RETURNED BY NetSock_RxDataHandlerDatagram() : - * NET_SOCK_ERR_INVALID_DATA_SIZE Socket data receive buffer insufficient size; * some, but not all, socket data deframed * into receive buffer (see Note #2a2). * * -- RETURNED BY NetSock_RxDataHandlerStream() : -- * NET_SOCK_ERR_RX_Q_CLOSED Socket receive queue closed. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address length. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * * ---------- RETURNED BY NetOS_Lock() : ----------- * NET_OS_ERR_LOCK Network access NOT acquired. *$PAGE* * Return(s) : Number of positive data octets received, if NO errors (see Note #7a). * * NET_SOCK_BSD_RTN_CODE_CONN_CLOSED, if socket connection closed (see Note #7b). * * NET_SOCK_BSD_ERR_RX, otherwise (see Note #7c1). * * Caller(s) : NetSock_RxDataFrom(), * NetSock_RxData(). * * Note(s) : (2) (a) (1) (A) Datagram-type sockets transmit & receive all data atomically -- i.e. every * single, complete datagram transmitted MUST be received as a single, complete * datagram. * * (B) IEEE Std 1003.1, 2004 Edition, Section 'recv() : DESCRIPTION' summarizes * that "for message-based sockets, such as SOCK_DGRAM ... the entire message * shall be read in a single operation. If a message is too long to fit in * the supplied buffer, and MSG_PEEK is not set in the flags argument, the * excess bytes shall be discarded". * * (2) Thus, if the socket's type is datagram & the receive data buffer size is * NOT large enough for the received data, the receive data buffer is maximally * filled with receive data but the remaining data octets are discarded & * NET_SOCK_ERR_INVALID_DATA_SIZE error is returned. * * (b) (1) (A) (1) Stream-type sockets transmit & receive all data octets in one or more * non-distinct packets. In other words, the application data is NOT * bounded by any specific packet(s); rather, it is contiguous & sequenced * from one packet to the next. * * (2) IEEE Std 1003.1, 2004 Edition, Section 'recv() : DESCRIPTION' summarizes * that "for stream-based sockets, such as SOCK_STREAM, message boundaries * shall be ignored. In this case, data shall be returned to the user as * soon as it becomes available, and no data shall be discarded". * * (B) Thus, if the socket's type is stream & the receive data buffer size is NOT * large enough for the received data, the receive data buffer is maximally * filled with receive data & the remaining data octets remain queued for * later application-socket receives. * * (2) Thus, it is typical -- but NOT absolutely required -- that a single application * task ONLY receive or request to receive data from a stream-type socket. * * See also 'NetSock_RxDataHandlerDatagram() Note #2', * & 'NetSock_RxDataHandlerStream() Note #2'. * * (3) #### Only some socket receive flag options are implemented. If other flag options * are requested, NetSock_RxDataHandler() aborts & returns appropriate error codes so * that requested flag options are NOT silently ignored. * * (4) (a) Socket address structure 'Family' member returned in host-order & SHOULD NOT be * converted to network-order. * * (b) Socket address structure addresses MUST be converted from host-order to network- * order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (5) (a) Since 'paddr_len' parameter is both an input & output parameter (see 'Argument(s) : * paddr_len'), ... * * (1) its input value SHOULD be validated prior to use; ... * (2) while its output value MUST be initially configured to return a default error * value in case of any function exit due to error/fault conditions (see also * Note #8). * * (b) However, if 'paddr_len' is available, it SHOULD already be validated & initialized * by previous NetSock_RxData() function(s). * * (6) (a) If ... * * (1) NO IP options were received * OR * (2) NO IP options receive buffer is provided * OR * (3) IP options receive buffer NOT large enough for the received IP options * * ... then NO IP options are returned & any received IP options are silently discarded. * * (b) The IP options receive buffer size SHOULD be large enough to receive the maximum * IP options size, NET_IP_HDR_OPT_SIZE_MAX. * * (c) #### Received IP options should be provided/decoded via appropriate IP layer API. * * See also Note #10. *$PAGE* * (7) IEEE Std 1003.1, 2004 Edition, Section 'recv() : RETURN VALUE' states that : * * (a) "Upon successful completion, recv() shall return the length of the message in bytes." * * (b) "If no messages are available to be received and the peer has performed an orderly * shutdown, recv() shall return 0." * * (c) (1) "Otherwise, -1 shall be returned" ... * (2) "and 'errno' set to indicate the error." * * See also 'NetSock_RxDataHandlerDatagram() Note #7' * & 'NetSock_RxDataHandlerStream() Note #7'. * * (8) Pointers to variables that return length or size values MUST be initialized to return * zero PRIOR to all other validation or function handling in case of any error(s). * However, these pointed-to variables SHOULD already be validated & initialized by * previous NetSock_RxData() function(s). * * (9) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. * * (10) #### IP options arguments may NOT be necessary (remove if unnecessary). ********************************************************************************************************* */ static NET_SOCK_RTN_CODE NetSock_RxDataHandler (NET_SOCK_ID sock_id, void *pdata_buf, CPU_INT16S data_buf_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN *paddr_len, void *pip_opts_buf, CPU_INT08U ip_opts_buf_len, CPU_INT08U *pip_opts_len, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) CPU_INT16U flag_mask; #endif NET_SOCK *psock; NET_SOCK_RTN_CODE rtn_code; #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* --------------- VALIDATE RX DATA BUF --------------- */ if (pdata_buf == (void *)0) { NET_CTR_ERR_INC(NetSock_ErrNullPtrCtr); *perr = NET_SOCK_ERR_NULL_PTR; return (NET_SOCK_BSD_ERR_RX); } if (data_buf_len < 1) { NET_CTR_ERR_INC(NetSock_ErrNullSizeCtr); *perr = NET_SOCK_ERR_NULL_SIZE; return (NET_SOCK_BSD_ERR_RX); } /* ----------------- VALIDATE RX FLAGS ---------------- */ flag_mask = NET_SOCK_FLAG_NONE | NET_SOCK_FLAG_RX_DATA_PEEK | NET_SOCK_FLAG_RX_NO_BLOCK; /* If any invalid flags req'd, rtn err (see Note #3). */ if (((CPU_INT16U)flags & ~flag_mask) != NET_SOCK_FLAG_NONE) { NET_CTR_ERR_INC(NetSock_ErrInvalidFlagsCtr); *perr = NET_SOCK_ERR_INVALID_FLAG; return (NET_SOCK_BSD_ERR_RX); } #endif /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (NET_SOCK_BSD_ERR_RX); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_RX); } #endif /*$PAGE*/ /* ------------------- RX SOCK DATA ------------------- */ psock = &NetSock_Tbl[sock_id]; switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: rtn_code = NetSock_RxDataHandlerDatagram((NET_SOCK_ID )sock_id, (NET_SOCK *)psock, (void *)pdata_buf, (CPU_INT16S )data_buf_len, (CPU_INT16S )flags, (NET_SOCK_ADDR *)paddr_remote, (NET_SOCK_ADDR_LEN *)paddr_len, (void *)pip_opts_buf, (CPU_INT08U )ip_opts_buf_len, (CPU_INT08U *)pip_opts_len, (NET_ERR *)perr); break; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: rtn_code = NetSock_RxDataHandlerStream((NET_SOCK_ID )sock_id, (NET_SOCK *)psock, (void *)pdata_buf, (CPU_INT16S )data_buf_len, (CPU_INT16S )flags, (NET_SOCK_ADDR *)paddr_remote, (NET_SOCK_ADDR_LEN *)paddr_len, (NET_ERR *)perr); break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #9. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ } /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); return (rtn_code); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RxDataHandlerDatagram() * * Description : (1) Receive data from a datagram-type socket : * * (a) Validate socket connection state * (b) Wait on socket receive queue for packet buffer(s) * (c) Get remote host address See Notes #4 & #5 * * (d) Configure socket transmit : * (1) Configure socket flags * * (e) Receive socket data from appropriate transport layer * (f) Free socket receive packet buffer(s) * (g) Return socket data received * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to receive data. * ------- Argument checked in NetSock_RxDataHandler(). * * psock Pointer to socket. * ----- Argument validated in NetSock_RxDataHandler(). * * pdata_buf Pointer to an application data buffer that will receive the socket's received * --------- data. * * Argument checked in NetSock_RxDataHandler(). * * data_buf_len Size of the application data buffer (in octets) [see Note #2b]. * ------------ Argument checked in NetSock_RxDataHandler(). * * flags Flags to select receive options; bit-field flags logically OR'd : * ----- * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_RX_DATA_PEEK Receive socket data without consuming * the socket data; i.e. socket data * NOT removed from application receive * queue(s). * NET_SOCK_FLAG_RX_NO_BLOCK Receive socket data without blocking * (see Note #3). * * Argument checked in NetSock_RxDataHandler(). * * paddr_remote Pointer to an address buffer that will receive the socket address structure * with the received data's remote address (see Notes #4 & #5), if NO errors. * * paddr_len Pointer to a variable to ... : * * (a) Pass the size of the address buffer pointed to by 'paddr_remote'. * (b) (1) Return the actual size of socket address structure with the * received data's remote address, if NO errors; * (2) Return 0, otherwise. * * See also Note #4b. * * pip_opts_buf Pointer to buffer to receive possible IP options (see Note #6a), if NO errors. * * ip_opts_buf_len Size of IP options receive buffer (in octets) [see Note #6b]. * * pip_opts_len Pointer to variable that will receive the return size of any received IP options, * if NO errors. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket data successfully received; check return * value for number of data octets received. * * NET_SOCK_ERR_INVALID_DATA_SIZE Socket data receive buffer insufficient size; * some, but not all, socket data deframed * into receive buffer (see Note #2b). * * NET_SOCK_ERR_RX_Q_EMPTY Socket receive queue empty. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * * NET_ERR_RX Receive error. * * --------- RETURNED BY NetOS_Lock() : ---------- * NET_OS_ERR_LOCK Network access NOT acquired. * * Return(s) : Number of positive data octets received, if NO errors (see Note #7a). * * NET_SOCK_BSD_ERR_RX, otherwise (see Note #7c). * * Caller(s) : NetSock_RxDataHandler(). *$PAGE* * Note(s) : (2) (a) (1) Datagram-type sockets transmit & receive all data atomically -- i.e. every single, * complete datagram transmitted MUST be received as a single, complete datagram. * * (2) IEEE Std 1003.1, 2004 Edition, Section 'recv() : DESCRIPTION' summarizes that * "for message-based sockets, such as SOCK_DGRAM ... the entire message shall be * read in a single operation. If a message is too long to fit in the supplied * buffer, and MSG_PEEK is not set in the flags argument, the excess bytes shall * be discarded". * * (b) Thus, if the socket's type is datagram & the receive data buffer size is NOT large * enough for the received data, the receive data buffer is maximally filled with receive * data but the remaining data octets are discarded & NET_SOCK_ERR_INVALID_DATA_SIZE * error is returned. * * See also 'NetSock_RxDataHandler() Note #2a'. * * (3) If global socket blocking ('NET_SOCK_CFG_BLOCK_SEL') configured for blocking operation * ('NET_SOCK_BLOCK_SEL_BLOCK' or 'NET_SOCK_BLOCK_SEL_DFLT') but 'flags' argument set to * 'NET_SOCK_FLAG_RX_NO_BLOCK'; socket receive does NOT block, regardless if the socket * is configured to block. * * (4) (a) If a pointer to remote address buffer is provided, it is assumed that the remote * address buffer has been previously validated for the remote address to be returned. * * (b) If a pointer to remote address buffer is provided, it is assumed that a pointer to * an address length buffer is also available & has been previously validated. * * (c) The remote address is obtained from the first packet buffer. In other words, if * multiple packet buffers are received for a fragmented datagram, the remote address * is obtained from the first fragment of the datagram. * * (5) (a) Socket address structure 'Family' member returned in host-order & SHOULD NOT be * converted to network-order. * * (b) Socket address structure addresses MUST be converted from host-order to network- * order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (6) (a) If ... * * (1) NO IP options were received * OR * (2) NO IP options receive buffer is provided * OR * (3) IP options receive buffer NOT large enough for the received IP options * * ... then NO IP options are returned & any received IP options are silently discarded. * * (b) The IP options receive buffer size SHOULD be large enough to receive the maximum * IP options size, NET_IP_HDR_OPT_SIZE_MAX. * * (c) #### Received IP options should be provided/decoded via appropriate IP layer API. * * See also Note #12. *$PAGE* * (7) IEEE Std 1003.1, 2004 Edition, Section 'recv() : RETURN VALUE' states that : * * (a) "Upon successful completion, recv() shall return the length of the message in bytes." * * (b) "If no messages are available to be received and the peer has performed an orderly * shutdown, recv() shall return 0." * * (1) Since the socket receive return value of '0' is reserved for socket connection * closes; NO socket receive -- fault or non-fault -- should ever return '0' octets * received. * * (2) However, since NO actual connections are implemented for datagram-type sockets * (see 'NetSock_ConnHandlerDatagram() Note #2a'), NO actual socket connections * can be closed on datagram-type sockets. Therefore, datagram-type socket * receives MUST NEVER return '0'. * * (c) (1) "Otherwise, -1 shall be returned" ... * (2) "and 'errno' set to indicate the error." * * See also 'NetSock_RxDataHandler() Note #7'. * * (8) Pointers to variables that return length or size values MUST be initialized to return * zero PRIOR to all other validation or function handling in case of any error(s). * However, these pointed-to variables SHOULD already be validated & initialized by * previous NetSock_RxData() function(s). * * (9) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. * * (10) (a) Transport layer SHOULD typically free &/or discard packet buffer(s) after * receiving application data. * * (b) However, if received packet buffer(s) NOT consumed AND any socket receive * queue error(s) occur; socket receive MUST free/discard packet buffer(s). * * (11) On ANY errors, network resources MUST be appropriately freed : * * (a) NetSock_RxDataHandlerDatagram() assumes that datagram-type sockets have been * previously validated as configured by caller function(s). Therefore, on any * internal socket connection error(s), the socket MUST be closed. * * (12) #### IP options arguments may NOT be necessary (remove if unnecessary). ********************************************************************************************************* */ /*$PAGE*/ static NET_SOCK_RTN_CODE NetSock_RxDataHandlerDatagram (NET_SOCK_ID sock_id, NET_SOCK *psock, void *pdata_buf, CPU_INT16S data_buf_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN *paddr_len, void *pip_opts_buf, CPU_INT08U ip_opts_buf_len, CPU_INT08U *pip_opts_len, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_SOCK_ADDR_IP *paddr_ip; #endif #if (NET_SOCK_CFG_BLOCK_SEL != NET_SOCK_BLOCK_SEL_NO_BLOCK) CPU_BOOLEAN no_block; #endif CPU_BOOLEAN block; CPU_BOOLEAN peek; CPU_BOOLEAN free; NET_BUF *pbuf_head; NET_BUF *pbuf_head_next; NET_BUF_HDR *pbuf_head_hdr; NET_BUF_HDR *pbuf_head_next_hdr; CPU_INT16U flags_transport; CPU_INT16S data_len_tot; NET_ERR err; NET_ERR err_rtn; /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_BOUND: /* If sock NOT conn'd to remote addr ... */ if (paddr_remote == (NET_SOCK_ADDR *)0) { /* ... & remote addr NOT provided, ... */ NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; /* ... rtn invalid op err. */ return (NET_SOCK_BSD_ERR_RX); } break; case NET_SOCK_STATE_CONN: break; case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* ---------------- WAIT ON SOCK RX Q ----------------- */ #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_NO_BLOCK) block = DEF_NO; #else no_block = DEF_BIT_IS_SET(flags, NET_SOCK_FLAG_RX_NO_BLOCK); if (no_block == DEF_YES) { /* If 'No Block' flag set, ... */ block = DEF_NO; /* ... do NOT block (see Note #3). */ } else { #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_BLOCK) /* Else block if cfg'd, ... */ block = DEF_YES; #else /* ... or chk sock's block flag. */ block = DEF_BIT_IS_SET(psock->Flags, NET_SOCK_FLAG_BLOCK); #endif } #endif if (block != DEF_YES) { /* If non-blocking sock rx ... */ if (psock->RxQ_Head == (NET_BUF *)0) { /* ... & no rx'd data pkts, ... */ *perr = NET_SOCK_ERR_RX_Q_EMPTY; /* ... rtn rx Q empty err. */ return (NET_SOCK_BSD_ERR_RX); } } NetOS_Unlock(); NetOS_Sock_RxQ_Wait(sock_id, perr); NetOS_Lock(&err); if ( err != NET_OS_ERR_NONE) { *perr = err; /* Rtn err from NetOS_Lock(). */ return (NET_SOCK_BSD_ERR_RX); } switch (*perr) { case NET_SOCK_ERR_NONE: break; case NET_SOCK_ERR_RX_Q_EMPTY: /* Rtn err from NetOS_Sock_RxQ_Wait(). */ return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_ERR_RX_Q_SIGNAL_ABORT: case NET_SOCK_ERR_RX_Q_SIGNAL_FAULT: default: *perr = NET_SOCK_ERR_FAULT; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ } if (psock->RxQ_Head == (NET_BUF *)0) { /* If still NO rx'd data pkts, ... */ *perr = NET_SOCK_ERR_RX_Q_EMPTY; /* ... rtn rx Q empty err. */ return (NET_SOCK_BSD_ERR_RX); } /* Cfg rx pkt buf ptrs. */ pbuf_head = (NET_BUF *) psock->RxQ_Head; pbuf_head_hdr = (NET_BUF_HDR *)&pbuf_head->Hdr; pbuf_head_next = (NET_BUF *) pbuf_head_hdr->NextPrimListPtr; /* ----------------- GET REMOTE ADDR ------------------ */ if (paddr_remote != (NET_SOCK_ADDR *)0) { /* If remote addr buf avail, ... */ /* ... rtn datagram src addr (see Note #4). */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) paddr_ip = (NET_SOCK_ADDR_IP *)paddr_remote; /* Cfg remote addr struct (see Note #5). */ NET_UTIL_VAL_SET_HOST_16(&paddr_ip->Family, NET_SOCK_ADDR_FAMILY_IP_V4); NET_UTIL_VAL_COPY_SET_NET_16(&paddr_ip->Port, &pbuf_head_hdr->TCP_UDP_PortSrc); NET_UTIL_VAL_COPY_SET_NET_32(&paddr_ip->Addr, &pbuf_head_hdr->IP_AddrSrc); Mem_Clr((void *)&paddr_ip->Unused[0], (CPU_SIZE_T) NET_SOCK_ADDR_IP_NBR_OCTETS_UNUSED); *paddr_len = NET_SOCK_ADDR_IP_SIZE; #else /* See Notes #9 & #11a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_SOCK_BSD_ERR_RX); #endif } /*$PAGE*/ /* ------------------- CFG SOCK RX -------------------- */ /* Cfg sock rx flags. */ peek = DEF_BIT_IS_SET(flags, NET_SOCK_FLAG_RX_DATA_PEEK); /* ------------------- RX SOCK DATA ------------------- */ switch (psock->Protocol) { /* Rx app data from transport layer rx. */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) case NET_SOCK_PROTOCOL_UDP: /* Cfg transport rx flags. */ flags_transport = NET_UDP_FLAG_NONE; if (peek == DEF_YES) { DEF_BIT_SET(flags_transport, NET_UDP_FLAG_RX_DATA_PEEK); } data_len_tot = (CPU_INT16S)NetUDP_RxAppData((NET_BUF *) pbuf_head, (void *) pdata_buf, (CPU_INT16U ) data_buf_len, (CPU_INT16U ) flags_transport, (void *) pip_opts_buf, (CPU_INT08U ) ip_opts_buf_len, (CPU_INT08U *) pip_opts_len, (NET_ERR *)&err); switch (err) { case NET_UDP_ERR_NONE: err_rtn = NET_SOCK_ERR_NONE; break; case NET_UDP_ERR_INVALID_DATA_SIZE: err_rtn = NET_SOCK_ERR_INVALID_DATA_SIZE; break; case NET_ERR_INIT_INCOMPLETE: case NET_UDP_ERR_NULL_PTR: case NET_UDP_ERR_INVALID_FLAG: case NET_ERR_RX: default: err_rtn = NET_ERR_RX; break; } break; #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Notes #9 & #11a. */ (void)&flags_transport; /* Prevent compiler warning. */ (void)&peek; NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ } switch (err_rtn) { /* Demux transport-to-sock layer err. */ case NET_SOCK_ERR_NONE: case NET_SOCK_ERR_INVALID_DATA_SIZE: break; case NET_ERR_RX: default: *perr = err_rtn; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* ---------------- FREE SOCK RX PKTS ----------------- */ free = DEF_NO; /* Transport layer SHOULD free pkts (see Note #10a). */ if (peek == DEF_YES) { /* Signal sock rx Q to negate non-consuming peek. */ NetOS_Sock_RxQ_Signal(sock_id, &err); if (err != NET_SOCK_ERR_NONE) { /* If sock rx Q signal failed, ... */ peek = DEF_NO; /* ... consume pkt buf(s); ... */ free = DEF_YES; /* ... i.e. free/discard pkt buf(s) [see Note #10b]. */ } } if (peek != DEF_YES) { /* If peek opt NOT req'd, pkt buf(s) consumed : ... */ if (pbuf_head_next != (NET_BUF *)0) { /* ... if rem'ing rx Q non-empty, ... */ /* ... unlink from prev'ly q'd pkt buf(s); ... */ pbuf_head_next_hdr = (NET_BUF_HDR *)&pbuf_head_next->Hdr; pbuf_head_next_hdr->PrevPrimListPtr = (void *) 0; } /* ... & set new sock rx Q head. */ psock->RxQ_Head = (NET_BUF *)pbuf_head_next; if (psock->RxQ_Head == (NET_BUF *)0) { /* If head now points to NULL, .. */ psock->RxQ_Tail = (NET_BUF *)0; /* .. tail also points to NULL. */ } if (free == DEF_YES) { /* If NOT freed by transport layer, ... */ NetSock_RxPktDiscard(pbuf_head, perr); /* ... free/discard pkt buf(s) [see Note #10b]. */ return (NET_SOCK_BSD_ERR_RX); } } /* ---------------- RTN RX'D SOCK DATA ---------------- */ if (data_len_tot < 1) { /* If rx'd data len < 1, ... */ *perr = NET_SOCK_ERR_RX_Q_EMPTY; /* ... rtn rx Q empty err (see Note #7b1). */ return (NET_SOCK_BSD_ERR_RX); } *perr = err_rtn; return ((NET_SOCK_RTN_CODE)data_len_tot); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RxDataHandlerStream() * * Description : (1) Receive data from a stream-type socket : * * (a) Validate socket connection state * (b) Get remote host address See Notes #4 & #5 * * (c) Configure socket receive : * (1) Get socket's transport connection identification handler * (2) Configure socket flags * * (d) Receive socket data from appropriate transport layer * (e) Return socket data received * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to receive data. * ------- Argument checked in NetSock_RxDataHandler(). * * psock Pointer to socket. * ----- Argument validated in NetSock_RxDataHandler(). * * pdata_buf Pointer to an application data buffer that will receive the socket's received * --------- data. * * Argument checked in NetSock_RxDataHandler(). * * data_buf_len Size of the application data buffer (in octets). * ------------ Argument checked in NetSock_RxDataHandler(). * * flags Flags to select receive options; bit-field flags logically OR'd : * ----- * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_RX_DATA_PEEK Receive socket data without consuming * the socket data; i.e. socket data * NOT removed from application receive * queue(s). * NET_SOCK_FLAG_RX_NO_BLOCK Receive socket data without blocking * (see Note #3). * * Argument checked in NetSock_RxDataHandler(). * * paddr_remote Pointer to an address buffer that will receive the socket address structure * with the received data's remote address (see Notes #4 & #5), if NO errors. * * paddr_len Pointer to a variable to ... : * * (a) Pass the size of the address buffer pointed to by 'paddr_remote'. * (b) (1) Return the actual size of socket address structure with the * received data's remote address, if NO errors; * (2) Return 0, otherwise. * * See Note #4b. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket data successfully received; check return * value for number of data octets received. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address length. * NET_SOCK_ERR_RX_Q_EMPTY Socket receive queue empty. * NET_SOCK_ERR_RX_Q_CLOSED Socket receive queue closed. * * NET_ERR_RX Receive error. * * ---- RETURNED BY NetConn_AddrRemoteGet() : ---- * --- RETURNED BY NetConn_ID_TransportGet() : --- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * * Return(s) : Number of positive data octets received, if NO errors (see Note #7a). * * NET_SOCK_BSD_RTN_CODE_CONN_CLOSED, if socket connection closed (see Note #7b). * * NET_SOCK_BSD_ERR_RX, otherwise (see Note #7c1). * * Caller(s) : NetSock_RxDataHandler(). *$PAGE* * Note(s) : (2) (a) (1) Stream-type sockets transmit & receive all data octets in one or more non- * distinct packets. In other words, the application data is NOT bounded by * any specific packet(s); rather, it is contiguous & sequenced from one packet * to the next. * * (2) IEEE Std 1003.1, 2004 Edition, Section 'recv() : DESCRIPTION' summarizes * that "for stream-based sockets, such as SOCK_STREAM, message boundaries * shall be ignored. In this case, data shall be returned to the user as * soon as it becomes available, and no data shall be discarded". * * (b) (1) Thus, if the socket's type is stream & the receive data buffer size is NOT * large enough for the received data, the receive data buffer is maximally * filled with receive data & the remaining data octets remain queued for * later application-socket receives. * * (2) Therefore, a stream-type socket receive is signaled ONLY when data is * received for a socket connection where data was previously unavailable. * * (c) Consequently, it is typical -- but NOT absolutely required -- that a single * application task only receive or request to receive application data from a * stream-type socket. * * See also 'NetSock_RxDataHandler() Note #2b'. * * (3) If global socket blocking ('NET_SOCK_CFG_BLOCK_SEL') configured for blocking operation * ('NET_SOCK_BLOCK_SEL_BLOCK' or 'NET_SOCK_BLOCK_SEL_DFLT') but 'flags' argument set to * 'NET_SOCK_FLAG_TX_NO_BLOCK'; socket receive does NOT configure the transport layer * receive to block, regardless if the socket is configured to block. * * (4) (a) If a pointer to remote address buffer is provided, it is assumed that the remote * address buffer has been previously validated for the remote address to be returned. * * (b) If a pointer to remote address buffer is provided, it is assumed that a pointer to * an address length buffer is also available & has been previously validated. * * (c) The remote address is obtained from the socket connection's remote address. * * (5) (a) Socket address structure 'Family' member returned in host-order & SHOULD NOT be * converted to network-order. * * (b) Socket address structure addresses MUST be converted from host-order to network- * order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (6) (a) Socket connection addresses are maintained in network-order. * * (b) Since the port number & address are copied from a network-order multi-octet array * into local variables & then into a network-order socket address structure, they do * NOT need to be converted from host-order to network-order. * * (7) IEEE Std 1003.1, 2004 Edition, Section 'recv() : RETURN VALUE' states that : * * (a) "Upon successful completion, recv() shall return the length of the message in bytes." * * (b) "If no messages are available to be received and the peer has performed an orderly * shutdown, recv() shall return 0." * * (1) Since the socket receive return value of '0' is reserved for socket connection * closes; NO socket receive -- fault or non-fault -- should ever return '0' octets * received. * * (c) (1) "Otherwise, -1 shall be returned" ... * (2) "and 'errno' set to indicate the error." * * See also 'NetSock_RxDataHandler() Note #7'. * * (8) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. * * (9) On ANY errors, network resources MUST be appropriately freed : * * (a) NetSock_RxDataHandlerStream() assumes that stream-type sockets have been previously * validated as connected by caller function(s). Therefore, on any internal socket * connection error(s), the socket MUST be closed. * * (b) Since transport layer error(s) may NOT be critical &/or may be transitory, NO network * or socket resource(s) are closed/freed. * * (c) If transport layer reports closed receive queue, socket layer is free to close/free * ALL network or transport connection resource(s). * * See also 'net_tcp.c NetTCP_RxAppData() Note #3e3A1'. * * (10) 'sock_id' may NOT be necessary but included for completeness. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_SOCK_RTN_CODE NetSock_RxDataHandlerStream (NET_SOCK_ID sock_id, NET_SOCK *psock, void *pdata_buf, CPU_INT16S data_buf_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN *paddr_len, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_SOCK_ADDR_IP *paddr_ip; NET_IP_ADDR remote_addr; #endif #if (NET_SOCK_CFG_BLOCK_SEL != NET_SOCK_BLOCK_SEL_NO_BLOCK) CPU_BOOLEAN no_block; #endif CPU_BOOLEAN block; CPU_BOOLEAN peek; NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; NET_PORT_NBR remote_port; NET_SOCK_ADDR_LEN addr_len; CPU_INT08U addr_remote[NET_SOCK_CFG_ADDR_LEN]; CPU_INT16U flags_transport; CPU_INT16S data_len_tot; NET_ERR err; NET_ERR err_rtn; (void)&sock_id; /* Prevent compiler warning (see Note #10). */ /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CONN_DONE: psock->State = NET_SOCK_STATE_CONN; break; case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: break; case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* ----------------- GET REMOTE ADDR ------------------ */ conn_id = psock->ID_Conn; if (paddr_remote != (NET_SOCK_ADDR *)0) { /* If remote addr buf avail, ... */ /* ... rtn sock conn's remote addr (see Note #4c). */ addr_len = sizeof(addr_remote); NetConn_AddrRemoteGet((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr_remote[0], (NET_CONN_ADDR_LEN *)&addr_len, (NET_ERR *) perr); if (*perr != NET_CONN_ERR_NONE) { /* See Note #9a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); return (NET_SOCK_BSD_ERR_RX); } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) if (addr_len != NET_SOCK_CFG_ADDR_LEN) { /* See Note #9a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return (NET_SOCK_BSD_ERR_RX); } #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) Mem_Copy((void *)&remote_port, (void *)&addr_remote[NET_SOCK_ADDR_IP_IX_PORT], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&remote_addr, (void *)&addr_remote[NET_SOCK_ADDR_IP_IX_ADDR], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); paddr_ip = (NET_SOCK_ADDR_IP *)paddr_remote; /* Cfg remote addr struct (see Note #5). */ NET_UTIL_VAL_SET_HOST_16(&paddr_ip->Family, NET_SOCK_ADDR_FAMILY_IP_V4); NET_UTIL_VAL_COPY_16(&paddr_ip->Port, &remote_port); /* Copy preserves net-order (see Note #6b). */ NET_UTIL_VAL_COPY_32(&paddr_ip->Addr, &remote_addr); /* Copy preserves net-order (see Note #6b). */ Mem_Clr((void *) &paddr_ip->Unused[0], (CPU_SIZE_T) NET_SOCK_ADDR_IP_NBR_OCTETS_UNUSED); *paddr_len = NET_SOCK_ADDR_IP_SIZE; #else /* See Notes #8 & #9a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_SOCK_BSD_ERR_RX); #endif } /* ------------------- CFG SOCK RX -------------------- */ /* Get transport conn id. */ conn_id_transport = NetConn_ID_TransportGet(conn_id, perr); if (*perr != NET_CONN_ERR_NONE) { /* See Note #9a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); return (NET_SOCK_BSD_ERR_RX); } /* Cfg sock rx flags. */ #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_NO_BLOCK) block = DEF_NO; #else no_block = DEF_BIT_IS_SET(flags, NET_SOCK_FLAG_RX_NO_BLOCK); if (no_block == DEF_YES) { /* If 'No Block' flag set, ... */ block = DEF_NO; /* ... do NOT block (see Note #3). */ } else { #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_BLOCK) /* Else block if cfg'd, ... */ block = DEF_YES; #else /* ... or chk sock's block flag. */ block = DEF_BIT_IS_SET(psock->Flags, NET_SOCK_FLAG_BLOCK); #endif } #endif peek = DEF_BIT_IS_SET(flags, NET_SOCK_FLAG_RX_DATA_PEEK); /*$PAGE*/ /* ------------------- RX SOCK DATA ------------------- */ switch (psock->Protocol) { /* Rx app data from transport layer rx. */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: /* Cfg transport rx flags. */ flags_transport = NET_TCP_FLAG_NONE; if (block == DEF_YES) { DEF_BIT_SET(flags_transport, NET_TCP_FLAG_RX_BLOCK); } if (peek == DEF_YES) { DEF_BIT_SET(flags_transport, NET_TCP_FLAG_RX_DATA_PEEK); } data_len_tot = (CPU_INT16S)NetTCP_RxAppData((NET_TCP_CONN_ID) conn_id_transport, (void *) pdata_buf, (CPU_INT16U ) data_buf_len, (CPU_INT16U ) flags_transport, (NET_ERR *)&err); switch (err) { case NET_TCP_ERR_NONE: err_rtn = NET_SOCK_ERR_NONE; break; case NET_TCP_ERR_RX_Q_EMPTY: err_rtn = NET_SOCK_ERR_RX_Q_EMPTY; break; case NET_TCP_ERR_RX_Q_CLOSED: err_rtn = NET_SOCK_ERR_RX_Q_CLOSED; break; case NET_TCP_ERR_INVALID_CONN: case NET_TCP_ERR_INVALID_CONN_OP: case NET_TCP_ERR_INVALID_CONN_STATE: case NET_TCP_ERR_CONN_NOT_USED: case NET_TCP_ERR_CONN_FAIL: case NET_TCP_ERR_CONN_DATA_INVALID: case NET_TCP_ERR_RX_Q_SIGNAL_ABORT: case NET_TCP_ERR_RX_Q_SIGNAL_FAULT: err_rtn = NET_SOCK_ERR_FAULT; break; case NET_ERR_INIT_INCOMPLETE: case NET_OS_ERR_LOCK: default: err_rtn = NET_ERR_RX; break; } break; #endif #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Notes #8 & #9a. */ (void)&conn_id_transport; /* Prevent compiler warnings. */ (void)&flags_transport; NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ } switch (err_rtn) { /* Demux transport-to-sock layer err. */ case NET_SOCK_ERR_NONE: break; case NET_SOCK_ERR_RX_Q_CLOSED: /* If transport layer rx Q closed, ... */ if (psock->State == NET_SOCK_STATE_CLOSING_DATA_AVAIL) { NetSock_CloseHandler(psock, DEF_YES, DEF_YES); /* ... close/free sock's conn(s) [see Note #9c] ... */ } *perr = err_rtn; /* ... & rtn closed code (see Note #7c1). */ return (NET_SOCK_BSD_RTN_CODE_CONN_CLOSED); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_ERR_RX_Q_EMPTY: case NET_SOCK_ERR_FAULT: case NET_ERR_RX: default: *perr = err_rtn; return (NET_SOCK_BSD_ERR_RX); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* ---------------- RTN RX'D SOCK DATA ---------------- */ if (data_len_tot < 1) { /* If rx'd data len < 1, ... */ *perr = NET_SOCK_ERR_RX_Q_EMPTY; /* ... rtn rx Q empty err (see Note #7b1). */ return (NET_SOCK_BSD_ERR_RX); } *perr = err_rtn; return ((NET_SOCK_RTN_CODE)data_len_tot); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_TxDataHandler() * * Description : (1) Transmit data through a socket : * * (a) Validate transmit data See Note #2 * (b) Validate transmit flags See Note #3 * (c) Acquire network lock * (d) Validate socket used * (e) Validate remote address See Note #4 * (f) Transmit socket data * (g) Release network lock * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to transmit data. * * p_data Pointer to application data to transmit. * * data_len Length of application data to transmit (in octets) [see Note #2]. * * flags Flags to select transmit options (see Note #3); bit-field flags logically OR'd : * * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_TX_NO_BLOCK Transmit socket data without blocking. * * paddr_remote Pointer to destination address buffer (see Note #4). * * addr_len Length of destination address buffer (in octets). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NULL_PTR Argument 'p_data' passed a NULL pointer. * NET_SOCK_ERR_INVALID_TYPE Invalid socket type. * NET_SOCK_ERR_INVALID_FLAG Invalid socket flags. * NET_SOCK_ERR_INVALID_DATA_SIZE Invalid data size (see Notes #2b & #2a1B2). * * --------- RETURNED BY NetSock_IsUsed() : --------- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_SOCK Invalid socket number. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * * --- RETURNED BY NetSock_IsValidAddrRemote() : ---- * NET_SOCK_ERR_INVALID_FAMILY Invalid socket address family. * NET_SOCK_ERR_INVALID_CONN Invalid socket connection. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address structure length. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_INVALID_PORT_NBR Invalid socket port number. * * - RETURNED BY NetSock_TxDataHandlerDatagram() : -- * -- RETURNED BY NetSock_TxDataHandlerStream() : --- * NET_SOCK_ERR_NONE Socket data successfully transmitted; check return * value for number of data octets transmitted. * * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * * NET_ERR_TX Transitory transmit error. * * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * - RETURNED BY NetSock_TxDataHandlerDatagram() : -- * NET_SOCK_ERR_ADDR_IN_USE Socket address already in use. * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_NONE_AVAIL NO available connections to allocate. * NET_CONN_ERR_INVALID_FAMILY Invalid network connection family. * NET_CONN_ERR_INVALID_TYPE Invalid network connection type. * NET_CONN_ERR_INVALID_LIST_IX Invalid network connection list index. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * -- RETURNED BY NetSock_TxDataHandlerStream() : --- * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * * ----------- RETURNED BY NetOS_Lock() : ----------- * NET_OS_ERR_LOCK Network access NOT acquired. *$PAGE* * Return(s) : Number of positive data octets transmitted, if NO errors (see Note #5a1). * * NET_SOCK_BSD_RTN_CODE_CONN_CLOSED, if socket connection closed (see Note #5b). * * NET_SOCK_BSD_ERR_TX, otherwise (see Note #5a2A). * * Caller(s) : sendto(). * * Note(s) : (2) (a) (1) (A) Datagram-type sockets transmit & receive all data atomically -- i.e. every * single, complete datagram transmitted MUST be received as a single, complete * datagram. Thus, each call to transmit data MUST be transmitted in a single, * complete datagram. * * (B) (1) IEEE Std 1003.1, 2004 Edition, Section 'send() : DESCRIPTION' states * that "if the message is too long to pass through the underlying protocol, * send() shall fail and no data shall be transmitted". * * (2) Since IP transmit fragmentation is NOT currently supported (see 'net_ip.h * Note #1e'), if the socket's type is datagram & the requested transmit * data length is greater than the socket/transport layer MTU, then NO data * is transmitted & NET_SOCK_ERR_INVALID_DATA_SIZE error is returned. * * (2) (A) (1) Stream-type sockets transmit & receive all data octets in one or more * non-distinct packets. In other words, the application data is NOT * bounded by any specific packet(s); rather, it is contiguous & sequenced * from one packet to the next. * * (2) Thus, if the socket's type is stream & the socket's transmit data queue(s) * are NOT large enough for the transmitted data, the transmit data queue(s) * are maximally filled with transmit data & the remaining data octets are * discarded but may be re-transmitted by later application-socket transmits. * * (3) Therefore, NO stream-type socket transmit data length should be "too long * to pass through the underlying protocol" & cause the socket transmit to * "fail ... [with] no data ... transmitted" (see Note #2a1B1). * * (B) Thus, it is typical -- but NOT absolutely required -- that a single application * task ONLY transmit or request to transmit data to a stream-type socket. * * (b) 'data_len' of 0 octets NOT allowed. * * See also 'NetSock_TxDataHandlerDatagram() Note #2', * & 'NetSock_TxDataHandlerStream() Note #3'. * * (3) #### Only some socket transmit flag options are implemented. If other flag options are * requested, NetSock_TxData() handler function(s) abort & return appropriate error codes * so that requested flag options are NOT silently ignored. * * (4) (a) Socket address structure 'Family' member MUST be configured in host-order & MUST * NOT be converted to/from network-order. * * (b) Socket address structure addresses MUST be configured/converted from host-order * to network-order. * * See also 'net_sock.h NETWORK SOCKET ADDRESS DATA TYPES Note #2'. * * (5) (a) IEEE Std 1003.1, 2004 Edition, Section 'send() : RETURN VALUE' states that : * * (1) "Upon successful completion, send() shall return the number of bytes sent." * * (A) Section 'send() : DESCRIPTION' elaborates that "successful completion * of a call to sendto() does not guarantee delivery of the message". * * (B) Thus, applications SHOULD verify the actual returned number of data * octets transmitted &/or prepared for transmission. * * (2) (A) "Otherwise, -1 shall be returned" ... * (1) Section 'send() : DESCRIPTION' elaborates that "a return value of * -1 indicates only locally-detected errors". * * (B) "and 'errno' set to indicate the error." * * (b) ???? Although NO socket send() specification states to return '0' when the socket's * connection is closed, it seems reasonable to return '0' since it is possible for the * socket connection to be close()'d or shutdown() by the remote host. * * (1) Since the socket transmit return value of '0' is reserved for socket connection * closes; NO socket transmit -- fault or non-fault -- should ever return '0' octets * transmitted. * * See also 'NetSock_TxDataHandlerDatagram() Note #6' * & 'NetSock_TxDataHandlerStream() Note #5'. * * (6) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'SockType' is incorrectly modified. ********************************************************************************************************** */ /*$PAGE*/ static NET_SOCK_RTN_CODE NetSock_TxDataHandler (NET_SOCK_ID sock_id, void *p_data, CPU_INT16S data_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_SOCK_ADDR_LEN addr_len, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) CPU_BOOLEAN valid; CPU_INT16U flag_mask; #endif NET_SOCK *psock; NET_SOCK_RTN_CODE rtn_code; #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ----------------- VALIDATE TX DATA ----------------- */ if (p_data == (void *)0) { /* Validate data ptr. */ NET_CTR_ERR_INC(NetSock_ErrNullPtrCtr); *perr = NET_SOCK_ERR_NULL_PTR; return (NET_SOCK_BSD_ERR_TX); } if (data_len < 1) { /* Validate data len (see Note #2b). */ NET_CTR_ERR_INC(NetSock_ErrTxInvalidSizeCtr); *perr = NET_SOCK_ERR_INVALID_DATA_SIZE; return (NET_SOCK_BSD_ERR_TX); } /* ----------------- VALIDATE TX FLAGS ---------------- */ flag_mask = NET_SOCK_FLAG_NONE | NET_SOCK_FLAG_TX_NO_BLOCK; /* If any invalid flags req'd, rtn err (see Note #3). */ if (((CPU_INT16U)flags & ~flag_mask) != NET_SOCK_FLAG_NONE) { NET_CTR_ERR_INC(NetSock_ErrInvalidFlagsCtr); *perr = NET_SOCK_ERR_INVALID_FLAG; return (NET_SOCK_BSD_ERR_TX); } #endif /* ----------------- ACQUIRE NET LOCK ----------------- */ NetOS_Lock(perr); if (*perr != NET_OS_ERR_NONE) { return (NET_SOCK_BSD_ERR_TX); } #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* ---------------- VALIDATE SOCK USED ---------------- */ (void)NetSock_IsUsed(sock_id, perr); if (*perr != NET_SOCK_ERR_NONE) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_TX); } #endif psock = &NetSock_Tbl[sock_id]; #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) /* --------------- VALIDATE REMOTE ADDR --------------- */ if (paddr_remote != (NET_SOCK_ADDR *)0) { valid = NetSock_IsValidAddrRemote(paddr_remote, addr_len, psock, perr); if (valid != DEF_YES) { NetOS_Unlock(); return (NET_SOCK_BSD_ERR_TX); } } #endif /*$PAGE*/ /* ------------------- TX SOCK DATA ------------------- */ switch (psock->SockType) { case NET_SOCK_TYPE_DATAGRAM: rtn_code = NetSock_TxDataHandlerDatagram((NET_SOCK_ID )sock_id, (NET_SOCK *)psock, (void *)p_data, (CPU_INT16S )data_len, (CPU_INT16S )flags, (NET_SOCK_ADDR *)paddr_remote, (NET_ERR *)perr); break; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) case NET_SOCK_TYPE_STREAM: rtn_code = NetSock_TxDataHandlerStream((NET_SOCK_ID )sock_id, (NET_SOCK *)psock, (void *)p_data, (CPU_INT16S )data_len, (CPU_INT16S )flags, (NET_ERR *)perr); break; #endif case NET_SOCK_TYPE_NONE: default: /* See Note #6. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidSockTypeCtr); NetOS_Unlock(); *perr = NET_SOCK_ERR_INVALID_TYPE; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ } /* ----------------- RELEASE NET LOCK ----------------- */ NetOS_Unlock(); return (rtn_code); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_TxDataHandlerDatagram() * * Description : (1) Transmit data through a datagram-type socket : * * (a) Validate socket connection state * * (b) Configure socket transmit : * (1) Configure source/destination addresses for transmit * (2) Configure socket flags * * (c) Transmit socket data via appropriate transport layer * (d) Return socket data transmitted length * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to receive data. * ------- Argument checked in NetSock_TxDataHandler(). * * psock Pointer to socket. * ----- Argument validated in NetSock_TxDataHandler(). * * p_data Pointer to application data. * ------ Argument checked in NetSock_TxDataHandler(). * * data_len Length of application data (in octets) [see Note #2]. * -------- Argument checked in NetSock_TxDataHandler(). * * flags Flags to select transmit options; bit-field flags logically OR'd : * ----- * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_TX_NO_BLOCK Transmit socket data without blocking * (see Note #3). * * Argument checked in NetSock_TxDataHandler(). * * paddr_remote Pointer to destination address buffer (see Note #4). * ------------ Argument checked in NetSock_TxDataHandler(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket data successfully transmitted. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_ADDR_LEN Invalid socket address length. * NET_SOCK_ERR_INVALID_DATA_SIZE Invalid data size (see Notes #2b & #2a2B). * * NET_ERR_TX Transitory transmit error. * * -- RETURNED BY NetSock_BindHandler() : --- * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_ADDR Invalid socket address. * NET_SOCK_ERR_ADDR_IN_USE Socket address already in use. * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * NET_SOCK_ERR_CONN_FAIL Socket connection operation(s) failed. * NET_CONN_ERR_NONE_AVAIL NO available connections to allocate. * NET_CONN_ERR_INVALID_FAMILY Invalid network connection family. * NET_CONN_ERR_INVALID_TYPE Invalid network connection type. * NET_CONN_ERR_INVALID_LIST_IX Invalid network connection list index. * NET_CONN_ERR_ADDR_IN_USE Network connection address already in use. * * -- RETURNED BY NetConn_AddrLocalGet() : -- * -- RETURNED BY NetConn_AddrRemoteGet() : - * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection(s) NOT currently used. * NET_CONN_ERR_NULL_PTR Argument(s) passed a NULL pointer. * NET_CONN_ERR_INVALID_ADDR_LEN Invalid network connection address length. * NET_CONN_ERR_ADDR_NOT_USED Network connection address NOT in use. * * Return(s) : Number of positive data octets transmitted, if NO errors (see Note #6a1). * * NET_SOCK_BSD_RTN_CODE_CONN_CLOSED, if socket connection closed (see Note #6b). * * NET_SOCK_BSD_ERR_TX, otherwise (see Note #6a2A). * * Caller(s) : NetSock_TxDataHandler(). *$PAGE* * Note(s) : (2) (a) (1) Datagram-type sockets transmit & receive all data atomically -- i.e. every * single, complete datagram transmitted MUST be received as a single, complete * datagram. Thus, each call to transmit data MUST be transmitted in a single, * complete datagram. * * (2) (A) IEEE Std 1003.1, 2004 Edition, Section 'send() : DESCRIPTION' states that * "if the message is too long to pass through the underlying protocol, send() * shall fail and no data shall be transmitted". * * (B) Since IP transmit fragmentation is NOT currently supported (see 'net_ip.h * Note #1e'), if the socket's type is datagram & the requested transmit * data length is greater than the socket/transport layer MTU, then NO data * is transmitted & NET_SOCK_ERR_INVALID_DATA_SIZE error is returned. * * (b) 'data_len' of 0 octets NOT allowed. * * See also 'NetSock_TxDataHandler() Note #2a'. * * (3) If global socket blocking ('NET_SOCK_CFG_BLOCK_SEL') configured for blocking operation * ('NET_SOCK_BLOCK_SEL_BLOCK' or 'NET_SOCK_BLOCK_SEL_DFLT') but 'flags' argument set to * 'NET_SOCK_FLAG_TX_NO_BLOCK'; socket transmit does NOT configure the transport layer * transmit to block, regardless if the socket is configured to block. * * (4) If a pointer to remote address buffer is provided, it is assumed that the remote * address buffer & remote address buffer length have been previously validated. * * (5) (a) A socket's local address MUST be available in order to transmit. * * (b) Since only a single host address is supported (see 'net_ip.h Note #1a'), always * use this single host address for the socket's local address when transmitting * packets, regardless of whether a protocol's wildcard address is specified in the * socket connection's local address structure. * * (6) (a) IEEE Std 1003.1, 2004 Edition, Section 'send() : RETURN VALUE' states that : * * (1) "Upon successful completion, send() shall return the number of bytes sent." * * (A) Section 'send() : DESCRIPTION' elaborates that "successful completion * of a call to sendto() does not guarantee delivery of the message". * * (B) Thus, applications SHOULD verify the actual returned number of data * octets transmitted &/or prepared for transmission. * * (2) (A) "Otherwise, -1 shall be returned" ... * (1) Section 'send() : DESCRIPTION' elaborates that "a return value of * -1 indicates only locally-detected errors". * * (B) "and 'errno' set to indicate the error." * * (b) ???? Although NO socket send() specification states to return '0' when the socket's * connection is closed, it seems reasonable to return '0' since it is possible for the * socket connection to be close()'d or shutdown() by the remote host. * * (1) Since the socket transmit return value of '0' is reserved for socket connection * closes; NO socket transmit -- fault or non-fault -- should ever return '0' octets * transmitted. * * (2) However, since NO actual connections are implemented for datagram-type sockets * (see 'NetSock_ConnHandlerDatagram() Note #2a'), NO actual socket connections * can be closed on datagram-type sockets. Therefore, datagram-type socket * transmits MUST NEVER return '0'. * * See also 'NetSock_TxDataHandler() Note #5'. * * (7) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. * * (8) On ANY errors, network resources MUST be appropriately freed : * * (a) NetSock_TxDataHandlerDatagram() assumes that internal socket configuration * has been previously validated by caller function(s). Therefore, on any * internal socket configuration error(s), the socket MUST be closed. * * (b) NetSock_TxDataHandlerDatagram() assumes that any internal socket connection * error(s) on datagram-type sockets may NOT be critical &/or may be transitory; * thus NO network or socket resource(s) are closed/freed. * * (c) Since transport layer error(s) may NOT be critical &/or may be transitory, NO * network or socket resource(s) are closed/freed. * * (9) #### Transport & IP layer parameters/options NOT yet implemented. * * (10) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'Protocol' is incorrectly modified. * * (11) 'sock_id' may NOT be necessary but included for completeness. ********************************************************************************************************* */ /*$PAGE*/ static NET_SOCK_RTN_CODE NetSock_TxDataHandlerDatagram (NET_SOCK_ID sock_id, NET_SOCK *psock, void *p_data, CPU_INT16S data_len, CPU_INT16S flags, NET_SOCK_ADDR *paddr_remote, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) NET_SOCK_ADDR_IP *paddr_ip; NET_IP_ADDR src_addr; NET_IP_ADDR dest_addr; #endif #if (NET_SOCK_CFG_BLOCK_SEL != NET_SOCK_BLOCK_SEL_NO_BLOCK) CPU_BOOLEAN no_block; #endif CPU_BOOLEAN block; NET_CONN_ID conn_id; CPU_INT08U addr_local[NET_SOCK_CFG_ADDR_LEN]; CPU_INT08U addr_remote[NET_SOCK_CFG_ADDR_LEN]; NET_SOCK_ADDR_LEN addr_len; NET_PORT_NBR src_port; NET_PORT_NBR dest_port; CPU_INT16U flags_transport; CPU_INT16S data_len_tot; NET_ERR err; NET_ERR err_rtn; (void)&sock_id; /* Prevent compiler warning (see Note #11). */ /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED: /* If sock closed, bind to random local addr. */ (void)NetSock_BindHandler((NET_SOCK_ID )sock_id, (NET_SOCK_ADDR *)0, (NET_SOCK_ADDR_LEN)0, (CPU_BOOLEAN )DEF_YES, (NET_ERR *)perr); if (*perr != NET_SOCK_ERR_NONE) { return (NET_SOCK_BSD_ERR_TX); } break; case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_CONN: break; case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* -------------- CFG TX SRC/DEST ADDRS --------------- */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) conn_id = psock->ID_Conn; /* Cfg local/src addr (see Note #5). */ addr_len = sizeof(addr_local); NetConn_AddrLocalGet((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr_local[0], (NET_CONN_ADDR_LEN *)&addr_len, (NET_ERR *) perr); if (*perr != NET_CONN_ERR_NONE) { return (NET_SOCK_BSD_ERR_TX); } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) if (addr_len != NET_SOCK_CFG_ADDR_LEN) { /* See Note #8a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return (NET_SOCK_BSD_ERR_TX); } #endif Mem_Copy((void *)&src_port, (void *)&addr_local[NET_SOCK_ADDR_IP_IX_PORT], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&src_addr, (void *)&addr_local[NET_SOCK_ADDR_IP_IX_ADDR], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); src_port = NET_UTIL_NET_TO_HOST_16(src_port); src_addr = NET_UTIL_NET_TO_HOST_32(src_addr); if (src_addr == NET_SOCK_ADDR_IP_WILD_CARD) { /* If wildcard addr, ... */ src_addr = NetIP_AddrThisHost; /* ... subst this host's IP addr (see Note #5b). */ } /* Cfg remote/dest addr. */ if (paddr_remote == (NET_SOCK_ADDR *)0) { /* If remote addr NOT provided, ... */ /* ... get sock conn's remote addr. */ addr_len = sizeof(addr_remote); NetConn_AddrRemoteGet((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr_remote[0], (NET_CONN_ADDR_LEN *)&addr_len, (NET_ERR *) perr); if (*perr != NET_CONN_ERR_NONE) { return (NET_SOCK_BSD_ERR_TX); } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) if (addr_len != NET_SOCK_CFG_ADDR_LEN) { /* See Note #8a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); *perr = NET_SOCK_ERR_INVALID_ADDR_LEN; return (NET_SOCK_BSD_ERR_TX); } #endif Mem_Copy((void *)&dest_port, (void *)&addr_remote[NET_SOCK_ADDR_IP_IX_PORT], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); Mem_Copy((void *)&dest_addr, (void *)&addr_remote[NET_SOCK_ADDR_IP_IX_ADDR], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_ADDR); dest_port = NET_UTIL_NET_TO_HOST_16(dest_port); dest_addr = NET_UTIL_NET_TO_HOST_32(dest_addr); } else { /* Else cfg remote addr (see Note #4). */ paddr_ip = (NET_SOCK_ADDR_IP *)paddr_remote; dest_port = NET_UTIL_VAL_GET_NET_16(&paddr_ip->Port); dest_addr = NET_UTIL_VAL_GET_NET_32(&paddr_ip->Addr); } #else /* See Notes #7 & #8a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_SOCK_BSD_ERR_TX); #endif /*$PAGE*/ /* ------------------- CFG SOCK TX -------------------- */ /* Cfg sock tx flags. */ #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_NO_BLOCK) block = DEF_NO; #else no_block = DEF_BIT_IS_SET(flags, NET_SOCK_FLAG_TX_NO_BLOCK); if (no_block == DEF_YES) { /* If 'No Block' flag set, ... */ block = DEF_NO; /* ... do NOT block (see Note #3). */ } else { #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_BLOCK) /* Else block if cfg'd, ... */ block = DEF_YES; #else /* ... or chk sock's block flag. */ block = DEF_BIT_IS_SET(psock->Flags, NET_SOCK_FLAG_BLOCK); #endif } #endif /*$PAGE*/ /* ------------------- TX SOCK DATA ------------------- */ switch (psock->Protocol) { /* Tx app data via transport layer tx. */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) case NET_SOCK_PROTOCOL_UDP: /* Cfg transport tx flags. */ flags_transport = NET_UDP_FLAG_NONE; if (block == DEF_YES) { DEF_BIT_SET(flags_transport, NET_UDP_FLAG_TX_BLOCK); } data_len_tot = (CPU_INT16S)NetUDP_TxAppData((void *) p_data, (CPU_INT16U ) data_len, (NET_IP_ADDR ) src_addr, (NET_UDP_PORT_NBR) src_port, (NET_IP_ADDR ) dest_addr, (NET_UDP_PORT_NBR) dest_port, (NET_IP_TOS ) NET_IP_TOS_DFLT, /* #### See Note #9. */ (NET_IP_TTL ) NET_IP_TTL_DFLT, (CPU_INT16U ) flags_transport, (CPU_INT16U ) NET_IP_FLAG_NONE, (void *) 0, (NET_ERR *)&err); switch (err) { case NET_UDP_ERR_NONE: err_rtn = NET_SOCK_ERR_NONE; break; case NET_UDP_ERR_INVALID_DATA_SIZE: err_rtn = NET_SOCK_ERR_INVALID_DATA_SIZE; break; case NET_ERR_INIT_INCOMPLETE: case NET_ERR_INVALID_PROTOCOL: case NET_UDP_ERR_NULL_PTR: case NET_UDP_ERR_INVALID_LEN_DATA: case NET_UDP_ERR_INVALID_PORT_NBR: case NET_UDP_ERR_INVALID_FLAG: case NET_BUF_ERR_NULL_PTR: case NET_BUF_ERR_NONE_AVAIL: case NET_BUF_ERR_INVALID_TYPE: case NET_BUF_ERR_INVALID_SIZE: case NET_BUF_ERR_INVALID_LEN: case NET_BUF_ERR_INVALID_IX: case NET_UTIL_ERR_NULL_PTR: case NET_UTIL_ERR_NULL_SIZE: case NET_UTIL_ERR_INVALID_PROTOCOL: case NET_ERR_TX: default: err_rtn = NET_ERR_TX; break; } break; #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Notes #10 & #8a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ } switch (err_rtn) { /* Demux transport-to-sock layer err. */ case NET_SOCK_ERR_NONE: break; case NET_SOCK_ERR_INVALID_DATA_SIZE: case NET_ERR_TX: default: *perr = err_rtn; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* -------------- RTN TX'D SOCK DATA LEN -------------- */ if (data_len_tot < 1) { /* If tx'd data len < 1, ... */ *perr = NET_SOCK_ERR_INVALID_DATA_SIZE; /* ... rtn invalid tx data size err (see Note #6b1). */ return (NET_SOCK_BSD_ERR_TX); } *perr = err_rtn; return ((NET_SOCK_RTN_CODE)data_len_tot); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_TxDataHandlerStream() * * Description : (1) Transmit data through a stream-type socket : * * (a) Validate socket connection state * * (b) Configure socket transmit : * (1) Get socket's transport connection identification handler * (2) Configure socket flags * * (c) Transmit socket data via appropriate transport layer * (d) Return socket data transmitted length * * * Argument(s) : sock_id Socket descriptor/handle identifier of socket to receive data. * ------- Argument checked in NetSock_TxDataHandler(). * * psock Pointer to socket. * ----- Argument validated in NetSock_TxDataHandler(). * * p_data Pointer to application data. * ------ Argument checked in NetSock_TxDataHandler(). * * data_len Length of application data (in octets) [see Note #3]. * -------- Argument checked in NetSock_TxDataHandler(). * * flags Flags to select transmit options; bit-field flags logically OR'd : * ----- * NET_SOCK_FLAG_NONE No socket flags selected. * NET_SOCK_FLAG_TX_NO_BLOCK Transmit socket data without blocking * (see Note #4). * * Argument checked in NetSock_TxDataHandler(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket data successfully transmitted. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * NET_SOCK_ERR_FAULT Socket fault; connection(s) aborted. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * NET_SOCK_ERR_INVALID_STATE Invalid socket state. * NET_SOCK_ERR_INVALID_OP Invalid socket operation. * NET_SOCK_ERR_INVALID_DATA_SIZE Invalid data size (see Note #3b). * * NET_ERR_TX Transitory transmit error. * * - RETURNED BY NetConn_ID_TransportGet() : - * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * Return(s) : Number of positive data octets transmitted, if NO errors (see Note #5a1). * * NET_SOCK_BSD_RTN_CODE_CONN_CLOSED, if socket connection closed (see Note #5b). * * NET_SOCK_BSD_ERR_TX, otherwise (see Note #5a2A). * * Caller(s) : NetSock_TxDataHandler(). *$PAGE* * Note(s) : (2) Stream-type sockets may transmit from the following states : * * (a) Unconnected states : * * (A) #### Unconnected state(s) transmit NOT yet implemented; * see also 'net_tcp.c NetTCP_TxConnAppData() Note #3bA'. * * (1) CLOSED * (A) Bind to local port * (B) Connect to remote host * (C) (1) Transmit data with connection request(s)? * OR * (2) Queue transmit data until connected to remote host? * * (2) BOUND * (A) Connect to remote host * (B) (1) Transmit data with connection request(s)? * OR * (2) Queue transmit data until connected to remote host? * * (3) LISTEN * (A) Connect to remote host * (B) (1) Transmit data with connection request(s)? * OR * (2) Queue transmit data until connected to remote host? * * (4) CONNECTION-IN-PROGRESS * (A) Queue transmit data until connected to remote host? * * (b) Connected states : * * (1) CONNECTED * * (3) (a) (1) (A) Stream-type sockets transmit & receive all data octets in one or more * non-distinct packets. In other words, the application data is NOT * bounded by any specific packet(s); rather, it is contiguous & sequenced * from one packet to the next. * * (B) Thus, if the socket's type is stream & the socket's transmit data queue(s) * are NOT large enough for the transmitted data, the transmit data queue(s) * are maximally filled with transmit data & the remaining data octets are * discarded but may be re-transmitted by later application-socket transmits. * * (C) Therefore, NO stream-type socket transmit data length should be "too long * to pass through the underlying protocol" & cause the socket transmit to * "fail ... [with] no data ... transmitted" (IEEE Std 1003.1, 2004 Edition, * Section 'send() : DESCRIPTION'). * * (2) Thus, it is typical -- but NOT absolutely required -- that a single application * task ONLY transmit or request to transmit data to a stream-type socket. * * (b) 'data_len' of 0 octets NOT allowed. * * See also 'NetSock_TxDataHandler() Note #2'. *$PAGE* * (4) If global socket blocking ('NET_SOCK_CFG_BLOCK_SEL') configured for blocking operation * ('NET_SOCK_BLOCK_SEL_BLOCK' or 'NET_SOCK_BLOCK_SEL_DFLT') but 'flags' argument set to * 'NET_SOCK_FLAG_TX_NO_BLOCK'; socket transmit does NOT configure the transport layer * transmit to block, regardless if the socket is configured to block. * * (5) (a) IEEE Std 1003.1, 2004 Edition, Section 'send() : RETURN VALUE' states that : * * (1) "Upon successful completion, send() shall return the number of bytes sent." * * (A) Section 'send() : DESCRIPTION' elaborates that "successful completion * of a call to sendto() does not guarantee delivery of the message". * * (B) Thus, applications SHOULD verify the actual returned number of data * octets transmitted &/or prepared for transmission. * * (2) (A) "Otherwise, -1 shall be returned" ... * (1) Section 'send() : DESCRIPTION' elaborates that "a return value of * -1 indicates only locally-detected errors". * * (B) "and 'errno' set to indicate the error." * * (b) ???? Although NO socket send() specification states to return '0' when the socket's * connection is closed, it seems reasonable to return '0' since it is possible for the * socket connection to be close()'d or shutdown() by the remote host. * * (1) Since the socket transmit return value of '0' is reserved for socket connection * closes; NO socket transmit -- fault or non-fault -- should ever return '0' octets * transmitted. * * See also 'NetSock_TxDataHandler() Note #5'. * * (6) On ANY errors, network resources MUST be appropriately freed : * * (a) NetSock_TxDataHandlerStream() assumes that internal socket configuration * has been previously validated by caller function(s). Therefore, on any * internal socket configuration error(s), the socket MUST be closed. * * (b) NetSock_TxDataHandlerStream() assumes that any internal socket connection * error(s) on stream-type sockets may NOT be critical &/or may be transitory; * thus NO network or socket resource(s) are closed/freed. * * (c) Since transport layer error(s) may NOT be critical &/or may be transitory, NO * network or socket resource(s) are closed/freed. * * (7) Default case already invalidated in NetSock_Open(). However, the default case is * included as an extra precaution in case 'Protocol' is incorrectly modified. * * (8) 'sock_id' may NOT be necessary but included for completeness. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_SOCK_RTN_CODE NetSock_TxDataHandlerStream (NET_SOCK_ID sock_id, NET_SOCK *psock, void *p_data, CPU_INT16S data_len, CPU_INT16S flags, NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_SOCK_CFG_BLOCK_SEL != NET_SOCK_BLOCK_SEL_NO_BLOCK) CPU_BOOLEAN no_block; #endif CPU_BOOLEAN block; NET_CONN_ID conn_id; NET_CONN_ID conn_id_transport; CPU_INT16U flags_transport; CPU_INT16S data_len_tot; NET_ERR err; NET_ERR err_rtn; (void)&sock_id; /* Prevent compiler warning (see Note #8). */ /* ------------- VALIDATE SOCK CONN STATE ------------- */ switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_CLOSED; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CONN_DONE: psock->State = NET_SOCK_STATE_CONN; break; case NET_SOCK_STATE_CONN: break; case NET_SOCK_STATE_CLOSED: /* #### Bind to local port & ... */ case NET_SOCK_STATE_BOUND: /* ... tx conn req to remote host; Q tx data? */ case NET_SOCK_STATE_LISTEN: /* #### Q/tx data with conn req? */ case NET_SOCK_STATE_CONN_IN_PROGRESS: /* #### Q tx data until conn complete? */ /* #### NOT yet implemented (see Note #2aA). */ NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: NET_CTR_ERR_INC(NetSock_ErrInvalidOpCtr); *perr = NET_SOCK_ERR_INVALID_OP; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: default: NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidStateCtr); *perr = NET_SOCK_ERR_INVALID_STATE; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* ------------------- CFG SOCK TX -------------------- */ /* Get transport conn id. */ conn_id = psock->ID_Conn; conn_id_transport = NetConn_ID_TransportGet(conn_id, perr); if (*perr != NET_CONN_ERR_NONE) { /* See Note #6a. */ NetSock_CloseSock(psock, DEF_YES, DEF_YES); return (NET_SOCK_BSD_ERR_TX); } /* Cfg sock tx flags. */ #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_NO_BLOCK) block = DEF_NO; #else no_block = DEF_BIT_IS_SET(flags, NET_SOCK_FLAG_TX_NO_BLOCK); if (no_block == DEF_YES) { /* If 'No Block' flag set, ... */ block = DEF_NO; /* ... do NOT block (see Note #4). */ } else { #if (NET_SOCK_CFG_BLOCK_SEL == NET_SOCK_BLOCK_SEL_BLOCK) /* Else block if cfg'd, ... */ block = DEF_YES; #else /* ... or chk sock's block flag. */ block = DEF_BIT_IS_SET(psock->Flags, NET_SOCK_FLAG_BLOCK); #endif } #endif /*$PAGE*/ /* ------------------- TX SOCK DATA ------------------- */ switch (psock->Protocol) { /* Tx app data via transport layer tx. */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT case NET_SOCK_PROTOCOL_TCP: /* Cfg transport tx flags. */ flags_transport = NET_TCP_FLAG_NONE; if (block == DEF_YES) { DEF_BIT_SET(flags_transport, NET_TCP_FLAG_TX_BLOCK); } data_len_tot = (CPU_INT16S)NetTCP_TxConnAppData((NET_TCP_CONN_ID) conn_id_transport, (void *) p_data, (CPU_INT16U ) data_len, (CPU_INT16U ) flags_transport, (NET_ERR *)&err); switch (err) { case NET_TCP_ERR_NONE: err_rtn = NET_SOCK_ERR_NONE; break; case NET_TCP_ERR_INVALID_DATA_SIZE: err_rtn = NET_SOCK_ERR_INVALID_DATA_SIZE; break; case NET_TCP_ERR_CONN_NOT_USED: case NET_TCP_ERR_CONN_CLOSE: case NET_TCP_ERR_CONN_FAULT: case NET_TCP_ERR_CONN_DATA_INVALID: case NET_TCP_ERR_INVALID_CONN: case NET_TCP_ERR_INVALID_CONN_STATE: case NET_TCP_ERR_TX_Q_SIGNAL_ABORT: case NET_TCP_ERR_TX_Q_SIGNAL_FAULT: case NET_TCP_ERR_TX: case NET_CONN_ERR_INVALID_FAMILY: case NET_CONN_ERR_INVALID_ADDR: case NET_CONN_ERR_INVALID_ADDR_LEN: err_rtn = NET_SOCK_ERR_FAULT; break; case NET_ERR_INIT_INCOMPLETE: case NET_TCP_ERR_NULL_PTR: case NET_TCP_ERR_INVALID_CONN_OP: case NET_TCP_ERR_INVALID_LEN_SEG: case NET_TCP_ERR_CONN_ACK_NONE: case NET_TCP_ERR_CONN_ACK_DLYD: case NET_TCP_ERR_CONN_ACK_PREVLY_TXD: case NET_TCP_ERR_CONN_ACK_INVALID: case NET_TCP_ERR_NONE_AVAIL: case NET_TCP_ERR_TX_Q_FULL: case NET_TCP_ERR_TX_Q_SUSPEND: case NET_OS_ERR_LOCK: case NET_ERR_TX: default: err_rtn = NET_ERR_TX; break; } break; #endif #endif case NET_SOCK_PROTOCOL_NONE: default: /* See Notes #7 & #6a. */ (void)&conn_id_transport; /* Prevent compiler warnings. */ (void)&flags_transport; NetSock_CloseSock(psock, DEF_YES, DEF_YES); NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); *perr = NET_SOCK_ERR_INVALID_PROTOCOL; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ } switch (err_rtn) { /* Demux transport-to-sock layer err. */ case NET_SOCK_ERR_NONE: break; case NET_SOCK_ERR_INVALID_DATA_SIZE: case NET_SOCK_ERR_FAULT: case NET_ERR_TX: default: *perr = err_rtn; return (NET_SOCK_BSD_ERR_TX); /* Prevent 'break NOT reachable' compiler warning. */ } /*$PAGE*/ /* -------------- RTN TX'D SOCK DATA LEN -------------- */ if (data_len_tot < 1) { /* If tx'd data len < 1, ... */ *perr = NET_SOCK_ERR_INVALID_DATA_SIZE; /* ... rtn invalid tx data size err (see Note #5b1). */ return (NET_SOCK_BSD_ERR_TX); } *perr = err_rtn; return ((NET_SOCK_RTN_CODE)data_len_tot); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Get() * * Description : (1) Allocate & initialize a socket : * * (a) Get a socket * (b) Validate socket * (c) Initialize socket * (d) Update socket pool statistics * (e) Return pointer to socket * OR * Null pointer & error code, on failure * * (2) The socket pool is implemented as a stack : * * (a) 'NetSock_PoolPtr' points to the head of the socket pool. * * (b) Sockets' 'NextSockPtr's link each socket to form the socket pool stack. * * (c) Sockets are inserted & removed at the head of the socket pool stack. * * * Sockets are * inserted & removed * at the head * (see Note #2c) * * | NextSockPtr * | (see Note #2b) * v | * | * ------- ------- v ------- ------- * Socket Pool ---->| |------>| |------>| |------>| | * Pointer | | | | | | | | * | | | | | | | | * (see Note #2a) ------- ------- ------- ------- * * | | * |<----------- Pool of Free Sockets ------------>| * | (see Note #2) | * * * Argument(s) : perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket successfully allocated & initialized. * NET_SOCK_ERR_NONE_AVAIL NO available sockets to allocate. * NET_SOCK_ERR_INVALID_TYPE Socket is NOT a valid type. * * Return(s) : Pointer to socket, if NO errors. * * Pointer to NULL, otherwise. * * Caller(s) : NetSock_Open(). * * Note(s) : (3) (a) Socket pool is accessed by 'NetSock_PoolPtr' during execution of * * (1) NetSock_Init() * (2) NetSock_Get() * (3) NetSock_Free() * * (b) Since the primary tasks of the network protocol suite are prevented from running * concurrently (see 'net.h Note #2'), it is NOT necessary to protect the shared * resources of the socket pool since no asynchronous access from other network * tasks is possible. ********************************************************************************************************* */ /*$PAGE*/ static NET_SOCK *NetSock_Get (NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_SOCK *psock; NET_ERR stat_err; /* --------------------- GET SOCK --------------------- */ if (NetSock_PoolPtr != (NET_SOCK *)0) { /* If sock pool NOT empty, get sock from pool. */ psock = (NET_SOCK *)NetSock_PoolPtr; NetSock_PoolPtr = (NET_SOCK *)psock->NextSockPtr; } else { /* If none avail, rtn err. */ NET_CTR_ERR_INC(NetSock_ErrNoneAvailCtr); *perr = NET_SOCK_ERR_NONE_AVAIL; return ((NET_SOCK *)0); } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------------ VALIDATE SOCK ------------------- */ if (psock->Type != NET_SOCK_TYPE_SOCK) { NetSock_Discard(psock); NET_CTR_ERR_INC(NetSock_ErrInvalidTypeCtr); *perr = NET_SOCK_ERR_INVALID_TYPE; return ((NET_SOCK *)0); } #endif /* -------------------- INIT SOCK --------------------- */ NetSock_Clr(psock); DEF_BIT_SET(psock->Flags, NET_SOCK_FLAG_USED); /* Set sock as used. */ psock->State = NET_SOCK_STATE_CLOSED; /* -------------- UPDATE SOCK POOL STATS -------------- */ NetStat_PoolEntryUsedInc(&NetSock_PoolStat, &stat_err); *perr = NET_SOCK_ERR_NONE; return (psock); /* -------------------- RTN SOCK ---------------------- */ } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_GetConnTransport() * * Description : (1) Allocate a transport layer connection : * * (a) Get a transport connection * (b) Set connection handle identifiers * * * Argument(s) : psock Pointer to a socket. * ----- Argument validated in NetSock_Listen(), * NetSock_ConnHandlerStream(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket transport connection successfully * allocated. * NET_SOCK_ERR_CONN_FAIL Socket transport connection allocation or * configuration failed. * NET_SOCK_ERR_INVALID_FAMILY Invalid socket protocol family. * NET_SOCK_ERR_INVALID_PROTOCOL Invalid socket protocol. * * - RETURNED BY NetConn_ID_TransportSet() : - * NET_CONN_ERR_INVALID_CONN Invalid network connection number. * NET_CONN_ERR_NOT_USED Network connection NOT currently used. * * Return(s) : Transport connection handler identifer, if NO errors. * * NET_CONN_ID_NONE, otherwise. * * Caller(s) : NetSock_Listen(), * NetSock_ConnHandlerStream(). * * Note(s) : (2) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. * * (3) On ANY errors after the transport connection is allocated, the transport connection * MUST be freed. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static NET_CONN_ID NetSock_GetConnTransport (NET_SOCK *psock, NET_ERR *perr) { #if (NET_SOCK_CFG_FAMILY != NET_SOCK_FAMILY_IP_V4) /* See Note #2. */ #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #endif NET_CONN_ID conn_id_transport; NET_CONN_ID conn_id; CPU_BOOLEAN conn_err; NET_ERR err; /* -------------- GET TRANSPORT CONN -------------- */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT conn_id_transport = (NET_CONN_ID)NetTCP_ConnGet(&err); *perr = (err == NET_TCP_ERR_NONE) ? NET_SOCK_ERR_NONE : NET_SOCK_ERR_CONN_FAIL; #else NET_CTR_ERR_INC(NetSock_ErrInvalidProtocolCtr); (void)&conn_id_transport; /* Prevent compiler warnings. */ (void)&err; *perr = NET_SOCK_ERR_CONN_FAIL; #endif #else /* See Note #2. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; return (NET_CONN_ID_NONE); #endif if (*perr != NET_SOCK_ERR_NONE) { return (NET_CONN_ID_NONE); } /* ----------------- SET CONN IDs ----------------- */ conn_id = psock->ID_Conn; conn_err = DEF_NO; /* Set conn's transport id. */ NetConn_ID_TransportSet(conn_id, conn_id_transport, perr); if (*perr != NET_CONN_ERR_NONE) { conn_err = DEF_YES; } /* Set transport's conn id. */ if (conn_err == DEF_NO) { #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT NetTCP_ConnSetID_Conn((NET_TCP_CONN_ID) conn_id_transport, (NET_CONN_ID ) conn_id, (NET_ERR *)&err); *perr = (err != NET_TCP_ERR_NONE) ? NET_SOCK_ERR_CONN_FAIL : NET_SOCK_ERR_NONE; #endif #else /* See Note #2. */ conn_err = DEF_YES; #endif } if (*perr != NET_SOCK_ERR_NONE) { conn_err = DEF_YES; } if (conn_err != DEF_NO) { /* If any errs, free transport conn (see Note #3). */ #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) #ifdef NET_TCP_MODULE_PRESENT NetTCP_ConnFree((NET_TCP_CONN_ID)conn_id_transport); #endif #else /* See Note #2. */ NET_CTR_ERR_INC(NetSock_ErrInvalidFamilyCtr); *perr = NET_SOCK_ERR_INVALID_FAMILY; #endif return (NET_CONN_ID_NONE); } *perr = NET_SOCK_ERR_NONE; return (conn_id_transport); } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CloseHandler() * * Description : (1) Close a socket for valid socket close operations : * * (a) Close socket * (b) Free socket * * * Argument(s) : psock Pointer to a socket. * ----- Argument validated in NetSock_Close(), * NetSock_CloseHandlerStream(), * NetSock_CloseSockFromClose(), * various. * * close_conn Indicate whether to close network connection (see Note #2) : * * DEF_YES Close network connection. * DEF_NO Do NOT close network connection. * * close_conn_transport Indicate whether to close transport connection (see Note #2) : * * DEF_YES Close transport connection. * DEF_NO Do NOT close transport connection. * * Return(s) : none. * * Caller(s) : NetSock_Close(), * NetSock_CloseHandlerStream(), * NetSock_CloseSockFromClose(), * various. * * Note(s) : (2) Except when closed from the network connection layer, a socket SHOULD close its * network connection(s). * * See also 'NetSock_CloseSockHandler() Note #2a'. * * (3) On any socket close handler errors, socket already discarded in close handler (see * 'NetSock_FreeHandler() Note #3'). * * #### Continued access to the discarded socket by the application layer will likely * corrupt the network socket layer. * * See also 'NetSock_Close() Note #2'. ********************************************************************************************************* */ static void NetSock_CloseHandler (NET_SOCK *psock, CPU_BOOLEAN close_conn, CPU_BOOLEAN close_conn_transport) { NET_ERR err; /* ------------------- CLOSE SOCK --------------------- */ NetSock_CloseSockHandler(psock, close_conn, close_conn_transport, &err); if (err != NET_SOCK_ERR_NONE) { /* See Note #3. */ return; } /* -------------------- FREE SOCK --------------------- */ NetSock_Free(psock); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CloseSock() * * Description : (1) Close a socket due to socket connection fault(s) : * * (a) Update socket close statistic(s) * (b) Close socket * * * (2) (a) Socket connection closed when : * * (1) Socket parameters are corrupted : * (A) Family * (B) Protocol * (C) Type * (D) State * * (2) Certain valid socket operations fail * * (3) Socket connection(s) close internally (see Note #1c) * * See also 'NetSock_CloseFromConn() Note #1'. * * (b) Frees socket resources, closes socket connection(s), & returns socket to CLOSED * state -- but does NOT free the socket since NO mechanism or API exists to close * an application's reference to the socket. * * When a socket is internally closed, ALL application-to-socket access fails & * forces the application to close the socket. * * (c) #### When socket connection operations fail & close the socket, the socket MUST * abort continued/further socket operations. In other words, when certain fatal * socket errors are returned, the application MUST immediately close the socket : * * (1) NET_SOCK_ERR_NOT_USED * (2) NET_SOCK_ERR_INVALID_FAMILY * (3) NET_SOCK_ERR_INVALID_PROTOCOL * (4) NET_SOCK_ERR_INVALID_TYPE * (5) NET_SOCK_ERR_INVALID_STATE * (6) NET_SOCK_ERR_FAULT * * See also 'NetSock_Close() Note #2'. * * * Argument(s) : psock Pointer to a socket. * ----- Argument validated in various. * * close_conn Indicate whether to close network connection (see Note #3) : * * DEF_YES Close network connection. * DEF_NO Do NOT close network connection. * * close_conn_transport Indicate whether to close transport connection (see Note #3) : * * DEF_YES Close transport connection. * DEF_NO Do NOT close transport connection. * * Return(s) : none. * * Caller(s) : various, * NetSock_CloseFromConn(). * * Note(s) : (3) Except when closed from the network connection layer, a socket SHOULD close its * network connection(s). * * See also 'NetSock_CloseSockHandler() Note #2a'. * * (4) If socket close handler fails, socket already discarded in close handler (see * 'NetSock_FreeHandler() Note #3'). * * #### Continued access to the discarded socket by the application layer will likely * corrupt the network socket layer (see Note #2c). ********************************************************************************************************* */ /*$PAGE*/ static void NetSock_CloseSock (NET_SOCK *psock, CPU_BOOLEAN close_conn, CPU_BOOLEAN close_conn_transport) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_ERR err; /* ---------------- UPDATE CLOSE STATS ---------------- */ NET_CTR_ERR_INC(NetSock_ErrCloseCtr); /* -------------------- CLOSE SOCK -------------------- */ NetSock_CloseSockHandler(psock, close_conn, close_conn_transport, &err); if (err != NET_SOCK_ERR_NONE) { /* See Note #4. */ return; } /* Close sock (see Note #2b). */ psock->Family = NET_SOCK_FAMILY_NONE; psock->Protocol = NET_SOCK_PROTOCOL_NONE; psock->SockType = NET_SOCK_TYPE_NONE; psock->State = NET_SOCK_STATE_CLOSED_FAULT; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CloseSockHandler() * * Description : (1) Close a socket : * * (a) Free socket * (b) Close socket connection(s) See Note #2 * * * Argument(s) : psock Pointer to a socket. * ----- Argument validated in NetSock_CloseHandler(), * NetSock_CloseSockHandler(). * * close_conn Indicate whether to close network connection (see Note #2a) : * * DEF_YES Close network connection. * DEF_NO Do NOT close network connection. * * close_conn_transport Indicate whether to close transport connection (see Note #2a) : * * DEF_YES Close transport connection. * DEF_NO Do NOT close transport connection. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Socket connection successfully closed. * NET_SOCK_ERR_NOT_USED Socket NOT currently used. * NET_SOCK_ERR_CLOSED Socket already closed. * * - RETURNED BY NetSock_FreeHandler() : - * NET_SOCK_ERR_INVALID_TYPE Socket is NOT a valid socket type. * NET_SOCK_ERR_CONN_SIGNAL_CLR Socket connection signal clear failed. * NET_SOCK_ERR_RX_Q_SIGNAL_CLR Socket receive queue signal clear failed. * * Return(s) : none. * * Caller(s) : NetSock_CloseHandler(), * NetSock_CloseSock(). * * Note(s) : (2) (a) When a socket closes, specified socket network connection(s) MAY be closed * &/or network connection handle identifier(s) MAY be cleared : * * (1) Network connection * (2) Transport connection * * See also 'NetSock_CloseHandler() Note #2', * 'NetSock_CloseSock() Note #3', * 'NetSock_CloseSockFromClose() Note #3', * & 'NetSock_CloseFromConn() Note #1'. * * (A) A socket may maintain its network connection despite closing the transport * connection, but a socket MUST NOT close the network connection but expect * to maintain the transport connection. * * (B) Network connection(s) MAY be closed even if socket close fails (see also * Note #4). * * (b) Socket's network connection handle identifier MUST be : * * (1) Obtained PRIOR to any socket free operation * (2) Cleared after socket connection(s) closed * * (3) #### To prevent closing a socket already closed via previous socket close, * NetSock_CloseSockHandler() checks the socket's 'USED' flag BEFORE closing * the socket. * * This prevention is only best-effort since any invalid duplicate socket closes * MAY be asynchronous to potentially valid socket opens. Thus the invalid socket * close(s) MAY corrupt the socket's valid operation(s). * * However, since the primary tasks of the network protocol suite are prevented * from running concurrently (see 'net.h Note #2'), it is NOT necessary to protect * socket resources from possible corruption since no asynchronous access from * other network tasks is possible. * * (4) On any socket close handler errors, socket already discarded in close handler (see * 'NetSock_FreeHandler() Note #3a'). * * #### Continued access to the discarded socket by the application layer will likely * corrupt the network socket layer. * * See also 'NetSock_Close() Note #2'. ********************************************************************************************************* */ /*$PAGE*/ static void NetSock_CloseSockHandler (NET_SOCK *psock, CPU_BOOLEAN close_conn, CPU_BOOLEAN close_conn_transport, NET_ERR *perr) { #if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) CPU_BOOLEAN used; #endif NET_CONN_ID conn_id; /* --------------- VALIDATE SOCK CLOSE ---------------- */ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) used = DEF_BIT_IS_SET(psock->Flags, NET_SOCK_FLAG_USED); if (used != DEF_YES) { /* If sock NOT used, ... */ NET_CTR_ERR_INC(NetSock_ErrNotUsedCtr); *perr = NET_SOCK_ERR_NOT_USED; /* ... rtn but do NOT close (see Note #3). */ return; } #endif switch (psock->State) { case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: default: break; /* Sock NOT re-closed if already free/closed. */ case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: *perr = NET_SOCK_ERR_NOT_USED; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_CLOSED_FAULT: *perr = NET_SOCK_ERR_NONE; return; /* Prevent 'break NOT reachable' compiler warning. */ } /* -------------------- FREE SOCK --------------------- */ conn_id = psock->ID_Conn; /* Get sock's net conn id (see Note #2b1). */ NetSock_FreeHandler(psock, perr); /* ------------------ CLOSE CONN(S) ------------------- */ if (close_conn == DEF_YES) { /* If req'd, close conn(s) [see Note #2a]. */ NetConn_CloseFromApp(conn_id, close_conn_transport); } /* Chk free err(s) AFTER conn close(s) [see Note #2aB]. */ if (*perr != NET_SOCK_ERR_NONE) { /* On free err(s), abort sock close (see Note #4). */ return; } /* ------------------ CLR SOCK CONN ------------------- */ psock->ID_Conn = NET_CONN_ID_NONE; /* Clr sock's net conn id (see Note #2b2). */ *perr = NET_SOCK_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CloseSockFromClose() * * Description : (1) Close a socket due to socket close/closing faults : * * (a) Update socket close statistic(s) * (b) Close socket * * * (2) (a) (1) MUST ONLY be called by socket closing functions (see Note #2b). * * (2) Close socket connection for the following socket close/closing faults : * * (A) Socket close parameters are corrupted : * (1) Type * (2) State * * (b) Frees socket resources, closes socket connection(s), returns socket to CLOSED * state AND frees the socket since the close was initiated by the application. * * See also 'NetSock_CloseHandler() Note #1'. * * See also 'NetSock_CloseSock() Note #2'. * * * Argument(s) : psock Pointer to a socket. * ----- Argument validated in NetSock_Close(), * NetSock_CloseHandlerStream(). * * Return(s) : none. * * Caller(s) : NetSock_Close(), * NetSock_CloseHandlerStream(). * * Note(s) : (3) A socket closing with fault(s) SHOULD close its network connection(s). * * See also 'NetSock_CloseSockHandler() Note #2a'. * * (4) If socket close handler fails, socket already discarded in close handler (see * 'NetSock_FreeHandler() Note #3'). * * #### Continued access to the discarded socket by the application layer will likely * corrupt the network socket layer. * * See also 'NetSock_Close() Note #2'. ********************************************************************************************************* */ static void NetSock_CloseSockFromClose (NET_SOCK *psock) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif /* ---------------- UPDATE CLOSE STATS ---------------- */ NET_CTR_ERR_INC(NetSock_ErrCloseCtr); /* -------------------- CLOSE SOCK -------------------- */ NetSock_CloseHandler(psock, DEF_YES, DEF_YES); /* See Note #3. */ } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CloseConn() * * Description : (1) Close a socket's network connection(s) : * * (a) Remove connection handle identifier from socket's connection accept queue * (b) Close network connection(s) * * * (2) Closes socket network connection(s) ONLY; does NOT free or close socket(s). * * * Argument(s) : conn_id Handle identifier of network connection to close. * * Return(s) : none. * * Caller(s) : NetSock_RxPktDemux(), * NetSock_Accept(). * * Note(s) : none. ********************************************************************************************************* */ static void NetSock_CloseConn (NET_CONN_ID conn_id) { NetSock_CloseConnFree(conn_id); NetConn_CloseFromApp(conn_id, DEF_YES); /* See Note #1b. */ } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_CloseConnFree() * * Description : Close/free network connection from socket. * * Argument(s) : conn_id Handle identifier of network connection. * * Return(s) : none. * * Caller(s) : NetSock_CloseConn(). * * Note(s) : (1) Network connections are de-referenced from cloned socket application connections. * * See also 'NetSock_FreeConnFromSock() Note #2b'. ********************************************************************************************************* */ static void NetSock_CloseConnFree (NET_CONN_ID conn_id) { NET_SOCK_ID sock_id; NET_ERR err; /* ----------------- GET SOCK ID ------------------ */ sock_id = (NET_SOCK_ID)NetConn_ID_AppCloneGet(conn_id, &err); /* Get clone sock app conn (see Note #1). */ if (err != NET_CONN_ERR_NONE) { return; } /* ------------- FREE CONN FROM SOCK -------------- */ NetSock_FreeConnFromSock(sock_id, conn_id); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Free() * * Description : (1) Free a socket : * * (a) Clear socket controls * (b) Free socket back to socket pool * (c) Update socket pool statistics * * * Argument(s) : psock Pointer to a socket. * ----- Argument validated in NetSock_Close(), * NetSock_CloseHandler(), * NetSock_CloseHandlerStream(). * * Return(s) : none. * * Caller(s) : NetSock_Close(), * NetSock_CloseHandler(), * NetSock_CloseHandlerStream(). * * Note(s) : none. ********************************************************************************************************* */ static void NetSock_Free (NET_SOCK *psock) { NET_ERR err; /* --------------------- CLR SOCK --------------------- */ psock->State = NET_SOCK_STATE_FREE; /* Set sock as freed/NOT used. */ DEF_BIT_CLR(psock->Flags, NET_SOCK_FLAG_USED); #if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED) NetSock_Clr(psock); #endif /* -------------------- FREE SOCK --------------------- */ psock->NextSockPtr = (void *)NetSock_PoolPtr; NetSock_PoolPtr = (NET_SOCK *)psock; /* -------------- UPDATE SOCK POOL STATS -------------- */ NetStat_PoolEntryUsedDec(&NetSock_PoolStat, &err); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_FreeHandler() * * Description : (1) Free a socket : * * (a) Free socket address See Note #2 * (b) Clear socket connection * (c) Free socket packet buffer queues * * * Argument(s) : psock Pointer to a socket. * ----- Argument checked in NetSock_CloseSockHandler(). * * perr Pointer to variable that will receive the return error code from this function * (see Note #3) : * * NET_SOCK_ERR_NONE Socket connection successfully freed. * NET_SOCK_ERR_INVALID_TYPE Socket is NOT a valid socket type. * * --- RETURNED BY NetOS_Sock_ConnReqClr() : ---- * - RETURNED BY NetOS_Sock_ConnAcceptQ_Clr() : - * -- RETURNED BY NetOS_Sock_ConnCloseClr() : --- * NET_SOCK_ERR_CONN_SIGNAL_CLR Socket connection signal clear failed. * * ----- RETURNED BY NetOS_Sock_RxQ_Clr() : ----- * NET_SOCK_ERR_RX_Q_SIGNAL_CLR Socket receive queue signal clear failed. * * Return(s) : none. * * Caller(s) : NetSock_CloseSockHandler(). * * Note(s) : (2) Since connection address information is required to free the socket address, * the socket address MUST be freed PRIOR to the network connection. * * See also 'NetSock_FreeAddr() Note #1' * & 'NetSock_CloseSockHandler() Notes #1a & #1b'. * * (3) (a) On ANY free socket connection handler error, socket is discarded & caller * function MUST NOT further handle or re-discard the socket. * * (b) ALL network resources linked to the socket MUST be freed PRIOR to socket * free or discard so that no network resources are lost. * * (c) The error code returned by 'perr' for a socket discard refers to the last * free socket error ONLY. * * (4) See 'net_sock.h NETWORK SOCKET DATA TYPE Note #3'. ********************************************************************************************************* */ /*$PAGE*/ static void NetSock_FreeHandler (NET_SOCK *psock, NET_ERR *perr) { #if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif CPU_BOOLEAN discard; NET_ERR err_discard; NET_ERR err; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------------ VALIDATE TYPE ------------------- */ if (psock->Type != NET_SOCK_TYPE_SOCK) { NetSock_Discard(psock); NET_CTR_ERR_INC(NetSock_ErrInvalidTypeCtr); *perr = NET_SOCK_ERR_INVALID_TYPE; return; } #endif /* ------------------ FREE SOCK ADDR ------------------ */ NetSock_FreeAddr(psock); /* See Note #2. */ /* ------------------- CLR SOCK CONN ------------------ */ discard = DEF_NO; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) NetOS_Sock_ConnReqClr(psock->ID, &err); if (err != NET_SOCK_ERR_NONE) { /* If sock conn req NOT clr'd, ... */ discard = DEF_YES; /* ... discard sock (see Note #3b). */ err_discard = err; } NetOS_Sock_ConnReqAbort(psock->ID, &err); /* Abort wait on sock conn req. */ NetSock_ConnAcceptQ_Clr(psock); /* Clr sock conn accept Q. */ NetOS_Sock_ConnAcceptQ_Clr(psock->ID, &err); if (err != NET_SOCK_ERR_NONE) { /* If sock conn accept Q NOT clr'd, ... */ discard = DEF_YES; /* ... discard sock (see Note #3b). */ err_discard = err; } NetOS_Sock_ConnAcceptQ_Abort(psock->ID, &err); /* Abort wait on sock conn accept Q. */ NetOS_Sock_ConnCloseClr(psock->ID, &err); if (err != NET_SOCK_ERR_NONE) { /* If sock conn close NOT clr'd, ... */ discard = DEF_YES; /* ... discard sock (see Note #3b). */ err_discard = err; } NetOS_Sock_ConnCloseAbort(psock->ID, &err); /* Abort wait on sock conn close. */ #endif /* ------------------ FREE SOCK Q's ------------------- */ NetSock_FreeBufQ(&psock->RxQ_Head, &psock->RxQ_Tail); #if 0 /* See Note #4. */ NetSock_FreeBufQ(&psock->TxQ_Head, &psock->TxQ_Tail); #endif NetOS_Sock_RxQ_Clr(psock->ID, &err); /* Clr sock rx Q. */ if (err != NET_SOCK_ERR_NONE) { /* If sock rx Q NOT clr'd, ... */ discard = DEF_YES; /* ... discard sock (see Note #3b). */ err_discard = err; } NetOS_Sock_RxQ_Abort(psock->ID, &err); /* Abort wait on sock rx Q. */ /* -------------- DISCARD SOCK ON ERR(S) -------------- */ if (discard != DEF_NO) { /* On sock free err(s), ... */ psock->State = NET_SOCK_STATE_DISCARD; NetSock_Discard(psock); /* ... discard sock (see Note #3a). */ *perr = err_discard; /* See Note #3c. */ return; } *perr = NET_SOCK_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_FreeAddr() * * Description : Free socket address. * * (1) Since connection address information is required to free the socket address, * the socket address MUST be freed PRIOR to closing the network connection. * * * Argument(s) : psock Pointer to a socket. * ----- Argument validated in NetSock_Close(). * * Return(s) : none. * * Caller(s) : NetSock_FreeHandler(). * * Note(s) : (2) The 'NET_SOCK_CFG_FAMILY' pre-processor 'else'-conditional code will never be * compiled/linked since 'net_sock.h' ensures that the family type configuration * constant (NET_SOCK_CFG_FAMILY) is configured with an appropriate family type * value (see 'net_sock.h CONFIGURATION ERRORS'). The 'else'-conditional code * is included for completeness & as an extra precaution in case 'net_sock.h' is * incorrectly modified. ********************************************************************************************************* */ static void NetSock_FreeAddr (NET_SOCK *psock) { NET_CONN_ID conn_id; CPU_INT08U addr[NET_SOCK_CFG_ADDR_LEN]; NET_SOCK_ADDR_LEN addr_len; NET_PORT_NBR port_nbr; NET_ERR err; switch (psock->State) { case NET_SOCK_STATE_FREE: case NET_SOCK_STATE_DISCARD: case NET_SOCK_STATE_CLOSED_FAULT: return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_SOCK_STATE_NONE: case NET_SOCK_STATE_CLOSED: case NET_SOCK_STATE_CLOSE_IN_PROGRESS: case NET_SOCK_STATE_CLOSING_DATA_AVAIL: case NET_SOCK_STATE_BOUND: case NET_SOCK_STATE_LISTEN: case NET_SOCK_STATE_CONN: case NET_SOCK_STATE_CONN_IN_PROGRESS: case NET_SOCK_STATE_CONN_DONE: default: break; } conn_id = psock->ID_Conn; addr_len = sizeof(addr); NetConn_AddrLocalGet((NET_CONN_ID ) conn_id, (CPU_INT08U *)&addr[0], (NET_CONN_ADDR_LEN *)&addr_len, (NET_ERR *)&err); if (err != NET_CONN_ERR_NONE) { return; } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) if (addr_len != NET_SOCK_CFG_ADDR_LEN) { return; } #endif #if (NET_SOCK_CFG_FAMILY == NET_SOCK_FAMILY_IP_V4) Mem_Copy((void *)&port_nbr, (void *)&addr[NET_SOCK_ADDR_IP_IX_PORT], (CPU_SIZE_T) NET_SOCK_ADDR_IP_LEN_PORT); port_nbr = NET_UTIL_NET_TO_HOST_16(port_nbr); #else /* See Note #2. */ (void)&port_nbr; /* Prevent compiler warning. */ return; #endif NetSock_RandomPortNbrFree(port_nbr, &err); /* Free port nbr to random port nbr Q (if necessary). */ } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_FreeBufQ() * * Description : Free a socket's buffer queue. * * Argument(s) : pbuf_q_head Pointer to a socket buffer queue's head pointer. * * pbuf_q_tail Pointer to a socket buffer queue's tail pointer. * * Return(s) : none. * * Caller(s) : NetSock_FreeHandler(). * * Note(s) : none. ********************************************************************************************************* */ static void NetSock_FreeBufQ (NET_BUF **pbuf_q_head, NET_BUF **pbuf_q_tail) { NET_BUF *pbuf_q; /* Free buf Q. */ pbuf_q = *pbuf_q_head; NetBuf_FreeBufQ_PrimList((NET_BUF *)pbuf_q, (NET_CTR *)0); /* Clr buf Q ptrs to NULL. */ *pbuf_q_head = (NET_BUF *)0; *pbuf_q_tail = (NET_BUF *)0; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Clr() * * Description : Clear socket controls. * * Argument(s) : psock Pointer to a socket. * ----- Argument validated in NetSock_Init(), * NetSock_Get(), * NetSock_Free(). * * Return(s) : none. * * Caller(s) : NetSock_Init(), * NetSock_Get(), * NetSock_Free(). * * Note(s) : (1) See 'net_sock.h NETWORK SOCKET DATA TYPE Note #3'. ********************************************************************************************************* */ static void NetSock_Clr (NET_SOCK *psock) { #if ((NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) && \ (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED)) NET_CONN_ID *pconn_id; NET_SOCK_Q_SIZE i; #endif NET_SOCK_ID sock_id; NET_ERR err; psock->NextSockPtr = (void *)0; psock->RxQ_Head = (NET_BUF *)0; psock->RxQ_Tail = (NET_BUF *)0; #if 0 /* See Note #1. */ psock->TxQ_Head = (NET_BUF *)0; psock->TxQ_Tail = (NET_BUF *)0; #endif psock->ID_Conn = NET_CONN_ID_NONE; psock->Family = NET_SOCK_FAMILY_NONE; psock->Protocol = NET_SOCK_PROTOCOL_NONE; psock->SockType = NET_SOCK_TYPE_NONE; psock->State = NET_SOCK_STATE_FREE; psock->Flags = NET_SOCK_FLAG_NONE; #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) /* ------------ CLR SOCK CONN ACCEPT Q VALS ----------- */ psock->ConnAcceptQ_SizeMax = NET_SOCK_Q_SIZE_NONE; psock->ConnAcceptQ_SizeCur = 0; psock->ConnAcceptQ_HeadIx = 0; psock->ConnAcceptQ_TailIx = 0; #if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED) pconn_id = &psock->ConnAcceptQ[0]; for (i = 0; i < NET_SOCK_CFG_CONN_ACCEPT_Q_SIZE_MAX; i++) { *pconn_id = NET_CONN_ID_NONE; pconn_id++; } #endif #endif /* ------------ CFG SOCK DFLT TIMEOUT VALS ------------ */ sock_id = psock->ID; NetOS_Sock_RxQ_TimeoutDflt(sock_id, &err); #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) NetOS_Sock_ConnReqTimeoutDflt(sock_id, &err); NetOS_Sock_ConnAcceptQ_TimeoutDflt(sock_id, &err); NetOS_Sock_ConnCloseTimeoutDflt(sock_id, &err); #endif } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Copy() * * Description : Copy a socket. * * Argument(s) : psock_dest Pointer to socket to receive socket copy. * ---------- Argument validated in NetSock_Accept(). * * psock_src Pointer to socket to copy. * --------- Argument validated in NetSock_Accept(). * * Return(s) : none. * * Caller(s) : NetSock_Accept(). * * Note(s) : none. ********************************************************************************************************* */ #if (NET_SOCK_CFG_TYPE_STREAM_EN == DEF_ENABLED) static void NetSock_Copy (NET_SOCK *psock_dest, NET_SOCK *psock_src) { psock_dest->Family = psock_src->Family; psock_dest->Protocol = psock_src->Protocol; psock_dest->SockType = psock_src->SockType; psock_dest->ID_Conn = psock_src->ID_Conn; psock_dest->State = psock_src->State; psock_dest->Flags = psock_src->Flags; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetSock_Discard() * * Description : (1) Discard an invalid/corrupted socket : * * (a) Discard socket from available socket pool See Note #2 * (b) Update socket pool statistics * * (2) Assumes socket is invalid/corrupt & MUST be removed. Socket removed simply by NOT * returning the socket back to the socket pool. * * * Argument(s) : psock Pointer to an invalid/corrupted socket. * * Return(s) : none. * * Caller(s) : NetSock_Get(), * NetSock_FreeHandler(). * * Note(s) : none. ********************************************************************************************************* */ static void NetSock_Discard (NET_SOCK *psock) { NET_ERR stat_err; /* ------------------- DISCARD SOCK ------------------- */ (void)&psock; /* Prevent compiler warning (see Note #2). */ /* --------------- UPDATE DISCARD STATS --------------- */ NetStat_PoolEntryLostInc(&NetSock_PoolStat, &stat_err); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RandomPortNbrGet() * * Description : Get a random port number from the random port number queue. * * (1) Random port number queue is a FIFO Q implemented as a circular ring array : * * (a) 'NetSock_RandomPortNbrQ_HeadIx' points to the next available port number. * * (b) 'NetSock_RandomPortNbrQ_TailIx' points to the next available queue entry * to insert freed port numbers. * * (c) 'NetSock_RandomPortNbrQ_HeadIx'/'NetSock_RandomPortNbrQ_TailIx' advance : * * (1) By increment; * (2) Reset to minimum index value when maximum index value reached. * * * Index to next available * port number in random port Index to next available * number queue entry to free port number * (see Note #1a) (see Note #1b) * * | | * | | * v v * ------------------------------------------------------- * | | | | | | | | | | * | | | | | | | | | | * | | | | | | | | | | * ------------------------------------------------------- * * ----------> * FIFO indices advance by * increment (see Note #1c1) * * | | * |<-------------- Circular Ring FIFO Q --------------->| * | (see Note #1) | * * * Argument(s) : perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Port number successfully retrieved. * NET_SOCK_ERR_PORT_NBR_NONE_AVAIL Port number NOT available. * * Return(s) : Random port number, if NO errors. * * NET_SOCK_PORT_NBR_NONE, otherwise. * * Caller(s) : NetSock_BindHandler(). * * Note(s) : none. ********************************************************************************************************* */ /*$PAGE*/ static NET_PORT_NBR NetSock_RandomPortNbrGet (NET_ERR *perr) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif NET_PORT_NBR port_nbr; /* ---------- VALIDATE NBR USED ----------- */ if (NetSock_RandomPortNbrQ_NbrUsed >= NET_SOCK_PORT_NBR_RANDOM_NBR) { NET_CTR_ERR_INC(NetSock_ErrRandomPortNbrNoneAvailCtr); *perr = NET_SOCK_ERR_PORT_NBR_NONE_AVAIL; return (NET_SOCK_PORT_NBR_NONE); } /* - GET PORT NBR FROM RANDOM PORT NBR Q -- */ port_nbr = NetSock_RandomPortNbrQ[NetSock_RandomPortNbrQ_HeadIx]; #if (NET_DBG_CFG_MEM_CLR_EN == DEF_ENABLED) NetSock_RandomPortNbrQ[NetSock_RandomPortNbrQ_HeadIx] = NET_SOCK_PORT_NBR_NONE; #endif NetSock_RandomPortNbrQ_HeadIx++; if (NetSock_RandomPortNbrQ_HeadIx >= NET_SOCK_PORT_NBR_RANDOM_NBR) { /* If head ix > max ix, ... */ NetSock_RandomPortNbrQ_HeadIx = 0; /* ... reset to min ix (see Note #1c2). */ } NetSock_RandomPortNbrQ_NbrUsed++; *perr = NET_SOCK_ERR_NONE; return (port_nbr); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RandomPortNbrFree() * * Description : (1) Free a port number back to the random port number queue : * * (a) Validate port number in random port number range & NOT currently in queue * (b) Free port number back to random port number queue * * * Argument(s) : port_nbr Port number to verify. * * perr Pointer to variable that will receive the return error code from this function : * * NET_SOCK_ERR_NONE Port number freed successfully. * NET_SOCK_ERR_INVALID_PORT_NBR Port number NOT in random port range. * NET_SOCK_ERR_INVALID_PORT_Q_NBR_USED Invalid number queue entries used. * NET_SOCK_ERR_PORT_NBR_IN_Q Port number already in random port * number queue. * * Return(s) : none. * * Caller(s) : NetSock_FreeAddr(). * * Note(s) : none. ********************************************************************************************************* */ static void NetSock_RandomPortNbrFree (NET_PORT_NBR port_nbr, NET_ERR *perr) { #if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \ (NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) CPU_BOOLEAN random_port_nbr_in_q; #endif CPU_BOOLEAN random_port_nbr_range; /* ---- VALIDATE RANDOM PORT NBR RANGE ---- */ random_port_nbr_range = NetSock_RandomPortNbrChkRange(port_nbr); if (random_port_nbr_range != DEF_YES) { *perr = NET_SOCK_ERR_INVALID_PORT_NBR; return; } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ---------- VALIDATE NBR USED ----------- */ if (NetSock_RandomPortNbrQ_NbrUsed < 1) { NET_CTR_ERR_INC(NetSock_ErrRandomPortNbrQ_UsedCtr); *perr = NET_SOCK_ERR_INVALID_PORT_Q_NBR_USED; return; } /* ------ VALIDATE PORT NBR NOT IN Q ------ */ random_port_nbr_in_q = NetSock_RandomPortNbrSrch(port_nbr); if (random_port_nbr_in_q != DEF_NO) { NET_CTR_ERR_INC(NetSock_ErrRandomPortNbrQ_NbrInQ_Ctr); *perr = NET_SOCK_ERR_PORT_NBR_IN_Q; return; } #endif /* -- FREE PORT NBR TO RANDOM PORT NBR Q -- */ NetSock_RandomPortNbrQ[NetSock_RandomPortNbrQ_TailIx] = port_nbr; NetSock_RandomPortNbrQ_TailIx++; if (NetSock_RandomPortNbrQ_TailIx >= NET_SOCK_PORT_NBR_RANDOM_NBR) { /* If tail ix > max ix, ... */ NetSock_RandomPortNbrQ_TailIx = 0; /* ... reset to min ix. */ } NetSock_RandomPortNbrQ_NbrUsed--; *perr = NET_SOCK_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RandomPortNbrChkRange() * * Description : Check if port number within random port number range. * * Argument(s) : port_nbr Port number to verify. * * Return(s) : DEF_NO, if port number NOT within random port number range. * * DEF_YES, if port number within random port number range. * * Caller(s) : NetSock_IsValidAddrLocal(), * NetSock_RandomPortNbrFree(). * * Note(s) : (1) Random port numbers reserved for sockets that transmit before or without previously * having binded to a local address. ********************************************************************************************************* */ static CPU_BOOLEAN NetSock_RandomPortNbrChkRange (NET_PORT_NBR port_nbr) { CPU_BOOLEAN random_port_nbr_range; random_port_nbr_range = DEF_YES; if (port_nbr < NET_SOCK_PORT_NBR_RANDOM_MIN) { random_port_nbr_range = DEF_NO; } if (port_nbr > NET_SOCK_PORT_NBR_RANDOM_MAX) { random_port_nbr_range = DEF_NO; } return (random_port_nbr_range); } /*$PAGE*/ /* ********************************************************************************************************* * NetSock_RandomPortNbrSrch() * * Description : Search random port number queue for specific port number. * * Argument(s) : port_nbr Port number to search. * * Return(s) : DEF_NO, if port number NOT in random port number queue. * * DEF_YES, if port number in random port number queue. * * Caller(s) : NetSock_RandomPortNbrFree(). * * Note(s) : (1) Assumes queue indices valid. * * (2) If ALL port numbers in queue searched & queue tail index NOT found, tail index MUST * be invalid -- outside the range of table indices. ********************************************************************************************************* */ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) static CPU_BOOLEAN NetSock_RandomPortNbrSrch (NET_PORT_NBR port_nbr) { CPU_BOOLEAN found; CPU_BOOLEAN done; NET_PORT_NBR ix; NET_PORT_NBR_QTY nbr; found = DEF_NO; done = DEF_NO; ix = NetSock_RandomPortNbrQ_HeadIx; /* See Note #1. */ nbr = 0; while (done == DEF_NO) { /* Srch random port nbr Q for port nbr. */ if (ix == NetSock_RandomPortNbrQ_TailIx) { /* If ix @ tail, port nbr NOT found. */ done = DEF_YES; } else { found = (NetSock_RandomPortNbrQ[ix] == port_nbr) ? DEF_YES : DEF_NO; if (found == DEF_YES) { /* If port nbr found, ... */ done = DEF_YES; /* ... abort successful srch. */ } else { nbr++; if (nbr >= NET_SOCK_PORT_NBR_RANDOM_NBR) { /* If nbr srch'd > nbr of port nbr's, ... */ done = DEF_YES; /* ... abort srch; port nbr Q corrupted (see Note #2). */ } else { ix++; if (ix >= NET_SOCK_PORT_NBR_RANDOM_NBR) { /* If ix > max ix, ... */ ix = 0; /* ... reset to min ix. */ } } } } } return (found); } #endif /*$PAGE*/ /* ********************************************************************************************************* * MODULE END * * Note(s) : (1) See 'MODULE Note #1' & 'net_sock.h MODULE Note #1'. ********************************************************************************************************* */ #endif /* End of net sock module include (see Note #1). */