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