mirror of https://github.com/ARMmbed/mbed-os.git
Cellular: Unit tests for Non-IP socket
parent
d301e13610
commit
ba3727b4e8
|
@ -51,26 +51,26 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_at_handler)
|
|||
FileHandle_stub fh1;
|
||||
FileHandle_stub fh2;
|
||||
FileHandle_stub fh3;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
AT_CellularDevice dev(&fh1); // AT fh1 ref count 1
|
||||
|
||||
EXPECT_TRUE(dev.open_network(&fh1));
|
||||
EXPECT_TRUE(dev.open_network(&fh1)); // AT fh1 ref count 2
|
||||
EXPECT_TRUE(dev.open_sms(&fh2));
|
||||
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
|
||||
EXPECT_TRUE(dev.open_information(&fh3));
|
||||
ATHandler_stub::fh_value = &fh1;
|
||||
EXPECT_TRUE(dev.open_power(&fh1));
|
||||
EXPECT_TRUE(dev.open_power(&fh1)); // AT fh1 ref count 3
|
||||
|
||||
ATHandler_stub::fh_value = NULL;
|
||||
|
||||
AT_CellularDevice *dev2 = new AT_CellularDevice(&fh1);
|
||||
EXPECT_TRUE(dev2->open_information(&fh1));
|
||||
ATHandler *at = dev2->get_at_handler();
|
||||
AT_CellularDevice *dev2 = new AT_CellularDevice(&fh1); // AT fh1 ref count 4
|
||||
EXPECT_TRUE(dev2->open_information(&fh1)); // AT fh1 ref count 5
|
||||
ATHandler *at = dev2->get_at_handler(); // AT fh1 ref count 6
|
||||
EXPECT_TRUE(at->get_ref_count() == 6);
|
||||
delete dev2; // AT fh1 2 refs deleted -> ref count 4
|
||||
EXPECT_TRUE(at->get_ref_count() == 4);
|
||||
delete dev2;
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
AT_CellularDevice dev3(&fh1);
|
||||
EXPECT_TRUE(dev3.release_at_handler(at) == NSAPI_ERROR_OK);
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
AT_CellularDevice dev3(&fh1); // AT fh1 ref count 5
|
||||
EXPECT_TRUE(dev3.release_at_handler(at) == NSAPI_ERROR_OK); // AT fh1 ref count 4
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 4);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_network)
|
||||
|
@ -129,42 +129,39 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_network)
|
|||
{
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::ref_count = 0;
|
||||
|
||||
EXPECT_TRUE(dev.open_network(&fh1));
|
||||
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
|
||||
dev.close_network();
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
|
||||
EXPECT_TRUE(ATHANDLER_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_sms)
|
||||
{
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::ref_count = 0;
|
||||
|
||||
EXPECT_TRUE(dev.open_sms(&fh1));
|
||||
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
|
||||
dev.close_sms();
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
|
||||
EXPECT_TRUE(ATHANDLER_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_power)
|
||||
{
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::ref_count = 0;
|
||||
|
||||
EXPECT_TRUE(dev.open_power(&fh1));
|
||||
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
|
||||
dev.close_power();
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
|
||||
EXPECT_TRUE(ATHANDLER_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
|
||||
|
@ -188,7 +185,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
|
|||
AT_CellularBase_stub::handler_value = AT_CellularBase_stub::handler_at_constructor_value;
|
||||
|
||||
dev.close_information();
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == kATHandler_destructor_ref_ount);
|
||||
EXPECT_TRUE(ATHANDLER_REF_COUNT_AT_DESTRUCTOR == kATHandler_destructor_ref_ount);
|
||||
|
||||
ATHandler_stub::fh_value = NULL;
|
||||
}
|
||||
|
@ -205,7 +202,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_set_timeout)
|
|||
EXPECT_TRUE(ATHandler_stub::default_timeout == true);
|
||||
|
||||
EXPECT_TRUE(dev.open_sms(&fh1));
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
|
||||
dev.set_timeout(5000);
|
||||
EXPECT_TRUE(ATHandler_stub::timeout == 5000);
|
||||
|
@ -224,7 +221,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_modem_debug_on)
|
|||
EXPECT_TRUE(ATHandler_stub::debug_on == true);
|
||||
|
||||
EXPECT_TRUE(dev.open_sms(&fh1));
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 1);
|
||||
EXPECT_TRUE(ATHandler_stub::ref_count == 2);
|
||||
|
||||
dev.modem_debug_on(true);
|
||||
EXPECT_TRUE(ATHandler_stub::debug_on == true);
|
||||
|
@ -305,7 +302,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
|
|||
AT_CellularDevice *dev = new AT_CellularDevice(&fh1);
|
||||
|
||||
ATHandler *at = dev->get_at_handler();
|
||||
EXPECT_TRUE(at->get_ref_count() == 1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 2);
|
||||
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);
|
||||
|
||||
CellularContext *ctx = dev->create_context(NULL);
|
||||
|
@ -313,12 +310,12 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
|
|||
|
||||
dev = new AT_CellularDevice(&fh1);
|
||||
at = dev->get_at_handler();
|
||||
EXPECT_TRUE(at->get_ref_count() == 1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 2);
|
||||
ctx = dev->create_context(NULL);
|
||||
CellularContext *ctx1 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
CellularContext *ctx2 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 4);
|
||||
CellularContext *ctx2 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 5);
|
||||
|
||||
EXPECT_TRUE(ctx);
|
||||
EXPECT_TRUE(ctx1);
|
||||
|
@ -329,20 +326,20 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_create_delete_context)
|
|||
EXPECT_TRUE(xx);
|
||||
|
||||
dev->delete_context(ctx);
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
EXPECT_TRUE(at->get_ref_count() == 4);
|
||||
dev->delete_context(ctx1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 2);
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
dev->delete_context(NULL);
|
||||
EXPECT_TRUE(at->get_ref_count() == 2);
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
dev->delete_context(ctx2);
|
||||
EXPECT_TRUE(at->get_ref_count() == 1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 2);
|
||||
|
||||
ctx = dev->create_context(NULL);
|
||||
EXPECT_TRUE(at->get_ref_count() == 2);
|
||||
ctx1 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 3);
|
||||
ctx2 = dev->create_context(&fh1);
|
||||
ctx1 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 4);
|
||||
ctx2 = dev->create_context(&fh1);
|
||||
EXPECT_TRUE(at->get_ref_count() == 5);
|
||||
EXPECT_TRUE(dev->release_at_handler(at) == NSAPI_ERROR_OK);
|
||||
EXPECT_TRUE(ctx);
|
||||
EXPECT_TRUE(ctx1);
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* 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/cellular/CellularNonIPSocket.h"
|
||||
#include "CellularContext_stub.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
// Control the rtos EventFlags stub. See EventFlags_stub.cpp
|
||||
extern std::list<uint32_t> eventFlagsStubNextRetval;
|
||||
|
||||
static bool callback_is_called;
|
||||
static void my_callback()
|
||||
{
|
||||
callback_is_called = true;
|
||||
}
|
||||
|
||||
class TestCellularNonIPSocket : public testing::Test {
|
||||
protected:
|
||||
CellularNonIPSocket *socket;
|
||||
ControlPlane_netif_stub *cp_netif;
|
||||
CellularContext_stub cellular_context;
|
||||
nsapi_size_t dataSize;
|
||||
char dataBuf[10];
|
||||
|
||||
virtual void SetUp()
|
||||
{
|
||||
socket = new CellularNonIPSocket();
|
||||
cp_netif = NULL;
|
||||
dataSize = 10;
|
||||
}
|
||||
|
||||
virtual void TearDown()
|
||||
{
|
||||
delete socket;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, open_null_cp_netif)
|
||||
{
|
||||
EXPECT_EQ(socket->open(static_cast<ControlPlane_netif *>(NULL)), NSAPI_ERROR_PARAMETER);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, open_null_context)
|
||||
{
|
||||
EXPECT_EQ(socket->open(static_cast<CellularContext *>(NULL)), NSAPI_ERROR_PARAMETER);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, open_context)
|
||||
{
|
||||
EXPECT_EQ(socket->open((CellularContext *)&cellular_context), NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, open_cp_netif)
|
||||
{
|
||||
cp_netif = cellular_context.get_cp_netif();
|
||||
EXPECT_EQ(socket->open((ControlPlane_netif *)cp_netif), NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, open_twice)
|
||||
{
|
||||
EXPECT_EQ(socket->open((CellularContext *)&cellular_context), NSAPI_ERROR_OK);
|
||||
EXPECT_EQ(socket->open((CellularContext *)&cellular_context), NSAPI_ERROR_PARAMETER);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, close)
|
||||
{
|
||||
socket->open((CellularContext *)&cellular_context);
|
||||
EXPECT_EQ(socket->close(), NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, close_no_open)
|
||||
{
|
||||
EXPECT_EQ(socket->close(), NSAPI_ERROR_NO_SOCKET);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, sigio)
|
||||
{
|
||||
callback_is_called = false;
|
||||
socket->open((CellularContext *)&cellular_context);
|
||||
socket->sigio(mbed::callback(my_callback));
|
||||
socket->close(); // Trigger event;
|
||||
EXPECT_EQ(callback_is_called, true);
|
||||
}
|
||||
|
||||
/* send */
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, send_no_open)
|
||||
{
|
||||
EXPECT_EQ(socket->send((char *)dataBuf, dataSize), NSAPI_ERROR_NO_SOCKET);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, send_error_would_block)
|
||||
{
|
||||
socket->open((CellularContext *)&cellular_context);
|
||||
cp_netif = cellular_context.get_cp_netif();
|
||||
cp_netif->return_value = NSAPI_ERROR_WOULD_BLOCK;
|
||||
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
|
||||
EXPECT_EQ(socket->send(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, send_error_other)
|
||||
{
|
||||
socket->open((CellularContext *)&cellular_context);
|
||||
cp_netif = cellular_context.get_cp_netif();
|
||||
cp_netif->return_value = NSAPI_ERROR_NO_MEMORY;
|
||||
EXPECT_EQ(socket->send(dataBuf, dataSize), NSAPI_ERROR_NO_MEMORY);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, send_error_no_timeout)
|
||||
{
|
||||
socket->open((CellularContext *)&cellular_context);
|
||||
cp_netif = cellular_context.get_cp_netif();
|
||||
cp_netif->return_value = NSAPI_ERROR_WOULD_BLOCK;
|
||||
socket->set_blocking(false);
|
||||
EXPECT_EQ(socket->send(dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, send)
|
||||
{
|
||||
socket->open((CellularContext *)&cellular_context);
|
||||
cp_netif = cellular_context.get_cp_netif();
|
||||
cp_netif->return_value = dataSize;
|
||||
EXPECT_EQ(socket->send(dataBuf, dataSize), dataSize);
|
||||
}
|
||||
|
||||
TEST_F(TestCellularNonIPSocket, recv)
|
||||
{
|
||||
EXPECT_EQ(socket->recv(&dataBuf, dataSize), NSAPI_ERROR_NO_SOCKET);
|
||||
|
||||
socket->open((CellularContext *)&cellular_context);
|
||||
cp_netif = cellular_context.get_cp_netif();
|
||||
|
||||
cp_netif->return_value = 100;
|
||||
EXPECT_EQ(socket->recv(&dataBuf, dataSize), 100);
|
||||
|
||||
cp_netif->return_value = NSAPI_ERROR_WOULD_BLOCK;
|
||||
eventFlagsStubNextRetval.push_back(0);
|
||||
eventFlagsStubNextRetval.push_back(osFlagsError); // Break the wait loop
|
||||
EXPECT_EQ(socket->recv(&dataBuf, dataSize), NSAPI_ERROR_WOULD_BLOCK);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
####################
|
||||
# UNIT TESTS
|
||||
####################
|
||||
|
||||
# Add test specific include paths
|
||||
set(unittest-includes ${unittest-includes}
|
||||
../features/netsocket/cellular
|
||||
)
|
||||
|
||||
set(unittest-sources
|
||||
../features/netsocket/cellular/CellularNonIPSocket.cpp
|
||||
)
|
||||
|
||||
set(unittest-test-sources
|
||||
features/netsocket/cellular/CellularNonIPSocket/test_CellularNonIPSocket.cpp
|
||||
stubs/NetworkInterface_stub.cpp
|
||||
stubs/NetworkStack_stub.cpp
|
||||
stubs/EventFlags_stub.cpp
|
||||
stubs/Mutex_stub.cpp
|
||||
)
|
|
@ -26,11 +26,13 @@
|
|||
#ifndef __AT_HANDLER_STUB_H__
|
||||
#define __AT_HANDLER_STUB_H__
|
||||
|
||||
#define ATHANDLER_REF_COUNT_AT_DESTRUCTOR -909
|
||||
|
||||
static const int kRead_string_table_size = 100;
|
||||
static const int kRead_int_table_size = 100;
|
||||
static const int kResp_stop_count_default = 100;
|
||||
// set reference count to -909 to separate it from zero so we can test that ATHandler is really deleted.
|
||||
static const int kATHandler_destructor_ref_ount = -909;
|
||||
static const int kATHandler_destructor_ref_ount = ATHANDLER_REF_COUNT_AT_DESTRUCTOR;
|
||||
static const int kATHandler_urc_table_max_size = 10;
|
||||
static const int kATHandler_urc_string_max_size = 16;
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ using namespace mbed;
|
|||
|
||||
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
|
||||
AT_CellularBase(at), _is_blocking(true), _is_connected(false),
|
||||
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false), _cp_netif(NULL)
|
||||
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false)
|
||||
{
|
||||
_stack = NULL;
|
||||
_pdp_type = DEFAULT_PDP_TYPE;
|
||||
|
@ -36,6 +36,7 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
|
|||
_cid = -1;
|
||||
_new_context_set = false;
|
||||
_next = NULL;
|
||||
_cp_netif = NULL;
|
||||
}
|
||||
|
||||
AT_CellularContext::~AT_CellularContext()
|
||||
|
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* 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 "cellular/framework/API/CellularContext.h"
|
||||
#include "ControlPlane_netif_stub.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class CellularContext_stub : public CellularContext {
|
||||
public:
|
||||
std::list<nsapi_error_t> return_values;
|
||||
nsapi_error_t return_value;
|
||||
ControlPlane_netif_stub *my_cp_netif;
|
||||
|
||||
CellularContext_stub()
|
||||
{
|
||||
return_value = 0;
|
||||
my_cp_netif = NULL;
|
||||
}
|
||||
~CellularContext_stub()
|
||||
{
|
||||
if (my_cp_netif) {
|
||||
delete my_cp_netif;
|
||||
my_cp_netif = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void set_file_handle(UARTSerial *serial, PinName dcd_pin, bool active_high)
|
||||
{
|
||||
};
|
||||
|
||||
void enable_hup(bool enable)
|
||||
{
|
||||
};
|
||||
|
||||
void set_file_handle(FileHandle *fh)
|
||||
{
|
||||
};
|
||||
|
||||
nsapi_error_t connect()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
nsapi_error_t set_device_ready()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
nsapi_error_t set_sim_ready()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
nsapi_error_t register_to_network()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
nsapi_error_t attach_to_network()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
nsapi_error_t check_operation(nsapi_error_t err, ContextOperation op)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
uint32_t get_timeout_for_operation(ContextOperation op) const
|
||||
{
|
||||
uint32_t timeout = 10 * 60 * 1000; // default timeout is 10 minutes as registration and attach may take time
|
||||
return timeout;
|
||||
};
|
||||
|
||||
bool is_connected()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
NetworkStack * get_stack()
|
||||
{
|
||||
return NULL;
|
||||
};
|
||||
|
||||
const char * get_ip_address()
|
||||
{
|
||||
return NULL;
|
||||
};
|
||||
|
||||
void attach(Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
};
|
||||
|
||||
nsapi_error_t set_blocking(bool blocking)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
void set_plmn(const char *plmn)
|
||||
{
|
||||
};
|
||||
|
||||
void set_sim_pin(const char *sim_pin)
|
||||
{
|
||||
};
|
||||
|
||||
nsapi_error_t connect(const char *sim_pin, const char *apn, const char *uname,
|
||||
const char *pwd)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
void set_credentials(const char *apn, const char *uname, const char *pwd)
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
const char * get_netmask()
|
||||
{
|
||||
return NULL;
|
||||
};
|
||||
|
||||
const char * get_gateway()
|
||||
{
|
||||
return NULL;
|
||||
};
|
||||
|
||||
bool get_context()
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
bool set_new_context(int cid)
|
||||
{
|
||||
return true;
|
||||
};
|
||||
|
||||
nsapi_error_t do_activate_context()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
void do_connect()
|
||||
{
|
||||
};
|
||||
|
||||
nsapi_error_t disconnect()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
nsapi_error_t get_apn_backoff_timer(int &backoff_timer)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
nsapi_error_t get_rate_control(
|
||||
CellularContext::RateControlExceptionReports &reports,
|
||||
CellularContext::RateControlUplinkTimeUnit &timeUnit, int &uplinkRate)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
nsapi_error_t get_pdpcontext_params(pdpContextList_t ¶ms_list)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
// Called by CellularDevice for network and cellular device changes
|
||||
void cellular_callback(nsapi_event_t ev, intptr_t ptr)
|
||||
{
|
||||
};
|
||||
|
||||
void call_network_cb(nsapi_connection_status_t status)
|
||||
{
|
||||
};
|
||||
|
||||
ControlPlane_netif_stub *get_cp_netif()
|
||||
{
|
||||
if (!my_cp_netif) {
|
||||
my_cp_netif = new ControlPlane_netif_stub();
|
||||
}
|
||||
return my_cp_netif;
|
||||
};
|
||||
|
||||
nsapi_error_t activate_non_ip_context()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
nsapi_error_t setup_control_plane_opt()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
};
|
||||
|
||||
void deactivate_ip_context()
|
||||
{
|
||||
};
|
||||
|
||||
void deactivate_non_ip_context()
|
||||
{
|
||||
};
|
||||
|
||||
void set_disconnect()
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 "netsocket/cellular/ControlPlane_netif.h"
|
||||
#include <list>
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class ControlPlane_netif_stub : public ControlPlane_netif {
|
||||
public:
|
||||
std::list<nsapi_error_t> return_values;
|
||||
nsapi_error_t return_value;
|
||||
|
||||
ControlPlane_netif_stub()
|
||||
{
|
||||
return_value = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual nsapi_error_t send(const void *cpdata, nsapi_size_t cpdata_length)
|
||||
{
|
||||
if (!return_values.empty()) {
|
||||
nsapi_error_t ret = return_values.front();
|
||||
return_values.pop_front();
|
||||
return ret;
|
||||
}
|
||||
return return_value;
|
||||
};
|
||||
|
||||
virtual nsapi_error_t recv(void *cpdata, nsapi_size_t cpdata_length)
|
||||
{
|
||||
if (!return_values.empty()) {
|
||||
nsapi_error_t ret = return_values.front();
|
||||
return_values.pop_front();
|
||||
return ret;
|
||||
}
|
||||
return return_value;
|
||||
};
|
||||
|
||||
virtual void data_received(){};
|
||||
|
||||
virtual void attach(void (*callback)(void *), void *data) {};
|
||||
};
|
||||
|
||||
}
|
|
@ -276,6 +276,11 @@ protected: // Device specific implementations might need these so protected
|
|||
*/
|
||||
virtual void enable_hup(bool enable) = 0;
|
||||
|
||||
/** Triggers control plane's operations needed when control plane data is received,
|
||||
* like socket event, for example.
|
||||
*/
|
||||
void cp_data_received();
|
||||
|
||||
// member variables needed in target override methods
|
||||
NetworkStack *_stack; // must be pointer because of PPP
|
||||
pdp_type_t _pdp_type;
|
||||
|
@ -292,6 +297,8 @@ protected: // Device specific implementations might need these so protected
|
|||
const char *_pwd;
|
||||
PinName _dcd_pin;
|
||||
bool _active_high;
|
||||
|
||||
ControlPlane_netif *_cp_netif;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,7 +46,7 @@ using namespace mbed;
|
|||
|
||||
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
|
||||
AT_CellularBase(at), _is_connected(false), _is_blocking(true),
|
||||
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false), _cp_netif(NULL)
|
||||
_current_op(OP_INVALID), _device(device), _nw(0), _fh(0), _cp_req(cp_req), _nonip_req(nonip_req), _cp_in_use(false)
|
||||
{
|
||||
tr_info("New CellularContext %s (%p)", apn ? apn : "", this);
|
||||
_stack = NULL;
|
||||
|
@ -64,6 +64,7 @@ AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, co
|
|||
_next = NULL;
|
||||
_dcd_pin = NC;
|
||||
_active_high = false;
|
||||
_cp_netif = NULL;
|
||||
}
|
||||
|
||||
AT_CellularContext::~AT_CellularContext()
|
||||
|
@ -75,6 +76,10 @@ AT_CellularContext::~AT_CellularContext()
|
|||
if (_nw) {
|
||||
_device->close_network();
|
||||
}
|
||||
|
||||
if (_cp_netif) {
|
||||
delete _cp_netif;
|
||||
}
|
||||
}
|
||||
|
||||
void AT_CellularContext::set_file_handle(FileHandle *fh)
|
||||
|
@ -363,10 +368,10 @@ bool AT_CellularContext::get_context()
|
|||
if (get_property(pdp_type_t_to_cellular_property(pdp_type)) ||
|
||||
((pdp_type == IPV4V6_PDP_TYPE && (modem_supports_ipv4 || modem_supports_ipv6)) && !_nonip_req)) {
|
||||
_pdp_type = pdp_type;
|
||||
_cid = cid;
|
||||
}
|
||||
}
|
||||
}
|
||||
_cid = cid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_at.resp_stop();
|
||||
|
@ -401,15 +406,15 @@ bool AT_CellularContext::set_new_context(int cid)
|
|||
} else if (modem_supports_ipv6 && modem_supports_ipv4) {
|
||||
strncpy(pdp_type_str, "IPV4V6", sizeof(pdp_type_str));
|
||||
pdp_type = IPV4V6_PDP_TYPE;
|
||||
} else if (modem_supports_ipv6) {
|
||||
} else if (modem_supports_ipv6) {
|
||||
strncpy(pdp_type_str, "IPV6", sizeof(pdp_type_str));
|
||||
pdp_type = IPV6_PDP_TYPE;
|
||||
} else if (modem_supports_ipv4) {
|
||||
} else if (modem_supports_ipv4) {
|
||||
strncpy(pdp_type_str, "IP", sizeof(pdp_type));
|
||||
pdp_type = IPV4_PDP_TYPE;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//apn: "If the value is null or omitted, then the subscription value will be requested."
|
||||
bool success = false;
|
||||
|
@ -680,50 +685,50 @@ void AT_CellularContext::deactivate_non_ip_context()
|
|||
|
||||
void AT_CellularContext::deactivate_context()
|
||||
{
|
||||
// CGACT and CGATT commands might take up to 3 minutes to respond.
|
||||
_at.set_at_timeout(180 * 1000);
|
||||
_is_context_active = false;
|
||||
size_t active_contexts_count = 0;
|
||||
_at.cmd_start("AT+CGACT?");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+CGACT:");
|
||||
while (_at.info_resp()) {
|
||||
int context_id = _at.read_int();
|
||||
int context_activation_state = _at.read_int();
|
||||
if (context_activation_state == 1) {
|
||||
active_contexts_count++;
|
||||
if (context_id == _cid) {
|
||||
_is_context_active = true;
|
||||
}
|
||||
// CGACT and CGATT commands might take up to 3 minutes to respond.
|
||||
_at.set_at_timeout(180 * 1000);
|
||||
_is_context_active = false;
|
||||
size_t active_contexts_count = 0;
|
||||
_at.cmd_start("AT+CGACT?");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+CGACT:");
|
||||
while (_at.info_resp()) {
|
||||
int context_id = _at.read_int();
|
||||
int context_activation_state = _at.read_int();
|
||||
if (context_activation_state == 1) {
|
||||
active_contexts_count++;
|
||||
if (context_id == _cid) {
|
||||
_is_context_active = true;
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
CellularNetwork::RadioAccessTechnology rat = CellularNetwork::RAT_GSM;
|
||||
// always return NSAPI_ERROR_OK
|
||||
CellularNetwork::registration_params_t reg_params;
|
||||
_nw->get_registration_params(reg_params);
|
||||
rat = reg_params._act;
|
||||
// 3GPP TS 27.007:
|
||||
// For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR
|
||||
if (_is_context_active && (rat < CellularNetwork::RAT_E_UTRAN || active_contexts_count > 1)) {
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+CGACT=0,");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
}
|
||||
|
||||
if (_new_context_set) {
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+CGDCONT=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
CellularNetwork::RadioAccessTechnology rat = CellularNetwork::RAT_GSM;
|
||||
// always return NSAPI_ERROR_OK
|
||||
CellularNetwork::registration_params_t reg_params;
|
||||
_nw->get_registration_params(reg_params);
|
||||
rat = reg_params._act;
|
||||
// 3GPP TS 27.007:
|
||||
// For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR
|
||||
if (_is_context_active && (rat < CellularNetwork::RAT_E_UTRAN || active_contexts_count > 1)) {
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+CGATT=0");
|
||||
_at.cmd_start("AT+CGACT=0,");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.restore_at_timeout();
|
||||
}
|
||||
|
||||
if (_new_context_set) {
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+CGDCONT=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
}
|
||||
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+CGATT=0");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.restore_at_timeout();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::get_apn_backoff_timer(int &backoff_timer)
|
||||
|
|
|
@ -136,8 +136,6 @@ protected:
|
|||
|
||||
// tells if CCIOTOPTI received green from network for CP optimisation use
|
||||
bool _cp_in_use;
|
||||
|
||||
ControlPlane_netif *_cp_netif;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -68,6 +68,8 @@ AT_CellularDevice::~AT_CellularDevice()
|
|||
curr = next;
|
||||
release_at_handler(at);
|
||||
}
|
||||
|
||||
release_at_handler(_at);
|
||||
}
|
||||
|
||||
// each parser is associated with one filehandle (that is UART)
|
||||
|
|
|
@ -9,15 +9,16 @@ public:
|
|||
AT_ControlPlane_netif(ATHandler &at, int cid);
|
||||
virtual ~AT_ControlPlane_netif();
|
||||
|
||||
protected:
|
||||
|
||||
// ControlPlane_netif
|
||||
// +CSODCP: 3GPP 27007 10.1.43
|
||||
virtual nsapi_size_or_error_t send(const void *cpdata, nsapi_size_t cpdata_length);
|
||||
// +CRTDCP: 3GPP 27007 10.1.44
|
||||
virtual nsapi_size_or_error_t recv(void *cpdata, nsapi_size_t cpdata_length);
|
||||
virtual void attach(void (*callback)(void *), void *data);
|
||||
virtual void data_received();
|
||||
virtual void attach(void (*callback)(void *), void *data);
|
||||
|
||||
protected:
|
||||
// Id of the PDP context that enables the control plane data connection
|
||||
int _cid;
|
||||
|
||||
|
|
|
@ -38,4 +38,9 @@ MBED_WEAK CellularContext *CellularContext::get_default_instance()
|
|||
}
|
||||
#endif // CELLULAR_DEVICE
|
||||
|
||||
void CellularContext::cp_data_received()
|
||||
{
|
||||
_cp_netif->data_received();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -131,7 +131,7 @@ void QUECTEL_BG96_CellularContext::urc_nidd()
|
|||
_at.read_string(nipd_string, sizeof(nipd_string));
|
||||
|
||||
if (!strcmp(nipd_string, "recv")) {
|
||||
_cp_netif->data_received();
|
||||
cp_data_received();
|
||||
} else if (!strcmp(nipd_string, "open")) {
|
||||
urc_nidd_open();
|
||||
} else if (!strcmp(nipd_string, "close")) {
|
||||
|
|
|
@ -21,17 +21,19 @@
|
|||
|
||||
using namespace mbed;
|
||||
|
||||
CellularNonIPSocket::CellularNonIPSocket(CellularContext *cellular_context)
|
||||
CellularNonIPSocket::CellularNonIPSocket()
|
||||
: _timeout(osWaitForever),
|
||||
_readers(0), _writers(0), _pending(0),
|
||||
_cp_netif(NULL),
|
||||
_opened(false)
|
||||
{
|
||||
open(cellular_context);
|
||||
}
|
||||
{}
|
||||
|
||||
nsapi_error_t CellularNonIPSocket::open(CellularContext *cellular_context)
|
||||
{
|
||||
if (cellular_context == NULL) {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
return open(cellular_context->get_cp_netif());
|
||||
}
|
||||
|
||||
|
@ -42,10 +44,6 @@ CellularNonIPSocket::~CellularNonIPSocket()
|
|||
|
||||
nsapi_error_t CellularNonIPSocket::open(ControlPlane_netif *cp_netif)
|
||||
{
|
||||
if (_opened) {
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
_lock.lock();
|
||||
|
||||
if (_cp_netif != NULL || cp_netif == NULL) {
|
||||
|
@ -161,7 +159,6 @@ nsapi_size_or_error_t CellularNonIPSocket::recv(void *buffer, nsapi_size_t size)
|
|||
// Release lock before blocking so other threads
|
||||
// accessing this object aren't blocked
|
||||
_lock.unlock();
|
||||
printf("\nWAITWAITWAIT\n");
|
||||
flag = _event_flag.wait_any(READ_FLAG, _timeout);
|
||||
_lock.lock();
|
||||
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "ControlPlane_netif.h"
|
||||
#include "CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
//Socket implementation for non ip datagrams over cellular control plane
|
||||
class CellularNonIPSocket : public Socket {
|
||||
public:
|
||||
|
@ -37,12 +39,9 @@ public:
|
|||
*/
|
||||
virtual ~CellularNonIPSocket();
|
||||
|
||||
/** Creates and opens a socket on the given cellular context.
|
||||
*
|
||||
* @param cellular_context Cellular PDP context over which this socket
|
||||
* is sending and receiving data.
|
||||
/** Creates a socket.
|
||||
*/
|
||||
CellularNonIPSocket(mbed::CellularContext *cellular_context);
|
||||
CellularNonIPSocket();
|
||||
|
||||
/** Opens a socket on the given cellular context.
|
||||
*
|
||||
|
@ -52,7 +51,7 @@ public:
|
|||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_PARAMETER otherwise
|
||||
*/
|
||||
nsapi_error_t open(mbed::CellularContext *cellular_context);
|
||||
virtual nsapi_error_t open(mbed::CellularContext *cellular_context);
|
||||
|
||||
/** Opens a socket that will use the given control plane interface for data delivery.
|
||||
* Attaches the event as callback to the control plane interface.
|
||||
|
@ -62,7 +61,7 @@ public:
|
|||
* NSAPI_ERROR_PARAMETER otherwise
|
||||
*
|
||||
*/
|
||||
nsapi_error_t open(mbed::ControlPlane_netif *cp_netif);
|
||||
virtual nsapi_error_t open(mbed::ControlPlane_netif *cp_netif);
|
||||
|
||||
/** Closes socket
|
||||
*
|
||||
|
@ -124,7 +123,6 @@ public:
|
|||
virtual nsapi_error_t bind(const SocketAddress &address);
|
||||
|
||||
protected:
|
||||
CellularNonIPSocket();
|
||||
virtual void event();
|
||||
|
||||
uint32_t _timeout;
|
||||
|
@ -141,10 +139,12 @@ protected:
|
|||
static const int WRITE_FLAG = 0x2u;
|
||||
static const int FINISHED_FLAG = 0x3u;
|
||||
|
||||
mbed::ControlPlane_netif *_cp_netif;
|
||||
ControlPlane_netif *_cp_netif;
|
||||
bool _opened;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // CELLULARNONIPSOCKET_H
|
||||
|
||||
/** @}*/
|
||||
|
|
|
@ -30,6 +30,10 @@ public:
|
|||
ControlPlane_netif() {}
|
||||
virtual ~ControlPlane_netif() {}
|
||||
|
||||
protected:
|
||||
friend class CellularNonIPSocket;
|
||||
friend class CellularContext;
|
||||
|
||||
/** Send data over cellular control plane
|
||||
*
|
||||
* @param cpdata Buffer of data to be sent over control plane connection
|
||||
|
@ -48,6 +52,17 @@ public:
|
|||
*/
|
||||
virtual nsapi_size_or_error_t recv(void *cpdata, nsapi_size_t cpdata_length) = 0;
|
||||
|
||||
/** Receives data from the control plane PDP context
|
||||
*
|
||||
* This function is called by cellular PDP context when data
|
||||
* is received from network. It will invoke the callback set
|
||||
* by the above attach.
|
||||
*
|
||||
* @param buffer Buffer containing received data
|
||||
* @param size Size of data in bytes
|
||||
*/
|
||||
virtual void data_received() = 0;
|
||||
|
||||
/** Register a callback on state change of the socket
|
||||
*
|
||||
* The specified callback will be called on state changes such as when
|
||||
|
@ -61,17 +76,6 @@ public:
|
|||
* @param data Argument to pass to callback
|
||||
*/
|
||||
virtual void attach(void (*callback)(void *), void *data) = 0;
|
||||
|
||||
/** Receives data from the control plane PDP context
|
||||
*
|
||||
* This function is called by cellular PDP context when data
|
||||
* is received from network. It will invoke the callback set
|
||||
* by the above attach.
|
||||
*
|
||||
* @param buffer Buffer containing received data
|
||||
* @param size Size of data in bytes
|
||||
*/
|
||||
virtual void data_received() = 0;
|
||||
};
|
||||
|
||||
} // mbed namespace
|
||||
|
|
Loading…
Reference in New Issue