Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXAS21002 FXOS8700Q
download_test.cpp
00001 /* 00002 * mbed Microcontroller Library 00003 * Copyright (c) 2006-2018 ARM Limited 00004 * 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); 00008 * you may not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, 00015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 */ 00019 00020 /* 00021 * Based on mbed-stress-test by Marcus Chang @ Arm Mbed - http://github.com/ARMmbed/mbed-stress-test 00022 */ 00023 00024 #include "mbed.h" 00025 #include "unity/unity.h" 00026 #include "greentea-client/test_env.h" 00027 #include <string> 00028 00029 #define MAX_THREADS 5 00030 00031 #define MAX_RETRIES 3 00032 00033 #ifdef MBED_CONF_DOWNLOAD_TEST_URL_HOST 00034 const char dl_host[] = MBED_CONF_DOWNLOAD_TEST_URL_HOST; 00035 #else 00036 const char dl_host[] = "armmbed.github.io"; 00037 #endif 00038 #ifdef MBED_CONF_DOWNLOAD_TEST_URL_PATH 00039 const char dl_path[] = MBED_CONF_DOWNLOAD_TEST_URL_PATH; 00040 #else 00041 const char dl_path[] = "/mbed-test-files/alice.txt"; 00042 #endif 00043 00044 const char req_template[] = "GET %s HTTP/1.1\nHost: %s\n\n"; 00045 00046 #define REQ_BUF_SIZE 256 00047 #define RECV_BUF_SIZE 1024 00048 00049 static char g_request_buffer[MAX_THREADS][REQ_BUF_SIZE]; // the default request is 65bytes long. 00050 static char g_receive_buffer[MAX_THREADS * RECV_BUF_SIZE]; 00051 00052 static volatile bool event_fired[MAX_THREADS] = { }; 00053 00054 static void socket_event_0(void) { event_fired[0] = true; } 00055 static void socket_event_1(void) { event_fired[1] = true; } 00056 static void socket_event_2(void) { event_fired[2] = true; } 00057 static void socket_event_3(void) { event_fired[3] = true; } 00058 static void socket_event_4(void) { event_fired[4] = true; } 00059 00060 00061 size_t download_test(NetworkInterface* interface, const unsigned char* data, size_t data_length, size_t buff_size, uint32_t thread_id) { 00062 int result = -1; 00063 00064 TEST_ASSERT_MESSAGE(MAX_THREADS > thread_id, "Unsupported thread ID"); 00065 TEST_ASSERT_MESSAGE((MAX_THREADS * RECV_BUF_SIZE) >= buff_size, "Cannot test with the requested buffer size"); 00066 00067 /* setup TCP socket */ 00068 TCPSocket tcpsocket(interface); 00069 00070 for (int tries = 0; tries < MAX_RETRIES; tries++) { 00071 result = tcpsocket.connect(dl_host, 80); 00072 TEST_ASSERT_MESSAGE(result != NSAPI_ERROR_NO_SOCKET, "out of sockets"); 00073 00074 if (result == 0) { 00075 break; 00076 } 00077 ThisThread::sleep_for(1000); 00078 printf("[NET-%d] Connection failed. Retry %d of %d\r\n", thread_id, tries, MAX_RETRIES); 00079 } 00080 TEST_ASSERT_EQUAL_INT_MESSAGE(0, result, "failed to connect"); 00081 00082 if (thread_id == 0) { 00083 // technically this is non-threaded mode 00084 tcpsocket.sigio(socket_event_0); 00085 } else if (thread_id == 1) { 00086 tcpsocket.sigio(socket_event_1); 00087 } else if (thread_id == 2) { 00088 tcpsocket.sigio(socket_event_2); 00089 } else if (thread_id == 3) { 00090 tcpsocket.sigio(socket_event_3); 00091 } else if (thread_id == 4) { 00092 tcpsocket.sigio(socket_event_4); 00093 } else { 00094 TEST_ASSERT_MESSAGE(0, "wrong thread id"); 00095 } 00096 printf("[NET-%d] Registered socket callback function\r\n", thread_id); 00097 event_fired[thread_id] = false; 00098 00099 /* setup request */ 00100 char *request = g_request_buffer[thread_id]; 00101 00102 /* construct request */ 00103 size_t req_len = snprintf(request, REQ_BUF_SIZE-1, req_template, dl_path, dl_host); 00104 request[req_len] = 0; 00105 printf("[NET-%d] Request header (%u): %s\r\n", thread_id, req_len, request); 00106 00107 /* send request to server */ 00108 result = tcpsocket.send(request, req_len); 00109 TEST_ASSERT_EQUAL_INT_MESSAGE(req_len, result, "failed to send"); 00110 00111 /* read response */ 00112 char* receive_buffer = &g_receive_buffer[thread_id * RECV_BUF_SIZE]; 00113 00114 tcpsocket.set_blocking(false); 00115 printf("[NET-%d] Non-blocking socket mode set\r\n", thread_id); 00116 00117 size_t received_bytes = 0; 00118 int body_index = -1; 00119 00120 float speed; 00121 float percent; 00122 uint32_t time_left; 00123 Timer timer; 00124 timer.start(); 00125 00126 /* loop until all expected bytes have been received */ 00127 while (received_bytes < data_length) { 00128 /* wait for async event */ 00129 while(!event_fired[thread_id]) { 00130 if (thread_id > 0) { 00131 ThisThread::yield(); 00132 } 00133 } 00134 event_fired[thread_id] = false; 00135 00136 /* loop until all data has been read from socket */ 00137 do { 00138 result = tcpsocket.recv(receive_buffer, buff_size); 00139 TEST_ASSERT_MESSAGE((result == NSAPI_ERROR_WOULD_BLOCK) || (result >= 0), 00140 "failed to read socket"); 00141 00142 if (result > 0) { 00143 /* skip HTTP header */ 00144 if (body_index < 0) { 00145 /* note that there are no required Response headers and their length may greatly vary */ 00146 std::string header(receive_buffer, result); 00147 body_index = header.find("\r\n\r\n"); 00148 if (body_index < 0) { 00149 continue; 00150 } else { 00151 printf("[NET-%d] Found body index: %d\r\n", thread_id, body_index); 00152 00153 /* remove header before comparison */ 00154 memmove(receive_buffer, &receive_buffer[body_index + 4], result - body_index - 4); 00155 00156 TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(data, receive_buffer, result - body_index - 4, 00157 "character mismatch in header"); 00158 00159 received_bytes += (result - body_index - 4); 00160 } 00161 } else { 00162 TEST_ASSERT_EQUAL_STRING_LEN_MESSAGE(&data[received_bytes], receive_buffer, result, 00163 "character mismatch in body"); 00164 00165 received_bytes += result; 00166 } 00167 00168 speed = float(received_bytes) / timer.read(); 00169 percent = float(received_bytes) * 100 / float(data_length); 00170 time_left = (data_length - received_bytes) / speed; 00171 printf("[NET-%d] Received bytes: %u, (%.2f%%, %.2fKB/s, ETA: %02d:%02d:%02d)\r\n", 00172 thread_id, received_bytes, percent, speed / 1024, 00173 time_left / 3600, (time_left / 60) % 60, time_left % 60); 00174 } 00175 } 00176 while ((result > 0) && (received_bytes < data_length)); 00177 } 00178 00179 TEST_ASSERT_MESSAGE(body_index >= 0, "failed to find body"); 00180 00181 timer.stop(); 00182 float f_received_bytes = float(received_bytes); 00183 printf("[NET-%d] Downloaded: %.2fKB (%.2fKB/s, %.2f secs)\r\n", thread_id, 00184 f_received_bytes / 1024., 00185 f_received_bytes / (timer.read() * 1024.), 00186 timer.read()); 00187 00188 return received_bytes; 00189 } 00190
Generated on Tue Jul 12 2022 20:20:58 by
