mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			Merge pull request #12694 from kivaisan/remove_netsocket_icetea_and_tcpserver
Remove netsocket icetea tests and TCPServerpull/12885/head
						commit
						4f9d21b16a
					
				| 
						 | 
				
			
			@ -1,158 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018 ARM Limited. All rights reserved.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the License); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include "NetworkStack.h"
 | 
			
		||||
#include "NetworkInterface.h"
 | 
			
		||||
 | 
			
		||||
#include "mbed-client-cli/ns_cmdline.h"
 | 
			
		||||
#include "mbed-trace/mbed_trace.h"
 | 
			
		||||
 | 
			
		||||
#include "ip4string.h"
 | 
			
		||||
 | 
			
		||||
#define WIFI 2
 | 
			
		||||
#if !defined(MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE) || \
 | 
			
		||||
    (MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE == WIFI && !defined(MBED_CONF_NSAPI_DEFAULT_WIFI_SSID))
 | 
			
		||||
#error [NOT_SUPPORTED] No network configuration found for this target.
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#define TRACE_GROUP "Aifc"
 | 
			
		||||
 | 
			
		||||
NetworkInterface *net;
 | 
			
		||||
 | 
			
		||||
NetworkInterface *get_interface(void)
 | 
			
		||||
{
 | 
			
		||||
    return net;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cmd_ifup(int argc, char *argv[]);
 | 
			
		||||
int cmd_ifdown(int argc, char *argv[]);
 | 
			
		||||
int cmd_ifconfig(int argc, char *argv[]);
 | 
			
		||||
 | 
			
		||||
const char *MAN_IFCONFIG = "  ifup      interface up\r\n"\
 | 
			
		||||
                           "  ifdown      interface down\r\n";
 | 
			
		||||
 | 
			
		||||
static void ifconfig_print()
 | 
			
		||||
{
 | 
			
		||||
    if (!net) {
 | 
			
		||||
        cmd_printf("No interface configured\r\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    const char *str = net->get_ip_address();
 | 
			
		||||
    if (str) {
 | 
			
		||||
        uint8_t buf[4];
 | 
			
		||||
        if (stoip4(str, strlen(str), buf)) {
 | 
			
		||||
            cmd_printf("IPv4 if addr: %s\r\n", str);
 | 
			
		||||
        } else {
 | 
			
		||||
            cmd_printf("IPv6 if addr:\r\n [0]: %s\r\n", str);
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        cmd_printf("No IP address\r\n");
 | 
			
		||||
    }
 | 
			
		||||
    str = net->get_mac_address();
 | 
			
		||||
    if (str) {
 | 
			
		||||
        cmd_printf("MAC-48: %s\r\n", str);
 | 
			
		||||
    } else {
 | 
			
		||||
        cmd_printf("MAC-48: unknown\r\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void cmd_ifconfig_init(void)
 | 
			
		||||
{
 | 
			
		||||
    cmd_add("ifup", cmd_ifup, "ifconfig up", MAN_IFCONFIG);
 | 
			
		||||
    cmd_add("ifdown", cmd_ifdown, "ifconfig down", MAN_IFCONFIG);
 | 
			
		||||
    cmd_add("ifconfig", cmd_ifconfig, "ifconfig", MAN_IFCONFIG);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cmd_ifconfig(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    ifconfig_print();
 | 
			
		||||
    return CMDLINE_RETCODE_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cmd_ifup(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    if (!net) {
 | 
			
		||||
        net = NetworkInterface::get_default_instance();
 | 
			
		||||
    }
 | 
			
		||||
    int err =  net->connect();
 | 
			
		||||
    if (err != NSAPI_ERROR_OK) {
 | 
			
		||||
        return CMDLINE_RETCODE_FAIL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ifconfig_print();
 | 
			
		||||
    return CMDLINE_RETCODE_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int cmd_ifdown(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    if (!net) {
 | 
			
		||||
        return CMDLINE_RETCODE_FAIL;
 | 
			
		||||
    }
 | 
			
		||||
    int err = net->disconnect();
 | 
			
		||||
    if (err != NSAPI_ERROR_OK) {
 | 
			
		||||
        return CMDLINE_RETCODE_FAIL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return CMDLINE_RETCODE_SUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
const char *networkstack_error_to_str(int errorcode)
 | 
			
		||||
{
 | 
			
		||||
    switch (errorcode) {
 | 
			
		||||
        case NSAPI_ERROR_OK:
 | 
			
		||||
            return "NSAPI_ERROR_OK";
 | 
			
		||||
        case NSAPI_ERROR_WOULD_BLOCK:
 | 
			
		||||
            return "NSAPI_ERROR_WOULD_BLOCK";
 | 
			
		||||
        case NSAPI_ERROR_UNSUPPORTED:
 | 
			
		||||
            return "NSAPI_ERROR_UNSUPPORTED";
 | 
			
		||||
        case NSAPI_ERROR_PARAMETER:
 | 
			
		||||
            return "NSAPI_ERROR_PARAMETER";
 | 
			
		||||
        case NSAPI_ERROR_NO_CONNECTION:
 | 
			
		||||
            return "NSAPI_ERROR_NO_CONNECTION";
 | 
			
		||||
        case NSAPI_ERROR_NO_SOCKET:
 | 
			
		||||
            return "NSAPI_ERROR_NO_SOCKET";
 | 
			
		||||
        case NSAPI_ERROR_NO_ADDRESS:
 | 
			
		||||
            return "NSAPI_ERROR_NO_ADDRESS";
 | 
			
		||||
        case NSAPI_ERROR_NO_MEMORY:
 | 
			
		||||
            return "NSAPI_ERROR_NO_MEMORY";
 | 
			
		||||
        case NSAPI_ERROR_NO_SSID:
 | 
			
		||||
            return "NSAPI_ERROR_NO_SSID";
 | 
			
		||||
        case NSAPI_ERROR_DNS_FAILURE:
 | 
			
		||||
            return "NSAPI_ERROR_DNS_FAILURE";
 | 
			
		||||
        case NSAPI_ERROR_DHCP_FAILURE:
 | 
			
		||||
            return "NSAPI_ERROR_DHCP_FAILURE";
 | 
			
		||||
        case NSAPI_ERROR_AUTH_FAILURE:
 | 
			
		||||
            return "NSAPI_ERROR_AUTH_FAILURE";
 | 
			
		||||
        case NSAPI_ERROR_DEVICE_ERROR:
 | 
			
		||||
            return "NSAPI_ERROR_DEVICE_ERROR";
 | 
			
		||||
        case NSAPI_ERROR_IN_PROGRESS:
 | 
			
		||||
            return "NSAPI_ERROR_IN_PROGRESS";
 | 
			
		||||
        case NSAPI_ERROR_ALREADY:
 | 
			
		||||
            return "NSAPI_ERROR_ALREADY";
 | 
			
		||||
        case NSAPI_ERROR_IS_CONNECTED:
 | 
			
		||||
            return "NSAPI_ERROR_IS_CONNECTED";
 | 
			
		||||
        case NSAPI_ERROR_CONNECTION_LOST:
 | 
			
		||||
            return "NSAPI_ERROR_CONNECTION_LOST";
 | 
			
		||||
        case NSAPI_ERROR_CONNECTION_TIMEOUT:
 | 
			
		||||
            return "NSAPI_ERROR_CONNECTION_TIMEOUT";
 | 
			
		||||
        default:
 | 
			
		||||
            return "unknown error code";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,34 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018 ARM Limited. All rights reserved.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the License); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef CMD_IFCONFIG_H
 | 
			
		||||
#define CMD_IFCONFIG_H
 | 
			
		||||
 | 
			
		||||
#include "NetworkInterface.h"
 | 
			
		||||
#include "NetworkStack.h"
 | 
			
		||||
 | 
			
		||||
/** Get a pointer to a network interface instance
 | 
			
		||||
 *
 | 
			
		||||
 * Allowed interface types (depend on application configurations):
 | 
			
		||||
 * cell0, wlan0, eth0, mesh0
 | 
			
		||||
 *
 | 
			
		||||
 *  @return         pointer to the network interface, or NULL if unrecognized or ambiguous
 | 
			
		||||
 */
 | 
			
		||||
NetworkInterface *get_interface(void);
 | 
			
		||||
 | 
			
		||||
void cmd_ifconfig_init(void);
 | 
			
		||||
const char *networkstack_error_to_str(int errorcode);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -1,25 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018 ARM Limited. All rights reserved.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the License); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef CMD_SOCKET_H_
 | 
			
		||||
#define CMD_SOCKET_H_
 | 
			
		||||
 | 
			
		||||
#include "nsapi_types.h"
 | 
			
		||||
 | 
			
		||||
int handle_nsapi_error(const char *function, nsapi_error_t ret);
 | 
			
		||||
int handle_nsapi_size_or_error(const char *function, nsapi_size_or_error_t ret);
 | 
			
		||||
void cmd_socket_init(void);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1,69 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018 ARM Limited. All rights reserved.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the License); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include "mbed.h"
 | 
			
		||||
#include "mbed-client-cli/ns_cmdline.h"
 | 
			
		||||
#include "cmd_ifconfig.h"
 | 
			
		||||
#include "cmd_socket.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Macros for setting console flow control.
 | 
			
		||||
 */
 | 
			
		||||
#define CONSOLE_FLOWCONTROL_RTS     1
 | 
			
		||||
#define CONSOLE_FLOWCONTROL_CTS     2
 | 
			
		||||
#define CONSOLE_FLOWCONTROL_RTSCTS  3
 | 
			
		||||
#define mbed_console_concat_(x) CONSOLE_FLOWCONTROL_##x
 | 
			
		||||
#define mbed_console_concat(x) mbed_console_concat_(x)
 | 
			
		||||
#define CONSOLE_FLOWCONTROL mbed_console_concat(MBED_CONF_TARGET_CONSOLE_UART_FLOW_CONTROL)
 | 
			
		||||
 | 
			
		||||
#define SERIAL_CONSOLE_BAUD_RATE 115200
 | 
			
		||||
 | 
			
		||||
void cmd_ready_cb(int retcode)
 | 
			
		||||
{
 | 
			
		||||
    cmd_next(retcode);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void wrap_printf(const char *f, va_list a)
 | 
			
		||||
{
 | 
			
		||||
    vprintf(f, a);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    cmd_init(&wrap_printf);
 | 
			
		||||
    cmd_ifconfig_init();
 | 
			
		||||
    cmd_socket_init();
 | 
			
		||||
 | 
			
		||||
    int c;
 | 
			
		||||
    while ((c = getchar()) != EOF) {
 | 
			
		||||
        cmd_char_input(c);
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FileHandle *mbed::mbed_override_console(int)
 | 
			
		||||
{
 | 
			
		||||
    static BufferedSerial console(STDIO_UART_TX, STDIO_UART_RX, SERIAL_CONSOLE_BAUD_RATE);
 | 
			
		||||
#if CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTS
 | 
			
		||||
    console.set_flow_control(SerialBase::RTS, STDIO_UART_RTS, NC);
 | 
			
		||||
#elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_CTS
 | 
			
		||||
    console.set_flow_control(SerialBase::CTS, NC, STDIO_UART_CTS);
 | 
			
		||||
#elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTSCTS
 | 
			
		||||
    console.set_flow_control(SerialBase::RTSCTS, STDIO_UART_RTS, STDIO_UART_CTS);
 | 
			
		||||
#endif
 | 
			
		||||
    return &console;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +0,0 @@
 | 
			
		|||
{
 | 
			
		||||
    "macros": [
 | 
			
		||||
        "MEM_ALLOC=malloc",
 | 
			
		||||
        "MEM_FREE=free",
 | 
			
		||||
        "MBED_HEAP_STATS_ENABLED=1",
 | 
			
		||||
        "MBED_MEM_TRACING_ENABLED"
 | 
			
		||||
    ],
 | 
			
		||||
    "target_overrides": {
 | 
			
		||||
        "*": {
 | 
			
		||||
            "mbed-trace.enable": 1,
 | 
			
		||||
            "platform.stdio-baud-rate": 115200,
 | 
			
		||||
            "platform.stdio-convert-newlines": true,
 | 
			
		||||
            "platform.stdio-buffered-serial": true,
 | 
			
		||||
            "platform.stdio-flush-at-exit": true,
 | 
			
		||||
            "drivers.uart-serial-rxbuf-size": 768
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,242 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018 ARM Limited. All rights reserved.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the License); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
 | 
			
		||||
#include "ip6string.h"
 | 
			
		||||
#include "strconv.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int8_t strtohex(uint8_t *out, const char *str, int8_t max_length)
 | 
			
		||||
{
 | 
			
		||||
    int8_t i = 0;
 | 
			
		||||
    char *rd = (char *)str;
 | 
			
		||||
    uint8_t *wr = out;
 | 
			
		||||
    while (*rd != 0) {
 | 
			
		||||
        if (i > max_length) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        *wr++ = strtoul(rd, &rd, 16);
 | 
			
		||||
        while (!isxdigit((int)*rd) && *rd != 0) {
 | 
			
		||||
            rd++; //skip some invalid characters
 | 
			
		||||
        }
 | 
			
		||||
        i++;
 | 
			
		||||
    }
 | 
			
		||||
    return i;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int hexstr_to_bytes_inplace(char *str)
 | 
			
		||||
{
 | 
			
		||||
    int16_t len, i, j;
 | 
			
		||||
    if (str == NULL) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    len = strlen(str);
 | 
			
		||||
    if (len < 2 || (len + 1) % 3 != 0) {
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    for (i = 0, j = 0; i < len; i += 3, ++j) {
 | 
			
		||||
        str[j] = (char)strtol(str + i, 0, 16);
 | 
			
		||||
    }
 | 
			
		||||
    return j;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// convert hex string (eg. "76 ab ff") to binary array
 | 
			
		||||
int string_to_bytes(const char *str, uint8_t *buf, int bytes)
 | 
			
		||||
{
 | 
			
		||||
    int len = strlen(str);
 | 
			
		||||
    if (len <= (3 * bytes - 1)) {
 | 
			
		||||
        int i;
 | 
			
		||||
        for (i = 0; i < bytes; i++) {
 | 
			
		||||
            if (i * 3 < len) {
 | 
			
		||||
                buf[i] = (uint8_t)strtoul(str + i * 3, 0, 16);
 | 
			
		||||
            } else {
 | 
			
		||||
                buf[i] = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int16_t hextostr(const uint8_t *buf, uint16_t buf_length, char *out, int16_t out_length, char delimiter)
 | 
			
		||||
{
 | 
			
		||||
    int16_t outLeft = out_length;
 | 
			
		||||
    int16_t arrLeft = buf_length;
 | 
			
		||||
    const uint8_t *rd = buf;
 | 
			
		||||
    int retcode = 0;
 | 
			
		||||
    char *wr = out;
 | 
			
		||||
    while (arrLeft > 0 && outLeft > 0) {
 | 
			
		||||
        retcode = snprintf(wr, outLeft, "%02x", *rd);
 | 
			
		||||
 | 
			
		||||
        if (retcode <= 0 || retcode >= outLeft) {
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        outLeft -= retcode;
 | 
			
		||||
        wr += retcode;
 | 
			
		||||
        arrLeft --;
 | 
			
		||||
        rd++;
 | 
			
		||||
        if (delimiter && arrLeft > 0 && outLeft > 0) {
 | 
			
		||||
            *wr++ = delimiter;
 | 
			
		||||
            outLeft--;
 | 
			
		||||
            *wr = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return (int16_t)(wr - out);
 | 
			
		||||
}
 | 
			
		||||
int replace_hexdata(char *str)
 | 
			
		||||
{
 | 
			
		||||
    char *ptr = str;
 | 
			
		||||
    if (str == NULL) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    while (*ptr) {
 | 
			
		||||
        if (ptr[0] == '\\') {
 | 
			
		||||
            if (ptr[1] == 'n') {
 | 
			
		||||
                ptr[0] = 0x0a;
 | 
			
		||||
                memmove(ptr + 1, ptr + 2, strlen(ptr + 2) + 1);
 | 
			
		||||
            } else if (ptr[1] == 'r') {
 | 
			
		||||
                ptr[0] = 0x0d;
 | 
			
		||||
                memmove(ptr + 1, ptr + 2, strlen(ptr + 2) + 1);
 | 
			
		||||
            } else if (ptr[1] == 'x') {
 | 
			
		||||
                char *end;
 | 
			
		||||
                ptr[0] = (char)strtoul(ptr + 2, &end, 16);
 | 
			
		||||
                memmove(ptr + 1, end, strlen(end) + 1);
 | 
			
		||||
            } else if (isdigit((int)ptr[1])) {
 | 
			
		||||
                char *end;
 | 
			
		||||
                ptr[0] = strtoul(ptr + 1, &end, 10);
 | 
			
		||||
                memmove(ptr + 1, end, strlen(end) + 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        ptr++;
 | 
			
		||||
    }
 | 
			
		||||
    return ptr - str;
 | 
			
		||||
}
 | 
			
		||||
bool is_visible(uint8_t *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
    while (len--) {
 | 
			
		||||
        if (!isalnum(*buf) && *buf != ' ') {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        buf++;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *strdupl(const char *str)
 | 
			
		||||
{
 | 
			
		||||
    if (!str) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
    char *p = malloc(strlen(str) + 1);
 | 
			
		||||
    if (!p) {
 | 
			
		||||
        return p;
 | 
			
		||||
    }
 | 
			
		||||
    strcpy(p, str);
 | 
			
		||||
    return p;
 | 
			
		||||
}
 | 
			
		||||
int strnlen_(const char *s, int n)
 | 
			
		||||
{
 | 
			
		||||
    char *end = memchr(s, 0, n);
 | 
			
		||||
    return end ? end - s : n;
 | 
			
		||||
}
 | 
			
		||||
char *strndupl(const char *s, int n)
 | 
			
		||||
{
 | 
			
		||||
    char *p = NULL;
 | 
			
		||||
    int len = strnlen_(s, n);
 | 
			
		||||
    p = malloc(len + 1);
 | 
			
		||||
    if (!p) {
 | 
			
		||||
        return p;
 | 
			
		||||
    }
 | 
			
		||||
    p[len] = 0;
 | 
			
		||||
    return memcpy(p, s, len);
 | 
			
		||||
}
 | 
			
		||||
int strnicmp_(char const *a, char const *b, int n)
 | 
			
		||||
{
 | 
			
		||||
    for (; (n > 0 && *a != 0 && *b != 0) ; a++, b++, n--) {
 | 
			
		||||
        int d = tolower((int) * a) - tolower((int) * b);
 | 
			
		||||
        if (d != 0 || !*a) {
 | 
			
		||||
            return d;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* HELPING PRINT FUNCTIONS for cmd_printf */
 | 
			
		||||
 | 
			
		||||
static inline uint8_t context_split_mask(uint_fast8_t split_value)
 | 
			
		||||
{
 | 
			
		||||
    return (uint8_t) - (0x100u >> split_value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint8_t *bitcopy(uint8_t *restrict dst, const uint8_t *restrict src, uint_fast8_t bits)
 | 
			
		||||
{
 | 
			
		||||
    uint_fast8_t bytes = bits / 8;
 | 
			
		||||
    bits %= 8;
 | 
			
		||||
 | 
			
		||||
    if (bytes) {
 | 
			
		||||
        dst = (uint8_t *) memcpy(dst, src, bytes) + bytes;
 | 
			
		||||
        src += bytes;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (bits) {
 | 
			
		||||
        uint_fast8_t split_bit = context_split_mask(bits);
 | 
			
		||||
        *dst = (*src & split_bit) | (*dst & ~ split_bit);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char tmp_print_buffer[128] = {0};
 | 
			
		||||
 | 
			
		||||
char *print_ipv6(const void *addr_ptr)
 | 
			
		||||
{
 | 
			
		||||
    ip6tos(addr_ptr, tmp_print_buffer);
 | 
			
		||||
    return tmp_print_buffer;
 | 
			
		||||
}
 | 
			
		||||
char *print_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len)
 | 
			
		||||
{
 | 
			
		||||
    char *str = tmp_print_buffer;
 | 
			
		||||
    int retval;
 | 
			
		||||
    char tmp[40];
 | 
			
		||||
    uint8_t addr[16] = {0};
 | 
			
		||||
 | 
			
		||||
    if (prefix_len != 0) {
 | 
			
		||||
        if (prefix == NULL || prefix_len > 128) {
 | 
			
		||||
            return "<err>";
 | 
			
		||||
        }
 | 
			
		||||
        bitcopy(addr, prefix, prefix_len);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ip6tos(addr, tmp);
 | 
			
		||||
    retval = snprintf(str, 128, "%s/%u", tmp, prefix_len);
 | 
			
		||||
    if (retval <= 0) {
 | 
			
		||||
        return "";
 | 
			
		||||
    }
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
char *print_array(const uint8_t *buf, uint16_t len)
 | 
			
		||||
{
 | 
			
		||||
    int16_t retcode = hextostr(buf, len, tmp_print_buffer, 128, ':');
 | 
			
		||||
    if (retcode > 0) {
 | 
			
		||||
        //yeah, something is converted
 | 
			
		||||
    }
 | 
			
		||||
    return tmp_print_buffer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,98 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018 ARM Limited. All rights reserved.
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the License); you may
 | 
			
		||||
 * not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef STRCONVERSION_H
 | 
			
		||||
#define STRCONVERSION_H
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "ns_types.h"
 | 
			
		||||
 | 
			
		||||
/** Convert hex string to binary array
 | 
			
		||||
 * e.g.
 | 
			
		||||
 * char str[] = {30, 31, 32, 33};
 | 
			
		||||
 * uint8_t buffer[4];
 | 
			
		||||
 * strtohex( buffer, str, 4 );
 | 
			
		||||
 */
 | 
			
		||||
int8_t  strtohex(uint8_t *out, const char *str, int8_t max_length);
 | 
			
		||||
 | 
			
		||||
/** Convert space separated hex string (eg. "76 ab ff") to binary array.
 | 
			
		||||
 */
 | 
			
		||||
int string_to_bytes(const char *str, uint8_t *buf, int bytes);
 | 
			
		||||
 | 
			
		||||
/** Convert a colon/space separated hex string (eg. "76:ab:ff") to binary
 | 
			
		||||
 * array (inplace) returning the number of the bytes in the array.
 | 
			
		||||
 */
 | 
			
		||||
int hexstr_to_bytes_inplace(char *str);
 | 
			
		||||
 | 
			
		||||
/** Convert hex array to string
 | 
			
		||||
 */
 | 
			
		||||
int16_t hextostr(const uint8_t *buf, uint16_t buf_length, char *out, int16_t out_length, char delimiter);
 | 
			
		||||
/** Replace hex characters from string
 | 
			
		||||
 * e.g.
 | 
			
		||||
 *  "hello\\n" -> "hello\n"
 | 
			
		||||
 *  "hello\\r" -> "hello\r"
 | 
			
		||||
 *  "val: \\10" -> "val: \x0a"  //integer
 | 
			
		||||
 *  "val: \\x10" -> "val: \x10" //hex value
 | 
			
		||||
 *  @param str  string that will be replaced
 | 
			
		||||
 *  @return length
 | 
			
		||||
 */
 | 
			
		||||
int replace_hexdata(char *str);
 | 
			
		||||
/**
 | 
			
		||||
 * check if array contains only visible characters
 | 
			
		||||
 * = isalpha | isdigit
 | 
			
		||||
 */
 | 
			
		||||
bool is_visible(uint8_t *buf, int len);
 | 
			
		||||
 | 
			
		||||
/** Convert ipv6 address to string format
 | 
			
		||||
 */
 | 
			
		||||
char   *print_ipv6(const void *addr_ptr);
 | 
			
		||||
/** Convert ipv6 prefix to string format
 | 
			
		||||
 */
 | 
			
		||||
char *print_ipv6_prefix(const uint8_t *prefix, uint8_t prefix_len);
 | 
			
		||||
/** Convert binary array to string format and return static results
 | 
			
		||||
 */
 | 
			
		||||
char   *print_array(const uint8_t *buf, uint16_t len);
 | 
			
		||||
/** The strdupl() function shall return a pointer to a new string,
 | 
			
		||||
 * which is a duplicate of the string pointed to by s1. The returned pointer can be passed to free().
 | 
			
		||||
 * A null pointer is returned if the new string cannot be created.
 | 
			
		||||
 * strdupl are same than linux strdup, but this way we avoid to duplicate reference in linux
 | 
			
		||||
 */
 | 
			
		||||
char *strdupl(const char *str);
 | 
			
		||||
/** The strdup() function returns a pointer to a new string which is a duplicate of the string.
 | 
			
		||||
 * Memory for the new string is obtained with malloc(3), and can be freed with free(3).
 | 
			
		||||
 * The strndup() function is similar, but only copies at most n bytes. If s is longer than n,
 | 
			
		||||
 * only n bytes are copied, and a terminating null byte ('\0') is added.
 | 
			
		||||
 */
 | 
			
		||||
char *strndupl(const char *s, int n);
 | 
			
		||||
/** strnlen - determine the length of a fixed-size string
 | 
			
		||||
 * The strnlen() function returns the number of bytes in the string pointed to by s, excluding the terminating null bye ('\0'), but at most maxlen.
 | 
			
		||||
 * In doing this, strnlen() looks only at the first maxlen bytes at s and never beyond s+maxlen.
 | 
			
		||||
 * The strnlen() function returns strlen(s), if that is less than maxlen, or maxlen if there is no null byte ('\0')
 | 
			
		||||
 * among the first maxlen bytes pointed to by s.
 | 
			
		||||
 */
 | 
			
		||||
int strnlen_(const char *s, int n);
 | 
			
		||||
/** strnicmp compares a and b without sensitivity to case.
 | 
			
		||||
 * All alphabetic characters in the two arguments a and b are converted to lowercase before the comparison.
 | 
			
		||||
 */
 | 
			
		||||
int strnicmp_(char const *a, char const *b, int n);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10,6 +10,5 @@ Testcases
 | 
			
		|||
 | 
			
		||||
Current testcases:
 | 
			
		||||
 | 
			
		||||
-   [`netsocket`](https://github.com/ARMmbed/mbed-os/blob/master/TEST_APPS/testcases/netsocket)
 | 
			
		||||
-   [`example`](https://github.com/ARMmbed/mbed-os/blob/master/TEST_APPS/testcases/example)
 | 
			
		||||
-   [`nanostack_mac_tester`](https://github.com/ARMmbed/mbed-os/blob/master/TEST_APPS/testcases/nanostack_mac_tester)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,113 +0,0 @@
 | 
			
		|||
##Netsocket tests
 | 
			
		||||
 | 
			
		||||
This folder contains netsocket tests for Icetea
 | 
			
		||||
The tests located in this folder are dependent of the application [`socket_app`](https://github.com/ARMmbed/mbed-os/blob/master/TEST_APPS/device/socket_app)
 | 
			
		||||
 | 
			
		||||
The test cases in this folder are similar to [Network Socket test plan](https://github.com/ARMmbed/mbed-os/blob/master/TESTS/netsocket/README.md).
 | 
			
		||||
 | 
			
		||||
Icetea test cases are processed by passing commands through the `mbed-client-cli` command line. It is possible to manually replicate most test cases by following the instructions below.
 | 
			
		||||
 | 
			
		||||
In test cases with more than one device under test (DUT) the target device is given in the instructions as DUT1, DUT2 or DUT3.
 | 
			
		||||
 | 
			
		||||
## Test cases
 | 
			
		||||
 | 
			
		||||
### `SOCKET_BIND_PORT`
 | 
			
		||||
 | 
			
		||||
**Description:**
 | 
			
		||||
 | 
			
		||||
Open and bind port.
 | 
			
		||||
 | 
			
		||||
**Preconditions:**
 | 
			
		||||
 | 
			
		||||
1.  Network interface and stack are initialized.
 | 
			
		||||
2.  Network connection is up.
 | 
			
		||||
 | 
			
		||||
**Test steps:**
 | 
			
		||||
 | 
			
		||||
1.  Create a object by calling `socket new TCPSocket` on device
 | 
			
		||||
2.  Call `socket TCPSocket open`
 | 
			
		||||
3.  Call `socket TCPSocket bind port <any non-used port number>`
 | 
			
		||||
4.  Destroy socket `socket TCPSocket delete`
 | 
			
		||||
5.  Create a object by calling `socket new UDPSocket` on device
 | 
			
		||||
6.  Call `socket UDPSocket open`
 | 
			
		||||
7.  Call `socket UDPSocket bind port <any non-used port number>`
 | 
			
		||||
8.  Destroy socket `socket UDPSocket delete`
 | 
			
		||||
 | 
			
		||||
**Expected result:**
 | 
			
		||||
 | 
			
		||||
The test exits with status `PASS` without timeouts.
 | 
			
		||||
 | 
			
		||||
### `TCPSERVER_ACCEPT`
 | 
			
		||||
 | 
			
		||||
**Description:**
 | 
			
		||||
 | 
			
		||||
Test that `TCPServer::bind()`, `TCPServer::listen()`
 | 
			
		||||
and `TCPServer::accept()` works.
 | 
			
		||||
 | 
			
		||||
Requires 2 devices.
 | 
			
		||||
 | 
			
		||||
**Preconditions:**
 | 
			
		||||
 | 
			
		||||
1.  Network interface and stack are initialized.
 | 
			
		||||
2.  Network connection is up.
 | 
			
		||||
 | 
			
		||||
**Test steps:**
 | 
			
		||||
 | 
			
		||||
1.  DUT1: `socket new TCPServer`
 | 
			
		||||
    Command returns server base socket ID
 | 
			
		||||
2.  DUT1: `socket <base socket ID> open)`
 | 
			
		||||
3.  DUT1: `socket <base socket ID> bind port <port>)`
 | 
			
		||||
4.  DUT1: `socket <base socket ID> listen)`
 | 
			
		||||
5.  DUT1: Create a new TCPSocket `socket new TCPSocket`
 | 
			
		||||
    Command returns server socket ID
 | 
			
		||||
6.  DUT1: `socket <server socket ID> open`
 | 
			
		||||
7.  DUT2: Create a new TCPSocket `socket new TCPSocket`
 | 
			
		||||
    Command returns client socket ID
 | 
			
		||||
8.  DUT2: `socket <client socket ID> open`
 | 
			
		||||
9.  DUT2: `socket <client socket ID> connect <dut1 IP> <port>`
 | 
			
		||||
10. DUT1: `socket <base socket id> accept <server socket id>`
 | 
			
		||||
    Command should return new socket ID
 | 
			
		||||
11. DUT1: `socket <new socket ID> send hello`
 | 
			
		||||
12. DUT2: `socket <client socket ID> recv 5`
 | 
			
		||||
13. DUT2: Verify that it received "hello"
 | 
			
		||||
14. Destroy all sockets.
 | 
			
		||||
 | 
			
		||||
**Expected result:**
 | 
			
		||||
 | 
			
		||||
On DUT1 accept() call blocks until connection is received. Duration
 | 
			
		||||
of call verified to be within threshold.
 | 
			
		||||
 | 
			
		||||
The test exits with status `PASS` without timeouts.
 | 
			
		||||
 | 
			
		||||
### `TCPSOCKET_ECHOTEST_BURST_SHORT`
 | 
			
		||||
 | 
			
		||||
**Description:**
 | 
			
		||||
 | 
			
		||||
Send burst of packets to echo server and read incoming packets back.
 | 
			
		||||
 | 
			
		||||
**Preconditions:**
 | 
			
		||||
 | 
			
		||||
1.  Network interface and stack are initialized.
 | 
			
		||||
2.  Network connection is up.
 | 
			
		||||
3.  TCPSocket is open.
 | 
			
		||||
 | 
			
		||||
**Test steps:**
 | 
			
		||||
 | 
			
		||||
1.  Call `socket <socket ID> open`
 | 
			
		||||
2.  Call `socket <socket ID> connect echo.mbedcloudtesting.com 7`
 | 
			
		||||
    1.  Create 5 randomized strings
 | 
			
		||||
        (100, 200, 300, 120 and 500 characters)
 | 
			
		||||
    2.  Send each string `socket <socket ID> send <string>`
 | 
			
		||||
    3.  Receive total size of sent data
 | 
			
		||||
        `socket <socket ID> recv <total size>`
 | 
			
		||||
    4.  Verify that received data is identical to sent data
 | 
			
		||||
3.  Repeat 2 times
 | 
			
		||||
4.  Destroy the socket
 | 
			
		||||
 | 
			
		||||
**Expected result:**
 | 
			
		||||
 | 
			
		||||
All send() calls should return the packet size.
 | 
			
		||||
 | 
			
		||||
The received data matches the sent data.
 | 
			
		||||
 | 
			
		||||
The test exits with status `PASS` without timeouts.
 | 
			
		||||
| 
						 | 
				
			
			@ -1,73 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
Copyright 2018 ARM Limited
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
"""
 | 
			
		||||
from icetea_lib.bench import Bench
 | 
			
		||||
from icetea_lib.tools import test_case
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class MultipleTestcase(Bench):
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        testcase_args = {
 | 
			
		||||
            'status': "released",
 | 
			
		||||
            'component': ["mbed-os", "netsocket"],
 | 
			
		||||
            'type': "smoke",
 | 
			
		||||
            'subtype': "socket",
 | 
			
		||||
            'requirements': {
 | 
			
		||||
                "duts": {
 | 
			
		||||
                    "*": {
 | 
			
		||||
                        "count": 1,
 | 
			
		||||
                        "type": "hardware",
 | 
			
		||||
                        "application": {"name": "TEST_APPS-device-socket_app"}
 | 
			
		||||
                    },
 | 
			
		||||
                    "1": {"nick": "dut1"},
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        testcase_args.update(kwargs)
 | 
			
		||||
        Bench.__init__(self, **testcase_args)
 | 
			
		||||
 | 
			
		||||
    def setup(self):
 | 
			
		||||
        self.command("dut1", "ifup")
 | 
			
		||||
 | 
			
		||||
    def socket_bind_port(self, socket_type):
 | 
			
		||||
        response = self.command("dut1", "socket new " + socket_type)
 | 
			
		||||
        self.socket_id = int(response.parsed['socket_id'])
 | 
			
		||||
 | 
			
		||||
        self.command("dut1", "socket " + str(self.socket_id) + " open")
 | 
			
		||||
 | 
			
		||||
        self.command("dut1", "socket " + str(self.socket_id) + " bind port 1024")
 | 
			
		||||
 | 
			
		||||
    def teardown(self):
 | 
			
		||||
        self.command("dut1", "socket " + str(self.socket_id) + " delete")
 | 
			
		||||
        
 | 
			
		||||
        self.command("dut1", "ifdown")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@test_case(MultipleTestcase,
 | 
			
		||||
           name="TCPSOCKET_BIND_PORT",
 | 
			
		||||
           title="tcpsocket open and bind port",
 | 
			
		||||
           purpose="Verify TCPSocket can be created, opened and port binded")
 | 
			
		||||
def test1(self):
 | 
			
		||||
    self.socket_bind_port("TCPSocket")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@test_case(MultipleTestcase,
 | 
			
		||||
           name="UDPSOCKET_BIND_PORT",
 | 
			
		||||
           title="udpsocket open and bind port",
 | 
			
		||||
           purpose="Verify UDPSocket can be created, opened and port binded")
 | 
			
		||||
def test2(self):
 | 
			
		||||
    self.socket_bind_port("UDPSocket")
 | 
			
		||||
| 
						 | 
				
			
			@ -1,105 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
Copyright 2018 ARM Limited
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import threading
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
from icetea_lib.TestStepError import TestStepFail
 | 
			
		||||
from icetea_lib.bench import Bench
 | 
			
		||||
from interface import interfaceUp, interfaceDown
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Testcase(Bench):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        Bench.__init__(self,
 | 
			
		||||
                       name="TCPSERVER_ACCEPT",
 | 
			
		||||
                       title="TCPSERVER_ACCEPT",
 | 
			
		||||
                       purpose="Test that TCPServer::bind(), TCPServer::listen() and TCPServer::accept() works",
 | 
			
		||||
                       status="released",
 | 
			
		||||
                       component=["mbed-os", "netsocket"],
 | 
			
		||||
                       author="Juha Ylinen <juha.ylinen@arm.com>",
 | 
			
		||||
                       type="smoke",
 | 
			
		||||
                       subtype="socket",
 | 
			
		||||
                       requirements={
 | 
			
		||||
                           "duts": {
 | 
			
		||||
                               '*': {  # requirements for all nodes
 | 
			
		||||
                                   "count": 2,
 | 
			
		||||
                                   "type": "hardware",
 | 
			
		||||
                                   "application": {"name": "TEST_APPS-device-socket_app"}
 | 
			
		||||
                               },
 | 
			
		||||
                               "1": {"nick": "dut1"},
 | 
			
		||||
                               "2": {"nick": "dut2"}
 | 
			
		||||
                           }
 | 
			
		||||
                       }
 | 
			
		||||
                       )
 | 
			
		||||
 | 
			
		||||
    def setup(self):
 | 
			
		||||
        interface = interfaceUp(self, ["dut1"])
 | 
			
		||||
        self.server_ip = interface["dut1"]["ip"]
 | 
			
		||||
        interface = interfaceUp(self, ["dut2"])
 | 
			
		||||
        self.client_ip = interface["dut2"]["ip"]
 | 
			
		||||
 | 
			
		||||
    def clientThread(self):
 | 
			
		||||
        self.logger.info("Starting")
 | 
			
		||||
        time.sleep(5)  # wait accept from server
 | 
			
		||||
        self.command("dut2", "socket " + str(self.client_socket_id) + " open")
 | 
			
		||||
        self.command("dut2", "socket " + str(self.client_socket_id) + " connect " + str(self.server_ip) + " " + str(
 | 
			
		||||
            self.used_port))
 | 
			
		||||
 | 
			
		||||
    def case(self):
 | 
			
		||||
        self.used_port = 2000
 | 
			
		||||
 | 
			
		||||
        response = self.command("dut1", "socket new TCPServer")
 | 
			
		||||
        self.server_base_socket_id = int(response.parsed['socket_id'])
 | 
			
		||||
 | 
			
		||||
        self.command("dut1", "socket " + str(self.server_base_socket_id) + " open")
 | 
			
		||||
        self.command("dut1", "socket " + str(self.server_base_socket_id) + " bind port " + str(self.used_port))
 | 
			
		||||
        self.command("dut1", "socket " + str(self.server_base_socket_id) + " listen")
 | 
			
		||||
 | 
			
		||||
        response = self.command("dut1", "socket new TCPSocket")
 | 
			
		||||
        self.server_socket_id = int(response.parsed['socket_id'])
 | 
			
		||||
        self.command("dut1", "socket " + str(self.server_socket_id) + " open")
 | 
			
		||||
 | 
			
		||||
        response = self.command("dut2", "socket new TCPSocket")
 | 
			
		||||
        zero = response.timedelta
 | 
			
		||||
        self.client_socket_id = int(response.parsed['socket_id'])
 | 
			
		||||
 | 
			
		||||
        # Create a thread which calls client connect()
 | 
			
		||||
        t = threading.Thread(name='clientThread', target=self.clientThread)
 | 
			
		||||
        t.start()
 | 
			
		||||
 | 
			
		||||
        wait = 5
 | 
			
		||||
        response = self.command("dut1", "socket " + str(self.server_base_socket_id) + " accept " + str(self.server_socket_id))
 | 
			
		||||
        response.verify_response_duration(expected=wait, zero=zero, threshold_percent=10, break_in_fail=True)
 | 
			
		||||
        socket_id = int(response.parsed['socket_id'])
 | 
			
		||||
 | 
			
		||||
        t.join()
 | 
			
		||||
        self.command("dut1", "socket " + str(socket_id) + " send hello")
 | 
			
		||||
 | 
			
		||||
        response = self.command("dut2", "socket " + str(self.client_socket_id) + " recv 5")
 | 
			
		||||
        data = response.parsed['data'].replace(":", "")
 | 
			
		||||
 | 
			
		||||
        if data != "hello":
 | 
			
		||||
            raise TestStepFail("Received data doesn't match the sent data")
 | 
			
		||||
 | 
			
		||||
    def teardown(self):
 | 
			
		||||
        self.command("dut1", "socket " + str(self.server_socket_id) + " delete")
 | 
			
		||||
        self.command("dut1", "socket " + str(self.server_base_socket_id) + " delete")
 | 
			
		||||
        self.command("dut2", "socket " + str(self.client_socket_id) + " delete")
 | 
			
		||||
        
 | 
			
		||||
        interfaceDown(self, ["dut1"])
 | 
			
		||||
        interfaceDown(self, ["dut2"])
 | 
			
		||||
| 
						 | 
				
			
			@ -1,108 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
Copyright 2018 ARM Limited
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
import threading
 | 
			
		||||
import time
 | 
			
		||||
 | 
			
		||||
from icetea_lib.bench import Bench
 | 
			
		||||
from interface import interfaceUp, interfaceDown
 | 
			
		||||
#from mbed_clitest.tools import test_case
 | 
			
		||||
#from mbed_clitest.TestStepError import SkippedTestcaseException
 | 
			
		||||
from icetea_lib.TestStepError import TestStepFail
 | 
			
		||||
 | 
			
		||||
class Testcase(Bench):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        Bench.__init__(self,
 | 
			
		||||
                       name="TCPSOCKET_ACCEPT",
 | 
			
		||||
                       title = "TCPSOCKET_ACCEPT",
 | 
			
		||||
                       purpose = "Test that TCPSocket::bind(), TCPSocket::listen() and TCPSocket::accept() works",
 | 
			
		||||
                       status = "released",
 | 
			
		||||
                       component= ["mbed-os", "netsocket"],
 | 
			
		||||
                       type="smoke",
 | 
			
		||||
                       subtype="socket",
 | 
			
		||||
                       requirements={
 | 
			
		||||
                           "duts": {
 | 
			
		||||
                               '*': { #requirements for all nodes
 | 
			
		||||
                                    "count":2,
 | 
			
		||||
                                    "type": "hardware",
 | 
			
		||||
                                    "application": {
 | 
			
		||||
                                       "name": "TEST_APPS-device-socket_app"
 | 
			
		||||
                                    }
 | 
			
		||||
                                },
 | 
			
		||||
                                "1": {"nick": "dut1"},
 | 
			
		||||
                                "2": {"nick": "dut2"}
 | 
			
		||||
                           }
 | 
			
		||||
                       }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def setup(self):
 | 
			
		||||
        interface = interfaceUp(self, ["dut1"])
 | 
			
		||||
        self.server_ip = interface["dut1"]["ip"]
 | 
			
		||||
        interface = interfaceUp(self, ["dut2"])
 | 
			
		||||
        self.client_ip = interface["dut2"]["ip"]
 | 
			
		||||
 | 
			
		||||
    def clientThread(self):
 | 
			
		||||
        self.logger.info("Starting")
 | 
			
		||||
        time.sleep(5) #wait accept from server
 | 
			
		||||
        self.command("dut2", "socket " + str(self.client_socket_id) + " open")
 | 
			
		||||
        self.command("dut2", "socket " + str(self.client_socket_id) + " connect " + str(self.server_ip) + " " + str(self.used_port))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def case(self):
 | 
			
		||||
        self.used_port = 2000
 | 
			
		||||
 | 
			
		||||
        response = self.command("dut1", "socket new TCPSocket")
 | 
			
		||||
        self.server_base_socket_id = int(response.parsed['socket_id'])
 | 
			
		||||
 | 
			
		||||
        self.command("dut1", "socket " + str(self.server_base_socket_id) + " open")
 | 
			
		||||
        response = self.command("dut1", "socket " + str(self.server_base_socket_id) + " bind port " + str(self.used_port), report_cmd_fail = False)
 | 
			
		||||
        if response.retcode == -1:
 | 
			
		||||
            if (response.verify_trace("NSAPI_ERROR_UNSUPPORTED", break_in_fail = False)):
 | 
			
		||||
                raise SkippedTestcaseException("UNSUPPORTED")
 | 
			
		||||
            else:
 | 
			
		||||
                TestStepFail("Bind port failed")
 | 
			
		||||
        self.command("dut1", "socket " + str(self.server_base_socket_id) + " listen")
 | 
			
		||||
 | 
			
		||||
        response = self.command("dut2", "socket new TCPSocket")
 | 
			
		||||
        self.client_socket_id = int(response.parsed['socket_id'])
 | 
			
		||||
 | 
			
		||||
        #Create a thread which calls client connect()
 | 
			
		||||
        t = threading.Thread(name='clientThread', target=self.clientThread)
 | 
			
		||||
        t.start()
 | 
			
		||||
 | 
			
		||||
        response = self.command("dut1", "socket " + str(self.server_base_socket_id) + " accept")
 | 
			
		||||
 | 
			
		||||
        t.join()
 | 
			
		||||
        self.accept_socket_id = int(response.parsed['socket_id'])
 | 
			
		||||
        if response.timedelta < 5.0: # Check that socket accept call blocks
 | 
			
		||||
            raise TestStepFail("Longer response time expected")
 | 
			
		||||
 | 
			
		||||
        self.command("dut1", "socket " + str(self.accept_socket_id) + " send hello")
 | 
			
		||||
 | 
			
		||||
        response = self.command("dut2", "socket " + str(self.client_socket_id) + " recv 5")
 | 
			
		||||
        data = response.parsed['data'].replace(":","")
 | 
			
		||||
 | 
			
		||||
        if data != "hello":
 | 
			
		||||
            raise TestStepFail("Received data doesn't match the sent data")
 | 
			
		||||
 | 
			
		||||
    def teardown(self):
 | 
			
		||||
        response = self.command("dut2", "socket " + str(self.client_socket_id) + " delete")
 | 
			
		||||
        response = self.command("dut1", "socket " + str(self.server_base_socket_id) + " delete")
 | 
			
		||||
        response = self.command("dut1", "socket " + str(self.accept_socket_id) + " close") 
 | 
			
		||||
        
 | 
			
		||||
        interfaceDown(self, ["dut1"])
 | 
			
		||||
        interfaceDown(self, ["dut2"])
 | 
			
		||||
| 
						 | 
				
			
			@ -1,79 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
Copyright 2018 ARM Limited
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
"""
 | 
			
		||||
import string
 | 
			
		||||
 | 
			
		||||
from icetea_lib.Randomize.randomize import Randomize
 | 
			
		||||
from icetea_lib.bench import Bench, TestStepFail
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Testcase(Bench):
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        Bench.__init__(self,
 | 
			
		||||
                       name="TCPSOCKET_ECHOTEST_BURST_SHORT",
 | 
			
		||||
                       title="TCPSOCKET_ECHOTEST_BURST_SHORT",
 | 
			
		||||
                       purpose="Verify that TCPSocket can send burst of packets to echo server and read incoming packets",
 | 
			
		||||
                       status="released",
 | 
			
		||||
                       component=["mbed-os", "netsocket"],
 | 
			
		||||
                       author="Juha Ylinen <juha.ylinen@arm.com>",
 | 
			
		||||
                       type="smoke",
 | 
			
		||||
                       subtype="socket",
 | 
			
		||||
                       requirements={
 | 
			
		||||
                           "duts": {
 | 
			
		||||
                               '*': {  # requirements for all nodes
 | 
			
		||||
                                   "count": 1,
 | 
			
		||||
                                   "type": "hardware",
 | 
			
		||||
                                   "application": {
 | 
			
		||||
                                       "name": "TEST_APPS-device-socket_app"
 | 
			
		||||
                                   }
 | 
			
		||||
                               },
 | 
			
		||||
                               "1": {"nick": "dut1"},
 | 
			
		||||
                           }
 | 
			
		||||
                       }
 | 
			
		||||
                       )
 | 
			
		||||
 | 
			
		||||
    def setup(self):
 | 
			
		||||
        self.command("dut1", "ifup")
 | 
			
		||||
 | 
			
		||||
    def case(self):
 | 
			
		||||
        response = self.command("dut1", "socket new TCPSocket")
 | 
			
		||||
        self.socket_id = int(response.parsed['socket_id'])
 | 
			
		||||
 | 
			
		||||
        self.command("dut1", "socket " + str(self.socket_id) + " open")
 | 
			
		||||
        self.command("dut1", "socket " + str(self.socket_id) + " connect echo.mbedcloudtesting.com 7")
 | 
			
		||||
 | 
			
		||||
        for i in range(2):
 | 
			
		||||
            sentData = ""
 | 
			
		||||
            for size in (100, 200, 300, 120, 500):
 | 
			
		||||
                packet = Randomize.random_string(max_len=size, min_len=size, chars=string.ascii_uppercase)
 | 
			
		||||
                sentData += packet
 | 
			
		||||
                response = self.command("dut1", "socket " + str(self.socket_id) + " send " + str(packet))
 | 
			
		||||
                response.verify_trace("Socket::send() returned: " + str(size))
 | 
			
		||||
 | 
			
		||||
            received = 0
 | 
			
		||||
            data = ""
 | 
			
		||||
            totalSize = 1220
 | 
			
		||||
            while received < totalSize:
 | 
			
		||||
                response = self.command("dut1", "socket " + str(self.socket_id) + " recv " + str(totalSize))
 | 
			
		||||
                data += response.parsed['data'].replace(":", "")
 | 
			
		||||
                received += int(response.parsed['received_bytes'])
 | 
			
		||||
 | 
			
		||||
            if data != sentData:
 | 
			
		||||
                raise TestStepFail("Received data doesn't match the sent data")
 | 
			
		||||
 | 
			
		||||
    def teardown(self):
 | 
			
		||||
        self.command("dut1", "socket " + str(self.socket_id) + " delete")
 | 
			
		||||
        self.command("dut1", "ifdown")
 | 
			
		||||
| 
						 | 
				
			
			@ -1,16 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
Copyright (c) 2020 Arm Limited
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
"""
 | 
			
		||||
| 
						 | 
				
			
			@ -1,45 +0,0 @@
 | 
			
		|||
"""
 | 
			
		||||
Copyright 2018 ARM Limited
 | 
			
		||||
SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 | 
			
		||||
Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
you may not use this file except in compliance with the License.
 | 
			
		||||
You may obtain a copy of the License at
 | 
			
		||||
 | 
			
		||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 | 
			
		||||
Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
See the License for the specific language governing permissions and
 | 
			
		||||
limitations under the License.
 | 
			
		||||
"""
 | 
			
		||||
from icetea_lib.TestStepError import TestStepFail
 | 
			
		||||
 | 
			
		||||
'''
 | 
			
		||||
This interface script is intended to be a common library to be used in testcase scripts by testers.
 | 
			
		||||
It delegates setUp and tearDown functions with different provided network interface types using setUp() and tearDown() methods.
 | 
			
		||||
'''
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def interfaceUp(tc, duts):
 | 
			
		||||
    interfaces = {}
 | 
			
		||||
    for dut in duts:
 | 
			
		||||
        interface = {dut: {"ipv4": None, "ipv6": None}}
 | 
			
		||||
 | 
			
		||||
        resp = tc.command("%s" % dut, "ifup")
 | 
			
		||||
 | 
			
		||||
        ip = interface[dut]["ip"] = interface[dut]["ipv4"] = resp.parsed["address"]["ipv4"]
 | 
			
		||||
        if not ip:
 | 
			
		||||
            if resp.parsed["address"]["ipv6"]:
 | 
			
		||||
                ip = interface[dut]["ip"] = interface[dut]["ipv6"] = resp.parsed["address"]["ipv6"][0]
 | 
			
		||||
        if not ip:
 | 
			
		||||
            raise TestStepFail("Failed to parse IP address")
 | 
			
		||||
 | 
			
		||||
        interfaces.update(interface)
 | 
			
		||||
    return interfaces
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def interfaceDown(tc, duts):
 | 
			
		||||
    for dut in duts:
 | 
			
		||||
        tc.command(dut, "ifdown")
 | 
			
		||||
| 
						 | 
				
			
			@ -1,98 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2018, Arm Limited and affiliates
 | 
			
		||||
 * SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "gtest/gtest.h"
 | 
			
		||||
#include "features/netsocket/TCPSocket.h"
 | 
			
		||||
#include "features/netsocket/TCPServer.h"
 | 
			
		||||
#include "NetworkStack_stub.h"
 | 
			
		||||
 | 
			
		||||
// Control the rtos EventFlags stub. See EventFlags_stub.cpp
 | 
			
		||||
extern std::list<uint32_t> eventFlagsStubNextRetval;
 | 
			
		||||
 | 
			
		||||
class TestTCPServer : public testing::Test {
 | 
			
		||||
public:
 | 
			
		||||
    unsigned int dataSize = 10;
 | 
			
		||||
    char dataBuf[10];
 | 
			
		||||
protected:
 | 
			
		||||
    TCPSocket *socket;
 | 
			
		||||
    TCPServer *server;
 | 
			
		||||
    NetworkStackstub stack;
 | 
			
		||||
 | 
			
		||||
    virtual void SetUp()
 | 
			
		||||
    {
 | 
			
		||||
        server = new TCPServer();
 | 
			
		||||
        socket = new TCPSocket();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void TearDown()
 | 
			
		||||
    {
 | 
			
		||||
        stack.return_values.clear();
 | 
			
		||||
        eventFlagsStubNextRetval.clear();
 | 
			
		||||
        delete socket;
 | 
			
		||||
        delete server;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPServer, constructor)
 | 
			
		||||
{
 | 
			
		||||
    EXPECT_TRUE(server);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPServer, constructor_parameters)
 | 
			
		||||
{
 | 
			
		||||
    TCPServer serverParam(&stack);
 | 
			
		||||
    const SocketAddress a("127.0.0.1", 1024);
 | 
			
		||||
    EXPECT_EQ(serverParam.connect(a), NSAPI_ERROR_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPServer, accept)
 | 
			
		||||
{
 | 
			
		||||
    const SocketAddress a("127.0.0.1", 1024);
 | 
			
		||||
    EXPECT_EQ(socket->open(&stack), NSAPI_ERROR_OK);
 | 
			
		||||
    EXPECT_EQ(socket->connect(a), NSAPI_ERROR_OK);
 | 
			
		||||
    nsapi_error_t error;
 | 
			
		||||
    EXPECT_EQ(server->open(&stack), NSAPI_ERROR_OK);
 | 
			
		||||
    EXPECT_EQ(server->bind(a), NSAPI_ERROR_OK);
 | 
			
		||||
    server->listen(1);
 | 
			
		||||
    SocketAddress client_addr;
 | 
			
		||||
    EXPECT_EQ(server->accept(socket, &client_addr), NSAPI_ERROR_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPServer, accept_no_socket)
 | 
			
		||||
{
 | 
			
		||||
    SocketAddress client_addr;
 | 
			
		||||
    EXPECT_EQ(server->accept(socket, &client_addr), NSAPI_ERROR_NO_SOCKET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPServer, accept_error)
 | 
			
		||||
{
 | 
			
		||||
    SocketAddress client_addr;
 | 
			
		||||
    EXPECT_EQ(server->open(&stack), NSAPI_ERROR_OK);
 | 
			
		||||
    stack.return_value = NSAPI_ERROR_AUTH_FAILURE;
 | 
			
		||||
    EXPECT_EQ(server->accept(socket, &client_addr), NSAPI_ERROR_AUTH_FAILURE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPServer, accept_error_would_block)
 | 
			
		||||
{
 | 
			
		||||
    SocketAddress client_addr;
 | 
			
		||||
    EXPECT_EQ(server->open(&stack), NSAPI_ERROR_OK);
 | 
			
		||||
    stack.return_value = NSAPI_ERROR_WOULD_BLOCK;
 | 
			
		||||
    eventFlagsStubNextRetval.push_back(0);
 | 
			
		||||
    eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
 | 
			
		||||
 | 
			
		||||
    EXPECT_EQ(server->accept(socket, &client_addr), NSAPI_ERROR_WOULD_BLOCK);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,35 +0,0 @@
 | 
			
		|||
 | 
			
		||||
####################
 | 
			
		||||
# UNIT TESTS
 | 
			
		||||
####################
 | 
			
		||||
 | 
			
		||||
# Unit test suite name
 | 
			
		||||
set(TEST_SUITE_NAME "features_netsocket_TCPServer")
 | 
			
		||||
 | 
			
		||||
set(unittest-sources
 | 
			
		||||
  ../features/netsocket/SocketAddress.cpp
 | 
			
		||||
  ../features/netsocket/NetworkStack.cpp
 | 
			
		||||
  ../features/netsocket/InternetSocket.cpp
 | 
			
		||||
  ../features/netsocket/TCPSocket.cpp
 | 
			
		||||
  ../features/netsocket/TCPServer.cpp
 | 
			
		||||
  ../features/frameworks/nanostack-libservice/source/libip4string/ip4tos.c
 | 
			
		||||
  ../features/frameworks/nanostack-libservice/source/libip6string/ip6tos.c
 | 
			
		||||
  ../features/frameworks/nanostack-libservice/source/libip4string/stoip4.c
 | 
			
		||||
  ../features/frameworks/nanostack-libservice/source/libip6string/stoip6.c
 | 
			
		||||
  ../features/frameworks/nanostack-libservice/source/libBits/common_functions.c  
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
set(unittest-test-sources
 | 
			
		||||
  stubs/Mutex_stub.cpp
 | 
			
		||||
  stubs/mbed_assert_stub.cpp
 | 
			
		||||
  stubs/mbed_atomic_stub.c
 | 
			
		||||
  stubs/mbed_critical_stub.c
 | 
			
		||||
  stubs/equeue_stub.c
 | 
			
		||||
  stubs/EventQueue_stub.cpp
 | 
			
		||||
  stubs/mbed_error.c
 | 
			
		||||
  stubs/mbed_shared_queues_stub.cpp
 | 
			
		||||
  stubs/nsapi_dns_stub.cpp
 | 
			
		||||
  stubs/EventFlags_stub.cpp
 | 
			
		||||
  features/netsocket/TCPServer/test_TCPServer.cpp
 | 
			
		||||
  stubs/SocketStats_Stub.cpp
 | 
			
		||||
)
 | 
			
		||||
| 
						 | 
				
			
			@ -49,6 +49,33 @@ protected:
 | 
			
		|||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Control the rtos EventFlags stub. See EventFlags_stub.cpp
 | 
			
		||||
extern std::list<uint32_t> eventFlagsStubNextRetval;
 | 
			
		||||
 | 
			
		||||
class TestTCPServer : public testing::Test {
 | 
			
		||||
public:
 | 
			
		||||
    unsigned int dataSize = 10;
 | 
			
		||||
    char dataBuf[10];
 | 
			
		||||
protected:
 | 
			
		||||
    TCPSocket *socket;
 | 
			
		||||
    TCPSocket *server;
 | 
			
		||||
    NetworkStackstub stack;
 | 
			
		||||
 | 
			
		||||
    virtual void SetUp()
 | 
			
		||||
    {
 | 
			
		||||
        server = new TCPSocket();
 | 
			
		||||
        socket = new TCPSocket();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void TearDown()
 | 
			
		||||
    {
 | 
			
		||||
        stack.return_values.clear();
 | 
			
		||||
        eventFlagsStubNextRetval.clear();
 | 
			
		||||
        delete socket;
 | 
			
		||||
        delete server;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPSocket, get_proto)
 | 
			
		||||
{
 | 
			
		||||
    TCPSocketFriend tcpFriend;
 | 
			
		||||
| 
						 | 
				
			
			@ -231,6 +258,12 @@ TEST_F(TestTCPSocket, recv_from_null)
 | 
			
		|||
    EXPECT_EQ(socket->recvfrom(NULL, dataBuf, dataSize), NSAPI_ERROR_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPSocket, unsupported_api)
 | 
			
		||||
{
 | 
			
		||||
    SocketAddress addr;
 | 
			
		||||
    EXPECT_EQ(socket->join_multicast_group(addr), NSAPI_ERROR_UNSUPPORTED);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* listen */
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPSocket, listen_no_open)
 | 
			
		||||
| 
						 | 
				
			
			@ -246,9 +279,9 @@ TEST_F(TestTCPSocket, listen)
 | 
			
		|||
    EXPECT_EQ(socket->listen(1), NSAPI_ERROR_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* these tests will have to be readjusted after TCPServer is deprecated. */
 | 
			
		||||
/* TCP server */
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPSocket, accept_no_open)
 | 
			
		||||
TEST_F(TestTCPServer, accept_no_open)
 | 
			
		||||
{
 | 
			
		||||
    nsapi_error_t error;
 | 
			
		||||
    stack.return_value = NSAPI_ERROR_OK;
 | 
			
		||||
| 
						 | 
				
			
			@ -256,12 +289,17 @@ TEST_F(TestTCPSocket, accept_no_open)
 | 
			
		|||
    EXPECT_EQ(error, NSAPI_ERROR_NO_SOCKET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPSocket, accept)
 | 
			
		||||
TEST_F(TestTCPServer, accept)
 | 
			
		||||
{
 | 
			
		||||
    const SocketAddress a("127.0.0.1", 1024);
 | 
			
		||||
    EXPECT_EQ(socket->open(&stack), NSAPI_ERROR_OK);
 | 
			
		||||
    EXPECT_EQ(socket->connect(a), NSAPI_ERROR_OK);
 | 
			
		||||
    nsapi_error_t error;
 | 
			
		||||
    stack.return_value = NSAPI_ERROR_OK;
 | 
			
		||||
    EXPECT_EQ(server->open(&stack), NSAPI_ERROR_OK);
 | 
			
		||||
    EXPECT_EQ(server->bind(a), NSAPI_ERROR_OK);
 | 
			
		||||
    server->listen(1);
 | 
			
		||||
    socket->open(&stack);
 | 
			
		||||
    TCPSocket *sock = socket->accept(&error);
 | 
			
		||||
    TCPSocket *sock = server->accept(&error);
 | 
			
		||||
    EXPECT_NE(sock, nullptr);
 | 
			
		||||
    EXPECT_EQ(error, NSAPI_ERROR_OK);
 | 
			
		||||
    if (sock) {
 | 
			
		||||
| 
						 | 
				
			
			@ -269,19 +307,26 @@ TEST_F(TestTCPSocket, accept)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPSocket, accept_would_block)
 | 
			
		||||
TEST_F(TestTCPServer, accept_would_block)
 | 
			
		||||
{
 | 
			
		||||
    nsapi_error_t error;
 | 
			
		||||
    socket->open(&stack);
 | 
			
		||||
    EXPECT_EQ(server->open(&stack), NSAPI_ERROR_OK);
 | 
			
		||||
 | 
			
		||||
    stack.return_value = NSAPI_ERROR_WOULD_BLOCK;
 | 
			
		||||
    eventFlagsStubNextRetval.push_back(0);
 | 
			
		||||
    eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
 | 
			
		||||
 | 
			
		||||
    EXPECT_EQ(socket->accept(&error), nullptr);
 | 
			
		||||
    EXPECT_EQ(error, NSAPI_ERROR_WOULD_BLOCK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST_F(TestTCPSocket, unsupported_api)
 | 
			
		||||
TEST_F(TestTCPServer, accept_error)
 | 
			
		||||
{
 | 
			
		||||
    SocketAddress addr;
 | 
			
		||||
    EXPECT_EQ(socket->join_multicast_group(addr), NSAPI_ERROR_UNSUPPORTED);
 | 
			
		||||
    nsapi_error_t error;
 | 
			
		||||
    EXPECT_EQ(server->open(&stack), NSAPI_ERROR_OK);
 | 
			
		||||
    stack.return_value = NSAPI_ERROR_AUTH_FAILURE;
 | 
			
		||||
    TCPSocket *sock = server->accept(&error);
 | 
			
		||||
    EXPECT_EQ(server->accept(&error), nullptr);
 | 
			
		||||
    EXPECT_EQ(error, NSAPI_ERROR_AUTH_FAILURE);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,7 +153,7 @@
 | 
			
		|||
 | 
			
		||||
#define MEM_SIZE                    MBED_CONF_LWIP_MEM_SIZE
 | 
			
		||||
 | 
			
		||||
// One tcp_pcb_listen is needed for each TCPServer.
 | 
			
		||||
// One tcp_pcb_listen is needed for each TCP server.
 | 
			
		||||
// Each requires 72 bytes of RAM.
 | 
			
		||||
#define MEMP_NUM_TCP_PCB_LISTEN     MBED_CONF_LWIP_TCP_SERVER_MAX
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -172,7 +172,7 @@
 | 
			
		|||
// Each netbuf requires 64 bytes of RAM.
 | 
			
		||||
#define MEMP_NUM_NETBUF             MBED_CONF_LWIP_NUM_NETBUF
 | 
			
		||||
 | 
			
		||||
// One netconn is needed for each UDPSocket, TCPSocket or TCPServer.
 | 
			
		||||
// One netconn is needed for each UDPSocket or TCPSocket.
 | 
			
		||||
// Each requires 236 bytes of RAM (total rounded to multiple of 512).
 | 
			
		||||
#define MEMP_NUM_NETCONN            MBED_CONF_LWIP_SOCKET_MAX
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,7 +59,7 @@
 | 
			
		|||
            "value": false
 | 
			
		||||
        },
 | 
			
		||||
        "socket-max": {
 | 
			
		||||
            "help": "Maximum number of open TCPServer, TCPSocket and UDPSocket instances allowed, including one used internally for DNS.  Each requires 236 bytes of pre-allocated RAM",
 | 
			
		||||
            "help": "Maximum number of open TCPSocket and UDPSocket instances allowed, including one used internally for DNS.  Each requires 236 bytes of pre-allocated RAM",
 | 
			
		||||
            "value": 4
 | 
			
		||||
        },
 | 
			
		||||
        "tcp-enabled": {
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +67,7 @@
 | 
			
		|||
            "value": true
 | 
			
		||||
        },
 | 
			
		||||
        "tcp-server-max": {
 | 
			
		||||
            "help": "Maximum number of open TCPServer instances allowed.  Each requires 72 bytes of pre-allocated RAM",
 | 
			
		||||
            "help": "Maximum number of open TCP server instances allowed.  Each requires 72 bytes of pre-allocated RAM",
 | 
			
		||||
            "value": 4
 | 
			
		||||
        },
 | 
			
		||||
        "tcp-socket-max": {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -244,7 +244,6 @@ protected:
 | 
			
		|||
    friend class InternetSocket;
 | 
			
		||||
    friend class InternetDatagramSocket;
 | 
			
		||||
    friend class TCPSocket;
 | 
			
		||||
    friend class TCPServer;
 | 
			
		||||
 | 
			
		||||
    /** Opens a socket
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,75 +0,0 @@
 | 
			
		|||
/* Socket
 | 
			
		||||
 * Copyright (c) 2015 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "TCPServer.h"
 | 
			
		||||
 | 
			
		||||
TCPServer::TCPServer()
 | 
			
		||||
{
 | 
			
		||||
    _socket_stats.stats_update_proto(this, NSAPI_TCP);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
nsapi_error_t TCPServer::accept(TCPSocket *connection, SocketAddress *address)
 | 
			
		||||
{
 | 
			
		||||
    _lock.lock();
 | 
			
		||||
    nsapi_error_t ret;
 | 
			
		||||
 | 
			
		||||
    while (true) {
 | 
			
		||||
        if (!_socket) {
 | 
			
		||||
            ret = NSAPI_ERROR_NO_SOCKET;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        core_util_atomic_flag_clear(&_pending);
 | 
			
		||||
        void *socket;
 | 
			
		||||
        ret = _stack->socket_accept(_socket, &socket, address);
 | 
			
		||||
 | 
			
		||||
        if (0 == ret) {
 | 
			
		||||
            connection->_lock.lock();
 | 
			
		||||
 | 
			
		||||
            if (connection->_socket) {
 | 
			
		||||
                connection->close();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            connection->_stack = _stack;
 | 
			
		||||
            connection->_socket = socket;
 | 
			
		||||
            connection->_event = { connection, &TCPSocket::event };
 | 
			
		||||
            _stack->socket_attach(socket, connection->_event.thunk, &connection->_event);
 | 
			
		||||
            _socket_stats.stats_update_peer(connection, *address);
 | 
			
		||||
            _socket_stats.stats_update_socket_state(connection, SOCK_CONNECTED);
 | 
			
		||||
            connection->_lock.unlock();
 | 
			
		||||
            break;
 | 
			
		||||
        } else if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
 | 
			
		||||
            break;
 | 
			
		||||
        } else {
 | 
			
		||||
            uint32_t flag;
 | 
			
		||||
 | 
			
		||||
            // Release lock before blocking so other threads
 | 
			
		||||
            // accessing this object aren't blocked
 | 
			
		||||
            _lock.unlock();
 | 
			
		||||
            flag = _event_flag.wait_any(READ_FLAG, _timeout);
 | 
			
		||||
            _lock.lock();
 | 
			
		||||
 | 
			
		||||
            if (flag & osFlagsError) {
 | 
			
		||||
                // Timeout break
 | 
			
		||||
                ret = NSAPI_ERROR_WOULD_BLOCK;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _lock.unlock();
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,81 +0,0 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (c) 2015 ARM Limited
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** @file TCPServer.h Deprecated TCPServer class */
 | 
			
		||||
/** \addtogroup netsocket
 | 
			
		||||
 * @{*/
 | 
			
		||||
 | 
			
		||||
#ifndef TCPSERVER_H
 | 
			
		||||
#define TCPSERVER_H
 | 
			
		||||
 | 
			
		||||
#include "netsocket/InternetSocket.h"
 | 
			
		||||
#include "netsocket/TCPSocket.h"
 | 
			
		||||
#include "netsocket/NetworkStack.h"
 | 
			
		||||
#include "netsocket/NetworkInterface.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** TCP socket server
 | 
			
		||||
 */
 | 
			
		||||
class TCPServer : public TCPSocket {
 | 
			
		||||
public:
 | 
			
		||||
    /** Create an uninitialized socket
 | 
			
		||||
     *
 | 
			
		||||
     *  Must call open to initialize the socket on a network stack.
 | 
			
		||||
     */
 | 
			
		||||
    MBED_DEPRECATED_SINCE("mbed-os-5.10",
 | 
			
		||||
                          "TCPServer is deprecated, use TCPSocket")
 | 
			
		||||
    TCPServer();
 | 
			
		||||
 | 
			
		||||
    /** Create a socket on a network interface
 | 
			
		||||
     *
 | 
			
		||||
     *  Creates and opens a socket on the network stack of the given
 | 
			
		||||
     *  network interface.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param stack    Network stack as target for socket
 | 
			
		||||
     */
 | 
			
		||||
    template <typename S>
 | 
			
		||||
    MBED_DEPRECATED_SINCE("mbed-os-5.10",
 | 
			
		||||
                          "TCPServer is deprecated, use TCPSocket")
 | 
			
		||||
    TCPServer(S *stack)
 | 
			
		||||
    {
 | 
			
		||||
        open(stack);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Allow legacy TCPServer::accept() to override inherited Socket::accept()
 | 
			
		||||
    using TCPSocket::accept;
 | 
			
		||||
 | 
			
		||||
    /** Accepts a connection on a TCP socket
 | 
			
		||||
     *
 | 
			
		||||
     *  The server socket must be bound and set to listen for connections.
 | 
			
		||||
     *  On a new connection, creates a network socket using the specified
 | 
			
		||||
     *  socket instance.
 | 
			
		||||
     *
 | 
			
		||||
     *  By default, accept blocks until data is sent. If socket is set to
 | 
			
		||||
     *  non-blocking or times out, NSAPI_ERROR_WOULD_BLOCK is returned
 | 
			
		||||
     *  immediately.
 | 
			
		||||
     *
 | 
			
		||||
     *  @param connection TCPSocket instance that will handle the incoming connection.
 | 
			
		||||
     *  @param address    Destination for the remote address or NULL
 | 
			
		||||
     *  @return           0 on success, negative error code on failure
 | 
			
		||||
     */
 | 
			
		||||
    MBED_DEPRECATED_SINCE("mbed-os-5.10",
 | 
			
		||||
                          "TCPServer::accept() is deprecated, use Socket *Socket::accept() instead")
 | 
			
		||||
    nsapi_error_t accept(TCPSocket *connection, SocketAddress *address = NULL);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** @} */
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +177,6 @@ public:
 | 
			
		|||
    nsapi_error_t listen(int backlog = 1) override;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    friend class TCPServer;
 | 
			
		||||
    nsapi_protocol_t get_proto() override;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,6 @@
 | 
			
		|||
#include "netsocket/Socket.h"
 | 
			
		||||
#include "netsocket/UDPSocket.h"
 | 
			
		||||
#include "netsocket/TCPSocket.h"
 | 
			
		||||
#include "netsocket/TCPServer.h"
 | 
			
		||||
#include "netsocket/TLSSocketWrapper.h"
 | 
			
		||||
#include "netsocket/DTLSSocketWrapper.h"
 | 
			
		||||
#include "netsocket/TLSSocket.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue