takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers tcpsocket_thread_per_socket_safety.cpp Source File

tcpsocket_thread_per_socket_safety.cpp

00001 /*
00002  * Copyright (c) 2018, 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 #include "mbed.h"
00019 #include "TCPSocket.h"
00020 #include "greentea-client/test_env.h"
00021 #include "unity/unity.h"
00022 #include "utest.h"
00023 #include "tcp_tests.h"
00024 
00025 using namespace utest::v1;
00026 
00027 namespace {
00028 static const int SIGNAL_SIGIO1 = 0x1;
00029 static const int SIGNAL_SIGIO2 = 0x2;
00030 static const int SIGIO_TIMEOUT = 5000; //[ms]
00031 
00032 Thread thread(osPriorityNormal, tcp_global::TCP_OS_STACK_SIZE);
00033 volatile bool running = true;
00034 }
00035 
00036 static void _sigio_handler1(osThreadId id)
00037 {
00038     osSignalSet(id, SIGNAL_SIGIO1);
00039 }
00040 
00041 static void _sigio_handler2(osThreadId id)
00042 {
00043     osSignalSet(id, SIGNAL_SIGIO2);
00044 }
00045 
00046 static void check_const_len_rand_sequence()
00047 {
00048     TCPSocket sock;
00049     tcpsocket_connect_to_echo_srv(sock);
00050     sock.sigio(callback(_sigio_handler1, Thread::gettid()));
00051 
00052     static const int BUFF_SIZE = 10;
00053     static char rx_buff[BUFF_SIZE] = {0};
00054     static char tx_buff[BUFF_SIZE] = {0};
00055 
00056 
00057     int bytes2process;
00058     int recvd;
00059     int sent;
00060     while (running) {
00061         fill_tx_buffer_ascii(tx_buff, BUFF_SIZE);
00062         bytes2process = BUFF_SIZE;
00063         while (bytes2process > 0) {
00064             sent = sock.send(&(tx_buff[BUFF_SIZE - bytes2process]), bytes2process);
00065             if (sent == NSAPI_ERROR_WOULD_BLOCK ) {
00066                 if (osSignalWait(SIGNAL_SIGIO1, SIGIO_TIMEOUT).status == osEventTimeout) {
00067                     TEST_FAIL();
00068                     goto END;
00069                 }
00070                 continue;
00071             } else if (sent < 0) {
00072                 printf("network error %d\n", sent);
00073                 TEST_FAIL();
00074                 goto END;
00075             }
00076             bytes2process -= sent;
00077         }
00078 
00079         bytes2process = BUFF_SIZE;
00080         while (bytes2process > 0) {
00081             recvd = sock.recv(&(rx_buff[BUFF_SIZE - bytes2process]), bytes2process);
00082             if (recvd == NSAPI_ERROR_WOULD_BLOCK ) {
00083                 continue;
00084             } else if (recvd < 0) {
00085                 printf("network error %d\n", recvd);
00086                 TEST_FAIL();
00087                 goto END;
00088             }
00089             bytes2process -= recvd;
00090         }
00091 
00092         if (bytes2process != 0) {
00093             drop_bad_packets(sock, 0);
00094             TEST_FAIL();
00095             goto END;
00096         }
00097         TEST_ASSERT_EQUAL(0, memcmp(tx_buff, rx_buff, BUFF_SIZE));
00098     }
00099 END:
00100     TEST_ASSERT_EQUAL(NSAPI_ERROR_OK , sock.close());
00101 }
00102 
00103 static void check_var_len_rand_sequence()
00104 {
00105     TCPSocket sock;
00106     tcpsocket_connect_to_echo_srv(sock);
00107     sock.sigio(callback(_sigio_handler2, Thread::gettid()));
00108 
00109     static const int BUFF_SIZE = 1001;
00110     static char rx_buff[BUFF_SIZE];
00111     static char tx_buff[BUFF_SIZE];
00112     static const int pkt_size_diff = 100;
00113 
00114     int bytes2process;
00115     int recvd;
00116     int sent;
00117     for (int i = BUFF_SIZE; i > 0; i -= pkt_size_diff) {
00118         fill_tx_buffer_ascii(tx_buff, i);
00119         bytes2process = i;
00120         while (bytes2process > 0) {
00121             sent = sock.send(&(tx_buff[i - bytes2process]), bytes2process);
00122             if (sent == NSAPI_ERROR_WOULD_BLOCK ) {
00123                 if (osSignalWait(SIGNAL_SIGIO2, SIGIO_TIMEOUT).status == osEventTimeout) {
00124                     TEST_FAIL();
00125                     goto END;
00126                 }
00127                 continue;
00128             } else if (sent < 0) {
00129                 printf("[%02d] network error %d\n", i, sent);
00130                 TEST_FAIL();
00131                 goto END;
00132             }
00133             bytes2process -= sent;
00134         }
00135 
00136         bytes2process = i;
00137         while (bytes2process > 0) {
00138             recvd = sock.recv(&(rx_buff[i - bytes2process]), bytes2process);
00139             if (recvd == NSAPI_ERROR_WOULD_BLOCK ) {
00140                 continue;
00141             } else if (recvd < 0) {
00142                 printf("[%02d] network error %d\n", i, recvd);
00143                 TEST_FAIL();
00144                 goto END;
00145             }
00146             bytes2process -= recvd;
00147         }
00148 
00149         if (bytes2process != 0) {
00150             drop_bad_packets(sock, 0);
00151             TEST_FAIL();
00152             goto END;
00153         }
00154         TEST_ASSERT_EQUAL(0, memcmp(tx_buff, rx_buff, i));
00155     }
00156 END:
00157     TEST_ASSERT_EQUAL(NSAPI_ERROR_OK , sock.close());
00158 }
00159 
00160 void TCPSOCKET_THREAD_PER_SOCKET_SAFETY()
00161 {
00162     thread.start(callback(check_const_len_rand_sequence));
00163 
00164     check_var_len_rand_sequence();
00165 
00166     running = false;
00167     thread.join();
00168 }