void run() { // declare an instance of the USART and the stream that we'll use to write to it _usart=new MyUsart(57600); _outputStream=new UsartPollingOutputStream(*_usart); // declare the RTC that that stack requires. it's used for cache timeouts, DHCP lease expiry // and such like so it does not have to be calibrated for accuracy. A few seconds here or there // over a 24 hour period isn't going to make any difference. Start it ticking at zero which is // some way back in 2000 but that doesn't matter to us Rtc<RtcLsiClockFeature<Rtc32kHzLsiFrequencyProvider>,RtcSecondInterruptFeature> rtc; rtc.setTick(0); // declare an instance of the network stack MyNetworkStack::Parameters params; _net=new MyNetworkStack; // the stack requires the RTC params.base_rtc=&rtc; // It's nice to give the DHCP client a host name because then it'll show up in DHCP // 'active leases' page. In a home router this is often called 'attached devices' params.dhcp_hostname="stm32plus"; // subscribe to error events from the network stack _net->NetworkErrorEventSender.insertSubscriber(NetworkErrorEventSourceSlot::bind(this,&NetHttpClientTest::onError)); // Initialise the stack. This will reset the PHY, initialise the MAC // and attempt to create a link to our link partner. Ensure your cable // is plugged in when you run this or be prepared to handle the error if(!_net->initialise(params)) error(); // start the ethernet MAC Tx/Rx DMA channels // this will trigger the DHCP transaction if(!_net->startup()) error(); // look up the IP address for www.st.com *_outputStream << "Looking up the DNS address for www.st.com\r\n"; IpAddress address; if(!_net->dnsHostnameQuery("www.st.com",address)) { *_outputStream << "Failed to look up www.st.com\r\n"; error(); } *_outputStream << "Connecting to www.st.com:80\r\n"; // create the connection TcpClientConnection *ptr; if(!_net->tcpConnect<TcpClientConnection>(address,80,ptr)) { *_outputStream << "Failed to connect to www.st.com\r\n"; error(); } { // manage the connection pointer in a scoped_ptr so it's automatically deleted (and closed) // when it goes out of scope scoped_ptr<TcpClientConnection> conn(ptr); HttpClient httpClient(*conn); // set the parameters for the HTTP GET httpClient.setUri("/"); // get the root document httpClient.setHost("www.st.com"); // host header is mandatory for HTTP/1.1 // send it *_outputStream << "Sending request to server\r\n"; if(!httpClient.sendRequest()) { *_outputStream << "Failed to send the request to the server\r\n"; error(); } // must have a content-length for this test call int32_t contentLength; if((contentLength=httpClient.getResponseContentLength())==-1) { *_outputStream << "Server did not send a Content-Length header\r\n"; error(); } // read back the response in 100 byte chunks with a 60 second timeout uint8_t buffer[100]; uint32_t actuallyRead; *_outputStream << "Reading response body from the server\r\n"; while(contentLength) { // read a chunk if(!conn->receive(buffer,Min(contentLength,100L),actuallyRead,60000)) { *_outputStream << "Timed out waiting for data from the server\r\n"; error(); } if(actuallyRead==0) { *_outputStream << "The remote end has closed the connection\r\n"; error(); } // push out to the USART _outputStream->write(buffer,actuallyRead); // decrease amount remaining contentLength-=actuallyRead; } *_outputStream << "Finished reading response body\r\n"; } // finished, reset the board to try again for(;;); }
void run() { // declare an instance of the USART and the stream that we'll use to write to it _usart=new MyUsart(57600); _outputStream=new UsartPollingOutputStream(*_usart); // declare the RTC that that stack requires. it's used for cache timeouts, DHCP lease expiry // and such like so it does not have to be calibrated for accuracy. A few seconds here or there // over a 24 hour period isn't going to make any difference. Start it ticking at zero which is // some way back in 2000 but that doesn't matter to us Rtc<RtcLsiClockFeature<Rtc32kHzLsiFrequencyProvider>,RtcSecondInterruptFeature> rtc; rtc.setTick(0); // declare an instance of the network stack MyNetworkStack::Parameters params; _net=new MyNetworkStack; // the stack requires the RTC params.base_rtc=&rtc; // It's nice to give the DHCP client a host name because then it'll show up in DHCP // 'active leases' page. In a home router this is often called 'attached devices' params.dhcp_hostname="stm32plus"; // subscribe to error events from the network stack _net->NetworkErrorEventSender.insertSubscriber(NetworkErrorEventSourceSlot::bind(this,&NetTcpClientTest::onError)); // Initialise the stack. This will reset the PHY, initialise the MAC // and attempt to create a link to our link partner. Ensure your cable // is plugged in when you run this or be prepared to handle the error if(!_net->initialise(params)) error(); // start the ethernet MAC Tx/Rx DMA channels // this will trigger the DHCP transaction if(!_net->startup()) error(); *_outputStream << "The TCP client is ready to run\r\n"; TcpClientConnection *ptr; uint32_t actuallyReceived,actuallySent; char buffer[100]; for(;;) { // connect to the remote end using a random local ephemeral port if(_net->tcpConnect<TcpClientConnection>("192.168.1.3",12345,ptr)) { // manage the connection pointer in a scoped_ptr so it's automatically deleted (and closed) // when it goes out of scope scoped_ptr<TcpClientConnection> conn(ptr); // send 11 bytes of text and a newline to the other end (blocking). We have to copy the data to // a sram buffer before sending because the STM32 Ethernet DMA peripheral cannot transmit from // flash memory. (string constants are compiled into flash). strcpy(buffer,"Hello World\n"); if(conn->send(buffer,12,actuallySent) && actuallySent==12) { // receive the response line from the other end (blocking) if(conn->receive(buffer,100,actuallyReceived) && actuallyReceived>0) { // write the response to the USART stream _outputStream->write(buffer,actuallyReceived); } } } else *_outputStream << "Timed out while trying to connect, trying again...\r\n"; // pause for 5 seconds to avoid flooding the network before doing it again MillisecondTimer::delay(5000); } }