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:
|
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)
|
- [`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)
|
- [`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)
|
TEST_F(TestTCPSocket, get_proto)
|
||||||
{
|
{
|
||||||
TCPSocketFriend tcpFriend;
|
TCPSocketFriend tcpFriend;
|
||||||
|
|
@ -231,6 +258,12 @@ TEST_F(TestTCPSocket, recv_from_null)
|
||||||
EXPECT_EQ(socket->recvfrom(NULL, dataBuf, dataSize), NSAPI_ERROR_OK);
|
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 */
|
/* listen */
|
||||||
|
|
||||||
TEST_F(TestTCPSocket, listen_no_open)
|
TEST_F(TestTCPSocket, listen_no_open)
|
||||||
|
|
@ -246,9 +279,9 @@ TEST_F(TestTCPSocket, listen)
|
||||||
EXPECT_EQ(socket->listen(1), NSAPI_ERROR_OK);
|
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;
|
nsapi_error_t error;
|
||||||
stack.return_value = NSAPI_ERROR_OK;
|
stack.return_value = NSAPI_ERROR_OK;
|
||||||
|
|
@ -256,12 +289,17 @@ TEST_F(TestTCPSocket, accept_no_open)
|
||||||
EXPECT_EQ(error, NSAPI_ERROR_NO_SOCKET);
|
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;
|
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);
|
socket->open(&stack);
|
||||||
TCPSocket *sock = socket->accept(&error);
|
TCPSocket *sock = server->accept(&error);
|
||||||
EXPECT_NE(sock, nullptr);
|
EXPECT_NE(sock, nullptr);
|
||||||
EXPECT_EQ(error, NSAPI_ERROR_OK);
|
EXPECT_EQ(error, NSAPI_ERROR_OK);
|
||||||
if (sock) {
|
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;
|
nsapi_error_t error;
|
||||||
socket->open(&stack);
|
socket->open(&stack);
|
||||||
|
EXPECT_EQ(server->open(&stack), NSAPI_ERROR_OK);
|
||||||
|
|
||||||
stack.return_value = NSAPI_ERROR_WOULD_BLOCK;
|
stack.return_value = NSAPI_ERROR_WOULD_BLOCK;
|
||||||
eventFlagsStubNextRetval.push_back(0);
|
eventFlagsStubNextRetval.push_back(0);
|
||||||
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
|
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
|
||||||
|
|
||||||
EXPECT_EQ(socket->accept(&error), nullptr);
|
EXPECT_EQ(socket->accept(&error), nullptr);
|
||||||
EXPECT_EQ(error, NSAPI_ERROR_WOULD_BLOCK);
|
EXPECT_EQ(error, NSAPI_ERROR_WOULD_BLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(TestTCPSocket, unsupported_api)
|
TEST_F(TestTCPServer, accept_error)
|
||||||
{
|
{
|
||||||
SocketAddress addr;
|
nsapi_error_t error;
|
||||||
EXPECT_EQ(socket->join_multicast_group(addr), NSAPI_ERROR_UNSUPPORTED);
|
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
|
#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.
|
// Each requires 72 bytes of RAM.
|
||||||
#define MEMP_NUM_TCP_PCB_LISTEN MBED_CONF_LWIP_TCP_SERVER_MAX
|
#define MEMP_NUM_TCP_PCB_LISTEN MBED_CONF_LWIP_TCP_SERVER_MAX
|
||||||
|
|
||||||
|
|
@ -172,7 +172,7 @@
|
||||||
// Each netbuf requires 64 bytes of RAM.
|
// Each netbuf requires 64 bytes of RAM.
|
||||||
#define MEMP_NUM_NETBUF MBED_CONF_LWIP_NUM_NETBUF
|
#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).
|
// Each requires 236 bytes of RAM (total rounded to multiple of 512).
|
||||||
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
|
#define MEMP_NUM_NETCONN MBED_CONF_LWIP_SOCKET_MAX
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
"value": false
|
"value": false
|
||||||
},
|
},
|
||||||
"socket-max": {
|
"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
|
"value": 4
|
||||||
},
|
},
|
||||||
"tcp-enabled": {
|
"tcp-enabled": {
|
||||||
|
|
@ -67,7 +67,7 @@
|
||||||
"value": true
|
"value": true
|
||||||
},
|
},
|
||||||
"tcp-server-max": {
|
"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
|
"value": 4
|
||||||
},
|
},
|
||||||
"tcp-socket-max": {
|
"tcp-socket-max": {
|
||||||
|
|
|
||||||
|
|
@ -244,7 +244,6 @@ protected:
|
||||||
friend class InternetSocket;
|
friend class InternetSocket;
|
||||||
friend class InternetDatagramSocket;
|
friend class InternetDatagramSocket;
|
||||||
friend class TCPSocket;
|
friend class TCPSocket;
|
||||||
friend class TCPServer;
|
|
||||||
|
|
||||||
/** Opens a socket
|
/** 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;
|
nsapi_error_t listen(int backlog = 1) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class TCPServer;
|
|
||||||
nsapi_protocol_t get_proto() override;
|
nsapi_protocol_t get_proto() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@
|
||||||
#include "netsocket/Socket.h"
|
#include "netsocket/Socket.h"
|
||||||
#include "netsocket/UDPSocket.h"
|
#include "netsocket/UDPSocket.h"
|
||||||
#include "netsocket/TCPSocket.h"
|
#include "netsocket/TCPSocket.h"
|
||||||
#include "netsocket/TCPServer.h"
|
|
||||||
#include "netsocket/TLSSocketWrapper.h"
|
#include "netsocket/TLSSocketWrapper.h"
|
||||||
#include "netsocket/DTLSSocketWrapper.h"
|
#include "netsocket/DTLSSocketWrapper.h"
|
||||||
#include "netsocket/TLSSocket.h"
|
#include "netsocket/TLSSocket.h"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue