mirror of
https://github.com/dimoniche/solarium.vlad.git
synced 2026-01-30 04:53:30 +03:00
12355 lines
592 KiB
C
12355 lines
592 KiB
C
/*
|
||
*********************************************************************************************************
|
||
* 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). */
|
||
|