mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #8592 from deepikabhavnani/nw_stats_ver2
Network Socket Statisticspull/8798/head
commit
2009f028b1
|
@ -38,6 +38,10 @@ NetworkInterface *net;
|
||||||
Timer tc_bucket; // Timer to limit a test cases run time
|
Timer tc_bucket; // Timer to limit a test cases run time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
mbed_stats_socket_t tcp_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT];
|
||||||
|
#endif
|
||||||
|
|
||||||
char tcp_global::rx_buffer[RX_BUFF_SIZE];
|
char tcp_global::rx_buffer[RX_BUFF_SIZE];
|
||||||
char tcp_global::tx_buffer[TX_BUFF_SIZE];
|
char tcp_global::tx_buffer[TX_BUFF_SIZE];
|
||||||
|
|
||||||
|
@ -115,6 +119,13 @@ int split2half_rmng_tcp_test_time()
|
||||||
return (tcp_global::TESTS_TIMEOUT - tc_bucket.read()) / 2;
|
return (tcp_global::TESTS_TIMEOUT - tc_bucket.read()) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
int fetch_stats()
|
||||||
|
{
|
||||||
|
return SocketStats::mbed_stats_socket_get_each(&tcp_stats[0], MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Test setup
|
// Test setup
|
||||||
utest::v1::status_t greentea_setup(const size_t number_of_cases)
|
utest::v1::status_t greentea_setup(const size_t number_of_cases)
|
||||||
{
|
{
|
||||||
|
|
|
@ -24,6 +24,11 @@ void fill_tx_buffer_ascii(char *buff, size_t len);
|
||||||
nsapi_error_t tcpsocket_connect_to_echo_srv(TCPSocket &sock);
|
nsapi_error_t tcpsocket_connect_to_echo_srv(TCPSocket &sock);
|
||||||
nsapi_error_t tcpsocket_connect_to_discard_srv(TCPSocket &sock);
|
nsapi_error_t tcpsocket_connect_to_discard_srv(TCPSocket &sock);
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
extern mbed_stats_socket_t tcp_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT];
|
||||||
|
int fetch_stats(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Single testcase might take only half of the remaining execution time
|
* Single testcase might take only half of the remaining execution time
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -114,6 +114,13 @@ void tcpsocket_echotest_nonblock_receiver(void *receive_bytes)
|
||||||
|
|
||||||
void TCPSOCKET_ECHOTEST_NONBLOCK()
|
void TCPSOCKET_ECHOTEST_NONBLOCK()
|
||||||
{
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
int j = 0;
|
||||||
|
int count = fetch_stats();
|
||||||
|
for (; j < count; j++) {
|
||||||
|
TEST_ASSERT_EQUAL(SOCK_CLOSED, tcp_stats[j].state);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
tc_exec_time.start();
|
tc_exec_time.start();
|
||||||
time_allotted = split2half_rmng_tcp_test_time(); // [s]
|
time_allotted = split2half_rmng_tcp_test_time(); // [s]
|
||||||
|
|
||||||
|
@ -160,6 +167,15 @@ void TCPSOCKET_ECHOTEST_NONBLOCK()
|
||||||
bytes2send -= sent;
|
bytes2send -= sent;
|
||||||
}
|
}
|
||||||
printf("[Sender#%02d] bytes sent: %d\n", s_idx, pkt_s);
|
printf("[Sender#%02d] bytes sent: %d\n", s_idx, pkt_s);
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
count = fetch_stats();
|
||||||
|
for (j = 0; j < count; j++) {
|
||||||
|
if ((tcp_stats[j].state == SOCK_OPEN) && (tcp_stats[j].proto == NSAPI_TCP)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TEST_ASSERT_EQUAL(bytes2send, tcp_stats[j].sent_bytes);
|
||||||
|
#endif
|
||||||
tx_sem.wait(split2half_rmng_tcp_test_time());
|
tx_sem.wait(split2half_rmng_tcp_test_time());
|
||||||
thread->join();
|
thread->join();
|
||||||
delete thread;
|
delete thread;
|
||||||
|
|
|
@ -26,6 +26,12 @@ using namespace utest::v1;
|
||||||
|
|
||||||
void TCPSOCKET_OPEN_CLOSE_REPEAT()
|
void TCPSOCKET_OPEN_CLOSE_REPEAT()
|
||||||
{
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
int count = fetch_stats();
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
TEST_ASSERT_EQUAL(SOCK_CLOSED, tcp_stats[j].state);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
TCPSocket *sock = new TCPSocket;
|
TCPSocket *sock = new TCPSocket;
|
||||||
if (!sock) {
|
if (!sock) {
|
||||||
TEST_FAIL();
|
TEST_FAIL();
|
||||||
|
@ -36,4 +42,10 @@ void TCPSOCKET_OPEN_CLOSE_REPEAT()
|
||||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->close());
|
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->close());
|
||||||
}
|
}
|
||||||
delete sock;
|
delete sock;
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
count = fetch_stats();
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
TEST_ASSERT_EQUAL(SOCK_CLOSED, tcp_stats[j].state);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,17 @@ void TCPSOCKET_OPEN_LIMIT()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
int count = fetch_stats();
|
||||||
|
int open_count = 0;
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
if ((tcp_stats[j].state == SOCK_OPEN) && (tcp_stats[j].proto == NSAPI_TCP)) {
|
||||||
|
open_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TEST_ASSERT(open_count >= 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
TCPSocketItem *tmp;
|
TCPSocketItem *tmp;
|
||||||
for (TCPSocketItem *it = socket_list_head; it;) {
|
for (TCPSocketItem *it = socket_list_head; it;) {
|
||||||
++open_sockets[i];
|
++open_sockets[i];
|
||||||
|
|
|
@ -37,6 +37,10 @@ namespace {
|
||||||
NetworkInterface *net;
|
NetworkInterface *net;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
mbed_stats_socket_t udp_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT];
|
||||||
|
#endif
|
||||||
|
|
||||||
NetworkInterface *get_interface()
|
NetworkInterface *get_interface()
|
||||||
{
|
{
|
||||||
return net;
|
return net;
|
||||||
|
@ -76,6 +80,13 @@ void fill_tx_buffer_ascii(char *buff, size_t len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
int fetch_stats()
|
||||||
|
{
|
||||||
|
return SocketStats::mbed_stats_socket_get_each(&udp_stats[0], MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Test setup
|
// Test setup
|
||||||
utest::v1::status_t greentea_setup(const size_t number_of_cases)
|
utest::v1::status_t greentea_setup(const size_t number_of_cases)
|
||||||
{
|
{
|
||||||
|
|
|
@ -22,6 +22,11 @@ NetworkInterface *get_interface();
|
||||||
void drop_bad_packets(UDPSocket &sock, int orig_timeout);
|
void drop_bad_packets(UDPSocket &sock, int orig_timeout);
|
||||||
void fill_tx_buffer_ascii(char *buff, size_t len);
|
void fill_tx_buffer_ascii(char *buff, size_t len);
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
extern mbed_stats_socket_t udp_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT];
|
||||||
|
int fetch_stats(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test cases
|
* Test cases
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -121,6 +121,14 @@ void udpsocket_echotest_nonblock_receiver(void *receive_bytes)
|
||||||
|
|
||||||
void UDPSOCKET_ECHOTEST_NONBLOCK()
|
void UDPSOCKET_ECHOTEST_NONBLOCK()
|
||||||
{
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
int j = 0;
|
||||||
|
int count = fetch_stats();
|
||||||
|
for (; j < count; j++) {
|
||||||
|
TEST_ASSERT_EQUAL(SOCK_CLOSED, udp_stats[j].state);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SocketAddress udp_addr;
|
SocketAddress udp_addr;
|
||||||
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
|
get_interface()->gethostbyname(MBED_CONF_APP_ECHO_SERVER_ADDR, &udp_addr);
|
||||||
udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
|
udp_addr.set_port(MBED_CONF_APP_ECHO_SERVER_PORT);
|
||||||
|
@ -174,11 +182,27 @@ void UDPSOCKET_ECHOTEST_NONBLOCK()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(stack_mem);
|
free(stack_mem);
|
||||||
|
|
||||||
// Packet loss up to 30% tolerated
|
// Packet loss up to 30% tolerated
|
||||||
if (packets_sent > 0) {
|
if (packets_sent > 0) {
|
||||||
double loss_ratio = 1 - ((double)packets_recv / (double)packets_sent);
|
double loss_ratio = 1 - ((double)packets_recv / (double)packets_sent);
|
||||||
printf("Packets sent: %d, packets received %d, loss ratio %.2lf\r\n", packets_sent, packets_recv, loss_ratio);
|
printf("Packets sent: %d, packets received %d, loss ratio %.2lf\r\n", packets_sent, packets_recv, loss_ratio);
|
||||||
TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
|
TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
count = fetch_stats();
|
||||||
|
for (j = 0; j < count; j++) {
|
||||||
|
if ((NSAPI_UDP == udp_stats[j].proto) && (SOCK_OPEN == udp_stats[j].state)) {
|
||||||
|
TEST_ASSERT(udp_stats[j].sent_bytes != 0);
|
||||||
|
TEST_ASSERT(udp_stats[j].recv_bytes != 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loss_ratio = 1 - ((double)udp_stats[j].recv_bytes / (double)udp_stats[j].sent_bytes);
|
||||||
|
printf("Bytes sent: %d, bytes received %d, loss ratio %.2lf\r\n", udp_stats[j].sent_bytes, udp_stats[j].recv_bytes, loss_ratio);
|
||||||
|
TEST_ASSERT_DOUBLE_WITHIN(TOLERATED_LOSS_RATIO, EXPECTED_LOSS_RATIO, loss_ratio);
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
|
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,12 @@ using namespace utest::v1;
|
||||||
|
|
||||||
void UDPSOCKET_OPEN_CLOSE_REPEAT()
|
void UDPSOCKET_OPEN_CLOSE_REPEAT()
|
||||||
{
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
int count = fetch_stats();
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
TEST_ASSERT_EQUAL(SOCK_CLOSED, udp_stats[j].state);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
UDPSocket *sock = new UDPSocket;
|
UDPSocket *sock = new UDPSocket;
|
||||||
if (!sock) {
|
if (!sock) {
|
||||||
TEST_FAIL();
|
TEST_FAIL();
|
||||||
|
@ -36,4 +42,10 @@ void UDPSOCKET_OPEN_CLOSE_REPEAT()
|
||||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->close());
|
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock->close());
|
||||||
}
|
}
|
||||||
delete sock;
|
delete sock;
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
count = fetch_stats();
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
TEST_ASSERT_EQUAL(SOCK_CLOSED, udp_stats[j].state);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "UDPSocket.h"
|
#include "UDPSocket.h"
|
||||||
#include "unity/unity.h"
|
#include "unity/unity.h"
|
||||||
#include "utest.h"
|
#include "utest.h"
|
||||||
|
#include "SocketStats.h"
|
||||||
|
|
||||||
using namespace utest::v1;
|
using namespace utest::v1;
|
||||||
|
|
||||||
|
@ -69,7 +70,16 @@ void UDPSOCKET_OPEN_LIMIT()
|
||||||
if (!socket_list_head) {
|
if (!socket_list_head) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
int count = fetch_stats();
|
||||||
|
int open_count = 0;
|
||||||
|
for (int j = 0; j < count; j++) {
|
||||||
|
if ((udp_stats[j].state == SOCK_OPEN) && (udp_stats[j].proto == NSAPI_UDP)) {
|
||||||
|
open_count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TEST_ASSERT(open_count >= 3);
|
||||||
|
#endif
|
||||||
UDPSocketItem *tmp;
|
UDPSocketItem *tmp;
|
||||||
for (UDPSocketItem *it = socket_list_head; it;) {
|
for (UDPSocketItem *it = socket_list_head; it;) {
|
||||||
++open_sockets[i];
|
++open_sockets[i];
|
||||||
|
|
|
@ -31,6 +31,7 @@ set(unittest-test-sources
|
||||||
stubs/stoip4_stub.c
|
stubs/stoip4_stub.c
|
||||||
stubs/ip4tos_stub.c
|
stubs/ip4tos_stub.c
|
||||||
stubs/Kernel_stub.cpp
|
stubs/Kernel_stub.cpp
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/DTLSSocket/dtls_test_config.h\"")
|
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/DTLSSocket/dtls_test_config.h\"")
|
||||||
|
|
|
@ -30,6 +30,7 @@ set(unittest-test-sources
|
||||||
stubs/stoip4_stub.c
|
stubs/stoip4_stub.c
|
||||||
stubs/ip4tos_stub.c
|
stubs/ip4tos_stub.c
|
||||||
stubs/Kernel_stub.cpp
|
stubs/Kernel_stub.cpp
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/DTLSSocketWrapper/dtls_test_config.h\"")
|
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/DTLSSocketWrapper/dtls_test_config.h\"")
|
||||||
|
|
|
@ -33,4 +33,5 @@ set(unittest-test-sources
|
||||||
stubs/stoip4_stub.c
|
stubs/stoip4_stub.c
|
||||||
stubs/ip4tos_stub.c
|
stubs/ip4tos_stub.c
|
||||||
stubs/NetworkStack_stub.cpp
|
stubs/NetworkStack_stub.cpp
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,4 +25,5 @@ set(unittest-test-sources
|
||||||
stubs/EventFlags_stub.cpp
|
stubs/EventFlags_stub.cpp
|
||||||
stubs/stoip4_stub.c
|
stubs/stoip4_stub.c
|
||||||
stubs/ip4tos_stub.c
|
stubs/ip4tos_stub.c
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,4 +25,5 @@ set(unittest-test-sources
|
||||||
stubs/nsapi_dns_stub.cpp
|
stubs/nsapi_dns_stub.cpp
|
||||||
stubs/EventFlags_stub.cpp
|
stubs/EventFlags_stub.cpp
|
||||||
features/netsocket/NetworkInterface/test_NetworkInterface.cpp
|
features/netsocket/NetworkInterface/test_NetworkInterface.cpp
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -28,4 +28,5 @@ set(unittest-test-sources
|
||||||
stubs/nsapi_dns_stub.cpp
|
stubs/nsapi_dns_stub.cpp
|
||||||
stubs/EventFlags_stub.cpp
|
stubs/EventFlags_stub.cpp
|
||||||
features/netsocket/NetworkStack/test_NetworkStack.cpp
|
features/netsocket/NetworkStack/test_NetworkStack.cpp
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -28,4 +28,5 @@ set(unittest-test-sources
|
||||||
stubs/nsapi_dns_stub.cpp
|
stubs/nsapi_dns_stub.cpp
|
||||||
stubs/EventFlags_stub.cpp
|
stubs/EventFlags_stub.cpp
|
||||||
features/netsocket/TCPServer/test_TCPServer.cpp
|
features/netsocket/TCPServer/test_TCPServer.cpp
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -26,4 +26,5 @@ set(unittest-test-sources
|
||||||
stubs/EventFlags_stub.cpp
|
stubs/EventFlags_stub.cpp
|
||||||
stubs/stoip4_stub.c
|
stubs/stoip4_stub.c
|
||||||
stubs/ip4tos_stub.c
|
stubs/ip4tos_stub.c
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,6 +29,7 @@ set(unittest-test-sources
|
||||||
stubs/EventFlags_stub.cpp
|
stubs/EventFlags_stub.cpp
|
||||||
stubs/stoip4_stub.c
|
stubs/stoip4_stub.c
|
||||||
stubs/ip4tos_stub.c
|
stubs/ip4tos_stub.c
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/TLSSocket/tls_test_config.h\"")
|
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/TLSSocket/tls_test_config.h\"")
|
||||||
|
|
|
@ -28,6 +28,7 @@ set(unittest-test-sources
|
||||||
stubs/EventFlags_stub.cpp
|
stubs/EventFlags_stub.cpp
|
||||||
stubs/stoip4_stub.c
|
stubs/stoip4_stub.c
|
||||||
stubs/ip4tos_stub.c
|
stubs/ip4tos_stub.c
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/TLSSocketWrapper/tls_test_config.h\"")
|
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/TLSSocketWrapper/tls_test_config.h\"")
|
||||||
|
|
|
@ -26,4 +26,5 @@ set(unittest-test-sources
|
||||||
stubs/nsapi_dns_stub.cpp
|
stubs/nsapi_dns_stub.cpp
|
||||||
stubs/stoip4_stub.c
|
stubs/stoip4_stub.c
|
||||||
stubs/ip4tos_stub.c
|
stubs/ip4tos_stub.c
|
||||||
|
stubs/SocketStats_Stub.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* Copyright (c) 2018 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 "SocketStats.h"
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
int SocketStats::get_entry_position(const Socket *const reference_id)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size_t SocketStats::mbed_stats_socket_get_each(mbed_stats_socket_t *stats, size_t count)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketStats::SocketStats()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_new_socket_entry(const Socket *const reference_id)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_socket_state(const Socket *const reference_id, socket_state state)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_peer(const Socket *const reference_id, const SocketAddress &peer)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_proto(const Socket *const reference_id, nsapi_protocol_t proto)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_sent_bytes(const Socket *const reference_id, size_t sent_bytes)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_recv_bytes(const Socket *const reference_id, size_t recv_bytes)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
|
@ -450,7 +450,7 @@ private:
|
||||||
* @param func Callback to be called
|
* @param func Callback to be called
|
||||||
* @return 0 on success, negative error code on failure
|
* @return 0 on success, negative error code on failure
|
||||||
*/
|
*/
|
||||||
nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
|
virtual nsapi_error_t call_in(int delay, mbed::Callback<void()> func);
|
||||||
|
|
||||||
struct mbed_lwip_socket {
|
struct mbed_lwip_socket {
|
||||||
bool in_use;
|
bool in_use;
|
||||||
|
|
|
@ -24,6 +24,7 @@ InternetSocket::InternetSocket()
|
||||||
_readers(0), _writers(0), _pending(0),
|
_readers(0), _writers(0), _pending(0),
|
||||||
_factory_allocated(false)
|
_factory_allocated(false)
|
||||||
{
|
{
|
||||||
|
_socket_stats.stats_new_socket_entry(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
InternetSocket::~InternetSocket()
|
InternetSocket::~InternetSocket()
|
||||||
|
@ -48,6 +49,7 @@ nsapi_error_t InternetSocket::open(NetworkStack *stack)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
|
||||||
_socket = socket;
|
_socket = socket;
|
||||||
_event = callback(this, &InternetSocket::event);
|
_event = callback(this, &InternetSocket::event);
|
||||||
_stack->socket_attach(_socket, Callback<void()>::thunk, &_event);
|
_stack->socket_attach(_socket, Callback<void()>::thunk, &_event);
|
||||||
|
@ -72,7 +74,7 @@ nsapi_error_t InternetSocket::close()
|
||||||
_socket = 0;
|
_socket = 0;
|
||||||
ret = _stack->socket_close(socket);
|
ret = _stack->socket_close(socket);
|
||||||
_stack = 0; // Invalidate the stack pointer - otherwise open() fails.
|
_stack = 0; // Invalidate the stack pointer - otherwise open() fails.
|
||||||
|
_socket_stats.stats_update_socket_state(this, SOCK_CLOSED);
|
||||||
// Wakeup anything in a blocking operation
|
// Wakeup anything in a blocking operation
|
||||||
// on this socket
|
// on this socket
|
||||||
event();
|
event();
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "rtos/EventFlags.h"
|
#include "rtos/EventFlags.h"
|
||||||
#include "Callback.h"
|
#include "Callback.h"
|
||||||
#include "mbed_toolchain.h"
|
#include "mbed_toolchain.h"
|
||||||
|
#include "SocketStats.h"
|
||||||
|
|
||||||
/** Socket implementation that uses IP network stack.
|
/** Socket implementation that uses IP network stack.
|
||||||
* Not to be directly used by applications. Cannot be directly instantiated.
|
* Not to be directly used by applications. Cannot be directly instantiated.
|
||||||
|
@ -176,6 +177,7 @@ protected:
|
||||||
static const int FINISHED_FLAG = 0x3u;
|
static const int FINISHED_FLAG = 0x3u;
|
||||||
|
|
||||||
friend class DTLSSocket; // Allow DTLSSocket::connect() to do name resolution on the _stack
|
friend class DTLSSocket; // Allow DTLSSocket::connect() to do name resolution on the _stack
|
||||||
|
SocketStats _socket_stats;
|
||||||
|
|
||||||
#endif //!defined(DOXYGEN_ONLY)
|
#endif //!defined(DOXYGEN_ONLY)
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* Copyright (c) 2018 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 "SocketStats.h"
|
||||||
|
#include "platform/mbed_error.h"
|
||||||
|
#include "platform/mbed_assert.h"
|
||||||
|
#ifdef MBED_CONF_RTOS_PRESENT
|
||||||
|
#include "rtos/Kernel.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
SingletonPtr<PlatformMutex> SocketStats::_mutex;
|
||||||
|
mbed_stats_socket_t SocketStats::_stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT];
|
||||||
|
uint32_t SocketStats::_size = 0;
|
||||||
|
|
||||||
|
int SocketStats::get_entry_position(const Socket *const reference_id)
|
||||||
|
{
|
||||||
|
for (uint32_t j = 0; j < _size; j++) {
|
||||||
|
if (_stats[j].reference_id == reference_id) {
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
size_t SocketStats::mbed_stats_socket_get_each(mbed_stats_socket_t *stats, size_t count)
|
||||||
|
{
|
||||||
|
MBED_ASSERT(stats != NULL);
|
||||||
|
size_t i = 0;
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
memset(stats, 0, count * sizeof(mbed_stats_socket_t));
|
||||||
|
_mutex->lock();
|
||||||
|
for (uint32_t j = 0; j < count; j++) {
|
||||||
|
if (_stats[j].reference_id) {
|
||||||
|
memcpy(&stats[i], &_stats[j], sizeof(mbed_stats_socket_t));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_mutex->unlock();
|
||||||
|
#endif
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
SocketStats::SocketStats()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_new_socket_entry(const Socket *const reference_id)
|
||||||
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
_mutex->lock();
|
||||||
|
if (get_entry_position(reference_id) >= 0) {
|
||||||
|
// Duplicate entry
|
||||||
|
MBED_WARNING1(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STATS, MBED_ERROR_CODE_INVALID_INDEX), "Duplicate socket Reference ID ", reference_id);
|
||||||
|
} else if (_size < MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT) {
|
||||||
|
// Add new entry
|
||||||
|
_stats[_size].reference_id = (Socket *)reference_id;
|
||||||
|
_size++;
|
||||||
|
} else {
|
||||||
|
int position = -1;
|
||||||
|
uint64_t oldest_time = 0;
|
||||||
|
// Determine which entry in the list shall be over-written
|
||||||
|
for (uint32_t j = 0; j < MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT; j++) {
|
||||||
|
if (SOCK_CLOSED == _stats[j].state) {
|
||||||
|
if ((0 == oldest_time) || (oldest_time < _stats[j].last_change_tick)) {
|
||||||
|
oldest_time = _stats[j].last_change_tick;
|
||||||
|
position = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (-1 == position) {
|
||||||
|
MBED_ERROR(MBED_MAKE_ERROR(MBED_MODULE_NETWORK_STATS, MBED_ERROR_CODE_OUT_OF_RESOURCES), "List full with all open sockets");
|
||||||
|
}
|
||||||
|
memset(&_stats[position], 0, sizeof(mbed_stats_socket_t));
|
||||||
|
_stats[position].reference_id = (Socket *)reference_id;
|
||||||
|
}
|
||||||
|
_mutex->unlock();
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_socket_state(const Socket *const reference_id, socket_state state)
|
||||||
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
_mutex->lock();
|
||||||
|
int position = get_entry_position(reference_id);
|
||||||
|
if (position >= 0) {
|
||||||
|
_stats[position].state = state;
|
||||||
|
#ifdef MBED_CONF_RTOS_PRESENT
|
||||||
|
_stats[position].last_change_tick = rtos::Kernel::get_ms_count();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
_mutex->unlock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_peer(const Socket *const reference_id, const SocketAddress &peer)
|
||||||
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
_mutex->lock();
|
||||||
|
int position = get_entry_position(reference_id);
|
||||||
|
if ((position >= 0) && (!_stats[position].peer)) {
|
||||||
|
_stats[position].peer = peer;
|
||||||
|
}
|
||||||
|
_mutex->unlock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_proto(const Socket *const reference_id, nsapi_protocol_t proto)
|
||||||
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
_mutex->lock();
|
||||||
|
int position = get_entry_position(reference_id);
|
||||||
|
if (position >= 0) {
|
||||||
|
_stats[position].proto = proto;
|
||||||
|
}
|
||||||
|
_mutex->unlock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_sent_bytes(const Socket *const reference_id, size_t sent_bytes)
|
||||||
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
_mutex->lock();
|
||||||
|
int position = get_entry_position(reference_id);
|
||||||
|
if ((position >= 0) && ((int32_t)sent_bytes > 0)) {
|
||||||
|
_stats[position].sent_bytes += sent_bytes;
|
||||||
|
}
|
||||||
|
_mutex->unlock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketStats::stats_update_recv_bytes(const Socket *const reference_id, size_t recv_bytes)
|
||||||
|
{
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
_mutex->lock();
|
||||||
|
int position = get_entry_position(reference_id);
|
||||||
|
if ((position >= 0) && ((int32_t)recv_bytes > 0)) {
|
||||||
|
_stats[position].recv_bytes += recv_bytes;
|
||||||
|
}
|
||||||
|
_mutex->unlock();
|
||||||
|
#endif
|
||||||
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* Copyright (c) 2018 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SOCKET_STATS_H
|
||||||
|
#define SOCKET_STATS_H
|
||||||
|
|
||||||
|
#include "platform/SingletonPtr.h"
|
||||||
|
#include "platform/PlatformMutex.h"
|
||||||
|
#include "netsocket/Socket.h"
|
||||||
|
#include "SocketAddress.h"
|
||||||
|
#include "hal/ticker_api.h"
|
||||||
|
|
||||||
|
#ifndef MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT
|
||||||
|
#define MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT 10
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Enum of socket states
|
||||||
|
*
|
||||||
|
* Can be used to specify current state of socket - open, closed, connected or listen.
|
||||||
|
*
|
||||||
|
* @enum socket_state
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
SOCK_CLOSED, /**< Socket is closed and does not exist anymore in the system */
|
||||||
|
SOCK_OPEN, /**< Socket is open but not associated to any peer address */
|
||||||
|
SOCK_CONNECTED, /**< Socket is associated to peer address, either by connect() or sendto()/recvfrom() calls */
|
||||||
|
SOCK_LISTEN, /**< Socket is listening for incoming connections */
|
||||||
|
} socket_state;
|
||||||
|
|
||||||
|
/** Structure to parse socket statistics
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
Socket *reference_id; /**< Used for identifying socket */
|
||||||
|
SocketAddress peer; /**< Last associated peername of this socket (Destination address) */
|
||||||
|
socket_state state; /**< State of this socket */
|
||||||
|
nsapi_protocol_t proto; /**< Specifies a protocol used with socket */
|
||||||
|
size_t sent_bytes; /**< Data sent through this socket */
|
||||||
|
size_t recv_bytes; /**< Data received through this socket */
|
||||||
|
us_timestamp_t last_change_tick;/**< osKernelGetTick() when state last changed */
|
||||||
|
} mbed_stats_socket_t;
|
||||||
|
|
||||||
|
/** SocketStats class
|
||||||
|
*
|
||||||
|
* Class to get the network socket statistics
|
||||||
|
*/
|
||||||
|
class SocketStats {
|
||||||
|
public:
|
||||||
|
|
||||||
|
#if !defined(DOXYGEN_ONLY)
|
||||||
|
/** Create an socket statictics object
|
||||||
|
*
|
||||||
|
* Application users must not create class objects.
|
||||||
|
* Entities reporting network statistics create the class object.
|
||||||
|
* Application can fetch network statistics using static `mbed_stats_socket_get_each` API
|
||||||
|
* without creating an object.
|
||||||
|
*/
|
||||||
|
SocketStats();
|
||||||
|
virtual ~SocketStats()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/**
|
||||||
|
* Fill the passed array of structures with the socket statistics for each created socket.
|
||||||
|
*
|
||||||
|
* @param stats A pointer to an array of mbed_stats_socket_t structures to fill
|
||||||
|
* @param count The number of mbed_stats_socket_t structures in the provided array
|
||||||
|
* @return The number of mbed_stats_socket_t structures that have been filled.
|
||||||
|
* If the number of sockets on the system is less than or equal to count,
|
||||||
|
* it will equal the number of sockets created (active or closed).
|
||||||
|
* If the number of sockets on the system is greater than count,
|
||||||
|
* it will equal count.
|
||||||
|
*/
|
||||||
|
static size_t mbed_stats_socket_get_each(mbed_stats_socket_t *stats, size_t count);
|
||||||
|
|
||||||
|
#if !defined(DOXYGEN_ONLY)
|
||||||
|
/** Add entry of newly created socket in statistics array.
|
||||||
|
* API used by socket (TCP or UDP) layers only, not to be used by application.
|
||||||
|
*
|
||||||
|
* @param reference_id ID to identify socket in data array.
|
||||||
|
*
|
||||||
|
* @Note: The entry in the array is maintained even after the socket is closed.
|
||||||
|
* The entry is overwritten for sockets that were closed first, in case
|
||||||
|
* the socket creation count exceeds `MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT`.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void stats_new_socket_entry(const Socket *const reference_id);
|
||||||
|
|
||||||
|
/** Updates the state of the socket and records `tick_last_change`.
|
||||||
|
* API used by socket (TCP or UDP) layers only, not to be used by application.
|
||||||
|
*
|
||||||
|
* @param reference_id ID to identify socket in data array.
|
||||||
|
* @param state Parameter to update the current state of the socket.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void stats_update_socket_state(const Socket *const reference_id, socket_state state);
|
||||||
|
|
||||||
|
/** Update the peer information of the socket.
|
||||||
|
* API used by socket (TCP or UDP) layers only, not to be used by application.
|
||||||
|
*
|
||||||
|
* @param reference_id ID to identify socket in data array.
|
||||||
|
* @param peer Parameter to update destination peer information.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void stats_update_peer(const Socket *const reference_id, const SocketAddress &peer);
|
||||||
|
|
||||||
|
/** Update socket protocol.
|
||||||
|
* API used by socket (TCP or UDP) layers only, not to be used by application.
|
||||||
|
*
|
||||||
|
* @param reference_id ID to identify socket in data array.
|
||||||
|
* @param proto Parameter to update the protocol type of socket.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void stats_update_proto(const Socket *const reference_id, nsapi_protocol_t proto);
|
||||||
|
|
||||||
|
/** Update bytes sent on socket, which is cumulative count per socket.
|
||||||
|
* API used by socket (TCP or UDP) layers only, not to be used by application.
|
||||||
|
*
|
||||||
|
* @param reference_id ID to identify socket in data array.
|
||||||
|
* @param sent_bytes Parameter to append bytes sent over the socket.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void stats_update_sent_bytes(const Socket *const reference_id, size_t sent_bytes);
|
||||||
|
|
||||||
|
/** Update bytes received on socket, which is cumulative count per socket
|
||||||
|
* API used by socket (TCP or UDP) layers only, not to be used by application.
|
||||||
|
*
|
||||||
|
* @param reference_id ID to identify socket in data array.
|
||||||
|
* @param recv_bytes Parameter to append bytes the socket receives.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void stats_update_recv_bytes(const Socket *const reference_id, size_t recv_bytes);
|
||||||
|
|
||||||
|
#if MBED_CONF_NSAPI_SOCKET_STATS_ENABLE
|
||||||
|
private:
|
||||||
|
static mbed_stats_socket_t _stats[MBED_CONF_NSAPI_SOCKET_STATS_MAX_COUNT];
|
||||||
|
static SingletonPtr<PlatformMutex> _mutex;
|
||||||
|
static uint32_t _size;
|
||||||
|
|
||||||
|
/** Internal function to scan the array and get the position of the element in the list.
|
||||||
|
*
|
||||||
|
* @param reference_id ID to identify the socket in the data array.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
int get_entry_position(const Socket *const reference_id);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -20,6 +20,7 @@ using mbed::Callback;
|
||||||
|
|
||||||
TCPServer::TCPServer()
|
TCPServer::TCPServer()
|
||||||
{
|
{
|
||||||
|
_socket_stats.stats_update_proto(this, NSAPI_TCP);
|
||||||
}
|
}
|
||||||
|
|
||||||
TCPServer::~TCPServer()
|
TCPServer::~TCPServer()
|
||||||
|
@ -52,7 +53,8 @@ nsapi_error_t TCPServer::accept(TCPSocket *connection, SocketAddress *address)
|
||||||
connection->_socket = socket;
|
connection->_socket = socket;
|
||||||
connection->_event = Callback<void()>(connection, &TCPSocket::event);
|
connection->_event = Callback<void()>(connection, &TCPSocket::event);
|
||||||
_stack->socket_attach(socket, &Callback<void()>::thunk, &connection->_event);
|
_stack->socket_attach(socket, &Callback<void()>::thunk, &connection->_event);
|
||||||
|
_socket_stats.stats_update_peer(connection, *address);
|
||||||
|
_socket_stats.stats_update_socket_state(connection, SOCK_CONNECTED);
|
||||||
connection->_lock.unlock();
|
connection->_lock.unlock();
|
||||||
break;
|
break;
|
||||||
} else if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
|
} else if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
TCPSocket::TCPSocket()
|
TCPSocket::TCPSocket()
|
||||||
{
|
{
|
||||||
|
_socket_stats.stats_update_proto(this, NSAPI_TCP);
|
||||||
}
|
}
|
||||||
|
|
||||||
TCPSocket::TCPSocket(TCPSocket *parent, nsapi_socket_t socket, SocketAddress address)
|
TCPSocket::TCPSocket(TCPSocket *parent, nsapi_socket_t socket, SocketAddress address)
|
||||||
|
@ -28,7 +29,7 @@ TCPSocket::TCPSocket(TCPSocket *parent, nsapi_socket_t socket, SocketAddress add
|
||||||
_stack = parent->_stack;
|
_stack = parent->_stack;
|
||||||
_factory_allocated = true;
|
_factory_allocated = true;
|
||||||
_remote_peer = address;
|
_remote_peer = address;
|
||||||
|
_socket_stats.stats_new_socket_entry(this);
|
||||||
_event = mbed::Callback<void()>(this, &TCPSocket::event);
|
_event = mbed::Callback<void()>(this, &TCPSocket::event);
|
||||||
_stack->socket_attach(socket, &mbed::Callback<void()>::thunk, &_event);
|
_stack->socket_attach(socket, &mbed::Callback<void()>::thunk, &_event);
|
||||||
}
|
}
|
||||||
|
@ -64,6 +65,7 @@ nsapi_error_t TCPSocket::connect(const SocketAddress &address)
|
||||||
_pending = 0;
|
_pending = 0;
|
||||||
ret = _stack->socket_connect(_socket, address);
|
ret = _stack->socket_connect(_socket, address);
|
||||||
if ((_timeout == 0) || !(ret == NSAPI_ERROR_IN_PROGRESS || ret == NSAPI_ERROR_ALREADY)) {
|
if ((_timeout == 0) || !(ret == NSAPI_ERROR_IN_PROGRESS || ret == NSAPI_ERROR_ALREADY)) {
|
||||||
|
_socket_stats.stats_update_socket_state(this, SOCK_CONNECTED);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
blocking_connect_in_progress = true;
|
blocking_connect_in_progress = true;
|
||||||
|
@ -89,11 +91,13 @@ nsapi_error_t TCPSocket::connect(const SocketAddress &address)
|
||||||
|
|
||||||
/* Non-blocking connect gives "EISCONN" once done - convert to OK for blocking mode if we became connected during this call */
|
/* Non-blocking connect gives "EISCONN" once done - convert to OK for blocking mode if we became connected during this call */
|
||||||
if (ret == NSAPI_ERROR_IS_CONNECTED && blocking_connect_in_progress) {
|
if (ret == NSAPI_ERROR_IS_CONNECTED && blocking_connect_in_progress) {
|
||||||
|
_socket_stats.stats_update_socket_state(this, SOCK_CONNECTED);
|
||||||
ret = NSAPI_ERROR_OK;
|
ret = NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == NSAPI_ERROR_OK || ret == NSAPI_ERROR_IN_PROGRESS) {
|
if (ret == NSAPI_ERROR_OK || ret == NSAPI_ERROR_IN_PROGRESS) {
|
||||||
_remote_peer = address;
|
_remote_peer = address;
|
||||||
|
_socket_stats.stats_update_peer(this, _remote_peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
_lock.unlock();
|
_lock.unlock();
|
||||||
|
@ -178,6 +182,7 @@ nsapi_size_or_error_t TCPSocket::send(const void *data, nsapi_size_t size)
|
||||||
} else if (written == 0) {
|
} else if (written == 0) {
|
||||||
return NSAPI_ERROR_WOULD_BLOCK;
|
return NSAPI_ERROR_WOULD_BLOCK;
|
||||||
} else {
|
} else {
|
||||||
|
_socket_stats.stats_update_sent_bytes(this, written);
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,6 +213,7 @@ nsapi_size_or_error_t TCPSocket::recv(void *data, nsapi_size_t size)
|
||||||
_pending = 0;
|
_pending = 0;
|
||||||
ret = _stack->socket_recv(_socket, data, size);
|
ret = _stack->socket_recv(_socket, data, size);
|
||||||
if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
|
if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
|
||||||
|
_socket_stats.stats_update_recv_bytes(this, ret);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
uint32_t flag;
|
uint32_t flag;
|
||||||
|
@ -252,6 +258,9 @@ nsapi_error_t TCPSocket::listen(int backlog)
|
||||||
ret = NSAPI_ERROR_NO_SOCKET;
|
ret = NSAPI_ERROR_NO_SOCKET;
|
||||||
} else {
|
} else {
|
||||||
ret = _stack->socket_listen(_socket, backlog);
|
ret = _stack->socket_listen(_socket, backlog);
|
||||||
|
if (NSAPI_ERROR_OK == ret) {
|
||||||
|
_socket_stats.stats_update_socket_state(this, SOCK_LISTEN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_lock.unlock();
|
_lock.unlock();
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
|
|
||||||
UDPSocket::UDPSocket()
|
UDPSocket::UDPSocket()
|
||||||
{
|
{
|
||||||
|
_socket_stats.stats_update_proto(this, NSAPI_UDP);
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPSocket::~UDPSocket()
|
UDPSocket::~UDPSocket()
|
||||||
|
@ -34,6 +35,8 @@ nsapi_protocol_t UDPSocket::get_proto()
|
||||||
nsapi_error_t UDPSocket::connect(const SocketAddress &address)
|
nsapi_error_t UDPSocket::connect(const SocketAddress &address)
|
||||||
{
|
{
|
||||||
_remote_peer = address;
|
_remote_peer = address;
|
||||||
|
_socket_stats.stats_update_peer(this, _remote_peer);
|
||||||
|
_socket_stats.stats_update_socket_state(this, SOCK_CONNECTED);
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +60,10 @@ nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void
|
||||||
nsapi_size_or_error_t ret;
|
nsapi_size_or_error_t ret;
|
||||||
|
|
||||||
_writers++;
|
_writers++;
|
||||||
|
if (_socket) {
|
||||||
|
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
|
||||||
|
_socket_stats.stats_update_peer(this, address);
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!_socket) {
|
if (!_socket) {
|
||||||
ret = NSAPI_ERROR_NO_SOCKET;
|
ret = NSAPI_ERROR_NO_SOCKET;
|
||||||
|
@ -67,6 +73,7 @@ nsapi_size_or_error_t UDPSocket::sendto(const SocketAddress &address, const void
|
||||||
_pending = 0;
|
_pending = 0;
|
||||||
nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size);
|
nsapi_size_or_error_t sent = _stack->socket_sendto(_socket, address, data, size);
|
||||||
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) {
|
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) {
|
||||||
|
_socket_stats.stats_update_sent_bytes(this, sent);
|
||||||
ret = sent;
|
ret = sent;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -114,6 +121,9 @@ nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer,
|
||||||
|
|
||||||
_readers++;
|
_readers++;
|
||||||
|
|
||||||
|
if (_socket) {
|
||||||
|
_socket_stats.stats_update_socket_state(this, SOCK_OPEN);
|
||||||
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
if (!_socket) {
|
if (!_socket) {
|
||||||
ret = NSAPI_ERROR_NO_SOCKET;
|
ret = NSAPI_ERROR_NO_SOCKET;
|
||||||
|
@ -128,9 +138,11 @@ nsapi_size_or_error_t UDPSocket::recvfrom(SocketAddress *address, void *buffer,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_socket_stats.stats_update_peer(this, _remote_peer);
|
||||||
// Non-blocking sockets always return. Blocking only returns when success or errors other than WOULD_BLOCK
|
// Non-blocking sockets always return. Blocking only returns when success or errors other than WOULD_BLOCK
|
||||||
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) {
|
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) {
|
||||||
ret = recv;
|
ret = recv;
|
||||||
|
_socket_stats.stats_update_recv_bytes(this, recv);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
uint32_t flag;
|
uint32_t flag;
|
||||||
|
|
|
@ -30,6 +30,14 @@
|
||||||
"dns-cache-size": {
|
"dns-cache-size": {
|
||||||
"help": "Number of cached host name resolutions",
|
"help": "Number of cached host name resolutions",
|
||||||
"value": 3
|
"value": 3
|
||||||
|
},
|
||||||
|
"socket-stats-enable": {
|
||||||
|
"help": "Enable network socket statistics",
|
||||||
|
"value": false
|
||||||
|
},
|
||||||
|
"socket-stats-max-count": {
|
||||||
|
"help": "Maximum number of socket statistics cached",
|
||||||
|
"value": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"target_overrides": {
|
"target_overrides": {
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#ifndef SINGLETONPTR_H
|
#ifndef SINGLETONPTR_H
|
||||||
#define SINGLETONPTR_H
|
#define SINGLETONPTR_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
#include "platform/mbed_assert.h"
|
#include "platform/mbed_assert.h"
|
||||||
|
|
|
@ -254,6 +254,7 @@ typedef enum _mbed_error_type_t {
|
||||||
MBED_MODULE_DRIVER_USB 21 USB Driver
|
MBED_MODULE_DRIVER_USB 21 USB Driver
|
||||||
MBED_MODULE_TARGET_SDK 22 SDK
|
MBED_MODULE_TARGET_SDK 22 SDK
|
||||||
MBED_MODULE_BLE 23 BLE
|
MBED_MODULE_BLE 23 BLE
|
||||||
|
MBED_MODULE_NETWORK_STATS 24 Network Statistics
|
||||||
|
|
||||||
MBED_MODULE_UNKNOWN 255 Unknown module
|
MBED_MODULE_UNKNOWN 255 Unknown module
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
@ -284,6 +285,7 @@ typedef enum _mbed_module_type {
|
||||||
MBED_MODULE_DRIVER_USB,
|
MBED_MODULE_DRIVER_USB,
|
||||||
MBED_MODULE_TARGET_SDK,
|
MBED_MODULE_TARGET_SDK,
|
||||||
MBED_MODULE_BLE,
|
MBED_MODULE_BLE,
|
||||||
|
MBED_MODULE_NETWORK_STATS,
|
||||||
/* Add More entities here as required */
|
/* Add More entities here as required */
|
||||||
|
|
||||||
MBED_MODULE_UNKNOWN = 255,
|
MBED_MODULE_UNKNOWN = 255,
|
||||||
|
|
|
@ -1,33 +1,41 @@
|
||||||
{
|
{
|
||||||
"UBLOX_EVK_ODIN_W2": {
|
"UBLOX_EVK_ODIN_W2": {
|
||||||
|
"nsapi.socket-stats-enable": true,
|
||||||
"default_test_configuration": "NONE",
|
"default_test_configuration": "NONE",
|
||||||
"test_configurations": ["HEAPBLOCKDEVICE_AND_WIFI", "HEAPBLOCKDEVICE_AND_ETHERNET"]
|
"test_configurations": ["HEAPBLOCKDEVICE_AND_WIFI", "HEAPBLOCKDEVICE_AND_ETHERNET"]
|
||||||
},
|
},
|
||||||
"REALTEK_RTL8195AM": {
|
"REALTEK_RTL8195AM": {
|
||||||
|
"nsapi.socket-stats-enable": true,
|
||||||
"default_test_configuration": "NONE",
|
"default_test_configuration": "NONE",
|
||||||
"test_configurations": ["HEAPBLOCKDEVICE_AND_WIFI"]
|
"test_configurations": ["HEAPBLOCKDEVICE_AND_WIFI"]
|
||||||
},
|
},
|
||||||
"K64F": {
|
"K64F": {
|
||||||
|
"nsapi.socket-stats-enable": true,
|
||||||
"default_test_configuration": "HEAPBLOCKDEVICE_AND_ETHERNET",
|
"default_test_configuration": "HEAPBLOCKDEVICE_AND_ETHERNET",
|
||||||
"test_configurations": ["HEAPBLOCKDEVICE_AND_ETHERNET", "NANOSTACK_MAC_TESTER", "ESP8266_WIFI", "ETHERNET"]
|
"test_configurations": ["HEAPBLOCKDEVICE_AND_ETHERNET", "NANOSTACK_MAC_TESTER", "ESP8266_WIFI", "ETHERNET"]
|
||||||
},
|
},
|
||||||
"NUCLEO_F429ZI": {
|
"NUCLEO_F429ZI": {
|
||||||
|
"nsapi.socket-stats-enable": true,
|
||||||
"default_test_configuration": "HEAPBLOCKDEVICE_AND_ETHERNET",
|
"default_test_configuration": "HEAPBLOCKDEVICE_AND_ETHERNET",
|
||||||
"test_configurations": ["HEAPBLOCKDEVICE_AND_ETHERNET", "NANOSTACK_MAC_TESTER"]
|
"test_configurations": ["HEAPBLOCKDEVICE_AND_ETHERNET", "NANOSTACK_MAC_TESTER"]
|
||||||
},
|
},
|
||||||
"DISCO_L475VG_IOT01A": {
|
"DISCO_L475VG_IOT01A": {
|
||||||
|
"nsapi.socket-stats-enable": true,
|
||||||
"default_test_configuration": "NONE",
|
"default_test_configuration": "NONE",
|
||||||
"test_configurations": ["ISM43362_WIFI"]
|
"test_configurations": ["ISM43362_WIFI"]
|
||||||
},
|
},
|
||||||
"DISCO_F413ZH": {
|
"DISCO_F413ZH": {
|
||||||
|
"nsapi.socket-stats-enable": true,
|
||||||
"default_test_configuration": "NONE",
|
"default_test_configuration": "NONE",
|
||||||
"test_configurations": ["ISM43362_WIFI"]
|
"test_configurations": ["ISM43362_WIFI"]
|
||||||
},
|
},
|
||||||
"MTB_UBLOX_ODIN_W2": {
|
"MTB_UBLOX_ODIN_W2": {
|
||||||
|
"nsapi.socket-stats-enable": true,
|
||||||
"default_test_configuration": "NONE",
|
"default_test_configuration": "NONE",
|
||||||
"test_configurations": ["HEAPBLOCKDEVICE_AND_WIFI"]
|
"test_configurations": ["HEAPBLOCKDEVICE_AND_WIFI"]
|
||||||
},
|
},
|
||||||
"MTB_ADV_WISE_1530": {
|
"MTB_ADV_WISE_1530": {
|
||||||
|
"nsapi.socket-stats-enable": true,
|
||||||
"default_test_configuration": "NONE",
|
"default_test_configuration": "NONE",
|
||||||
"test_configurations": ["HEAPBLOCKDEVICE_AND_WIFI"]
|
"test_configurations": ["HEAPBLOCKDEVICE_AND_WIFI"]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue