📄 net_udp.c
字号:
CPU_SR cpu_sr;
#endif
CPU_INT16U udp_tot_len;
CPU_INT16U udp_data_len;
NET_CHK_SUM udp_chk_sum;
CPU_BOOLEAN udp_chk_sum_valid;
NET_UDP_PSEUDO_HDR udp_pseudo_hdr;
NET_BUF *pbuf_next;
NET_BUF_HDR *pbuf_next_hdr;
/* ---------------- VALIDATE UDP PORTS ---------------- */
NET_UTIL_VAL_COPY_GET_NET_16(&pbuf_hdr->TCP_UDP_PortSrc, &pudp_hdr->PortSrc);
if (pbuf_hdr->TCP_UDP_PortSrc == NET_UDP_PORT_NBR_RESERVED) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrPortSrcCtr);
*perr = NET_UDP_ERR_INVALID_PORT_NBR;
return;
}
NET_UTIL_VAL_COPY_GET_NET_16(&pbuf_hdr->TCP_UDP_PortDest, &pudp_hdr->PortDest);
if (pbuf_hdr->TCP_UDP_PortDest == NET_UDP_PORT_NBR_RESERVED) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrPortDestCtr);
*perr = NET_UDP_ERR_INVALID_PORT_NBR;
return;
}
/* ------------ VALIDATE UDP DATAGRAM LEN ------------- */
/* See Note #3. */
NET_UTIL_VAL_COPY_GET_NET_16(&udp_tot_len, &pudp_hdr->DatagramLen);
pbuf_hdr->TCP_UDP_TotLen = udp_tot_len;
if (pbuf_hdr->TCP_UDP_TotLen < NET_UDP_TOT_LEN_MIN) { /* If datagram len < min tot len, rtn err. */
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDatagramLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN;
return;
}
if (pbuf_hdr->TCP_UDP_TotLen > NET_UDP_TOT_LEN_MAX) { /* If datagram len > max tot len, rtn err. */
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDatagramLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN;
return;
}
if (pbuf_hdr->TCP_UDP_TotLen != pbuf_hdr->IP_DatagramLen) { /* If datagram len != IP datagram len, rtn err. */
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDatagramLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN;
return;
}
/*$PAGE*/
/* --------------- VALIDATE UDP CHK SUM --------------- */
/* See Note #4. */
NET_UTIL_VAL_COPY_GET_NET_16(&udp_chk_sum, &pudp_hdr->ChkSum);
if (udp_chk_sum != NET_UDP_HDR_CHK_SUM_NONE) { /* If chk sum rx'd, verify chk sum (see Note #4d). */
/* Prepare UDP chk sum pseudo-hdr (see Note #4e). */
udp_pseudo_hdr.AddrSrc = (NET_IP_ADDR)NET_UTIL_HOST_TO_NET_32(pbuf_hdr->IP_AddrSrc);
udp_pseudo_hdr.AddrDest = (NET_IP_ADDR)NET_UTIL_HOST_TO_NET_32(pbuf_hdr->IP_AddrDest);
udp_pseudo_hdr.Zero = (CPU_INT08U )0x00;
udp_pseudo_hdr.Protocol = (CPU_INT08U )NET_IP_HDR_PROTOCOL_UDP;
udp_pseudo_hdr.DatagramLen = (CPU_INT16U )NET_UTIL_HOST_TO_NET_16(pbuf_hdr->TCP_UDP_TotLen);
udp_chk_sum_valid = NetUtil_16BitOnesCplChkSumDataVerify((void *) pbuf,
(void *)&udp_pseudo_hdr,
(CPU_INT16U) NET_UDP_PSEUDO_HDR_SIZE,
(NET_ERR *) perr);
if (udp_chk_sum_valid != DEF_OK) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrChkSumCtr);
*perr = NET_UDP_ERR_INVALID_CHK_SUM;
return;
}
DEF_BIT_SET(pbuf_hdr->Flags, NET_BUF_FLAG_UDP_RX_CHK_SUM_VALID);
} else { /* Else discard or flag NO rx'd chk sum (see Note #4d3).*/
#if (NET_UDP_CFG_RX_CHK_SUM_DISCARD_EN != DEF_DISABLED)
NET_CTR_ERR_INC(NetUDP_ErrRxHdrChkSumCtr);
*perr = NET_UDP_ERR_INVALID_CHK_SUM;
return;
#endif
#if 0 /* Clr'd in NetBuf_Get() [see Note #4d3B]. */
DEF_BIT_CLR(pbuf_hdr->Flags, NET_BUF_FLAG_UDP_RX_CHK_SUM_VALID);
#endif
}
/* ----------------- UPDATE BUF CTRLS ----------------- */
/* Calc UDP data len/ix (see Note #5a). */
pbuf_hdr->TCP_UDP_HdrLen = NET_UDP_HDR_SIZE;
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
if (pbuf_hdr->TCP_UDP_HdrLen > udp_tot_len) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDataLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN_DATA;
return;
}
if (pbuf_hdr->TCP_UDP_HdrLen > pbuf_hdr->DataLen) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDataLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN_DATA;
return;
}
#endif
udp_data_len = udp_tot_len - pbuf_hdr->TCP_UDP_HdrLen;
pbuf_hdr->TCP_UDP_DataLen = udp_data_len;
pbuf_hdr->DataLen -= (NET_BUF_SIZE) pbuf_hdr->TCP_UDP_HdrLen;
pbuf_hdr->DataIx = pbuf_hdr->TCP_UDP_HdrDataIx + pbuf_hdr->TCP_UDP_HdrLen;
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_APP;
pbuf_next = (NET_BUF *)pbuf_hdr->NextBufPtr;
while (pbuf_next != (NET_BUF *)0) { /* Calc ALL pkt bufs' data len/ix (see Note #5b). */
pbuf_next_hdr = &pbuf_next->Hdr;
pbuf_next_hdr->DataIx = pbuf_next_hdr->TCP_UDP_HdrDataIx;
pbuf_next_hdr->TCP_UDP_HdrLen = 0; /* NULL UDP hdr len in each pkt buf. */
pbuf_next_hdr->TCP_UDP_TotLen = udp_tot_len; /* Dup UDP tot len & ... */
pbuf_next_hdr->TCP_UDP_DataLen = udp_data_len; /* ... data len in each pkt buf (see Note #5c). */
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_APP;
pbuf_next = (NET_BUF *)pbuf_next_hdr->NextBufPtr;
}
*perr = NET_UDP_ERR_NONE;
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetUDP_RxPktDemuxDatagram()
*
* Description : Demultiplex UDP datagram to appropriate socket or application connection.
*
* Argument(s) : pbuf Pointer to network buffer that received UDP datagram.
* ---- Argument checked in NetUDP_Rx().
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
* NET_ERR_RX Receive error; packet discarded.
* NET_ERR_RX_DEST Invalid destination; no connection available
* for received packet.
*
* -------- RETURNED BY NetSock_Rx() : --------
* NET_SOCK_ERR_NONE UDP datagram successfully received to
* socket connection.
*
* - RETURNED BY NetUDP_RxPktDemuxAppData() : -
* NET_APP_ERR_NONE UDP datagram successfully received to
* application connection.
*
* Return(s) : none.
*
* Caller(s) : NetUDP_Rx().
*
* Note(s) : (1) (a) Attempt demultiplex of received UDP datagram to socket connections first, if enabled.
*
* (b) On any error, attempt demultiplex to application connections, if enabled.
*
* (2) When network buffer is demultiplexed to socket or application receive, the buffer's reference
* counter is NOT incremented since the UDP layer does NOT maintain a reference to the buffer.
*********************************************************************************************************
*/
static void NetUDP_RxPktDemuxDatagram (NET_BUF *pbuf,
NET_ERR *perr)
{
#if ((NET_UDP_CFG_APP_API_SEL == NET_UDP_APP_API_SEL_APP ) || \
(NET_UDP_CFG_APP_API_SEL == NET_UDP_APP_API_SEL_SOCK_APP))
CPU_BOOLEAN rx_demux_app;
#endif
#if ((NET_UDP_CFG_APP_API_SEL == NET_UDP_APP_API_SEL_SOCK ) || \
(NET_UDP_CFG_APP_API_SEL == NET_UDP_APP_API_SEL_SOCK_APP)) /* If socks en'd, ... */
NetSock_Rx(pbuf, perr); /* ... attempt sock demux (see Note #1a). */
#endif
#if (NET_UDP_CFG_APP_API_SEL == NET_UDP_APP_API_SEL_APP)
rx_demux_app = DEF_YES;
#elif (NET_UDP_CFG_APP_API_SEL == NET_UDP_APP_API_SEL_SOCK_APP)
switch (*perr) {
case NET_SOCK_ERR_NONE:
rx_demux_app = DEF_NO;
break;
case NET_ERR_RX_DEST:
rx_demux_app = DEF_YES;
break;
case NET_ERR_INIT_INCOMPLETE:
case NET_ERR_RX:
default:
return; /* Prevent 'break NOT reachable' compiler warning. */
}
#endif
#if ((NET_UDP_CFG_APP_API_SEL == NET_UDP_APP_API_SEL_APP ) || \
(NET_UDP_CFG_APP_API_SEL == NET_UDP_APP_API_SEL_SOCK_APP)) /* If socks dis'd OR sock demux fails, ... */
if (rx_demux_app == DEF_YES) {
NetUDP_RxPktDemuxAppData(pbuf, perr); /* ... attempt app demux (see Note #1b). */
}
#endif
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetUDP_RxPktDemuxAppData()
*
* Description : Prepare UDP packet for application-specific UDP connection handler function.
*
* Argument(s) : pbuf Pointer to network buffer that received UDP datagram.
* ---- Argument checked in NetUDP_Rx().
*
* perr Pointer to variable that will receive the return error code from this function
* (see Note #1b) :
*
* -- RETURNED BY NetUDP_RxAppDataHandler() : ---
* NET_APP_ERR_NONE UDP datagram successfully received to
* application connection.
* NET_ERR_RX Receive error; packet discarded.
* NET_ERR_RX_DEST Invalid destination; no application connection
* available for received packet.
*
* Return(s) : none.
*
* Caller(s) : NetUDP_RxPktDemuxDatagram().
*
* Note(s) : (1) Application-specific UDP connection handler function is fully responsible for properly
* receiving, demultiplexing, & handling all UDP receive packets to the appropriate
* application connections.
*
* (a) (1) (A) (1) If the application-specific UDP connection handler function successfully
* demultiplexes UDP receive packets to an application connection, the handler
* function MUST at some point call NetUDP_RxAppData() to deframe the application
* data from the packet buffer(s) into an application array as well as copy any
* received IP options into an application IP options buffer.
*
* (a) The application-specific connection handler function may service the
* application data immediately within the handler function, in which case
* the application data SHOULD be serviced as quickly as possible since the
* network's global lock remains acquired for the full duration of the
* network receive. Thus, no other network receives or transmits can occur
* while the application-specific handler function executes.
*
* (b) The application-specific connection handler function may delay servicing
* the application data by some other application-specific data servicing
* function(s), in which case the servicing function(s) MUST :
*
* (1) Acquire the network's global lock PRIOR to calling NetUDP_RxAppData()
* (2) Release the network's global lock AFTER calling NetUDP_RxAppData()
*
* See 'NetUDP_RxAppData() Note #2'.
*
* (2) (a) If application-specific handler function calls NetUDP_RxAppData() for a
* specific UDP receive packet, the handler function MUST NOT free the UDP
* packet's network buffer(s), since NetUDP_RxAppData() frees the network
* buffer(s) [see 'NetUDP_RxAppData() Note #1c'].
*
* (b) If application-specific handler function does NOT call NetUDP_RxAppData()
* for a specific UDP receive packet, the handler function
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -