/*
*********************************************************************************************************
*                                              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  <net.h>


/*
*********************************************************************************************************
*                                               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).        */

