// Try to receive more incoming data from the socket. The mutex is alrady owned. void W5500Socket::ReceiveData() { const uint16_t len = getSn_RX_RSR(socketNum); if (len != 0) { // debugPrintf("%u available\n", len); NetworkBuffer * const lastBuffer = NetworkBuffer::FindLast(receivedData); // NOTE: reading only part of the received data doesn't work because the wizchip doesn't track the buffer pointer properly. // We could probably make it work by tracking the buffer pointer ourselves, just as we do when sending data, and using wiz_recv_data_at. if (lastBuffer != nullptr && lastBuffer->SpaceLeft() >= len) { wiz_recv_data(socketNum, lastBuffer->UnwrittenData(), len); ExecCommand(socketNum, Sn_CR_RECV); lastBuffer->dataLength += len; if (reprap.Debug(moduleNetwork)) { debugPrintf("Appended %u bytes\n", (unsigned int)len); } } else if (NetworkBuffer::Count(receivedData) < MaxBuffersPerSocket) { NetworkBuffer * const buf = NetworkBuffer::Allocate(); if (buf != nullptr) { wiz_recv_data(socketNum, buf->Data(), len); ExecCommand(socketNum, Sn_CR_RECV); buf->dataLength = (size_t)len; NetworkBuffer::AppendToList(&receivedData, buf); if (reprap.Debug(moduleNetwork)) { debugPrintf("Received %u bytes\n", (unsigned int)len); } } } // else debugPrintf("no buffer\n"); } }
int32_t WIZCHIP_EXPORT(recv)(uint8_t sn, uint8_t * buf, uint16_t len) { uint8_t tmp = 0; uint16_t recvsize = 0; CHECK_SOCKNUM(); CHECK_SOCKMODE(Sn_MR_TCP); CHECK_SOCKDATA(); recvsize = getSn_RxMAX(sn); if(recvsize < len) len = recvsize; while(1) { recvsize = getSn_RX_RSR(sn); tmp = getSn_SR(sn); if (tmp != SOCK_ESTABLISHED) { if(tmp == SOCK_CLOSE_WAIT) { if(recvsize != 0) break; else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { // dpgeorge: Getting here seems to be an orderly shutdown of the // socket, and trying to get POSIX behaviour we return 0 because: // "If no messages are available to be received and the peer has per‐ // formed an orderly shutdown, recv() shall return 0". // TODO this return value clashes with SOCK_BUSY in non-blocking mode. WIZCHIP_EXPORT(close)(sn); return 0; } } else { WIZCHIP_EXPORT(close)(sn); return SOCKERR_SOCKSTATUS; } } if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; if(recvsize != 0) break; MICROPY_THREAD_YIELD(); }; if(recvsize < len) len = recvsize; wiz_recv_data(sn, buf, len); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); return len; }
int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len) { uint8_t tmp = 0; uint16_t recvsize = 0; CHECK_SOCKNUM(); CHECK_SOCKMODE(Sn_MR_TCP); CHECK_SOCKDATA(); recvsize = getSn_RxMAX(sn); if(recvsize < len) len = recvsize; while(1) { recvsize = getSn_RX_RSR(sn); tmp = getSn_SR(sn); if (tmp != SOCK_ESTABLISHED) { if(tmp == SOCK_CLOSE_WAIT) { if(recvsize != 0) break; else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { close(sn); return SOCKERR_SOCKSTATUS; } } else { close(sn); return SOCKERR_SOCKSTATUS; } } if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; if(recvsize != 0) break; HAL_Delay(1); }; if(recvsize < len) len = recvsize; wiz_recv_data(sn, buf, len); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); return len; }
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; }
int32_t recv(uint8_t sn, uint8_t * buf, uint16_t len) { uint8_t tmp = 0; uint16_t recvsize = 0; //A20150601 : For integarating with W5300 #if _WIZCHIP_ == 5300 uint8_t head[2]; uint16_t mr; #endif // CHECK_SOCKNUM(); CHECK_SOCKMODE(Sn_MR_TCP); CHECK_SOCKDATA(); recvsize = getSn_RxMAX(sn); if(recvsize < len) len = recvsize; //A20150601 : For Integrating with W5300 #if _WIZCHIP_ == 5300 //sock_pack_info[sn] = PACK_COMPLETED; // for clear if(sock_remained_size[sn] == 0) { #endif // while(1) { recvsize = getSn_RX_RSR(sn); tmp = getSn_SR(sn); if (tmp != SOCK_ESTABLISHED) { if(tmp == SOCK_CLOSE_WAIT) { if(recvsize != 0) break; else if(getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { close(sn); return SOCKERR_SOCKSTATUS; } } else { close(sn); return SOCKERR_SOCKSTATUS; } } if((sock_io_mode & (1<<sn)) && (recvsize == 0)) return SOCK_BUSY; if(recvsize != 0) break; }; #if _WIZCHIP_ == 5300 } #endif //A20150601 : For integrating with W5300 #if _WIZCHIP_ == 5300 if((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN)) { mr = getMR(); if((getSn_MR(sn) & Sn_MR_ALIGN)==0) { wiz_recv_data(sn,head,2); if(mr & MR_FS) recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]); else recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]); sock_pack_info[sn] = PACK_FIRST; } sock_remained_size[sn] = recvsize; } if(len > sock_remained_size[sn]) len = sock_remained_size[sn]; recvsize = len; if(sock_pack_info[sn] & PACK_FIFOBYTE) { *buf = sock_remained_byte[sn]; buf++; sock_pack_info[sn] &= ~(PACK_FIFOBYTE); recvsize -= 1; sock_remained_size[sn] -= 1; } if(recvsize != 0) { wiz_recv_data(sn, buf, recvsize); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); } sock_remained_size[sn] -= recvsize; if(sock_remained_size[sn] != 0) { sock_pack_info[sn] |= PACK_REMAINED; if(recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE; } else sock_pack_info[sn] = PACK_COMPLETED; if(getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0; //len = recvsize; #else if(recvsize < len) len = recvsize; wiz_recv_data(sn, buf, len); setSn_CR(sn,Sn_CR_RECV); while(getSn_CR(sn)); #endif //M20150409 : Explicit Type Casting //return len; return (int32_t)len; }