Hi,
First, I’m sorry about my poor english write. I tried to explain the phenomenon that you had experience already. But, It isn’t easy to me.
Anyway, Your experience is all right and Sn_RX_FIFOR are valid after closing the socket.
It is the best solution that fast processes all data before overflow. But this solution depends on host performance and application complexity. This solution is not recommended.
So, If you accept to discard some packet, You can prevent from overflow. In addition, When you detected to over-sized packet (PACKET_INFO>1514), you will discard the packet (For discarding, close and re-open socket).
The below codes show to prevent overflow and discard packets.
// Assume that you can process the MACRAW data by this function.
void process_macraw_data(uint8* mac_data, uint32 len);
// main example
void main(void)
{
int32 remained_rsr = 0;
int32 rsr = 0;
int32 recv_len = 0;
uint8 data_buf[2048];
while(1)
{
switch(getSn_SSR(0))
{
case SOCK_MACRAW:
rsr = getSn_RX_RSR(0);
if(rsr > 0)
{
// check the received size.
if(getIINCHIP_MaxRX(0) - rsr < 1528) // Abnormal <-- Fro preventing overflow.
{
remained_rsr = rsr;
close(s);
while(remained_rsr > 0) // Process all received data.
{
recv_len = recvfrom(0,data_buf,remained_rsr,0,0);
remained_rsr -= (recv_len+1+2+4); // length of DATA packet size - 2bytes, length of CRC - 4 bytes
if(recv_len & 0x01) remained_rsr = -1; // if recv_len is odd
if(remained_rsr < 0)
{
// Error. It maybe receive an un-acceptable MACRAW data and should be ignored that.
close(s);
break;
}
process_macraw_data(data_buf,recv_len);
}
}
else // Normal
{
recv_len = recvfrom(0,data_buf,remained_rsr,0,0);
process_macraw_data(data_buf,recv_len);
}
}
break;
case SOCK_CLOSED:
socket(0,Sn_MR_MACRAW,0x1000,Sn_MR_MF); // open or re-open the MACRAW SOCKET with MAC filter flag.
break;
} // end switch
} // end while
} // end main
If overflow doesn’t occur, the over-size PACKET_INFO does not occur.
For more safe, add dection of over-sized PACKET_INFO code to recvfrom function.
uint32 recvfrom(SOCKET s, uint8 * buf, uint32 len, uint8 * addr, uint16 *port)
{
//
// omitted
//
if ( len > 0 )
{
switch (IINCHIP_READ(Sn_MR(s)) & 0x07) // check the mode of s-th SOCKET
{ // -----------------------------
case Sn_MR_UDP : // UDP mode
//
// omitted
//
break;
// -----------------------
case Sn_MR_IPRAW : // IPRAW mode
//
// omitted
//
break;
// -----------------------
case Sn_MR_MACRAW : // MACRAW mode
wiz_read_buf(s,(uint8*)head,2); // extract the PACKET-INFO
if(*((vuint16*)MR) & MR_FS) // check FIFO swap bit
head[0] = ((((head[0] << 8 ) & 0xFF00)) | ((head[0] >> 8)& 0x00FF));
data_len = (uint32)head[0]; // DATA packet length
if(data_len > 1514) // For dection over-sized PACKET_INFO
{
close(s);
setSn_CR(s,Sn_CR_OPEN);
while(getSn_CR(s));
return 0;
}
wiz_read_buf(s, buf, data_len); // data copy.
wiz_read_buf(s,(uint8*)crc, 4); // extract CRC data and ignore it.
break;
default :
break;
}
setSn_CR(s,Sn_CR_RECV); // recv
}
#ifdef __DEF_IINCHIP_DBG__
printf("recvfrom() end ..\r\n");
#endif
return data_len;
}
Thanks.