void UIPClient::stop() { if (data && data->state) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("before stop(), with data")); _dumpAllData(); #endif _flushBlocks(&data->packets_in[0]); if (data->state & UIP_CLIENT_REMOTECLOSED) { data->state = 0; } else { data->state |= UIP_CLIENT_CLOSE; } #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println(F("after stop()")); _dumpAllData(); #endif } #ifdef UIPETHERNET_DEBUG_CLIENT else { Serial.println(F("stop(), data: NULL")); } #endif data = NULL; UIPEthernetClass::tick(); }
void UIPClient::stop() { if (data) { _flushBlocks(&data->packets_in[0]); if (data->state & UIP_CLIENT_CLOSED) { uip_userdata_closed_t** cc = &UIPClient::closed_conns[0]; for (uint8_t i = 0; i < UIP_CONNS; i++) { if (*cc == (void*)data) { *cc = NULL; break; } cc++; } free(data); } else { data->state |= UIP_CLIENT_CLOSE; } data = NULL; } _uip_conn = NULL; UIPEthernet.tick(); }
void UIPClient::flush() { if (*this) { _flushBlocks(&data->packets_in[0]); } }
void UIPClient::uip_callback(uip_tcp_appstate_t *s) { uip_userdata_t *u = (uip_userdata_t *) s->user; if (!u && uip_connected()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println("UIPClient uip_connected"); #endif // We want to store some data in our connections, so allocate some space // for it. The connection_data struct is defined in a separate .h file, // due to the way the Arduino IDE works. (typedefs come after function // definitions.) u = (uip_userdata_t*) malloc(sizeof(uip_userdata_t)); if (u) { memset(u,0,sizeof(uip_userdata_t)); s->user = u; } } if (u) { if (uip_newdata()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.print("UIPClient uip_newdata, uip_len:"); Serial.println(uip_len); #endif if (uip_len && !(u->state & (UIP_CLIENT_CLOSE | UIP_CLIENT_CLOSED))) { memhandle newPacket = UIPEthernet.network.allocBlock(uip_len); if (newPacket != NOBLOCK) { memhandle* p = _currentBlock(&u->packets_in[0]); //if it's not the first packet if (*p != NOBLOCK) { uint8_t slot = p - &u->packets_in[0]; if (slot < UIP_SOCKET_NUMPACKETS-1) p++; //if this is the last slot stop this connection if (slot >= UIP_SOCKET_NUMPACKETS-2) { uip_stop(); //if there's no free slot left omit loosing this packet and (again) stop this connection if (slot == UIP_SOCKET_NUMPACKETS-1) goto reject_newdata; } } UIPEthernet.network.copyPacket(newPacket,0,UIPEthernet.in_packet,((uint8_t*)uip_appdata)-uip_buf,uip_len); *p = newPacket; goto finish_newdata; } reject_newdata: UIPEthernet.packetstate &= ~UIPETHERNET_FREEPACKET; uip_stop(); } } finish_newdata: if (u->state & UIP_CLIENT_RESTART) { u->state &= ~UIP_CLIENT_RESTART; uip_restart(); } // If the connection has been closed, save received but unread data. if (uip_closed() || uip_timedout()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println("UIPClient uip_closed"); #endif // drop outgoing packets not sent yet: _flushBlocks(&u->packets_out[0]); if (u->packets_in[0] != NOBLOCK) { uip_userdata_closed_t** closed_conn_data = &UIPClient::closed_conns[0]; for (uip_socket_ptr i = 0; i < UIP_CONNS; i++) { if (!*closed_conn_data) { *closed_conn_data = (uip_userdata_closed_t*)u; (*closed_conn_data)->lport = uip_conn->lport; break; } closed_conn_data++; } } u->state |= UIP_CLIENT_CLOSED; // disassociate appdata. s->user = NULL; goto nodata; } if (uip_acked()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println("UIPClient uip_acked"); #endif _eatBlock(&u->packets_out[0]); } if (uip_poll() || uip_rexmit()) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.println("UIPClient uip_poll"); #endif memhandle p = u->packets_out[0]; if (p != NOBLOCK) { if (u->packets_out[1] == NOBLOCK) { uip_len = u->out_pos; if (uip_len > 0) { UIPEthernet.network.resizeBlock(p,0,uip_len); } } else uip_len = UIPEthernet.network.blockSize(p); if (uip_len > 0) { UIPEthernet.uip_hdrlen = ((uint8_t*)uip_appdata)-uip_buf; UIPEthernet.uip_packet = UIPEthernet.network.allocBlock(UIPEthernet.uip_hdrlen+uip_len); if (UIPEthernet.uip_packet != NOBLOCK) { UIPEthernet.network.copyPacket(UIPEthernet.uip_packet,UIPEthernet.uip_hdrlen,p,0,uip_len); UIPEthernet.packetstate |= UIPETHERNET_SENDPACKET; uip_send(uip_appdata,uip_len); } return; } } } // don't close connection unless all outgoing packets are sent if (u->state & UIP_CLIENT_CLOSE) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.print("UIPClient state UIP_CLIENT_CLOSE"); #endif if (u->packets_out[0] == NOBLOCK) { #ifdef UIPETHERNET_DEBUG_CLIENT Serial.print("UIPClient state UIP_CLIENT_CLOSE -> free userdata"); #endif free(u); s->user = NULL; uip_close(); } else uip_stop(); } } nodata: UIPEthernet.uip_packet = NOBLOCK; uip_len=0; }