Merge pull request #8838 from 0xc0170/dev_rollup

Rollup v2 for 5.11rc1
pull/8863/head
Martin Kojtal 2018-11-24 21:37:02 +01:00 committed by GitHub
commit b16569dc3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 2100 additions and 287 deletions

View File

@ -141,7 +141,7 @@ matrix:
after_success:
# run astyle for all files on the branch
- git checkout -- .
- find -regex '.*\.\(h\|c\|hpp\|cpp\)' -type f | fgrep -v -f .astyleignore | xargs -n 100 -I {} bash -c "astyle -n --options=.astylerc \"{}\"" > astyle-branch.out;
- find -regex '.*\.\(h\|c\|hpp\|cpp\)$' -type f | fgrep -v -f .astyleignore | xargs -n 100 -I {} bash -c "astyle -n --options=.astylerc \"{}\"" > astyle-branch.out;
# update status if we succeeded, compare with master if possible
- |
CURR=$(cat astyle-branch.out | grep Formatted | wc -l)

View File

@ -45,7 +45,7 @@ void ASYNCHRONOUS_DNS_NON_ASYNC_AND_ASYNC()
TEST_ASSERT(strlen(addr.get_ip_address()) > 1);
}
semaphore.wait();
semaphore.wait(100);
TEST_ASSERT(data.result == NSAPI_ERROR_OK);

View File

@ -30,7 +30,7 @@ nsapi_error_t tcpsocket_connect_to_discard_srv(TCPSocket &sock);
int split2half_rmng_tcp_test_time(); // [s]
namespace tcp_global {
static const int TESTS_TIMEOUT = 960;
static const int TESTS_TIMEOUT = 480;
static const int TCP_OS_STACK_SIZE = 2048;
static const int RX_BUFF_SIZE = 1220;

View File

@ -66,8 +66,8 @@ void TCPSOCKET_RECV_TIMEOUT()
TEST_FAIL();
goto CLEANUP;
}
printf("MBED: recv() took: %dms\n", timer.read_ms());
TEST_ASSERT_INT_WITHIN(50, 150, timer.read_ms());
printf("MBED: recv() took: %dus\n", timer.read_us());
TEST_ASSERT_INT_WITHIN(51, 150, (timer.read_us() + 500) / 1000);
continue;
} else if (recvd < 0) {
printf("[pkt#%02d] network error %d\n", i, recvd);

View File

@ -89,7 +89,8 @@ void NETWORKINTERFACE_STATUS()
}
TEST_ASSERT_EQUAL(NSAPI_STATUS_GLOBAL_UP, status);
net->disconnect();
err = net->disconnect();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
status = wait_status_callback();
TEST_ASSERT_EQUAL(NSAPI_STATUS_DISCONNECTED, status);
@ -123,7 +124,8 @@ void NETWORKINTERFACE_STATUS_NONBLOCK()
}
TEST_ASSERT_EQUAL(NSAPI_STATUS_GLOBAL_UP, status);
net->disconnect();
err = net->disconnect();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
status = wait_status_callback();
TEST_ASSERT_EQUAL(NSAPI_STATUS_DISCONNECTED, status);
@ -150,7 +152,8 @@ void NETWORKINTERFACE_STATUS_GET()
wait(0.5);
}
net->disconnect();
err = net->disconnect();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
TEST_ASSERT_EQUAL(NSAPI_STATUS_DISCONNECTED, net->get_connection_status());
}

View File

@ -30,7 +30,7 @@ void wifi_connect_params_null(void)
error = wifi->connect(NULL, NULL);
wifi->disconnect();
TEST_ASSERT(error == NSAPI_ERROR_PARAMETER);
error = wifi->connect("", "");
error = wifi->connect("", "");
wifi->disconnect();
TEST_ASSERT(error == NSAPI_ERROR_PARAMETER);
}

View File

@ -32,7 +32,7 @@ void wifi_connect_secure(void)
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->set_credentials(MBED_CONF_APP_WIFI_SECURE_SSID, MBED_CONF_APP_WIFI_PASSWORD, get_security()));
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->connect());
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->disconnect());
}

View File

@ -185,12 +185,12 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_registration_params)
reg_params._periodic_tau = 3;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_params(CellularNetwork::C_EREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::StatusNotAvailable);
EXPECT_TRUE(reg_params._status == CellularNetwork::NotRegistered);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params._cell_id == -1 && reg_params._active_time == -1 && reg_params._periodic_tau == -1);
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_params(CellularNetwork::C_GREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::StatusNotAvailable);
EXPECT_TRUE(reg_params._status == CellularNetwork::NotRegistered);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params._cell_id == -1);
@ -201,12 +201,12 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_registration_params)
reg_params._periodic_tau = 3;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == nw.get_registration_params(CellularNetwork::C_EREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::StatusNotAvailable);
EXPECT_TRUE(reg_params._status == CellularNetwork::NotRegistered);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params._cell_id == -1 && reg_params._active_time == -1 && reg_params._periodic_tau == -1);
// Check get_registration_params without specifying the registration type
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_params(reg_params_check));
EXPECT_TRUE(reg_params_check._status == CellularNetwork::StatusNotAvailable);
EXPECT_TRUE(reg_params_check._status == CellularNetwork::NotRegistered);
EXPECT_TRUE(reg_params_check._act == CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params_check._cell_id == -1 && reg_params_check._active_time == -1 && reg_params_check._periodic_tau == -1);
}
@ -497,7 +497,7 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_signal_quality)
ATHandler_stub::int_value = 1;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_signal_quality(rs, ber));
EXPECT_TRUE(rs == 1 && ber == 1);
EXPECT_TRUE(rs == -111 && ber == 1);
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_3gpp_error)

View File

@ -0,0 +1,24 @@
/*
* 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.
*/
#ifndef UNITTESTS_FEATURES_NETSOCKET_DTLSSOCKET_DTLS_TEST_CONFIG_H_
#define UNITTESTS_FEATURES_NETSOCKET_DTLSSOCKET_DTLS_TEST_CONFIG_H_
#define MBEDTLS_SSL_CLI_C
#endif /* UNITTESTS_FEATURES_NETSOCKET_DTLSSOCKET_DTLS_TEST_CONFIG_H_ */

View File

@ -0,0 +1,73 @@
/*
* 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/DTLSSocket.h"
#include "NetworkStack_stub.h"
#include "mbed_error.h"
mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
{
return 0;
}
// Control the rtos EventFlags stub. See EventFlags_stub.cpp
extern std::list<uint32_t> eventFlagsStubNextRetval;
class TestDTLSSocket : public testing::Test {
public:
unsigned int dataSize = 10;
char dataBuf[10];
protected:
DTLSSocket *socket;
NetworkStackstub stack;
virtual void SetUp()
{
socket = new DTLSSocket();
}
virtual void TearDown()
{
stack.return_values.clear();
eventFlagsStubNextRetval.clear();
delete socket;
}
};
TEST_F(TestDTLSSocket, constructor)
{
EXPECT_TRUE(socket);
}
/* connect */
TEST_F(TestDTLSSocket, connect)
{
socket->open((NetworkStack *)&stack);
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(socket->connect("127.0.0.1", 1024), NSAPI_ERROR_OK);
}
TEST_F(TestDTLSSocket, connect_error)
{
socket->open((NetworkStack *)&stack);
stack.return_value = NSAPI_ERROR_DNS_FAILURE;
EXPECT_EQ(socket->connect("127.0.0.1", 1024), NSAPI_ERROR_DNS_FAILURE);
}

View File

@ -0,0 +1,40 @@
####################
# UNIT TESTS
####################
set(unittest-sources
../features/netsocket/SocketAddress.cpp
../features/netsocket/NetworkStack.cpp
../features/netsocket/InternetSocket.cpp
../features/netsocket/UDPSocket.cpp
../features/netsocket/DTLSSocket.cpp
../features/netsocket/DTLSSocketWrapper.cpp
../features/netsocket/TLSSocketWrapper.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
features/netsocket/DTLSSocket/test_DTLSSocket.cpp
stubs/Mutex_stub.cpp
stubs/mbed_assert_stub.c
stubs/equeue_stub.c
../features/nanostack/coap-service/test/coap-service/unittest/stub/mbedtls_stub.c
stubs/EventQueue_stub.cpp
stubs/mbed_shared_queues_stub.cpp
stubs/nsapi_dns_stub.cpp
stubs/EventFlags_stub.cpp
stubs/stoip4_stub.c
stubs/ip4tos_stub.c
stubs/Kernel_stub.cpp
)
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/DTLSSocket/dtls_test_config.h\"")
set_source_files_properties(features/netsocket/DTLSSocket/test_DTLSSocket.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})
set_source_files_properties(../features/netsocket/DTLSSocket.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})
set_source_files_properties(../features/netsocket/DTLSSocketWrapper.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})

View File

@ -0,0 +1,24 @@
/*
* 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.
*/
#ifndef UNITTESTS_FEATURES_NETSOCKET_DTLSSOCKETWRAPPER_TLS_TEST_CONFIG_H_
#define UNITTESTS_FEATURES_NETSOCKET_DTLSSOCKETWRAPPER_TLS_TEST_CONFIG_H_
#define MBEDTLS_SSL_CLI_C
#endif /* UNITTESTS_FEATURES_NETSOCKET_DTLSSOCKETWRAPPER_TLS_TEST_CONFIG_H_ */

View File

@ -0,0 +1,406 @@
/*
* 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/UDPSocket.h"
#include "features/netsocket/DTLSSocketWrapper.h"
#include "NetworkStack_stub.h"
#include "features/nanostack/coap-service/test/coap-service/unittest/stub/mbedtls_stub.h"
#include <cstring> //memset
#include "mbed_error.h"
mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
{
return 0;
}
// Control the rtos EventFlags stub. See EventFlags_stub.cpp
extern std::list<uint32_t> eventFlagsStubNextRetval;
class TestDTLSSocketWrapper : public testing::Test {
public:
unsigned int dataSize = 10;
char dataBuf[10];
protected:
UDPSocket *transport;
DTLSSocketWrapper *wrapper;
NetworkStackstub stack;
virtual void SetUp()
{
memset(mbedtls_stub.retArray, 0, sizeof(mbedtls_stub.retArray));
mbedtls_stub.useCounter = false;
mbedtls_stub.counter = 0;
mbedtls_stub.crt_expected_int = 0;
mbedtls_stub.expected_int = 0;
transport = new UDPSocket();
wrapper = new DTLSSocketWrapper(transport);
}
virtual void TearDown()
{
mbedtls_stub.useCounter = false;
stack.return_values.clear();
stack.return_socketAddress = SocketAddress();
eventFlagsStubNextRetval.clear();
delete wrapper;
}
char *cert = "-----BEGIN CERTIFICATE-----\
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\
-----END CERTIFICATE-----";
};
static bool callback_is_called;
static void my_callback()
{
callback_is_called = true;
}
TEST_F(TestDTLSSocketWrapper, constructor)
{
EXPECT_TRUE(wrapper);
}
TEST_F(TestDTLSSocketWrapper, constructor_hostname)
{
DTLSSocketWrapper *wrapper2 = new DTLSSocketWrapper(transport, "localhost");
}
/* connect */
TEST_F(TestDTLSSocketWrapper, connect)
{
transport->open((NetworkStack *)&stack);
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_IS_CONNECTED);
}
TEST_F(TestDTLSSocketWrapper, connect_no_open)
{
stack.return_value = NSAPI_ERROR_OK;
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK); //UDP doesn't mind.
}
/* connect: SSL-related errors */
TEST_F(TestDTLSSocketWrapper, connect_handshake_fail_ssl_handshake)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[1] = -1; // mbedtls_ssl_handshake error
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_AUTH_FAILURE);
}
TEST_F(TestDTLSSocketWrapper, connect_handshake_fail_ssl_handshake_in_progress)
{
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
mbedtls_stub.useCounter = true;
wrapper->set_timeout(1);
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
mbedtls_stub.retArray[1] = MBEDTLS_ERR_SSL_WANT_READ; // mbedtls_ssl_handshake error
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_IN_PROGRESS);
}
TEST_F(TestDTLSSocketWrapper, connect_handshake_fail_ssl_get_verify_result)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.uint32_value = 1; // mbedtls_ssl_get_verify_result error
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
}
TEST_F(TestDTLSSocketWrapper, connect_fail_ctr_drbg_seed)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.crt_expected_int = 1; // mbedtls_ctr_drbg_seed error
stack.return_value = NSAPI_ERROR_OK;
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_PARAMETER);
mbedtls_stub.crt_expected_int = 0;
}
TEST_F(TestDTLSSocketWrapper, connect_fail_ssl_setup)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[0] = 2; // mbedtls_ssl_setup error
stack.return_value = NSAPI_ERROR_OK;
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_PARAMETER);
}
/* send */
TEST_F(TestDTLSSocketWrapper, send_no_open)
{
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(wrapper->send(dataBuf, dataSize), NSAPI_ERROR_NO_CONNECTION);
}
TEST_F(TestDTLSSocketWrapper, send_in_one_chunk)
{
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[2] = dataSize; // mbedtls_ssl_write
transport->open((NetworkStack *)&stack);
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->send(dataBuf, dataSize), dataSize);
}
TEST_F(TestDTLSSocketWrapper, send_in_two_chunks)
{
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[2] = dataSize; // mbedtls_ssl_write
transport->open((NetworkStack *)&stack);
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->send(dataBuf, dataSize), dataSize);
}
TEST_F(TestDTLSSocketWrapper, send_error_would_block)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[2] = MBEDTLS_ERR_SSL_WANT_WRITE; // mbedtls_ssl_write
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->send(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
}
TEST_F(TestDTLSSocketWrapper, send_to)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[2] = dataSize; // mbedtls_ssl_write
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->sendto(a, dataBuf, dataSize), dataSize);
}
/* recv */
TEST_F(TestDTLSSocketWrapper, recv_no_open)
{
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(wrapper->recv(dataBuf, dataSize), NSAPI_ERROR_NO_CONNECTION);
}
TEST_F(TestDTLSSocketWrapper, recv_all_data)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[2] = dataSize; // mbedtls_ssl_write
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->recv(dataBuf, dataSize), dataSize);
}
TEST_F(TestDTLSSocketWrapper, recv_less_than_expected)
{
transport->open((NetworkStack *)&stack);
unsigned int lessThanDataSize = dataSize - 1;
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[2] = lessThanDataSize; // mbedtls_ssl_write
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->recv(dataBuf, dataSize), lessThanDataSize);
}
TEST_F(TestDTLSSocketWrapper, recv_would_block)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[2] = MBEDTLS_ERR_SSL_WANT_WRITE; // mbedtls_ssl_write
const SocketAddress a("127.0.0.1", 1024);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
EXPECT_EQ(wrapper->recv(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
}
TEST_F(TestDTLSSocketWrapper, recv_from_no_socket)
{
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->recvfrom(&a, dataBuf, dataSize), NSAPI_ERROR_NO_CONNECTION);
}
TEST_F(TestDTLSSocketWrapper, recv_from)
{
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
SocketAddress b;
EXPECT_EQ(wrapper->recvfrom(&b, dataBuf, dataSize), NSAPI_ERROR_OK);
}
TEST_F(TestDTLSSocketWrapper, recv_from_null)
{
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
stack.return_socketAddress = a;
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->recvfrom(NULL, dataBuf, dataSize), NSAPI_ERROR_OK);
}
/* set_root_ca_cert */
TEST_F(TestDTLSSocketWrapper, set_root_ca_cert)
{
EXPECT_EQ(wrapper->get_ca_chain(), static_cast<mbedtls_x509_crt *>(NULL));
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->set_root_ca_cert(cert, strlen(cert)), NSAPI_ERROR_OK);
EXPECT_NE(wrapper->get_ca_chain(), static_cast<mbedtls_x509_crt *>(NULL));
}
TEST_F(TestDTLSSocketWrapper, set_root_ca_cert_nolen)
{
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->set_root_ca_cert(cert), NSAPI_ERROR_OK);
}
TEST_F(TestDTLSSocketWrapper, set_root_ca_cert_invalid)
{
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
mbedtls_stub.useCounter = true;
mbedtls_stub.counter = 0;
mbedtls_stub.retArray[0] = 1; // mbedtls_x509_crt_parse error
EXPECT_EQ(wrapper->set_root_ca_cert(cert, strlen(cert)), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestDTLSSocketWrapper, set_client_cert_key)
{
EXPECT_EQ(wrapper->get_own_cert(), static_cast<mbedtls_x509_crt *>(NULL));
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->set_client_cert_key(cert, cert), NSAPI_ERROR_OK);
EXPECT_NE(wrapper->get_own_cert(), static_cast<mbedtls_x509_crt *>(NULL));
}
TEST_F(TestDTLSSocketWrapper, set_client_cert_key_invalid)
{
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[0] = 1; // mbedtls_x509_crt_parse error
EXPECT_EQ(wrapper->set_client_cert_key(cert, cert), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestDTLSSocketWrapper, set_client_cert_key_invalid_pem)
{
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[0] = 0; // mbedtls_x509_crt_parse ok
mbedtls_stub.retArray[1] = 1; // mbedtls_pk_parse_key error
EXPECT_EQ(wrapper->set_client_cert_key(cert, cert), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestDTLSSocketWrapper, bind)
{
transport->open((NetworkStack *)&stack);
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->bind(a), NSAPI_ERROR_OK);
}
TEST_F(TestDTLSSocketWrapper, bind_no_open)
{
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->bind(a), NSAPI_ERROR_NO_SOCKET);
}
TEST_F(TestDTLSSocketWrapper, sigio)
{
transport->open((NetworkStack *)&stack);
callback_is_called = false;
wrapper->sigio(mbed::callback(my_callback));
SocketAddress a("127.0.0.1", 1024);
wrapper->close(); //trigger events.
EXPECT_EQ(callback_is_called, true);
}
TEST_F(TestDTLSSocketWrapper, setsockopt)
{
transport->open((NetworkStack *)&stack);
EXPECT_EQ(wrapper->setsockopt(0, 0, 0, 0), NSAPI_ERROR_UNSUPPORTED);
}
TEST_F(TestDTLSSocketWrapper, getsockopt_no_stack)
{
EXPECT_EQ(wrapper->getsockopt(0, 0, 0, 0), NSAPI_ERROR_NO_SOCKET);
}
TEST_F(TestDTLSSocketWrapper, getsockopt)
{
transport->open((NetworkStack *)&stack);
EXPECT_EQ(wrapper->getsockopt(0, 0, 0, 0), NSAPI_ERROR_UNSUPPORTED);
}
/* unsupported */
TEST_F(TestDTLSSocketWrapper, listen_unsupported)
{
EXPECT_EQ(wrapper->listen(1), NSAPI_ERROR_UNSUPPORTED);
}
TEST_F(TestDTLSSocketWrapper, accept_unsupported)
{
nsapi_error_t error;
EXPECT_EQ(wrapper->accept(&error), static_cast<UDPSocket *>(NULL));
EXPECT_EQ(error, NSAPI_ERROR_UNSUPPORTED);
}

View File

@ -0,0 +1,38 @@
####################
# UNIT TESTS
####################
set(unittest-sources
../features/netsocket/SocketAddress.cpp
../features/netsocket/NetworkStack.cpp
../features/netsocket/InternetSocket.cpp
../features/netsocket/UDPSocket.cpp
../features/netsocket/DTLSSocketWrapper.cpp
../features/netsocket/TLSSocketWrapper.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
features/netsocket/DTLSSocketWrapper/test_DTLSSocketWrapper.cpp
stubs/Mutex_stub.cpp
stubs/mbed_assert_stub.c
stubs/equeue_stub.c
../features/nanostack/coap-service/test/coap-service/unittest/stub/mbedtls_stub.c
stubs/EventQueue_stub.cpp
stubs/mbed_shared_queues_stub.cpp
stubs/nsapi_dns_stub.cpp
stubs/EventFlags_stub.cpp
stubs/stoip4_stub.c
stubs/ip4tos_stub.c
stubs/Kernel_stub.cpp
)
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/DTLSSocketWrapper/dtls_test_config.h\"")
set_source_files_properties(features/netsocket/DTLSSocketWrapper/test_DTLSSocketWrapper.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})
set_source_files_properties(../features/netsocket/DTLSSocketWrapper.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})

View File

@ -62,7 +62,8 @@ TEST_F(TestTCPSocket, constructor)
TEST_F(TestTCPSocket, constructor_parameters)
{
TCPSocket socketParam = TCPSocket(dynamic_cast<NetworkStack *>(&stack));
TCPSocket socketParam = TCPSocket();
socketParam.open(dynamic_cast<NetworkStack *>(&stack));
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(socketParam.connect(a), NSAPI_ERROR_OK);
}

View File

@ -0,0 +1,71 @@
/*
* 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/TLSSocket.h"
#include "NetworkStack_stub.h"
#include "mbed_error.h"
mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
{
return 0;
}
// Control the rtos EventFlags stub. See EventFlags_stub.cpp
extern std::list<uint32_t> eventFlagsStubNextRetval;
class TestTLSSocket : public testing::Test {
public:
unsigned int dataSize = 10;
char dataBuf[10];
protected:
TLSSocket *socket;
NetworkStackstub stack;
virtual void SetUp()
{
socket = new TLSSocket();
}
virtual void TearDown()
{
stack.return_values.clear();
eventFlagsStubNextRetval.clear();
delete socket;
}
};
TEST_F(TestTLSSocket, constructor)
{
EXPECT_TRUE(socket);
}
/* connect */
TEST_F(TestTLSSocket, connect)
{
socket->open((NetworkStack *)&stack);
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(socket->connect("127.0.0.1", 1024), NSAPI_ERROR_OK);
}
TEST_F(TestTLSSocket, connect_no_open)
{
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(socket->connect("127.0.0.1", 1024), NSAPI_ERROR_NO_SOCKET);
}

View File

@ -0,0 +1,11 @@
/*
* tls_test_config.h
*/
#ifndef UNITTESTS_FEATURES_NETSOCKET_TLSSOCKET_TLS_TEST_CONFIG_H_
#define UNITTESTS_FEATURES_NETSOCKET_TLSSOCKET_TLS_TEST_CONFIG_H_
#define MBEDTLS_SSL_CLI_C
#endif /* UNITTESTS_FEATURES_NETSOCKET_TLSSOCKET_TLS_TEST_CONFIG_H_ */

View File

@ -0,0 +1,38 @@
####################
# UNIT TESTS
####################
set(unittest-sources
../features/netsocket/SocketAddress.cpp
../features/netsocket/NetworkStack.cpp
../features/netsocket/InternetSocket.cpp
../features/netsocket/TCPSocket.cpp
../features/netsocket/TLSSocket.cpp
../features/netsocket/TLSSocketWrapper.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
features/netsocket/TLSSocket/test_TLSSocket.cpp
stubs/Mutex_stub.cpp
stubs/mbed_assert_stub.c
stubs/equeue_stub.c
../features/nanostack/coap-service/test/coap-service/unittest/stub/mbedtls_stub.c
stubs/EventQueue_stub.cpp
stubs/mbed_shared_queues_stub.cpp
stubs/nsapi_dns_stub.cpp
stubs/EventFlags_stub.cpp
stubs/stoip4_stub.c
stubs/ip4tos_stub.c
)
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/TLSSocket/tls_test_config.h\"")
set_source_files_properties(features/netsocket/TLSSocket/test_TLSSocket.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})
set_source_files_properties(../features/netsocket/TLSSocket.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})
set_source_files_properties(../features/netsocket/TLSSocketWrapper.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})

View File

@ -0,0 +1,420 @@
/*
* 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/TLSSocketWrapper.h"
#include "NetworkStack_stub.h"
#include "features/nanostack/coap-service/test/coap-service/unittest/stub/mbedtls_stub.h"
#include <cstring> //memset
#include "mbed_error.h"
mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
{
return 0;
}
// Control the rtos EventFlags stub. See EventFlags_stub.cpp
extern std::list<uint32_t> eventFlagsStubNextRetval;
class TestTLSSocketWrapper : public testing::Test {
public:
unsigned int dataSize = 10;
char dataBuf[10];
protected:
TCPSocket *transport;
TLSSocketWrapper *wrapper;
NetworkStackstub stack;
virtual void SetUp()
{
memset(mbedtls_stub.retArray, 0, sizeof(mbedtls_stub.retArray));
mbedtls_stub.useCounter = false;
mbedtls_stub.counter = 0;
mbedtls_stub.crt_expected_int = 0;
mbedtls_stub.expected_int = 0;
transport = new TCPSocket();
wrapper = new TLSSocketWrapper(transport);
}
virtual void TearDown()
{
stack.return_values.clear();
eventFlagsStubNextRetval.clear();
delete wrapper;
}
char *cert = "-----BEGIN CERTIFICATE-----\
MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\
DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\
SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\
GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\
AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\
q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\
SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\
Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\
a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\
/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\
AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\
CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\
bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\
c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\
VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\
ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\
MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\
Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\
AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\
uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\
wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\
X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\
PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\
KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\
-----END CERTIFICATE-----";
};
static bool callback_is_called;
static void my_callback()
{
callback_is_called = true;
}
TEST_F(TestTLSSocketWrapper, constructor)
{
EXPECT_TRUE(wrapper);
}
TEST_F(TestTLSSocketWrapper, constructor_hostname)
{
TLSSocketWrapper *wrapper2 = new TLSSocketWrapper(transport, "localhost");
}
/* connect */
TEST_F(TestTLSSocketWrapper, connect)
{
transport->open((NetworkStack *)&stack);
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_IS_CONNECTED);
}
/* connect: TCP-related errors */
TEST_F(TestTLSSocketWrapper, connect_no_open)
{
stack.return_value = NSAPI_ERROR_OK;
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_NO_SOCKET);
}
TEST_F(TestTLSSocketWrapper, connect_error_in_progress_no_timeout)
{
transport->open((NetworkStack *)&stack);
stack.return_value = NSAPI_ERROR_IN_PROGRESS;
const SocketAddress a("127.0.0.1", 1024);
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_IN_PROGRESS);
}
TEST_F(TestTLSSocketWrapper, connect_with_timeout)
{
transport->open((NetworkStack *)&stack);
stack.return_value = NSAPI_ERROR_IN_PROGRESS;
const SocketAddress a("127.0.0.1", 1024);
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
wrapper->set_blocking(true);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_IN_PROGRESS);
}
TEST_F(TestTLSSocketWrapper, connect_error_is_connected)
{
transport->open((NetworkStack *)&stack);
const SocketAddress a("127.0.0.1", 1024);
wrapper->set_timeout(1);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[0] = 1; // mbedtls_ctr_drbg_seed error
}
/* connect: SSL-related errors */
TEST_F(TestTLSSocketWrapper, connect_fail_ctr_drbg_seed)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.crt_expected_int = 1; // mbedtls_ctr_drbg_seed error
stack.return_value = NSAPI_ERROR_OK;
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_PARAMETER);
mbedtls_stub.crt_expected_int = 0;
}
TEST_F(TestTLSSocketWrapper, connect_fail_ssl_setup)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[0] = 0; // mbedtls_ssl_config_defaults ok
mbedtls_stub.retArray[1] = 2; // mbedtls_ssl_setup error
stack.return_value = NSAPI_ERROR_OK;
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestTLSSocketWrapper, connect_handshake_fail_ssl_handshake)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[2] = -1; // mbedtls_ssl_handshake error
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_AUTH_FAILURE);
}
TEST_F(TestTLSSocketWrapper, connect_handshake_fail_ssl_handshake_in_progress)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
wrapper->set_timeout(1);
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
mbedtls_stub.retArray[2] = MBEDTLS_ERR_SSL_WANT_READ; // mbedtls_ssl_handshake error
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_IN_PROGRESS);
}
TEST_F(TestTLSSocketWrapper, connect_handshake_fail_ssl_get_verify_result)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.uint32_value = 1; // mbedtls_ssl_get_verify_result error
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
}
/* send */
TEST_F(TestTLSSocketWrapper, send_no_open)
{
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(wrapper->send(dataBuf, dataSize), NSAPI_ERROR_NO_CONNECTION);
}
TEST_F(TestTLSSocketWrapper, send_in_one_chunk)
{
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[3] = dataSize; // mbedtls_ssl_write
transport->open((NetworkStack *)&stack);
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->send(dataBuf, dataSize), dataSize);
}
TEST_F(TestTLSSocketWrapper, send_in_two_chunks)
{
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[3] = dataSize; // mbedtls_ssl_write
transport->open((NetworkStack *)&stack);
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->send(dataBuf, dataSize), dataSize);
}
TEST_F(TestTLSSocketWrapper, send_error_would_block)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[3] = MBEDTLS_ERR_SSL_WANT_WRITE; // mbedtls_ssl_write
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->send(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
}
TEST_F(TestTLSSocketWrapper, send_to)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[3] = dataSize; // mbedtls_ssl_write
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->sendto(a, dataBuf, dataSize), dataSize);
}
/* recv */
TEST_F(TestTLSSocketWrapper, recv_no_open)
{
stack.return_value = NSAPI_ERROR_OK;
EXPECT_EQ(wrapper->recv(dataBuf, dataSize), NSAPI_ERROR_NO_CONNECTION);
}
TEST_F(TestTLSSocketWrapper, recv_all_data)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[3] = dataSize; // mbedtls_ssl_write
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->recv(dataBuf, dataSize), dataSize);
}
TEST_F(TestTLSSocketWrapper, recv_less_than_expected)
{
transport->open((NetworkStack *)&stack);
unsigned int lessThanDataSize = dataSize - 1;
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[3] = lessThanDataSize; // mbedtls_ssl_write
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->recv(dataBuf, dataSize), lessThanDataSize);
}
TEST_F(TestTLSSocketWrapper, recv_would_block)
{
transport->open((NetworkStack *)&stack);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[3] = MBEDTLS_ERR_SSL_WANT_WRITE; // mbedtls_ssl_write
const SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
EXPECT_EQ(wrapper->recv(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
}
TEST_F(TestTLSSocketWrapper, recv_from_no_socket)
{
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->recvfrom(&a, dataBuf, dataSize), NSAPI_ERROR_NO_CONNECTION);
}
TEST_F(TestTLSSocketWrapper, recv_from)
{
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
SocketAddress b;
EXPECT_EQ(wrapper->recvfrom(&b, dataBuf, dataSize), NSAPI_ERROR_OK);
}
TEST_F(TestTLSSocketWrapper, recv_from_null)
{
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->connect(a), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->recvfrom(NULL, dataBuf, dataSize), NSAPI_ERROR_OK);
}
/* set_root_ca_cert */
TEST_F(TestTLSSocketWrapper, set_root_ca_cert)
{
EXPECT_EQ(wrapper->get_ca_chain(), static_cast<mbedtls_x509_crt *>(NULL));
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->set_root_ca_cert(cert, strlen(cert)), NSAPI_ERROR_OK);
EXPECT_NE(wrapper->get_ca_chain(), static_cast<mbedtls_x509_crt *>(NULL));
}
TEST_F(TestTLSSocketWrapper, set_root_ca_cert_nolen)
{
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->set_root_ca_cert(cert), NSAPI_ERROR_OK);
}
TEST_F(TestTLSSocketWrapper, set_root_ca_cert_invalid)
{
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[0] = 1; // mbedtls_x509_crt_parse error
EXPECT_EQ(wrapper->set_root_ca_cert(cert, strlen(cert)), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestTLSSocketWrapper, set_client_cert_key)
{
EXPECT_EQ(wrapper->get_own_cert(), static_cast<mbedtls_x509_crt *>(NULL));
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
EXPECT_EQ(wrapper->set_client_cert_key(cert, cert), NSAPI_ERROR_OK);
EXPECT_NE(wrapper->get_own_cert(), static_cast<mbedtls_x509_crt *>(NULL));
}
TEST_F(TestTLSSocketWrapper, set_client_cert_key_invalid)
{
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[0] = 1; // mbedtls_x509_crt_parse error
EXPECT_EQ(wrapper->set_client_cert_key(cert, cert), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestTLSSocketWrapper, set_client_cert_key_invalid_pem)
{
EXPECT_EQ(transport->open((NetworkStack *)&stack), NSAPI_ERROR_OK);
mbedtls_stub.useCounter = true;
mbedtls_stub.retArray[0] = 0; // mbedtls_x509_crt_parse ok
mbedtls_stub.retArray[1] = 1; // mbedtls_pk_parse_key error
EXPECT_EQ(wrapper->set_client_cert_key(cert, cert), NSAPI_ERROR_PARAMETER);
}
TEST_F(TestTLSSocketWrapper, bind)
{
transport->open((NetworkStack *)&stack);
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->bind(a), NSAPI_ERROR_OK);
}
TEST_F(TestTLSSocketWrapper, bind_no_open)
{
SocketAddress a("127.0.0.1", 1024);
EXPECT_EQ(wrapper->bind(a), NSAPI_ERROR_NO_SOCKET);
}
TEST_F(TestTLSSocketWrapper, sigio)
{
transport->open((NetworkStack *)&stack);
callback_is_called = false;
wrapper->sigio(mbed::callback(my_callback));
SocketAddress a("127.0.0.1", 1024);
wrapper->close(); //trigger events.
EXPECT_EQ(callback_is_called, true);
}
TEST_F(TestTLSSocketWrapper, setsockopt)
{
transport->open((NetworkStack *)&stack);
EXPECT_EQ(wrapper->setsockopt(0, 0, 0, 0), NSAPI_ERROR_UNSUPPORTED);
}
TEST_F(TestTLSSocketWrapper, getsockopt_no_stack)
{
EXPECT_EQ(wrapper->getsockopt(0, 0, 0, 0), NSAPI_ERROR_NO_SOCKET);
}
TEST_F(TestTLSSocketWrapper, getsockopt)
{
transport->open((NetworkStack *)&stack);
EXPECT_EQ(wrapper->getsockopt(0, 0, 0, 0), NSAPI_ERROR_UNSUPPORTED);
}
/* unsupported */
TEST_F(TestTLSSocketWrapper, listen_unsupported)
{
EXPECT_EQ(wrapper->listen(1), NSAPI_ERROR_UNSUPPORTED);
}
TEST_F(TestTLSSocketWrapper, accept_unsupported)
{
nsapi_error_t error;
EXPECT_EQ(wrapper->accept(&error), static_cast<TCPSocket *>(NULL));
EXPECT_EQ(error, NSAPI_ERROR_UNSUPPORTED);
}

View File

@ -0,0 +1,11 @@
/*
* tls_test_config.h
*/
#ifndef UNITTESTS_FEATURES_NETSOCKET_TLSSOCKET_TLS_TEST_CONFIG_H_
#define UNITTESTS_FEATURES_NETSOCKET_TLSSOCKET_TLS_TEST_CONFIG_H_
#define MBEDTLS_SSL_CLI_C
#endif /* UNITTESTS_FEATURES_NETSOCKET_TLSSOCKET_TLS_TEST_CONFIG_H_ */

View File

@ -0,0 +1,36 @@
####################
# UNIT TESTS
####################
set(unittest-sources
../features/netsocket/SocketAddress.cpp
../features/netsocket/NetworkStack.cpp
../features/netsocket/InternetSocket.cpp
../features/netsocket/TCPSocket.cpp
../features/netsocket/TLSSocketWrapper.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
features/netsocket/TLSSocketWrapper/test_TLSSocketWrapper.cpp
stubs/Mutex_stub.cpp
stubs/mbed_assert_stub.c
stubs/equeue_stub.c
../features/nanostack/coap-service/test/coap-service/unittest/stub/mbedtls_stub.c
stubs/EventQueue_stub.cpp
stubs/mbed_shared_queues_stub.cpp
stubs/nsapi_dns_stub.cpp
stubs/EventFlags_stub.cpp
stubs/stoip4_stub.c
stubs/ip4tos_stub.c
)
set(MBEDTLS_USER_CONFIG_FILE_PATH "\"../UNITTESTS/features/netsocket/TLSSocketWrapper/tls_test_config.h\"")
set_source_files_properties(features/netsocket/TLSSocketWrapper/test_TLSSocketWrapper.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})
set_source_files_properties(../features/netsocket/TLSSocketWrapper.cpp PROPERTIES COMPILE_DEFINITIONS MBEDTLS_USER_CONFIG_FILE=${MBEDTLS_USER_CONFIG_FILE_PATH})

View File

@ -25,6 +25,7 @@ class NetworkStackstub : public NetworkStack {
public:
std::list<nsapi_error_t> return_values;
nsapi_error_t return_value;
SocketAddress return_socketAddress;
NetworkStackstub()
{
@ -113,6 +114,9 @@ protected:
virtual nsapi_size_or_error_t socket_recvfrom(nsapi_socket_t handle, SocketAddress *address,
void *buffer, nsapi_size_t size)
{
if (return_socketAddress != SocketAddress()) {
*address = return_socketAddress;
}
if (!return_values.empty()) {
nsapi_error_t ret = return_values.front();
return_values.pop_front();

View File

@ -79,7 +79,8 @@ public:
AttachedEmergencyOnly,
RegisteredCSFBNotPreferredHome,
RegisteredCSFBNotPreferredRoaming,
AlreadyRegistered = 11 // our our definition when modem says that we are not registered but we have active PDP Context
AlreadyRegistered = 11, // our definition when modem says that we are not registered but we have active PDP Context
RegistrationStatusMax
};
/* Network registration type */
@ -107,7 +108,8 @@ public:
RAT_E_UTRAN,
RAT_CATM1,
RAT_NB1,
RAT_UNKNOWN
RAT_UNKNOWN,
RAT_MAX = 11 // to reserve string array
};
// 3GPP TS 27.007 - 7.3 PLMN selection +COPS
@ -342,7 +344,7 @@ public:
*/
virtual bool is_active_context() = 0;
/** Gets current network registration parameters:
/** Gets the latest received registration parameters from the network:
* type, status, access technology, cell_id, lac, active_time, periodic_tau.
*
* @param reg_params see registration_params_t
@ -351,7 +353,7 @@ public:
*/
virtual nsapi_error_t get_registration_params(registration_params_t &reg_params) = 0;
/** Gets the network registration parameters based on required registration type:
/** Gets the current network registration parameters from the network with type:
* status, access technology, cell_id, lac, active_time, periodic_tau.
*
* @param type see RegistrationType values

View File

@ -36,6 +36,9 @@ using namespace mbed_cellular_util;
// URCs should be handled fast, if you add debug traces within URC processing then you also need to increase this time
#define PROCESS_URC_TIME 20
// Suppress logging of very big packet payloads, maxlen is approximate due to write/read are cached
#define DEBUG_MAXLEN 80
const char *mbed::OK = "OK\r\n";
const uint8_t OK_LENGTH = 4;
const char *mbed::CRLF = "\r\n";
@ -281,8 +284,8 @@ void ATHandler::process_oob()
return;
}
lock();
tr_debug("process_oob readable=%d, pos=%u, len=%u", _fileHandle->readable(), _recv_pos, _recv_len);
if (_fileHandle->readable() || (_recv_pos < _recv_len)) {
tr_debug("AT OoB readable %d, len %u", _fileHandle->readable(), _recv_len - _recv_pos);
_current_scope = NotSet;
uint32_t timeout = _at_timeout;
_at_timeout = PROCESS_URC_TIME;
@ -302,8 +305,8 @@ void ATHandler::process_oob()
}
}
_at_timeout = timeout;
tr_debug("AT OoB done");
}
tr_debug("process_oob exit");
unlock();
}
@ -355,6 +358,7 @@ bool ATHandler::fill_buffer(bool wait_for_timeout)
// Reset buffer when full
if (sizeof(_recv_buff) == _recv_len) {
tr_error("AT overflow");
debug_print(_recv_buff, _recv_len);
reset_buffer();
}
@ -443,15 +447,22 @@ ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len)
return -1;
}
bool debug_on = _debug_on;
size_t read_len = 0;
for (; read_len < len; read_len++) {
int c = get_char();
if (c == -1) {
set_error(NSAPI_ERROR_DEVICE_ERROR);
_debug_on = debug_on;
return -1;
}
buf[read_len] = c;
if (_debug_on && read_len >= DEBUG_MAXLEN) {
debug_print("..", sizeof(".."));
_debug_on = false;
}
}
_debug_on = debug_on;
return read_len;
}
@ -739,13 +750,13 @@ device_err_t ATHandler::get_last_device_error() const
void ATHandler::set_error(nsapi_error_t err)
{
if (err != NSAPI_ERROR_OK) {
tr_debug("AT error %d", err);
}
if (_last_err == NSAPI_ERROR_OK) {
_last_err = err;
}
if (_last_err != err) {
tr_warn("AT error code changed from %d to %d!", _last_err, err);
}
}
int ATHandler::get_3gpp_error()
@ -977,7 +988,7 @@ bool ATHandler::consume_to_stop_tag()
return true;
}
tr_warn("AT stop tag not found");
tr_debug("AT stop tag not found");
set_error(NSAPI_ERROR_DEVICE_ERROR);
return false;
}
@ -1130,20 +1141,31 @@ size_t ATHandler::write(const void *data, size_t len)
fhs.fh = _fileHandle;
fhs.events = POLLOUT;
size_t write_len = 0;
bool debug_on = _debug_on;
for (; write_len < len;) {
int count = poll(&fhs, 1, poll_timeout());
if (count <= 0 || !(fhs.revents & POLLOUT)) {
set_error(NSAPI_ERROR_DEVICE_ERROR);
_debug_on = debug_on;
return 0;
}
ssize_t ret = _fileHandle->write((uint8_t *)data + write_len, len - write_len);
if (ret < 0) {
set_error(NSAPI_ERROR_DEVICE_ERROR);
_debug_on = debug_on;
return 0;
}
debug_print((char *)data + write_len, ret);
if (_debug_on && write_len < DEBUG_MAXLEN) {
if (write_len + ret < DEBUG_MAXLEN) {
debug_print((char *)data + write_len, ret);
} else {
debug_print("..", sizeof(".."));
_debug_on = false;
}
}
write_len += (size_t)ret;
}
_debug_on = debug_on;
return write_len;
}
@ -1175,13 +1197,14 @@ bool ATHandler::check_cmd_send()
void ATHandler::flush()
{
tr_debug("AT flush");
reset_buffer();
while (fill_buffer(false)) {
reset_buffer();
}
}
void ATHandler::debug_print(char *p, int len)
void ATHandler::debug_print(const char *p, int len)
{
#if MBED_CONF_CELLULAR_DEBUG_AT
if (_debug_on) {

View File

@ -524,7 +524,7 @@ private:
bool find_urc_handler(const char *prefix);
// print contents of a buffer to trace log
void debug_print(char *p, int len);
void debug_print(const char *p, int len);
};
} // namespace mbed

View File

@ -44,7 +44,7 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
AT_CellularBase(at), _ip_stack_type_requested(DEFAULT_STACK), _is_connected(false), _is_blocking(true),
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0)
{
tr_debug("AT_CellularContext::AT_CellularContext(): apn: %s", apn);
tr_info("New CellularContext %s (%p)", apn ? apn : "", this);
_stack = NULL;
_ip_stack_type = DEFAULT_STACK;
_authentication_type = CellularContext::CHAP;
@ -62,6 +62,8 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
AT_CellularContext::~AT_CellularContext()
{
tr_info("Delete CellularContext %s (%p)", _apn ? _apn : "", this);
(void)disconnect();
if (_nw) {
@ -71,12 +73,14 @@ AT_CellularContext::~AT_CellularContext()
void AT_CellularContext::set_file_handle(FileHandle *fh)
{
tr_info("CellularContext filehandle %p", fh);
_fh = fh;
_at.set_file_handle(_fh);
}
nsapi_error_t AT_CellularContext::connect()
{
tr_info("CellularContext connect");
if (_is_connected) {
return NSAPI_ERROR_IS_CONNECTED;
}
@ -200,6 +204,7 @@ void AT_CellularContext::attach(Callback<void(nsapi_event_t, intptr_t)> status_c
nsapi_error_t AT_CellularContext::set_blocking(bool blocking)
{
nsapi_error_t err = NSAPI_ERROR_OK;
tr_info("CellularContext set blocking %d", blocking);
#if NSAPI_PPP_AVAILABLE
err = nsapi_ppp_set_blocking(blocking);
#endif
@ -209,6 +214,7 @@ nsapi_error_t AT_CellularContext::set_blocking(bool blocking)
void AT_CellularContext::set_plmn(const char *plmn)
{
tr_info("CellularContext plmn %s", plmn);
_device->set_plmn(plmn);
}
@ -301,12 +307,6 @@ nsapi_error_t AT_CellularContext::do_user_authentication()
bool AT_CellularContext::get_context()
{
if (_apn) {
tr_debug("APN in use: %s", _apn);
} else {
tr_debug("NO APN");
}
_at.cmd_start("AT+CGDCONT?");
_at.cmd_stop();
_at.resp_start("+CGDCONT:");
@ -388,7 +388,8 @@ bool AT_CellularContext::get_context()
memcpy(_found_apn, apn, apn_len + 1);
}
tr_debug("Context id %d", _cid);
tr_info("Found PDP context %d", _cid);
return true;
}
@ -450,7 +451,7 @@ bool AT_CellularContext::set_new_context(int cid)
_ip_stack_type = tmp_stack;
_cid = cid;
_new_context_set = true;
tr_info("New PDP context id %d was created", _cid);
tr_info("New PDP context %d, stack %s", _cid, pdp_type);
}
return success;
@ -468,9 +469,10 @@ nsapi_error_t AT_CellularContext::do_activate_context()
_at.unlock();
// in PPP we don't activate any context but leave it to PPP stack
return err;
#endif // NSAPI_PPP_AVAILABLE
#else
// try to authenticate user before activating or modifying context
err = do_user_authentication();
#endif // NSAPI_PPP_AVAILABLE
} else {
err = NSAPI_ERROR_NO_CONNECTION;
}
@ -566,7 +568,7 @@ void AT_CellularContext::do_connect()
#if NSAPI_PPP_AVAILABLE
nsapi_error_t AT_CellularContext::open_data_channel()
{
tr_info("Open data channel in PPP mode");
tr_info("CellularContext PPP connect");
if (is_supported(AT_CGDATA)) {
_at.cmd_start("AT+CGDATA=\"PPP\",");
_at.write_int(_cid);
@ -596,7 +598,7 @@ nsapi_error_t AT_CellularContext::open_data_channel()
void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
{
tr_debug("AT_CellularContext::ppp_status_cb, network_callback called with event: %d, ptr: %d", ev, ptr);
tr_debug("ppp_status_cb: event %d, ptr %d", ev, ptr);
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
_is_connected = true;
} else {
@ -613,13 +615,14 @@ void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
nsapi_error_t AT_CellularContext::disconnect()
{
tr_info("CellularContext disconnect");
if (!_nw || !_is_connected) {
return NSAPI_ERROR_NO_CONNECTION;
}
#if NSAPI_PPP_AVAILABLE
nsapi_error_t err = nsapi_ppp_disconnect(_at.get_file_handle());
if (err != NSAPI_ERROR_OK) {
tr_error("Cellular disconnect failed!");
tr_error("CellularContext disconnect failed!");
// continue even in failure due to ppp disconnect in any case releases filehandle
}
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
@ -710,7 +713,6 @@ nsapi_error_t AT_CellularContext::get_rate_control(
int next_element = _at.read_int();
if (next_element >= 0) {
reports = (RateControlExceptionReports)next_element;
tr_debug("reports %d", reports);
next_element = _at.read_int();
} else {
comma_found = false;
@ -718,7 +720,6 @@ nsapi_error_t AT_CellularContext::get_rate_control(
if (comma_found && next_element >= 0) {
timeUnit = (RateControlUplinkTimeUnit)next_element;
tr_debug("time %d", timeUnit);
next_element = _at.read_int();
} else {
comma_found = false;
@ -726,7 +727,9 @@ nsapi_error_t AT_CellularContext::get_rate_control(
if (comma_found && next_element >= 0) {
uplinkRate = next_element;
tr_debug("rate %d", uplinkRate);
}
if (_at.get_last_error() == NSAPI_ERROR_OK) {
tr_debug("CGAPNRC: reports %d, time %d, rate %d", reports, timeUnit, uplinkRate);
}
}
_at.resp_stop();
@ -813,7 +816,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
cell_callback_data_t *data = (cell_callback_data_t *)ptr;
cellular_connection_status_t st = (cellular_connection_status_t)ev;
_cb_data.error = data->error;
tr_debug("AT_CellularContext::cellular_callback, network_callback called with event: %d, err: %d, data: %d", ev, data->error, data->status_data);
tr_debug("CellularContext: event %d, err %d, data %d", ev, data->error, data->status_data);
#if USE_APN_LOOKUP
if (st == CellularSIMStatusChanged && data->status_data == CellularSIM::SimStateReady &&
_cb_data.error == NSAPI_ERROR_OK) {
@ -880,13 +883,15 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
}
}
} else {
tr_debug("AT_CellularContext::cellular_callback, network_callback called with event: %d, ptr: %d", ev, ptr);
tr_debug("CellularContext: event %d, ptr %d", ev, ptr);
#if NSAPI_PPP_AVAILABLE
if (_is_blocking) {
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
tr_info("CellularContext IP %s", get_ip_address());
_cb_data.error = NSAPI_ERROR_OK;
_semaphore.release();
} else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
tr_info("PPP disconnected");
_cb_data.error = NSAPI_ERROR_NO_CONNECTION;
_semaphore.release();
}
@ -907,5 +912,8 @@ void AT_CellularContext::call_network_cb(nsapi_connection_status_t status)
if (_status_cb) {
_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _connect_status);
}
if (_nw && _connect_status == NSAPI_STATUS_DISCONNECTED) {
tr_info("CellularContext disconnected");
}
}
}

View File

@ -365,5 +365,17 @@ void AT_CellularDevice::modem_debug_on(bool on)
nsapi_error_t AT_CellularDevice::init_module()
{
#if MBED_CONF_MBED_TRACE_ENABLE
CellularInformation *information = open_information();
if (information) {
char *pbuf = new char[100];
nsapi_error_t ret = information->get_model(pbuf, sizeof(*pbuf));
close_information();
if (ret == NSAPI_ERROR_OK) {
tr_info("Model %s", pbuf);
}
delete[] pbuf;
}
#endif
return NSAPI_ERROR_OK;
}

View File

@ -37,6 +37,39 @@ static const at_reg_t at_reg[] = {
{ CellularNetwork::C_REG, "AT+CREG", "+CREG:"}
};
#if MBED_CONF_MBED_TRACE_ENABLE
static const char *const reg_type_str[(int)AT_CellularNetwork::RegistrationStatusMax] = {
"NotRegistered",
"RegisteredHomeNetwork",
"SearchingNetwork",
"RegistrationDenied",
"RegistrationUnknown",
"RegisteredRoaming",
"RegisteredSMSOnlyHome",
"RegisteredSMSOnlyRoaming",
"AttachedEmergencyOnly",
"RegisteredCSFBNotPreferredHome",
"RegisteredCSFBNotPreferredRoaming",
"AlreadyRegistered"
};
static const char *const rat_str[AT_CellularNetwork::RAT_MAX] = {
"GSM",
"GSM_COMPACT",
"UTRAN",
"EGPRS",
"HSDPA",
"HSUPA",
"HSDPA_HSUPA",
"E_UTRAN",
"CATM1",
"NB1",
"RAT unknown",
};
#endif
AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(atHandler),
_connection_status_cb(NULL), _op_act(RAT_UNKNOWN), _connect_status(NSAPI_STATUS_DISCONNECTED)
{
@ -79,7 +112,7 @@ AT_CellularNetwork::~AT_CellularNetwork()
void AT_CellularNetwork::urc_no_carrier()
{
tr_error("Data call failed: no carrier");
tr_info("NO CARRIER");
call_network_cb(NSAPI_STATUS_DISCONNECTED);
}
@ -89,7 +122,7 @@ void AT_CellularNetwork::urc_cgev()
if (_at.read_string(buf, 13) < 8) { // smallest string length we wan't to compare is 8
return;
}
tr_debug("urc_cgev: %s", buf);
tr_debug("CGEV: %s", buf);
bool call_cb = false;
// NOTE! If in future there will be 2 or more active contexts we might wan't to read context id also but not for now.
@ -116,26 +149,9 @@ void AT_CellularNetwork::urc_cgev()
void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
{
registration_params_t reg_params;
read_reg_params(reg_params);
#if MBED_CONF_MBED_TRACE_ENABLE
switch (reg_params._status) {
case NotRegistered:
tr_warn("not registered");
break;
case RegistrationDenied:
tr_warn("registration denied");
break;
case Unknown:
tr_warn("registration status unknown");
break;
default:
break;
}
#endif
read_reg_params(type, reg_params);
if (_at.get_last_error() == NSAPI_ERROR_OK && _connection_status_cb) {
tr_debug("type: %d, status: %d, lac: %d, cellID: %d, act: %d", type, reg_params._status, reg_params._lac, reg_params._cell_id, reg_params._act);
_reg_params._type = type;
cell_callback_data_t data;
data.error = NSAPI_ERROR_OK;
@ -159,19 +175,16 @@ void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
void AT_CellularNetwork::urc_creg()
{
tr_debug("urc_creg");
read_reg_params_and_compare(C_REG);
}
void AT_CellularNetwork::urc_cereg()
{
tr_debug("urc_cereg");
read_reg_params_and_compare(C_EREG);
}
void AT_CellularNetwork::urc_cgreg()
{
tr_debug("urc_cgreg");
read_reg_params_and_compare(C_GREG);
}
@ -258,18 +271,19 @@ nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn)
return _at.unlock_return_error();
}
void AT_CellularNetwork::read_reg_params(registration_params_t &reg_params)
void AT_CellularNetwork::read_reg_params(RegistrationType type, registration_params_t &reg_params)
{
const int MAX_STRING_LENGTH = 9;
char string_param[MAX_STRING_LENGTH] = {0};
reg_params._type = type;
int int_param = _at.read_int();
reg_params._status = (RegistrationStatus)int_param;
reg_params._status = (int_param >= 0 && int_param < RegistrationStatusMax) ? (RegistrationStatus)int_param : NotRegistered;
int len = _at.read_string(string_param, TWO_BYTES_HEX + 1);
if (len > 0) {
reg_params._lac = hex_str_to_int(string_param, TWO_BYTES_HEX);
tr_debug("lac %s %d", string_param, reg_params._lac);
} else {
reg_params._lac = -1;
}
@ -277,28 +291,25 @@ void AT_CellularNetwork::read_reg_params(registration_params_t &reg_params)
len = _at.read_string(string_param, FOUR_BYTES_HEX + 1);
if (len > 0) {
reg_params._cell_id = hex_str_to_int(string_param, FOUR_BYTES_HEX);
tr_debug("cell_id %s %d", string_param, reg_params._cell_id);
} else {
reg_params._cell_id = -1;
}
int_param = _at.read_int();
reg_params._act = (int_param == -1) ? RAT_UNKNOWN : (RadioAccessTechnology)int_param;
reg_params._act = (int_param >= 0 && int_param < RAT_MAX) ? (RadioAccessTechnology)int_param : RAT_UNKNOWN ;
// Skip [<cause_type>],[<reject_cause>]
_at.skip_param(2);
len = _at.read_string(string_param, ONE_BYTE_BINARY + 1);
reg_params._active_time = calculate_active_time(string_param, len);
if (reg_params._active_time != -1) {
tr_debug("active_time %s %d", string_param, reg_params._active_time);
}
len = _at.read_string(string_param, ONE_BYTE_BINARY + 1);
reg_params._periodic_tau = calculate_periodic_tau(string_param, len);
if (reg_params._periodic_tau == -1) {
tr_debug("periodic_tau %s %d", string_param, reg_params._periodic_tau);
}
#if MBED_CONF_MBED_TRACE_ENABLE
tr_debug("%s %s, LAC %d, cell %d, %s", at_reg[(int)type].urc_prefix, reg_type_str[reg_params._status], reg_params._lac, reg_params._cell_id, rat_str[reg_params._act]);
#endif
}
AT_CellularNetwork::RegistrationMode AT_CellularNetwork::has_registration(RegistrationType reg_type)
@ -485,6 +496,12 @@ nsapi_error_t AT_CellularNetwork::get_signal_quality(int &rssi, int &ber)
return NSAPI_ERROR_DEVICE_ERROR;
}
if (rssi == 99) {
rssi = 0;
} else {
rssi = -113 + 2 * rssi;
}
return _at.unlock_return_error();
}
@ -593,8 +610,7 @@ nsapi_error_t AT_CellularNetwork::get_registration_params(RegistrationType type,
_at.resp_start(rsp[i]);
(void)_at.read_int(); // ignore urc mode subparam
_reg_params._type = type;
read_reg_params(reg_params);
read_reg_params(type, reg_params);
_at.resp_stop();
_reg_params = reg_params;

View File

@ -117,7 +117,7 @@ private:
void urc_cgev();
void read_reg_params_and_compare(RegistrationType type);
void read_reg_params(registration_params_t &reg_params);
void read_reg_params(RegistrationType type, registration_params_t &reg_params);
// Returns active time(Table 10.5.163/3GPP TS 24.008: GPRS Timer 2 information element) in seconds
int calculate_active_time(const char *active_time_string, int active_time_length);

View File

@ -41,6 +41,18 @@ AT_CellularStack::~AT_CellularStack()
_socket = NULL;
}
int AT_CellularStack::find_socket_index(nsapi_socket_t handle)
{
int max_socket_count = get_max_socket_count();
for (int i = 0; i < max_socket_count; i++) {
if (_socket[i] == handle) {
return i;
}
}
return -1;
}
/** NetworkStack
*/
@ -115,21 +127,14 @@ nsapi_error_t AT_CellularStack::socket_open(nsapi_socket_t *handle, nsapi_protoc
}
}
int index = -1;
for (int i = 0; i < max_socket_count; i++) {
if (!_socket[i]) {
index = i;
break;
}
}
int index = find_socket_index(0);
if (index == -1) {
tr_error("No socket found!");
tr_error("No free sockets!");
_socket_mutex.unlock();
return NSAPI_ERROR_NO_SOCKET;
}
tr_info("Socket open index: %d", index);
tr_info("Socket %d open", index);
// create local socket structure, socket on modem is created when app calls sendto/recvfrom
_socket[index] = new CellularSocket;
CellularSocket *psock;
@ -156,18 +161,8 @@ nsapi_error_t AT_CellularStack::socket_close(nsapi_socket_t handle)
}
int sock_id = socket->id;
bool sock_created = socket->created;
int max_socket_count = get_max_socket_count();
int index = -1;
for (int i = 0; i < max_socket_count; i++) {
if (_socket[i] == socket) {
index = i;
break;
}
}
tr_info("Close socket index: %d id: %d created: %d", index, sock_id, socket->created);
int index = find_socket_index(handle);
if (index == -1) {
tr_error("No socket found to be closed");
return err;
@ -181,6 +176,12 @@ nsapi_error_t AT_CellularStack::socket_close(nsapi_socket_t handle)
err = socket_close_impl(sock_id);
}
if (!err) {
tr_info("Socket %d closed", index);
} else {
tr_info("Socket %d close (id %d, created %d, started %d, error %d)", index, sock_id, socket->created, socket->started, err);
}
_socket[index] = NULL;
delete socket;
@ -260,10 +261,8 @@ nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, con
_at.unlock();
if (ret_val != NSAPI_ERROR_OK) {
tr_error("Error creating socket to send to: %s error code: %d", addr.get_ip_address(), ret_val);
tr_error("Socket %d create %s error %d", find_socket_index(socket), addr.get_ip_address(), ret_val);
return ret_val;
} else {
tr_info("Success creating socket to send to: %s", addr.get_ip_address());
}
}
@ -276,14 +275,14 @@ nsapi_size_or_error_t AT_CellularStack::socket_sendto(nsapi_socket_t handle, con
ret_val = socket_sendto_impl(socket, addr, data, size);
if (ret_val > 0) {
tr_info("Success sending %d Bytes to: %s", ret_val, addr.get_ip_address());
} else if (ret_val != NSAPI_ERROR_WOULD_BLOCK) {
tr_error("Error sending to: %s error code: %d", addr.get_ip_address(), ret_val);
}
_at.unlock();
if (ret_val >= 0) {
tr_info("Socket %d sent %d bytes to %s port %d", find_socket_index(socket), ret_val, addr.get_ip_address(), addr.get_port());
} else if (ret_val != NSAPI_ERROR_WOULD_BLOCK) {
tr_error("Socket %d sendto %s error %d", find_socket_index(socket), addr.get_ip_address(), ret_val);
}
return ret_val;
}
@ -308,6 +307,7 @@ nsapi_size_or_error_t AT_CellularStack::socket_recvfrom(nsapi_socket_t handle, S
_at.unlock();
if (ret_val != NSAPI_ERROR_OK) {
tr_error("Socket %d create %s error %d", find_socket_index(socket), addr->get_ip_address(), ret_val);
return ret_val;
}
}
@ -318,6 +318,12 @@ nsapi_size_or_error_t AT_CellularStack::socket_recvfrom(nsapi_socket_t handle, S
_at.unlock();
if (ret_val >= 0) {
tr_info("Socket %d recv %d bytes from %s port %d", find_socket_index(socket), ret_val, addr->get_ip_address(), addr->get_port());
} else if (ret_val != NSAPI_ERROR_WOULD_BLOCK) {
tr_error("Socket %d recv error %d", find_socket_index(socket), ret_val);
}
return ret_val;
}

View File

@ -182,6 +182,8 @@ protected:
nsapi_ip_stack_t _stack_type;
private:
int find_socket_index(nsapi_socket_t handle);
// mutex for write/read to a _socket array, needed when multiple threads may open sockets simultaneously
PlatformMutex _socket_mutex;
};

View File

@ -162,7 +162,7 @@ void CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr)
{
if (ev >= NSAPI_EVENT_CELLULAR_STATUS_BASE && ev <= NSAPI_EVENT_CELLULAR_STATUS_END) {
cell_callback_data_t *ptr_data = (cell_callback_data_t *)ptr;
tr_debug("Device: network_callback called with event: %d, err: %d, data: %d", ev, ptr_data->error, ptr_data->status_data);
tr_debug("callback: %d, err: %d, data: %d", ev, ptr_data->error, ptr_data->status_data);
cellular_connection_status_t cell_ev = (cellular_connection_status_t)ev;
if (cell_ev == CellularRegistrationStatusChanged && _state_machine) {
// broadcast only network registration changes to state machine
@ -185,7 +185,7 @@ void CellularDevice::cellular_callback(nsapi_event_t ev, intptr_t ptr)
}
}
} else {
tr_debug("Device: network_callback called with event: %d, ptr: %d", ev, ptr);
tr_debug("callback: %d, ptr: %d", ev, ptr);
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
// we have been disconnected, reset state machine so that application can start connect sequence again
if (_state_machine) {

View File

@ -89,6 +89,7 @@ void CellularStateMachine::reset()
void CellularStateMachine::stop()
{
tr_debug("CellularStateMachine stop");
if (_queue_thread) {
_queue.break_dispatch();
_queue_thread->terminate();
@ -118,10 +119,10 @@ bool CellularStateMachine::power_on()
{
_cb_data.error = _power->on();
if (_cb_data.error != NSAPI_ERROR_OK && _cb_data.error != NSAPI_ERROR_UNSUPPORTED) {
tr_warn("Cellular start failed. Power off/on.");
tr_warn("Power on failed. Try to power off/on.");
_cb_data.error = _power->off();
if (_cb_data.error != NSAPI_ERROR_OK && _cb_data.error != NSAPI_ERROR_UNSUPPORTED) {
tr_error("Cellular power down failing after failed power up attempt!");
tr_error("Power off failed!");
}
return false;
}
@ -162,14 +163,14 @@ bool CellularStateMachine::open_sim()
if (state == CellularSIM::SimStatePinNeeded) {
if (strlen(_sim_pin)) {
tr_info("Entering PIN to open SIM");
tr_info("Entering PIN to open SIM.");
_cb_data.error = _sim->set_pin(_sim_pin);
if (_cb_data.error) {
tr_error("SIM pin set failed with: %d", _cb_data.error);
tr_error("Failed to set PIN: error %d", _cb_data.error);
}
} else {
// No sim pin provided even it's needed, stop state machine
tr_error("PIN required but No SIM pin provided.");
tr_error("PIN required but no SIM pin provided.");
_retry_count = RETRY_ARRAY_SIZE;
return false;
}
@ -185,7 +186,6 @@ bool CellularStateMachine::is_registered()
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
if (get_network_registration((CellularNetwork::RegistrationType) type, status, is_registered)) {
tr_debug("get_network_registration: type=%d, status=%d", type, status);
if (is_registered) {
break;
}
@ -242,7 +242,7 @@ bool CellularStateMachine::get_network_registration(CellularNetwork::Registratio
}
if (is_roaming) {
tr_warn("Roaming cellular network!");
tr_info("Roaming network.");
}
return true;
@ -250,7 +250,7 @@ bool CellularStateMachine::get_network_registration(CellularNetwork::Registratio
void CellularStateMachine::report_failure(const char *msg)
{
tr_error("Cellular stm failed with: %s", msg);
tr_error("CellularStateMachine failure: %s", msg);
_event_id = -1;
if (_event_status_cb) {
@ -258,7 +258,7 @@ void CellularStateMachine::report_failure(const char *msg)
_event_status_cb(_current_event, (intptr_t)&_cb_data);
}
tr_error("Target state %s was not reached. Returning from state: %s", get_state_string(_target_state), get_state_string(_state));
tr_error("CellularStateMachine target state %s, current state %s", get_state_string(_target_state), get_state_string(_state));
}
const char *CellularStateMachine::get_state_string(CellularState state) const
@ -332,7 +332,7 @@ void CellularStateMachine::enter_to_state(CellularState state)
void CellularStateMachine::retry_state_or_fail()
{
if (++_retry_count < RETRY_ARRAY_SIZE) {
tr_debug("Retry State %s, retry %d/%d", get_state_string(_state), _retry_count, RETRY_ARRAY_SIZE);
tr_debug("%s: retry %d/%d", get_state_string(_state), _retry_count, RETRY_ARRAY_SIZE);
_event_timeout = _retry_timeout_array[_retry_count];
_is_retry = true;
} else {
@ -343,19 +343,19 @@ void CellularStateMachine::retry_state_or_fail()
void CellularStateMachine::state_init()
{
// we should check that if power is already on then we can jump to device ready state
_cellularDevice.set_timeout(TIMEOUT_POWER_ON);
tr_info("Cellular state init (timeout %d ms)", TIMEOUT_POWER_ON);
tr_info("Start connecting (timeout %d s)", TIMEOUT_POWER_ON / 1000);
if (!_power) {
_power = _cellularDevice.open_power();
}
_cb_data.error = _power->is_device_ready();
if (_cb_data.error != NSAPI_ERROR_OK) {
_event_timeout = _start_time;
tr_info("Init state, waiting %d ms before POWER state)", _start_time);
if (_start_time > 0) {
tr_info("Startup delay %d ms", _start_time);
}
enter_to_state(STATE_POWER_ON);
} else {
tr_info("Device was ready to accept commands, jump to device ready");
enter_to_state(STATE_DEVICE_READY);
}
}
@ -363,7 +363,7 @@ void CellularStateMachine::state_init()
void CellularStateMachine::state_power_on()
{
_cellularDevice.set_timeout(TIMEOUT_POWER_ON);
tr_info("Cellular power ON (timeout %d ms)", TIMEOUT_POWER_ON);
tr_info("Modem power ON (timeout %d s)", TIMEOUT_POWER_ON / 1000);
if (power_on()) {
enter_to_state(STATE_DEVICE_READY);
} else {
@ -374,7 +374,7 @@ void CellularStateMachine::state_power_on()
bool CellularStateMachine::device_ready()
{
tr_info("Cellular device ready");
tr_info("Modem ready");
if (_cellularDevice.init_module() != NSAPI_ERROR_OK) {
return false;
}
@ -408,7 +408,7 @@ void CellularStateMachine::state_device_ready()
void CellularStateMachine::state_sim_pin()
{
_cellularDevice.set_timeout(TIMEOUT_SIM_PIN);
tr_info("Sim state (timeout %d ms)", TIMEOUT_SIM_PIN);
tr_info("Setup SIM (timeout %d s)", TIMEOUT_SIM_PIN / 1000);
if (open_sim()) {
if (!_network) {
_network = _cellularDevice.open_network();
@ -442,8 +442,8 @@ void CellularStateMachine::state_sim_pin()
void CellularStateMachine::state_registering()
{
_cellularDevice.set_timeout(TIMEOUT_NETWORK);
tr_info("Network registration (timeout %d s)", TIMEOUT_REGISTRATION / 1000);
if (is_registered()) {
tr_info("Sending Registration changed from plmn");
_cb_data.status_data = CellularNetwork::AlreadyRegistered;
_cb_data.error = NSAPI_ERROR_OK;
_event_status_cb(_current_event, (intptr_t)&_cb_data);
@ -463,11 +463,10 @@ void CellularStateMachine::state_registering()
void CellularStateMachine::state_manual_registering_network()
{
_cellularDevice.set_timeout(TIMEOUT_REGISTRATION);
tr_info("state_manual_registering_network");
tr_info("Manual registration %s (timeout %d s)", _plmn, TIMEOUT_REGISTRATION / 1000);
if (!_plmn_network_found) {
if (is_registered() && is_registered_to_plmn()) {
// we have to send registration changed event as network thinks that we are not registered even we have active PDP context
tr_info("Sending REgistration changed from plmn");
_cb_data.status_data = CellularNetwork::AlreadyRegistered;
_cb_data.error = NSAPI_ERROR_OK;
_event_status_cb(_current_event, (intptr_t)&_cb_data);
@ -486,8 +485,8 @@ void CellularStateMachine::state_manual_registering_network()
void CellularStateMachine::state_attaching()
{
_cellularDevice.set_timeout(TIMEOUT_CONNECT);
tr_info("Attaching network (timeout %d s)", TIMEOUT_CONNECT / 1000);
_cb_data.error = _network->set_attach();
tr_info("CellularStateMachine::state_attaching(): %d", _cb_data.error);
if (_cb_data.error == NSAPI_ERROR_OK) {
_cellularDevice.close_sim();
_sim = NULL;
@ -503,7 +502,7 @@ void CellularStateMachine::state_attaching()
void CellularStateMachine::continue_from_state(CellularState state)
{
_mutex.lock();
tr_info("Continue state from %s to %s", get_state_string((CellularStateMachine::CellularState)_state),
tr_info("%s => %s", get_state_string((CellularStateMachine::CellularState)_state),
get_state_string((CellularStateMachine::CellularState)state));
_state = state;
enter_to_state(state);
@ -533,7 +532,6 @@ nsapi_error_t CellularStateMachine::run_to_state(CellularStateMachine::CellularS
void CellularStateMachine::pre_event(CellularState state)
{
tr_debug("CellularStateMachine::pre_event, state: %s, _target_state: %s, _event_id: %d", get_state_string(state), get_state_string(_target_state), _event_id);
if (_target_state < state) {
// new wanted state will not be achieved with current _target_state so update it
_target_state = state;
@ -571,7 +569,20 @@ bool CellularStateMachine::get_current_status(CellularStateMachine::CellularStat
void CellularStateMachine::event()
{
tr_debug("CellularStateMachine::event(): %s", get_state_string(_state));
#if MBED_CONF_MBED_TRACE_ENABLE
if (_network) {
int rssi;
int ber;
if (_network->get_signal_quality(rssi, ber) == NSAPI_ERROR_OK) {
if (rssi == 0) {
tr_info("RSSI unknown");
} else {
tr_info("RSSI %d dBm", rssi);
}
}
}
#endif
_event_timeout = -1;
_is_retry = false;
@ -610,17 +621,16 @@ void CellularStateMachine::event()
}
if ((_target_state == _state && _cb_data.error == NSAPI_ERROR_OK && !_is_retry) || _event_id == STM_STOPPED) {
tr_info("Target state reached: %s, _cb_data.error: %d, _event_id: %d", get_state_string(_target_state), _cb_data.error, _event_id);
_event_id = -1;
return;
}
if (_next_state != _state || _event_timeout >= 0) {
if (_next_state != _state) { // state exit condition
tr_info("Cellular state from %s to %s", get_state_string((CellularStateMachine::CellularState)_state),
get_state_string((CellularStateMachine::CellularState)_next_state));
tr_debug("%s => %s", get_state_string((CellularStateMachine::CellularState)_state),
get_state_string((CellularStateMachine::CellularState)_next_state));
} else {
tr_info("Cellular event in %d seconds", _event_timeout);
tr_info("Continue after %d seconds", _event_timeout);
}
_state = _next_state;
if (_event_timeout == -1) {
@ -629,7 +639,7 @@ void CellularStateMachine::event()
_event_id = _queue.call_in(_event_timeout * 1000, callback(this, &CellularStateMachine::event));
if (!_event_id) {
_cb_data.error = NSAPI_ERROR_NO_MEMORY;
report_failure("Cellular event failure!");
report_failure("CellularStateMachine event failure!");
return;
}
}
@ -656,12 +666,6 @@ void CellularStateMachine::set_cellular_callback(mbed::Callback<void(nsapi_event
void CellularStateMachine::cellular_event_changed(nsapi_event_t ev, intptr_t ptr)
{
cell_callback_data_t *data = (cell_callback_data_t *)ptr;
if (ev >= NSAPI_EVENT_CELLULAR_STATUS_BASE && ev <= NSAPI_EVENT_CELLULAR_STATUS_END) {
tr_debug("FSM: cellular_event_changed called with event: %d, err: %d, data: %d _state: %s", ev, data->error, data->status_data, get_state_string(_state));
} else {
tr_debug("FSM: cellular_event_changed called with event: %d, ptr: %d _state: %s", ev, ptr, get_state_string(_state));
}
if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged &&
(_state == STATE_REGISTERING_NETWORK || _state == STATE_MANUAL_REGISTERING_NETWORK)) {
// expect packet data so only these states are valid

View File

@ -154,6 +154,8 @@ bool GEMALTO_CINTERION_CellularStack::is_protocol_supported(nsapi_protocol_t pro
nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_close_impl(int sock_id)
{
tr_debug("Cinterion close %d", sock_id);
_at.set_at_timeout(FAILURE_TIMEOUT);
_at.cmd_start("AT^SISC=");
@ -169,7 +171,6 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_close_impl(int sock_id)
_at.restore_at_timeout();
tr_debug("Closed socket %d (err %d)", sock_id, _at.get_last_error());
return _at.get_last_error();
}
@ -210,7 +211,7 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_open_defer(CellularSocket
}
socket->created = true;
tr_debug("Socket %d created (err %d)", socket->id, _at.get_last_error());
tr_debug("Cinterion open %d (err %d)", socket->id, _at.get_last_error());
return _at.get_last_error();
}
@ -247,20 +248,17 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::create_socket_impl(CellularSocket
if (paramValueLen >= 0) {
if (strcmp(paramTag, "srvType") == 0) {
if (strcmp(paramValue, "Socket") == 0) {
tr_debug("srvType %s", paramValue);
foundSrvType = true;
}
}
if (strcmp(paramTag, "address") == 0) {
if (strncmp(paramValue, "sock", sizeof("sock")) == 0) {
tr_debug("address %s", paramValue);
foundSrvType = true;
}
}
if (strcmp(paramTag, "conId") == 0) {
char buf[10];
std::sprintf(buf, "%d", connection_profile_id);
tr_debug("conId %s", paramValue);
if (strcmp(paramValue, buf) == 0) {
foundConIdType = true;
}
@ -287,8 +285,6 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::create_socket_impl(CellularSocket
_at.cmd_stop_read_resp();
}
tr_debug("Internet service %d (err %d)", internet_service_id, _at.get_last_error());
if (socket->proto == NSAPI_UDP) {
if (GEMALTO_CINTERION_Module::get_model() != GEMALTO_CINTERION_Module::ModelBGS2) {
return socket_open_defer(socket);
@ -301,8 +297,6 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::create_socket_impl(CellularSocket
nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(CellularSocket *socket,
const SocketAddress &address, const void *data, nsapi_size_t size)
{
tr_debug("Socket %d, sendto %s, len %d", socket->id, address.get_ip_address(), size);
if (socket->proto == NSAPI_UDP) {
const int ip_version = address.get_ip_version();
if ((ip_version == NSAPI_IPv4 && _stack_type != IPV4_STACK) ||
@ -404,8 +398,6 @@ sisw_retry:
_at.resp_stop();
_at.restore_at_timeout();
tr_debug("Socket %d sendto %s, %d bytes (err %d)", socket->id, address.get_ip_address(), accept_len, _at.get_last_error());
if (_at.get_last_error() == NSAPI_ERROR_OK) {
socket->tx_ready = false;
}
@ -416,8 +408,6 @@ sisw_retry:
nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
void *buffer, nsapi_size_t size)
{
tr_debug("Socket %d recvfrom %d bytes", socket->id, size);
// we must use this flag, otherwise ^SISR URC can come while we are reading response and there is
// no way to detect if that is really an URC or response
if (!socket->rx_avail) {
@ -504,7 +494,6 @@ sisr_retry:
port_start++; // skip ':'
int port = std::strtol(port_start, NULL, 10);
address->set_port(port);
tr_debug("IP address %s, port %d", address->get_ip_address(), address->get_port());
*ip_stop = tmp_ch; // restore original IP string
}
}
@ -518,8 +507,6 @@ sisr_retry:
_at.resp_stop();
tr_debug("Socket %d, recvfrom %s, %d bytes (err %d)", socket->id, socket->remoteAddress.get_ip_address(), len, _at.get_last_error());
return (_at.get_last_error() == NSAPI_ERROR_OK) ? (recv_len ? recv_len : NSAPI_ERROR_WOULD_BLOCK) : NSAPI_ERROR_DEVICE_ERROR;
}
@ -543,7 +530,6 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::create_connection_profile(int con
char paramTag[16];
int paramTagLen = _at.read_string(paramTag, sizeof(paramTag));
if (paramTagLen > 0) {
tr_debug("paramTag %s", paramTag);
char paramValue[100 + 1]; // APN may be up to 100 chars
int paramValueLen = _at.read_string(paramValue, sizeof(paramValue));
if (paramValueLen >= 0) {
@ -587,7 +573,7 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::create_connection_profile(int con
_at.cmd_stop_read_resp();
}
tr_debug("Connection profile %d, stack_type %d (err %d)", connection_profile_id, _stack_type, _at.get_last_error());
tr_debug("Cinterion profile %d, %s (err %d)", connection_profile_id, (_stack_type == IPV4_STACK) ? "IPv4" : "IPv6", _at.get_last_error());
return _at.get_last_error();
}

View File

@ -1,5 +1,17 @@
# Change Log
## [v4.7.2](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.7.2)
- Fix handling of duplicate blockwise ACK's
CoAP data buffer was not added into duplication info store when creating response for blockwise request.
This leads to case where whole bootstrap flow just timeouts if received any duplicate messages during blockwise operation.
Fixes error: IOTCLT-3188 - UDP connection fails for lost ACK sending
- Remove error trace when building reset message without options
This makes it possible to build the reset message without allocating option or getting error message.
-[Full Changelog](https://github.com/ARMmbed/mbed-coap/compare/v4.7.1...v4.7.2)
## [v4.7.1](https://github.com/ARMmbed/mbed-coap/releases/tag/v4.7.1)
- Fix CoAP stored blockwise message release and list continue

View File

@ -1,6 +1,6 @@
{
"name": "mbed-coap",
"version": "4.7.1",
"version": "4.7.2",
"description": "COAP library",
"keywords": [
"coap",

View File

@ -547,7 +547,10 @@ static int8_t sn_coap_builder_options_build(uint8_t **dst_packet_data_pptr, sn_c
/* * * * Check if Options are used at all * * * */
if (src_coap_msg_ptr->uri_path_ptr == NULL && src_coap_msg_ptr->token_ptr == NULL &&
src_coap_msg_ptr->content_format == COAP_CT_NONE && src_coap_msg_ptr->options_list_ptr == NULL) {
tr_error("sn_coap_builder_options_build - options not used!");
/* If the empty message is confirmable it is CoAP ping. */
if (src_coap_msg_ptr->msg_type != COAP_MSG_TYPE_CONFIRMABLE) {
tr_error("sn_coap_builder_options_build - options not used!");
}
return 0;
}

View File

@ -49,10 +49,12 @@
#if SN_COAP_DUPLICATION_MAX_MSGS_COUNT/* If Message duplication detection is not used at all, this part of code will not be compiled */
static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id, void *param);
static coap_duplication_info_s *sn_coap_protocol_linked_list_duplication_info_search(struct coap_s *handle, sn_nsdl_addr_s *scr_addr_ptr, uint16_t msg_id);
static coap_duplication_info_s *sn_coap_protocol_linked_list_duplication_info_search(const struct coap_s *handle, const sn_nsdl_addr_s *scr_addr_ptr, const uint16_t msg_id);
static void sn_coap_protocol_linked_list_duplication_info_remove(struct coap_s *handle, uint8_t *scr_addr_ptr, uint16_t port, uint16_t msg_id);
static void sn_coap_protocol_linked_list_duplication_info_remove_old_ones(struct coap_s *handle);
static bool sn_coap_protocol_update_duplicate_package_data(const struct coap_s *handle, const sn_nsdl_addr_s *dst_addr_ptr, const sn_coap_hdr_s *coap_msg_ptr, const int16_t data_size, const uint8_t *dst_packet_data_ptr);
#endif
#if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not enabled, this part of code will not be compiled */
static void sn_coap_protocol_linked_list_blockwise_msg_remove(struct coap_s *handle, coap_blockwise_msg_s *removed_msg_ptr);
static void sn_coap_protocol_linked_list_blockwise_payload_store(struct coap_s *handle, sn_nsdl_addr_s *addr_ptr, uint16_t stored_payload_len, uint8_t *stored_payload_ptr, uint8_t *token_ptr, uint8_t token_len, uint32_t block_number);
@ -65,6 +67,7 @@ static void sn_coap_protocol_handle_blockwise_timout(struct coa
static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn_nsdl_addr_s *src_addr_ptr, sn_coap_hdr_s *received_coap_msg_ptr, void *param);
static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coap_hdr_s *source_header_ptr);
#endif
#if ENABLE_RESENDINGS
static uint8_t sn_coap_protocol_linked_list_send_msg_store(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_ptr, uint16_t send_packet_data_len, uint8_t *send_packet_data_ptr, uint32_t sending_time, void *param);
static sn_nsdl_transmit_s *sn_coap_protocol_linked_list_send_msg_search(struct coap_s *handle,sn_nsdl_addr_s *src_addr_ptr, uint16_t msg_id);
@ -506,23 +509,12 @@ int16_t sn_coap_protocol_build(struct coap_s *handle, sn_nsdl_addr_s *dst_addr_p
#endif /* ENABLE_RESENDINGS */
#if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
if (src_coap_msg_ptr->msg_type == COAP_MSG_TYPE_ACKNOWLEDGEMENT &&
handle->sn_coap_duplication_buffer_size != 0) {
coap_duplication_info_s* info = sn_coap_protocol_linked_list_duplication_info_search(handle,
dst_addr_ptr,
src_coap_msg_ptr->msg_id);
/* Update package data to duplication info struct if it's not there yet */
if (info && info->packet_ptr == NULL) {
info->packet_ptr = handle->sn_coap_protocol_malloc(byte_count_built);
if (info->packet_ptr) {
memcpy(info->packet_ptr, dst_packet_data_ptr, byte_count_built);
info->packet_len = byte_count_built;
} else {
tr_error("sn_coap_protocol_build - failed to allocate duplication info!");
return -4;
}
}
// copy coap data buffer to duplicate list for resending purposes
if (!sn_coap_protocol_update_duplicate_package_data(handle, dst_addr_ptr, src_coap_msg_ptr, byte_count_built, dst_packet_data_ptr)) {
return -4;
}
#endif
#if SN_COAP_BLOCKWISE_ENABLED || SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* If Message blockwising is not enabled, this part of code will not be compiled */
@ -725,6 +717,7 @@ sn_coap_hdr_s *sn_coap_protocol_parse(struct coap_s *handle, sn_nsdl_addr_s *src
if (response) {
/* Check that response has been created */
if (response->packet_ptr) {
tr_debug("sn_coap_protocol_parse - send ack for duplicate message");
response->coap->sn_coap_tx_callback(response->packet_ptr,
response->packet_len, response->address, response->param);
}
@ -1154,7 +1147,7 @@ static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *h
}
/**************************************************************************//**
* \fn static int8_t sn_coap_protocol_linked_list_duplication_info_search(sn_nsdl_addr_s *addr_ptr, uint16_t msg_id)
* \fn static coap_duplication_info_s *sn_coap_protocol_linked_list_duplication_info_search(const struct coap_s *handle, const sn_nsdl_addr_s *scr_addr_ptr, const uint16_t msg_id)
*
* \brief Searches stored message from Linked list (Address and Message ID as key)
*
@ -1164,8 +1157,8 @@ static void sn_coap_protocol_linked_list_duplication_info_store(struct coap_s *h
* \return Return value is 0 when message found and -1 if not found
*****************************************************************************/
static coap_duplication_info_s* sn_coap_protocol_linked_list_duplication_info_search(struct coap_s *handle,
sn_nsdl_addr_s *addr_ptr, uint16_t msg_id)
static coap_duplication_info_s* sn_coap_protocol_linked_list_duplication_info_search(const struct coap_s *handle,
const sn_nsdl_addr_s *addr_ptr, const uint16_t msg_id)
{
/* Loop all nodes in Linked list for searching Message ID */
ns_list_foreach(coap_duplication_info_s, stored_duplication_info_ptr, &handle->linked_list_duplication_msgs) {
@ -2013,6 +2006,19 @@ static sn_coap_hdr_s *sn_coap_handle_blockwise_message(struct coap_s *handle, sn
}
sn_coap_builder_2(dst_ack_packet_data_ptr, src_coap_blockwise_ack_msg_ptr, handle->sn_coap_block_data_size);
#if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
// copy coap data buffer to duplicate list for resending purposes
if (!sn_coap_protocol_update_duplicate_package_data(handle,
src_addr_ptr,
src_coap_blockwise_ack_msg_ptr,
dst_packed_data_needed_mem,
dst_ack_packet_data_ptr)) {
sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
handle->sn_coap_protocol_free(dst_ack_packet_data_ptr);
return NULL;
}
#endif
handle->sn_coap_tx_callback(dst_ack_packet_data_ptr, dst_packed_data_needed_mem, src_addr_ptr, param);
sn_coap_parser_release_allocated_coap_msg_mem(handle, src_coap_blockwise_ack_msg_ptr);
@ -2509,3 +2515,32 @@ static sn_coap_hdr_s *sn_coap_protocol_copy_header(struct coap_s *handle, sn_coa
return destination_header_ptr;
}
#endif
#if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
static bool sn_coap_protocol_update_duplicate_package_data(const struct coap_s *handle,
const sn_nsdl_addr_s *dst_addr_ptr,
const sn_coap_hdr_s *coap_msg_ptr,
const int16_t data_size,
const uint8_t *dst_packet_data_ptr)
{
if (coap_msg_ptr->msg_type == COAP_MSG_TYPE_ACKNOWLEDGEMENT &&
handle->sn_coap_duplication_buffer_size != 0) {
coap_duplication_info_s* info = sn_coap_protocol_linked_list_duplication_info_search(handle,
dst_addr_ptr,
coap_msg_ptr->msg_id);
/* Update package data to duplication info struct if it's not there yet */
if (info && info->packet_ptr == NULL) {
info->packet_ptr = handle->sn_coap_protocol_malloc(data_size);
if (info->packet_ptr) {
memcpy(info->packet_ptr, dst_packet_data_ptr, data_size);
info->packet_len = data_size;
} else {
tr_error("sn_coap_protocol_update_duplication_package_data - failed to allocate duplication info!");
return false;
}
}
}
return true;
}
#endif

View File

@ -59,7 +59,12 @@ void mbedtls_ssl_conf_max_version(mbedtls_ssl_config *conf, int major, int minor
}
void mbedtls_ssl_config_init(mbedtls_ssl_config *a)
void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport )
{
}
void mbedtls_ssl_config_init( mbedtls_ssl_config *a )
{
}
@ -198,6 +203,16 @@ int mbedtls_ssl_write(mbedtls_ssl_context *a, const unsigned char *b, size_t c)
return mbedtls_stub.expected_int;
}
int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname )
{
return 0;
}
const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl )
{
return NULL;
}
//From crt_drbg.h
@ -252,6 +267,18 @@ int mbedtls_x509_crt_parse(mbedtls_x509_crt *a, const unsigned char *b, size_t c
return mbedtls_stub.expected_int;
}
int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix,
const mbedtls_x509_crt *crt )
{
return 0;
}
int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix,
uint32_t flags )
{
return 0;
}
//From entropy.h
void mbedtls_entropy_init(mbedtls_entropy_context *a)
{
@ -356,3 +383,6 @@ int mbedtls_ssl_session_reset(mbedtls_ssl_context *ssl)
}
return mbedtls_stub.expected_int;
}
void mbedtls_strerror( int ret, char *buf, size_t buflen ){
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 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.
*/
#include "DTLSSocket.h"
#define TRACE_GROUP "TLSS"
#include "mbed-trace/mbed_trace.h"
// This class requires Mbed TLS SSL/TLS client code
#if defined(MBEDTLS_SSL_CLI_C)
nsapi_error_t DTLSSocket::connect(const char *host, uint16_t port)
{
SocketAddress addr;
nsapi_error_t ret;
ret = _udp_socket.getpeername(&addr);
if (ret != NSAPI_ERROR_NO_CONNECTION) {
return ret;
}
if (!addr || ret == NSAPI_ERROR_NO_CONNECTION) {
nsapi_error_t err = _udp_socket._stack->gethostbyname(host, &addr);
if (err) {
return NSAPI_ERROR_DNS_FAILURE;
}
addr.set_port(port);
set_hostname(host);
_udp_socket.connect(addr); // UDPSocket::connect() cannot fail
}
return connect(addr);
}
DTLSSocket::~DTLSSocket()
{
// Make sure that DTLSSocketWrapper::close() is called before the transport is
// destroyed.
close();
}
#endif // MBEDTLS_SSL_CLI_C

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 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.
*/
#ifndef DTLSSOCKET_H
#define DTLSSOCKET_H
#include "DTLSSocketWrapper.h"
#include "SocketAddress.h"
#include "UDPSocket.h"
// This class requires Mbed TLS SSL/TLS client code
#if defined(MBEDTLS_SSL_CLI_C) || defined(DOXYGEN_ONLY)
class DTLSSocket : public DTLSSocketWrapper {
public:
/** Create an uninitialized DTLS socket
*
* Must call open to initialize the socket on a network stack.
*/
DTLSSocket() : DTLSSocketWrapper(&_udp_socket) {}
/** Destroy the DTLSSocket and closes the transport.
*/
virtual ~DTLSSocket();
/** Create a socket on a network interface
*
* Creates and opens a socket on the network stack of the given
* network interface.
* If hostname is also given, user is not required to call set_hostname() later.
*
* @param stack Network stack as target for socket
* @param hostname Hostname used for certificate verification
*/
template <typename S>
DTLSSocket(S *stack, const char *hostname = NULL) : DTLSSocketWrapper(&_udp_socket, hostname)
{
nsapi_error_t ret = _udp_socket.open(stack);
MBED_ASSERT(ret == NSAPI_ERROR_OK);
}
/** Opens a socket
*
* Creates a network socket on the network stack of the given
* network interface. Not needed if stack is passed to the
* socket's constructor.
*
* @param stack Network stack as target for socket
* @return 0 on success, negative error code on failure
*/
virtual nsapi_error_t open(NetworkStack *stack)
{
return _udp_socket.open(stack);
}
template <typename S>
nsapi_error_t open(S *stack)
{
return open(nsapi_create_stack(stack));
}
using DTLSSocketWrapper::connect;
/** Connects TCP socket to a remote host
*
* Initiates a connection to a remote server specified by either
* a domain name or an IP address and a port.
*
* @param host Hostname of the remote host
* @param port Port of the remote host
* @return 0 on success, negative error code on failure
*/
nsapi_error_t connect(const char *host, uint16_t port);
private:
UDPSocket _udp_socket;
};
#endif
#endif

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 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.
*/
#include "DTLSSocketWrapper.h"
#include "platform/Callback.h"
#include "drivers/Timer.h"
#include "events/mbed_events.h"
#include "rtos/Kernel.h"
#if defined(MBEDTLS_SSL_CLI_C)
DTLSSocketWrapper::DTLSSocketWrapper(Socket *transport, const char *hostname, control_transport control) :
TLSSocketWrapper(transport, hostname, control),
_int_ms_tick(0),
_timer_event_id(0),
_timer_expired(false)
{
mbedtls_ssl_conf_transport(get_ssl_config(), MBEDTLS_SSL_TRANSPORT_DATAGRAM);
mbedtls_ssl_set_timer_cb(get_ssl_context(), this, timing_set_delay, timing_get_delay);
}
void DTLSSocketWrapper::timing_set_delay(void *ctx, uint32_t int_ms, uint32_t fin_ms)
{
DTLSSocketWrapper *context = static_cast<DTLSSocketWrapper *>(ctx);
if (context->_timer_event_id) {
mbed::mbed_event_queue()->cancel(context->_timer_event_id);
context->_timer_expired = false;
}
if (fin_ms == 0) {
context->_timer_event_id = 0;
return;
}
context->_int_ms_tick = rtos::Kernel::get_ms_count() + int_ms;
context->_timer_event_id = mbed::mbed_event_queue()->call_in(fin_ms, context, &DTLSSocketWrapper::timer_event);
}
int DTLSSocketWrapper::timing_get_delay(void *ctx)
{
DTLSSocketWrapper *context = static_cast<DTLSSocketWrapper *>(ctx);
/* See documentation of "typedef int mbedtls_ssl_get_timer_t( void * ctx );" from ssl.h */
if (context->_timer_event_id == 0) {
return -1;
} else if (context->_timer_expired) {
return 2;
} else if (context->_int_ms_tick < rtos::Kernel::get_ms_count()) {
return 1;
} else {
return 0;
}
}
void DTLSSocketWrapper::timer_event(void)
{
_timer_expired = true;
event();
}
#endif /* MBEDTLS_SSL_CLI_C */

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 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.
*/
#ifndef DTLSSOCKETWRAPPER_H
#define DTLSSOCKETWRAPPER_H
#include "TLSSocketWrapper.h"
// This class requires Mbed TLS SSL/TLS client code
#if defined(MBEDTLS_SSL_CLI_C) || defined(DOXYGEN_ONLY)
class DTLSSocketWrapper : public TLSSocketWrapper {
public:
DTLSSocketWrapper(Socket *transport, const char *hostname = NULL, control_transport control = TRANSPORT_CONNECT_AND_CLOSE);
private:
static void timing_set_delay(void *ctx, uint32_t int_ms, uint32_t fin_ms);
static int timing_get_delay(void *ctx);
void timer_event();
uint64_t _int_ms_tick;
int _timer_event_id;
bool _timer_expired : 1;
};
#endif
#endif

View File

@ -175,6 +175,8 @@ protected:
static const int WRITE_FLAG = 0x2u;
static const int FINISHED_FLAG = 0x3u;
friend class DTLSSocket; // Allow DTLSSocket::connect() to do name resolution on the _stack
#endif //!defined(DOXYGEN_ONLY)
};

View File

@ -103,6 +103,9 @@ nsapi_error_t TCPSocket::connect(const SocketAddress &address)
nsapi_error_t TCPSocket::connect(const char *host, uint16_t port)
{
SocketAddress address;
if (!_socket) {
return NSAPI_ERROR_NO_SOCKET;
}
nsapi_error_t err = _stack->gethostbyname(host, &address);
if (err) {
return NSAPI_ERROR_DNS_FAILURE;

View File

@ -42,8 +42,14 @@ public:
* network interface.
*
* @param stack Network stack as target for socket
*
* @deprecated since mbed-os-5.11
*/
template <typename S>
MBED_DEPRECATED_SINCE("mbed-os-5.11",
"The TCPSocket(S *stack) constructor is deprecated."
"It discards the open() call return value."
"Use another constructor and call open() explicitly, instead.")
TCPSocket(S *stack)
{
open(stack);

View File

@ -25,14 +25,17 @@
nsapi_error_t TLSSocket::connect(const char *host, uint16_t port)
{
set_hostname(host);
nsapi_error_t ret = tcp_socket.connect(host, port);
if (ret) {
return ret;
nsapi_error_t ret = NSAPI_ERROR_OK;
if (!is_handshake_started()) {
ret = tcp_socket.connect(host, port);
if (ret == NSAPI_ERROR_OK || ret == NSAPI_ERROR_IN_PROGRESS) {
set_hostname(host);
}
if (ret != NSAPI_ERROR_OK && ret != NSAPI_ERROR_IS_CONNECTED) {
return ret;
}
}
return TLSSocketWrapper::do_handshake();
return TLSSocketWrapper::start_handshake(ret == NSAPI_ERROR_OK);
}
TLSSocket::~TLSSocket()
@ -44,4 +47,4 @@ TLSSocket::~TLSSocket()
close();
}
#endif // MBEDTLS_SSL_CLI_C
#endif // MBEDTLS_SSL_CLI_C

View File

@ -28,7 +28,7 @@
#include "mbedtls/error.h"
// This class requires Mbed TLS SSL/TLS client code
#if defined(MBEDTLS_SSL_CLI_C)
#if defined(MBEDTLS_SSL_CLI_C) || defined(DOXYGEN_ONLY)
/**
* \brief TLSSocket a wrapper around TCPSocket for interacting with TLS servers
@ -45,28 +45,15 @@ public:
*/
virtual ~TLSSocket();
/** Create a socket on a network interface
*
* Creates and opens a socket on the network stack of the given
* network interface.
* If hostname is also given, user is not required to call set_hostname() later.
*
* @param stack Network stack as target for socket
* @param hostname Hostname used for certificate verification
*/
template <typename S>
TLSSocket(S *stack, const char *hostname = NULL) : TLSSocketWrapper(&tcp_socket, hostname)
{
nsapi_error_t ret = tcp_socket.open(stack);
MBED_ASSERT(ret == NSAPI_ERROR_OK);
}
/** Opens a socket
*
* Creates a network socket on the network stack of the given
* network interface. Not needed if stack is passed to the
* socket's constructor.
*
* @note TLSSocket cannot be reopened after closing. It should be destructed to
* clear internal TLS memory structures.
*
* @param stack Network stack as target for socket
* @return 0 on success, negative error code on failure
*/

View File

@ -16,18 +16,22 @@
*/
#include "TLSSocketWrapper.h"
#include "platform/Callback.h"
#include "drivers/Timer.h"
#include "events/mbed_events.h"
#define TRACE_GROUP "TLSW"
#include "mbed-trace/mbed_trace.h"
#include "mbedtls/debug.h"
#include "mbed_error.h"
#include "Kernel.h"
// This class requires Mbed TLS SSL/TLS client code
#if defined(MBEDTLS_SSL_CLI_C)
TLSSocketWrapper::TLSSocketWrapper(Socket *transport, const char *hostname, control_transport control) :
_transport(transport),
_timeout(-1),
#ifdef MBEDTLS_X509_CRT_PARSE_C
_cacert(NULL),
_clicert(NULL),
@ -35,6 +39,7 @@ TLSSocketWrapper::TLSSocketWrapper(Socket *transport, const char *hostname, cont
_ssl_conf(NULL),
_connect_transport(control == TRANSPORT_CONNECT || control == TRANSPORT_CONNECT_AND_CLOSE),
_close_transport(control == TRANSPORT_CLOSE || control == TRANSPORT_CONNECT_AND_CLOSE),
_tls_initialized(false),
_handshake_completed(false),
_cacert_allocated(false),
_clicert_allocated(false),
@ -43,7 +48,9 @@ TLSSocketWrapper::TLSSocketWrapper(Socket *transport, const char *hostname, cont
mbedtls_entropy_init(&_entropy);
mbedtls_ctr_drbg_init(&_ctr_drbg);
mbedtls_ssl_init(&_ssl);
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_pk_init(&_pkctx);
#endif
if (hostname) {
set_hostname(hostname);
@ -58,9 +65,8 @@ TLSSocketWrapper::~TLSSocketWrapper()
mbedtls_entropy_free(&_entropy);
mbedtls_ctr_drbg_free(&_ctr_drbg);
mbedtls_ssl_free(&_ssl);
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_pk_free(&_pkctx);
#ifdef MBEDTLS_X509_CRT_PARSE_C
set_own_cert(NULL);
set_ca_chain(NULL);
#endif
@ -114,7 +120,7 @@ nsapi_error_t TLSSocketWrapper::set_client_cert_key(const char *client_cert_pem,
nsapi_error_t TLSSocketWrapper::set_client_cert_key(const void *client_cert, size_t client_cert_len,
const void *client_private_key_pem, size_t client_private_key_len)
{
#if !defined(MBEDTLS_X509_CRT_PARSE_C)
#if !defined(MBEDTLS_X509_CRT_PARSE_C) || !defined(MBEDTLS_PK_C)
return NSAPI_ERROR_UNSUPPORTED;
#else
@ -140,29 +146,34 @@ nsapi_error_t TLSSocketWrapper::set_client_cert_key(const void *client_cert, siz
}
nsapi_error_t TLSSocketWrapper::do_handshake()
nsapi_error_t TLSSocketWrapper::start_handshake(bool first_call)
{
nsapi_error_t _error;
const char DRBG_PERS[] = "mbed TLS client";
int ret;
if (!_transport) {
return NSAPI_ERROR_NO_SOCKET;
}
_transport->set_blocking(true);
if (_tls_initialized) {
return continue_handshake();
}
#ifdef MBEDTLS_X509_CRT_PARSE_C
tr_info("Starting TLS handshake with %s", _ssl.hostname);
#else
tr_info("Starting TLS handshake");
#endif
/*
* Initialize TLS-related stuf.
*/
int ret;
if ((ret = mbedtls_ctr_drbg_seed(&_ctr_drbg, mbedtls_entropy_func, &_entropy,
(const unsigned char *) DRBG_PERS,
sizeof(DRBG_PERS))) != 0) {
print_mbedtls_error("mbedtls_crt_drbg_init", ret);
_error = ret;
return _error;
return NSAPI_ERROR_PARAMETER;
}
tr_info("mbedtls_ssl_conf_rng()");
mbedtls_ssl_conf_rng(get_ssl_config(), mbedtls_ctr_drbg_random, &_ctr_drbg);
@ -172,29 +183,62 @@ nsapi_error_t TLSSocketWrapper::do_handshake()
mbedtls_debug_set_threshold(MBED_CONF_TLS_SOCKET_DEBUG_LEVEL);
#endif
tr_info("mbedtls_ssl_setup()");
tr_debug("mbedtls_ssl_setup()");
if ((ret = mbedtls_ssl_setup(&_ssl, get_ssl_config())) != 0) {
print_mbedtls_error("mbedtls_ssl_setup", ret);
_error = ret;
return _error;
return NSAPI_ERROR_PARAMETER;
}
_transport->set_blocking(false);
_transport->sigio(mbed::callback(this, &TLSSocketWrapper::event));
mbedtls_ssl_set_bio(&_ssl, this, ssl_send, ssl_recv, NULL);
#ifdef MBEDTLS_X509_CRT_PARSE_C
/* Start the handshake, the rest will be done in onReceive() */
tr_info("Starting TLS handshake with %s", _ssl.hostname);
#else
tr_info("Starting TLS handshake");
#endif
_tls_initialized = true;
do {
ret = continue_handshake();
if (first_call) {
if (ret == NSAPI_ERROR_ALREADY) {
ret = NSAPI_ERROR_IN_PROGRESS; // If first call should return IN_PROGRESS
}
if (ret == NSAPI_ERROR_IS_CONNECTED) {
ret = NSAPI_ERROR_OK; // If we happened to complete the request on the first call, return OK.
}
}
return ret;
}
nsapi_error_t TLSSocketWrapper::continue_handshake()
{
int ret;
if (_handshake_completed) {
return NSAPI_ERROR_IS_CONNECTED;
}
if (!_tls_initialized) {
return NSAPI_ERROR_NO_CONNECTION;
}
while (true) {
ret = mbedtls_ssl_handshake(&_ssl);
} while (ret != 0 && (ret == MBEDTLS_ERR_SSL_WANT_READ ||
ret == MBEDTLS_ERR_SSL_WANT_WRITE));
if (_timeout && (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)) {
uint32_t flag;
flag = _event_flag.wait_any(1, _timeout);
if (flag & osFlagsError) {
break;
}
} else {
break;
}
}
if (ret < 0) {
print_mbedtls_error("mbedtls_ssl_handshake", ret);
return ret;
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
return NSAPI_ERROR_ALREADY;
} else {
return NSAPI_ERROR_AUTH_FAILURE;
}
}
#ifdef MBEDTLS_X509_CRT_PARSE_C
@ -225,8 +269,7 @@ nsapi_error_t TLSSocketWrapper::do_handshake()
#endif
_handshake_completed = true;
return 0;
return NSAPI_ERROR_IS_CONNECTED;
}
@ -239,15 +282,42 @@ nsapi_error_t TLSSocketWrapper::send(const void *data, nsapi_size_t size)
}
tr_debug("send %d", size);
ret = mbedtls_ssl_write(&_ssl, (const unsigned char *) data, size);
while (true) {
if (!_handshake_completed) {
ret = continue_handshake();
if (ret != NSAPI_ERROR_IS_CONNECTED) {
if (ret == NSAPI_ERROR_ALREADY) {
ret = NSAPI_ERROR_NO_CONNECTION;
}
return ret;
}
}
ret = mbedtls_ssl_write(&_ssl, (const unsigned char *) data, size);
if (_timeout == 0) {
break;
} else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ) {
uint32_t flag;
flag = _event_flag.wait_any(1, _timeout);
if (flag & osFlagsError) {
// Timeout break
break;
}
} else {
break;
}
}
if (ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
ret == MBEDTLS_ERR_SSL_WANT_READ) {
// translate to socket error
return NSAPI_ERROR_WOULD_BLOCK;
}
if (ret < 0) {
print_mbedtls_error("mbedtls_ssl_write", ret);
return NSAPI_ERROR_DEVICE_ERROR;
}
return ret; // Assume "non negative errorcode" to be propagated from Socket layer
}
@ -266,15 +336,39 @@ nsapi_size_or_error_t TLSSocketWrapper::recv(void *data, nsapi_size_t size)
return NSAPI_ERROR_NO_SOCKET;
}
ret = mbedtls_ssl_read(&_ssl, (unsigned char *) data, size);
while (true) {
if (!_handshake_completed) {
ret = continue_handshake();
if (ret != NSAPI_ERROR_IS_CONNECTED) {
if (ret == NSAPI_ERROR_ALREADY) {
ret = NSAPI_ERROR_NO_CONNECTION;
}
return ret;
}
}
ret = mbedtls_ssl_read(&_ssl, (unsigned char *) data, size);
if (_timeout == 0) {
break;
} else if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_WANT_READ) {
uint32_t flag;
flag = _event_flag.wait_any(1, _timeout);
if (flag & osFlagsError) {
// Timeout break
break;
}
} else {
break;
}
}
if (ret == MBEDTLS_ERR_SSL_WANT_WRITE ||
ret == MBEDTLS_ERR_SSL_WANT_READ) {
// translate to socket error
return NSAPI_ERROR_WOULD_BLOCK;
} else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
/* MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY is not considered as error.
* Just ignre here. Once connection is closed, mbedtls_ssl_read()
* Just ignore here. Once connection is closed, mbedtls_ssl_read()
* will return 0.
*/
return 0;
@ -390,7 +484,7 @@ int TLSSocketWrapper::ssl_send(void *ctx, const unsigned char *buf, size_t len)
return size;
}
#ifdef MBEDTLS_X509_CRT_PARSE_C
#if defined(MBEDTLS_X509_CRT_PARSE_C)
mbedtls_x509_crt *TLSSocketWrapper::get_own_cert()
{
@ -427,7 +521,7 @@ void TLSSocketWrapper::set_ca_chain(mbedtls_x509_crt *crt)
_cacert_allocated = false;
}
_cacert = crt;
tr_info("mbedtls_ssl_conf_ca_chain()");
tr_debug("mbedtls_ssl_conf_ca_chain()");
mbedtls_ssl_conf_ca_chain(get_ssl_config(), _cacert, NULL);
}
@ -441,7 +535,6 @@ mbedtls_ssl_config *TLSSocketWrapper::get_ssl_config()
mbedtls_ssl_config_init(_ssl_conf);
_ssl_conf_allocated = true;
tr_info("mbedtls_ssl_config_defaults()");
if ((ret = mbedtls_ssl_config_defaults(_ssl_conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
@ -454,7 +547,6 @@ mbedtls_ssl_config *TLSSocketWrapper::get_ssl_config()
/* It is possible to disable authentication by passing
* MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
*/
tr_info("mbedtls_ssl_conf_authmode()");
mbedtls_ssl_conf_authmode(get_ssl_config(), MBEDTLS_SSL_VERIFY_REQUIRED);
}
return _ssl_conf;
@ -470,6 +562,11 @@ void TLSSocketWrapper::set_ssl_config(mbedtls_ssl_config *conf)
_ssl_conf = conf;
}
mbedtls_ssl_context *TLSSocketWrapper::get_ssl_context()
{
return &_ssl;
}
nsapi_error_t TLSSocketWrapper::close()
{
if (!_transport) {
@ -502,17 +599,18 @@ nsapi_error_t TLSSocketWrapper::close()
nsapi_error_t TLSSocketWrapper::connect(const SocketAddress &address)
{
nsapi_error_t ret = NSAPI_ERROR_OK;
if (!_transport) {
return NSAPI_ERROR_NO_SOCKET;
}
if (_connect_transport) {
nsapi_error_t ret = _transport->connect(address);
if (ret) {
if (!is_handshake_started() && _connect_transport) {
ret = _transport->connect(address);
if (ret && ret != NSAPI_ERROR_IS_CONNECTED) {
return ret;
}
}
return do_handshake();
return start_handshake(ret == NSAPI_ERROR_OK);
}
nsapi_error_t TLSSocketWrapper::bind(const SocketAddress &address)
@ -525,18 +623,17 @@ nsapi_error_t TLSSocketWrapper::bind(const SocketAddress &address)
void TLSSocketWrapper::set_blocking(bool blocking)
{
if (!_transport) {
return;
}
_transport->set_blocking(blocking);
set_timeout(blocking ? -1 : 0);
}
void TLSSocketWrapper::set_timeout(int timeout)
{
if (!_transport) {
return;
_timeout = timeout;
if (!is_handshake_started() && timeout != -1 && _connect_transport) {
// If we have not yet connected the transport, we need to modify its blocking mode as well.
// After connection is initiated, it is already set to non blocking mode
_transport->set_timeout(timeout);
}
_transport->set_timeout(timeout);
}
void TLSSocketWrapper::sigio(mbed::Callback<void()> func)
@ -544,8 +641,8 @@ void TLSSocketWrapper::sigio(mbed::Callback<void()> func)
if (!_transport) {
return;
}
// Allow sigio() to propagate to upper level and handle errors on recv() and send()
_transport->sigio(func);
_sigio = func;
_transport->sigio(mbed::callback(this, &TLSSocketWrapper::event));
}
nsapi_error_t TLSSocketWrapper::setsockopt(int level, int optname, const void *optval, unsigned optlen)
@ -577,6 +674,20 @@ nsapi_error_t TLSSocketWrapper::listen(int)
return NSAPI_ERROR_UNSUPPORTED;
}
void TLSSocketWrapper::event()
{
_event_flag.set(1);
if (_sigio) {
_sigio();
}
}
bool TLSSocketWrapper::is_handshake_started() const
{
return _tls_initialized;
}
nsapi_error_t TLSSocketWrapper::getpeername(SocketAddress *address)
{
if (!_handshake_completed) {

View File

@ -19,7 +19,8 @@
#define _MBED_HTTPS_TLS_SOCKET_WRAPPER_H_
#include "netsocket/Socket.h"
#include "rtos/EventFlags.h"
#include "platform/Callback.h"
#include "mbedtls/platform.h"
#include "mbedtls/ssl.h"
#include "mbedtls/entropy.h"
@ -27,7 +28,7 @@
#include "mbedtls/error.h"
// This class requires Mbed TLS SSL/TLS client code
#if defined(MBEDTLS_SSL_CLI_C)
#if defined(MBEDTLS_SSL_CLI_C) || defined(DOXYGEN_ONLY)
/**
* \brief TLSSocket a wrapper around Socket for interacting with TLS servers
@ -134,7 +135,7 @@ public:
virtual nsapi_error_t listen(int backlog = 1);
virtual nsapi_error_t getpeername(SocketAddress *address);
#if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(DOXYGEN)
#if defined(MBEDTLS_X509_CRT_PARSE_C) || defined(DOXYGEN_ONLY)
/** Get own certificate directly from Mbed TLS
* @return internal Mbed TLS X509 structure
*/
@ -167,12 +168,12 @@ public:
*/
void set_ssl_config(mbedtls_ssl_config *conf);
protected:
/**
* Helper for pretty-printing mbed TLS error codes
/** Get internal Mbed TLS contect structure.
* @return SSL context
*/
static void print_mbedtls_error(const char *name, int err);
mbedtls_ssl_context *get_ssl_context();
protected:
/** Initiates TLS Handshake
*
* Initiates a TLS handshake to a remote peer
@ -181,9 +182,28 @@ protected:
* Root CA certification must be set by set_ssl_ca_pem() before
* call this function.
*
* For non-blocking purposes, this functions needs to know whether this
* was a first call to Socket::connect() API so that NSAPI_ERROR_INPROGRESS
* does not happen twice.
*
* @parameter first_call is this a first call to Socket::connect() API.
* @return 0 on success, negative error code on failure
*/
nsapi_error_t do_handshake();
nsapi_error_t start_handshake(bool first_call);
bool is_handshake_started() const;
void event();
private:
/** Continue already initialised handshake */
nsapi_error_t continue_handshake();
/**
* Helper for pretty-printing mbed TLS error codes
*/
static void print_mbedtls_error(const char *name, int err);
#if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0
/**
@ -211,13 +231,17 @@ protected:
*/
static int ssl_send(void *ctx, const unsigned char *buf, size_t len);
private:
mbedtls_ssl_context _ssl;
#ifdef MBEDTLS_X509_CRT_PARSE_C
mbedtls_pk_context _pkctx;
#endif
mbedtls_ctr_drbg_context _ctr_drbg;
mbedtls_entropy_context _entropy;
rtos::EventFlags _event_flag;
mbed::Callback<void()> _sigio;
Socket *_transport;
int _timeout;
#ifdef MBEDTLS_X509_CRT_PARSE_C
mbedtls_x509_crt *_cacert;
@ -227,6 +251,7 @@ private:
bool _connect_transport: 1;
bool _close_transport: 1;
bool _tls_initialized: 1;
bool _handshake_completed: 1;
bool _cacert_allocated: 1;
bool _clicert_allocated: 1;

View File

@ -41,8 +41,13 @@ public:
*
* @tparam S Type of the Network stack.
* @param stack Network stack as target for socket.
* @deprecated since mbed-os-5.11
*/
template <typename S>
MBED_DEPRECATED_SINCE("mbed-os-5.11",
"The UDPSocket(S *stack) constructor is deprecated"
"It discards the open() call return value."
"Use another constructor and call open() explicitly, instead.")
UDPSocket(S *stack)
{
open(stack);

View File

@ -40,9 +40,12 @@
#include "netsocket/UDPSocket.h"
#include "netsocket/TCPSocket.h"
#include "netsocket/TCPServer.h"
#include "netsocket/TLSSocketWrapper.h"
#include "netsocket/DTLSSocketWrapper.h"
#include "netsocket/TLSSocket.h"
#include "netsocket/DTLSSocket.h"
#endif
#endif // __cplusplus
#endif

View File

@ -24,6 +24,7 @@
#include "mbed_trace.h"
#include <inttypes.h>
#include <stdlib.h>
#include "BufferedBlockDevice.h"
using namespace utest::v1;
@ -99,10 +100,7 @@ void test_random_program_read_erase()
BlockDevice *block_device = BlockDevice::get_default_instance();
if (!block_device) {
utest_printf("\nno block device found.\n");
return;
}
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
int err = block_device->init();
TEST_ASSERT_EQUAL(0, err);
@ -173,10 +171,7 @@ void test_multi_threads()
BlockDevice *block_device = BlockDevice::get_default_instance();
if (!block_device) {
utest_printf("\nno block device found.\n");
return;
}
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
int err = block_device->init();
TEST_ASSERT_EQUAL(0, err);
@ -297,7 +292,7 @@ void test_contiguous_erase_write_read()
// - Tests contiguous erase
// 2. Write smaller memory area
// - Tests contiguous sector writes
// 3. Rerun step 2 for whole erase region
// 3. Return step 2 for whole erase region
BlockDevice *block_device = BlockDevice::get_default_instance();
TEST_SKIP_UNLESS_MESSAGE(block_device != NULL, "\nno block device found.\n");
@ -326,7 +321,8 @@ void test_contiguous_erase_write_read()
if (write_read_buf_size < program_size * 2) {
write_read_buf_size = program_size * 2; // going over 10k
}
bd_size_t contiguous_write_read_blocks_per_region = write_read_buf_size / program_size; // 2 is minimum to test contiguous write
bd_size_t contiguous_write_read_blocks_per_region = write_read_buf_size /
program_size; // 2 is minimum to test contiguous write
write_read_buf_size = contiguous_write_read_blocks_per_region * program_size;
utest_printf("\ncontiguous_write_read_blocks_per_region=%" PRIu64, contiguous_write_read_blocks_per_region);
utest_printf("\nwrite_read_buf_size=%" PRIu64, write_read_buf_size);
@ -365,7 +361,8 @@ void test_contiguous_erase_write_read()
for (size_t i = 0; i < write_read_buf_size; i++) {
write_read_buf[i] = (uint8_t)rand();
}
utest_printf("\npre-filling memory, from 0x%" PRIx64 " of size 0x%" PRIx64, start_address + offset, write_read_buf_size);
utest_printf("\npre-filling memory, from 0x%" PRIx64 " of size 0x%" PRIx64, start_address + offset,
write_read_buf_size);
err = block_device->program((const void *)write_read_buf, start_address + offset, write_read_buf_size);
TEST_ASSERT_EQUAL(0, err);
}
@ -420,6 +417,61 @@ void test_contiguous_erase_write_read()
TEST_ASSERT_EQUAL(0, err);
}
void test_program_read_small_data_sizes()
{
utest_printf("\nTest program-read small data sizes, from 1 to 7 bytes..\n");
BlockDevice *bd = BlockDevice::get_default_instance();
TEST_SKIP_UNLESS_MESSAGE(bd != NULL, "\nno block device found.\n");
// use BufferedBlockDevice for better handling of block devices program and read
BufferedBlockDevice *block_device = new BufferedBlockDevice(bd);
// BlockDevice initialization
int err = block_device->init();
TEST_ASSERT_EQUAL(0, err);
const char write_buffer[] = "1234567";
char read_buffer[7] = {};
bd_size_t erase_size = block_device->get_erase_size();
bd_size_t program_size = block_device->get_program_size();
TEST_ASSERT(program_size > 0);
// Determine starting address
bd_addr_t start_address = 0;
for (int i = 1; i <= 7; i++) {
err = block_device->erase(start_address, erase_size);
TEST_ASSERT_EQUAL(0, err);
err = block_device->program((const void *)write_buffer, start_address, i);
TEST_ASSERT_EQUAL(0, err);
err = block_device->sync();
TEST_ASSERT_EQUAL(0, err);
err = block_device->read(read_buffer, start_address, i);
TEST_ASSERT_EQUAL(0, err);
err = memcmp(write_buffer, read_buffer, i);
TEST_ASSERT_EQUAL(0, err);
}
// BlockDevice deinitialization
err = block_device->deinit();
TEST_ASSERT_EQUAL(0, err);
delete block_device;
}
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
{
greentea_case_failure_abort_handler(source, reason);
return STATUS_CONTINUE;
}
// Test setup
utest::v1::status_t test_setup(const size_t number_of_cases)
{
@ -428,10 +480,11 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
}
Case cases[] = {
Case("Testing read write random blocks", test_random_program_read_erase),
Case("Testing Multi Threads Erase Program Read", test_multi_threads),
Case("Testing contiguous erase, write and read", test_contiguous_erase_write_read),
Case("Test BlockDevice::get_erase_value()", test_get_erase_value)
Case("Testing read write random blocks", test_random_program_read_erase, greentea_failure_handler),
Case("Testing multi threads erase program read", test_multi_threads, greentea_failure_handler),
Case("Testing contiguous erase, write and read", test_contiguous_erase_write_read, greentea_failure_handler),
Case("Testing BlockDevice::get_erase_value()", test_get_erase_value, greentea_failure_handler),
Case("Testing program read small data sizes", test_program_read_small_data_sizes, greentea_failure_handler)
};
Specification specification(test_setup, cases);

View File

@ -32,6 +32,10 @@
#include "wifi_conf.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*rtw_event_handler_t)(char *buf, int buf_len, int flags, void* handler_user_data );
typedef struct
@ -90,6 +94,10 @@ extern void wifi_reg_event_handler(unsigned int event_cmds, rtw_event_handler_t
*/
extern void wifi_unreg_event_handler(unsigned int event_cmds, rtw_event_handler_t handler_func);
#ifdef __cplusplus
}
#endif
/*\@}*/
#endif //_WIFI_INDICATE_H