Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002  * Copyright (c) 2013-2017, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #ifndef MBED_CONF_APP_CONNECT_STATEMENT
00019     #error [NOT_SUPPORTED] No network configuration found for this target.
00020 #endif
00021 
00022 #include "mbed.h"
00023 #include MBED_CONF_APP_HEADER_FILE
00024 #include "UDPSocket.h"
00025 #include "greentea-client/test_env.h"
00026 #include "unity/unity.h"
00027 #include "utest.h"
00028 
00029 using namespace utest::v1;
00030 
00031 
00032 #ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE
00033 #define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 64
00034 #endif
00035 
00036 #ifndef MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT
00037 #define MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT 500
00038 #endif
00039 
00040 namespace {
00041     char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0};
00042     char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0};
00043     const int ECHO_LOOPS = 16;
00044 }
00045 
00046 void prep_buffer(char *tx_buffer, size_t tx_size) {
00047     size_t i = 0;
00048 
00049     for (; i<tx_size; ++i) {
00050         tx_buffer[i] = (rand() % 10) + '0';
00051     }
00052 }
00053 
00054 void test_udp_echo() {
00055 
00056     NetworkInterface* net = MBED_CONF_APP_OBJECT_CONSTRUCTION;
00057     int err =  MBED_CONF_APP_CONNECT_STATEMENT;
00058 
00059     TEST_ASSERT_EQUAL(0, err);
00060 
00061     if (err) {
00062         printf("MBED: failed to connect with an error of %d\r\n", err);
00063         TEST_ASSERT_EQUAL(0, err);
00064     }
00065 
00066     printf("UDP client IP Address is %s\n", net->get_ip_address());
00067 
00068     UDPSocket sock;
00069     sock.open(net);
00070     sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
00071 
00072 #if defined(MBED_CONF_APP_ECHO_SERVER_ADDR) && defined(MBED_CONF_APP_ECHO_SERVER_PORT)
00073     SocketAddress udp_addr(MBED_CONF_APP_ECHO_SERVER_ADDR, MBED_CONF_APP_ECHO_SERVER_PORT);
00074 #else /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
00075     char recv_key[] = "host_port";
00076     char ipbuf[60] = {0};
00077     char portbuf[16] = {0};
00078     unsigned int port = 0;
00079 
00080     greentea_send_kv("target_ip", net->get_ip_address());
00081     greentea_send_kv("host_ip", " ");
00082     greentea_parse_kv(recv_key, ipbuf, sizeof(recv_key), sizeof(ipbuf));
00083 
00084     greentea_send_kv("host_port", " ");
00085     greentea_parse_kv(recv_key, portbuf, sizeof(recv_key), sizeof(ipbuf));
00086     sscanf(portbuf, "%u", &port);
00087 
00088     printf("MBED: UDP Server IP address received: %s:%d \n", ipbuf, port);
00089     SocketAddress udp_addr(ipbuf, port);
00090 #endif /* MBED_CONF_APP_ECHO_SERVER_ADDR && MBED_CONF_APP_ECHO_SERVER_PORT */
00091 
00092     int success = 0;
00093     for (int i = 0; success < ECHO_LOOPS; i++) {
00094         prep_buffer(tx_buffer, sizeof(tx_buffer));
00095         const int ret = sock.sendto(udp_addr, tx_buffer, sizeof(tx_buffer));
00096         if (ret >= 0) {
00097             printf("[%02d] sent %d bytes - %.*s  \n", i, ret, ret, tx_buffer);
00098         } else {
00099             printf("[%02d] Network error %d\n", i, ret);
00100             continue;
00101         }
00102 
00103         SocketAddress temp_addr;
00104         const int n = sock.recvfrom(&temp_addr, rx_buffer, sizeof(rx_buffer));
00105         if (n >= 0) {
00106             printf("[%02d] recv %d bytes - %.*s  \n", i, n, n, rx_buffer);
00107         } else {
00108             printf("[%02d] Network error %d\n", i, n);
00109             continue;
00110         }
00111 
00112         if ((temp_addr == udp_addr &&
00113              n == sizeof(tx_buffer) &&
00114              memcmp(rx_buffer, tx_buffer, sizeof(rx_buffer)) == 0)) {
00115             success += 1;
00116 
00117             printf("[%02d] success #%d\n", i, success);
00118             continue;
00119         }
00120 
00121         // failed, clean out any remaining bad packets
00122         sock.set_timeout(0);
00123         while (true) {
00124             err = sock.recvfrom(NULL, NULL, 0);
00125             if (err == NSAPI_ERROR_WOULD_BLOCK ) {
00126                 break;
00127             }
00128         }
00129         sock.set_timeout(MBED_CFG_UDP_CLIENT_ECHO_TIMEOUT);
00130     }
00131 
00132     sock.close();
00133     net->disconnect();
00134     TEST_ASSERT_EQUAL(ECHO_LOOPS, success);
00135 }
00136 
00137 
00138 // Test setup
00139 utest::v1::status_t test_setup(const size_t number_of_cases) {
00140     GREENTEA_SETUP(240, "udp_echo");
00141     return verbose_test_setup_handler(number_of_cases);
00142 }
00143 
00144 Case cases[] = {
00145     Case("UDP echo", test_udp_echo),
00146 };
00147 
00148 Specification specification(test_setup, cases);
00149 
00150 int main() {
00151     return !Harness::run(specification);
00152 }