int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) { uint8_t mr; uint8_t head[8]; uint16_t pack_len=0; CHECK_SOCKNUM(); //CHECK_SOCKMODE(Sn_MR_UDP); switch((mr=getSn_MR(sn)) & 0x0F) { case Sn_MR_UDP: case Sn_MR_MACRAW: break; #if ( _WIZCHIP_ < 5200 ) case Sn_MR_IPRAW: case Sn_MR_PPPoE: break; #endif default: return SOCKERR_SOCKMODE; } CHECK_SOCKDATA(); if(sock_remained_size[sn] == 0) { while(1) { pack_len = getSn_RX_RSR(sn); if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY; if(pack_len != 0) break; }; } sock_pack_info[sn] = PACK_COMPLETED; switch (mr & 0x07) { case Sn_MR_UDP : if(sock_remained_size[sn] == 0) { wiz_recv_data(sn, head, 8); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); // read peer's IP address, port number & packet length addr[0] = head[0]; addr[1] = head[1]; addr[2] = head[2]; addr[3] = head[3]; *port = head[4]; *port = (*port << 8) + head[5]; sock_remained_size[sn] = head[6]; sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; sock_pack_info[sn] = PACK_FIRST; } if(len < sock_remained_size[sn]) pack_len = len; else pack_len = sock_remained_size[sn]; // // Need to packet length check (default 1472) // wiz_recv_data(sn, buf, pack_len); // data copy. break; case Sn_MR_MACRAW : if(sock_remained_size[sn] == 0) { wiz_recv_data(sn, head, 2); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); // read peer's IP address, port number & packet length sock_remained_size[sn] = head[0]; sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1]; if(sock_remained_size[sn] > 1514) { close(sn); return SOCKFATAL_PACKLEN; } sock_pack_info[sn] = PACK_FIRST; } if(len < sock_remained_size[sn]) pack_len = len; else pack_len = sock_remained_size[sn]; wiz_recv_data(sn,buf,pack_len); break; #if ( _WIZCHIP_ < 5200 ) case Sn_MR_IPRAW: if(sock_remained_size[sn] == 0) { wiz_recv_data(sn, head, 6); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); addr[0] = head[0]; addr[1] = head[1]; addr[2] = head[2]; addr[3] = head[3]; sock_remained_size[sn] = head[4]; sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; sock_pack_info[sn] = PACK_FIRST; } // // Need to packet length check // if(len < sock_remained_size[sn]) pack_len = len; else pack_len = sock_remained_size[sn]; wiz_recv_data(sn, buf, pack_len); // data copy. break; #endif default: wiz_recv_ignore(sn, pack_len); // data copy. sock_remained_size[sn] = pack_len; break; } setSn_CR(sn,Sn_CR_RECV); /* wait to process the command... */ while(getSn_CR(sn)) ; sock_remained_size[sn] -= pack_len; if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; return pack_len; }
int32_t recvfrom(uint8_t sn, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port) { //M20150601 : For W5300 #if _WIZCHIP_ == 5300 uint16_t mr; uint16_t mr1; #else uint8_t mr; #endif // uint8_t head[8]; uint16_t pack_len=0; CHECK_SOCKNUM(); //CHECK_SOCKMODE(Sn_MR_UDP); //A20150601 #if _WIZCHIP_ == 5300 mr1 = getMR(); #endif switch((mr=getSn_MR(sn)) & 0x0F) { case Sn_MR_UDP: case Sn_MR_IPRAW: case Sn_MR_MACRAW: break; #if ( _WIZCHIP_ < 5200 ) case Sn_MR_PPPoE: break; #endif default: return SOCKERR_SOCKMODE; } CHECK_SOCKDATA(); if(sock_remained_size[sn] == 0) { while(1) { pack_len = getSn_RX_RSR(sn); if(getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; if( (sock_io_mode & (1<<sn)) && (pack_len == 0) ) return SOCK_BUSY; if(pack_len != 0) break; }; } //D20150601 : Move it to bottom // sock_pack_info[sn] = PACK_COMPLETED; switch (mr & 0x07) { case Sn_MR_UDP : if(sock_remained_size[sn] == 0) { wiz_recv_data(sn, head, 8); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); // read peer's IP address, port number & packet length //A20150601 : For W5300 #if _WIZCHIP_ == 5300 if(mr1 & MR_FS) { addr[0] = head[1]; addr[1] = head[0]; addr[2] = head[3]; addr[3] = head[2]; *port = head[5]; *port = (*port << 8) + head[4]; sock_remained_size[sn] = head[7]; sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6]; } else { #endif addr[0] = head[0]; addr[1] = head[1]; addr[2] = head[2]; addr[3] = head[3]; *port = head[4]; *port = (*port << 8) + head[5]; sock_remained_size[sn] = head[6]; sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; #if _WIZCHIP_ == 5300 } #endif sock_pack_info[sn] = PACK_FIRST; } if(len < sock_remained_size[sn]) pack_len = len; else pack_len = sock_remained_size[sn]; //A20150601 : For W5300 len = pack_len; #if _WIZCHIP_ == 5300 if(sock_pack_info[sn] & PACK_FIFOBYTE) { *buf++ = sock_remained_byte[sn]; pack_len -= 1; sock_remained_size[sn] -= 1; sock_pack_info[sn] &= ~PACK_FIFOBYTE; } #endif // // Need to packet length check (default 1472) // wiz_recv_data(sn, buf, pack_len); // data copy. break; case Sn_MR_MACRAW : if(sock_remained_size[sn] == 0) { wiz_recv_data(sn, head, 2); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); // read peer's IP address, port number & packet length sock_remained_size[sn] = head[0]; sock_remained_size[sn] = (sock_remained_size[sn] <<8) + head[1] -2; #if _WIZCHIP_ == W5300 if(sock_remained_size[sn] & 0x01) sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4; else sock_remained_size[sn] -= 4; #endif if(sock_remained_size[sn] > 1514) { close(sn); return SOCKFATAL_PACKLEN; } sock_pack_info[sn] = PACK_FIRST; } if(len < sock_remained_size[sn]) pack_len = len; else pack_len = sock_remained_size[sn]; wiz_recv_data(sn,buf,pack_len); break; //#if ( _WIZCHIP_ < 5200 ) case Sn_MR_IPRAW: if(sock_remained_size[sn] == 0) { wiz_recv_data(sn, head, 6); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); addr[0] = head[0]; addr[1] = head[1]; addr[2] = head[2]; addr[3] = head[3]; sock_remained_size[sn] = head[4]; //M20150401 : For Typing Error //sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5]; sock_pack_info[sn] = PACK_FIRST; } // // Need to packet length check // if(len < sock_remained_size[sn]) pack_len = len; else pack_len = sock_remained_size[sn]; wiz_recv_data(sn, buf, pack_len); // data copy. break; //#endif default: wiz_recv_ignore(sn, pack_len); // data copy. sock_remained_size[sn] = pack_len; break; } setSn_CR(sn,Sn_CR_RECV); /* wait to process the command... */ while(getSn_CR(sn)) ; sock_remained_size[sn] -= pack_len; //M20150601 : //if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; if(sock_remained_size[sn] != 0) { sock_pack_info[sn] |= PACK_REMAINED; #if _WIZCHIP_ == 5300 if(pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE; #endif } else sock_pack_info[sn] = PACK_COMPLETED; #if _WIZCHIP_ == 5300 pack_len = len; #endif // //M20150409 : Explicit Type Casting //return pack_len; return (int32_t)pack_len; }