mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #8579 from jarvte/cellular_context
Major refactoring: changing Network inheritance from CellularNetwork to new class CellularContextpull/8743/head
commit
4d07bcbd6e
|
@ -117,6 +117,7 @@ set(unittest-includes-base
|
|||
"${PROJECT_SOURCE_DIR}/../features/filesystem/littlefs/littlefs"
|
||||
"${PROJECT_SOURCE_DIR}/../features/cellular/framework/API"
|
||||
"${PROJECT_SOURCE_DIR}/../features/cellular/framework/AT"
|
||||
"${PROJECT_SOURCE_DIR}/../features/cellular/framework/device"
|
||||
"${PROJECT_SOURCE_DIR}/../features/cellular/framework"
|
||||
"${PROJECT_SOURCE_DIR}/../features/cellular/framework/common"
|
||||
"${PROJECT_SOURCE_DIR}/../features/lorawan"
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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 <string.h>
|
||||
#include "AT_CellularContext.h"
|
||||
#include "EventQueue.h"
|
||||
#include "ATHandler.h"
|
||||
#include "AT_CellularDevice.h"
|
||||
#include "FileHandle_stub.h"
|
||||
#include "CellularLog.h"
|
||||
#include "ATHandler_stub.h"
|
||||
#include "AT_CellularStack.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
||||
// AStyle ignored as the definition is not clear due to preprocessor usage
|
||||
// *INDENT-OFF*
|
||||
class TestAT_CellularContext : public testing::Test {
|
||||
protected:
|
||||
|
||||
void SetUp()
|
||||
{
|
||||
ATHandler_stub::int_count = kRead_int_table_size;
|
||||
ATHandler_stub::read_string_index = kRead_string_table_size;
|
||||
ATHandler_stub::resp_stop_success_count = kResp_stop_count_default;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::int_value = -1;
|
||||
}
|
||||
|
||||
void TearDown()
|
||||
{
|
||||
}
|
||||
};
|
||||
// *INDENT-ON*
|
||||
class my_stack : public AT_CellularStack {
|
||||
public:
|
||||
my_stack(ATHandler &atHandler) : AT_CellularStack(atHandler, 1, IPV4_STACK) {}
|
||||
virtual int get_max_socket_count()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
virtual int get_max_packet_size()
|
||||
{
|
||||
return 200;
|
||||
}
|
||||
virtual bool is_protocol_supported(nsapi_protocol_t protocol)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual nsapi_error_t socket_close_impl(int sock_id)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
virtual nsapi_error_t create_socket_impl(CellularSocket *socket)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
};
|
||||
|
||||
class my_AT_CTX : public AT_CellularContext {
|
||||
public:
|
||||
my_AT_CTX(ATHandler &at, CellularDevice *device, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN) :
|
||||
AT_CellularContext(at, device, apn) {}
|
||||
virtual ~my_AT_CTX() {}
|
||||
};
|
||||
|
||||
class my_AT_CTXIPV6 : public AT_CellularContext {
|
||||
public:
|
||||
my_AT_CTXIPV6(ATHandler &at, CellularDevice *device, const char *apn = MBED_CONF_NSAPI_DEFAULT_CELLULAR_APN) :
|
||||
AT_CellularContext(at, device, apn) {}
|
||||
virtual ~my_AT_CTXIPV6() {}
|
||||
};
|
||||
|
||||
static int network_cb_count;
|
||||
static void network_cb(nsapi_event_t ev, intptr_t intptr)
|
||||
{
|
||||
network_cb_count++;
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularContext, Create)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularContext *ctx = new AT_CellularContext(at, NULL);
|
||||
EXPECT_TRUE(ctx != NULL);
|
||||
delete ctx;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
####################
|
||||
# UNIT TESTS
|
||||
####################
|
||||
|
||||
# Add test specific include paths
|
||||
set(unittest-includes ${unittest-includes}
|
||||
features/cellular/framework/common/util
|
||||
../features/cellular/framework/common
|
||||
../features/cellular/framework/AT
|
||||
../features/cellular/framework/device
|
||||
)
|
||||
|
||||
# Source files
|
||||
set(unittest-sources
|
||||
../features/cellular/framework/AT/AT_CellularContext.cpp
|
||||
)
|
||||
|
||||
# Test files
|
||||
set(unittest-test-sources
|
||||
features/cellular/framework/AT/at_cellularcontext/at_cellularcontexttest.cpp
|
||||
stubs/ATHandler_stub.cpp
|
||||
stubs/AT_CellularBase_stub.cpp
|
||||
stubs/EventQueue_stub.cpp
|
||||
stubs/FileHandle_stub.cpp
|
||||
stubs/NetworkInterface_stub.cpp
|
||||
stubs/NetworkStack_stub.cpp
|
||||
stubs/us_ticker_stub.cpp
|
||||
stubs/mbed_assert_stub.c
|
||||
stubs/CellularDevice_stub.cpp
|
||||
stubs/CellularStateMachine_stub.cpp
|
||||
stubs/Semaphore_stub.cpp
|
||||
stubs/CellularUtil_stub.cpp
|
||||
stubs/equeue_stub.c
|
||||
)
|
|
@ -37,10 +37,10 @@ protected:
|
|||
|
||||
TEST_F(TestAT_CellularDevice, Create)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
|
||||
CellularDevice *dev2 = new AT_CellularDevice(que);
|
||||
CellularDevice *dev2 = new AT_CellularDevice(&fh1);
|
||||
|
||||
EXPECT_TRUE(dev2 != NULL);
|
||||
delete dev2;
|
||||
|
@ -48,11 +48,10 @@ TEST_F(TestAT_CellularDevice, Create)
|
|||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_at_handler)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
FileHandle_stub fh2;
|
||||
FileHandle_stub fh3;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
|
||||
EXPECT_TRUE(dev.open_network(&fh1));
|
||||
EXPECT_TRUE(dev.open_sms(&fh2));
|
||||
|
@ -66,59 +65,73 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_at_handler)
|
|||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_network)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
|
||||
EXPECT_TRUE(!dev.open_network(NULL));
|
||||
EXPECT_TRUE(dev.open_network(&fh1));
|
||||
CellularNetwork *nw = dev.open_network(NULL);
|
||||
CellularNetwork *nw1 = dev.open_network(&fh1);
|
||||
|
||||
EXPECT_TRUE(nw);
|
||||
EXPECT_TRUE(nw1);
|
||||
EXPECT_TRUE(nw1 == nw);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_sms)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
|
||||
EXPECT_TRUE(!dev.open_sms(NULL));
|
||||
EXPECT_TRUE(dev.open_sms(&fh1));
|
||||
CellularSMS *sms = dev.open_sms(NULL);
|
||||
CellularSMS *sms1 = dev.open_sms(&fh1);
|
||||
|
||||
EXPECT_TRUE(sms);
|
||||
EXPECT_TRUE(sms1);
|
||||
EXPECT_TRUE(sms1 == sms);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_power)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
|
||||
EXPECT_TRUE(!dev.open_power(NULL));
|
||||
EXPECT_TRUE(dev.open_power(&fh1));
|
||||
CellularPower *pwr = dev.open_power(NULL);
|
||||
CellularPower *pwr1 = dev.open_power(&fh1);
|
||||
|
||||
EXPECT_TRUE(pwr);
|
||||
EXPECT_TRUE(pwr1);
|
||||
EXPECT_TRUE(pwr1 == pwr);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_sim)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
|
||||
EXPECT_TRUE(! dev.open_sim(NULL));
|
||||
EXPECT_TRUE(dev.open_sim(&fh1));
|
||||
CellularSIM *sim = dev.open_sim(NULL);
|
||||
CellularSIM *sim1 = dev.open_sim(&fh1);
|
||||
|
||||
EXPECT_TRUE(sim);
|
||||
EXPECT_TRUE(sim1);
|
||||
EXPECT_TRUE(sim1 == sim);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_open_information)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
|
||||
EXPECT_TRUE(!dev.open_information(NULL));
|
||||
EXPECT_TRUE(dev.open_information(&fh1));
|
||||
CellularInformation *info = dev.open_information(NULL);
|
||||
CellularInformation *info1 = dev.open_information(&fh1);
|
||||
|
||||
EXPECT_TRUE(info);
|
||||
EXPECT_TRUE(info1);
|
||||
EXPECT_TRUE(info1 == info);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_network)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::ref_count = 0;
|
||||
|
||||
EXPECT_TRUE(dev.open_network(&fh1));
|
||||
|
@ -131,9 +144,8 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_network)
|
|||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_sms)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::ref_count = 0;
|
||||
|
||||
EXPECT_TRUE(dev.open_sms(&fh1));
|
||||
|
@ -146,9 +158,8 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_sms)
|
|||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_power)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::ref_count = 0;
|
||||
|
||||
EXPECT_TRUE(dev.open_power(&fh1));
|
||||
|
@ -161,9 +172,8 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_power)
|
|||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_sim)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::ref_count = 0;
|
||||
int ana = 0;
|
||||
|
||||
|
@ -182,9 +192,8 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_sim)
|
|||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::int_value = 0;
|
||||
|
||||
EXPECT_TRUE(dev.open_information(&fh1));
|
||||
|
@ -193,6 +202,7 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
|
|||
AT_CellularBase_stub::handler_value = NULL;
|
||||
dev.close_information();
|
||||
|
||||
EventQueue que;
|
||||
ATHandler_stub::fh_value = &fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
AT_CellularBase_stub::handler_value = &at;
|
||||
|
@ -208,9 +218,8 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_close_information)
|
|||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_set_timeout)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::timeout = 0;
|
||||
ATHandler_stub::default_timeout = false;
|
||||
|
||||
|
@ -231,9 +240,8 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_set_timeout)
|
|||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_modem_debug_on)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
ATHandler_stub::debug_on = false;
|
||||
|
||||
// no interfaces open so debug toggling should not affect
|
||||
|
@ -249,31 +257,16 @@ TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_modem_debug_on)
|
|||
dev.close_sim();
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_stack)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
|
||||
NetworkStack *stack = dev.get_stack();
|
||||
EXPECT_TRUE(stack == NULL);
|
||||
|
||||
EXPECT_TRUE(dev.open_network(&fh1));
|
||||
|
||||
stack = dev.get_stack();
|
||||
EXPECT_TRUE(stack == NULL); // Not in PPP so also null but this is got from the network class
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_get_send_delay)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
EXPECT_TRUE(0 == dev.get_send_delay());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularDevice, test_AT_CellularDevice_init_module)
|
||||
{
|
||||
EventQueue que;
|
||||
AT_CellularDevice dev(que);
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.init_module(NULL));
|
||||
FileHandle_stub fh1;
|
||||
AT_CellularDevice dev(&fh1);
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == dev.init_module());
|
||||
}
|
||||
|
|
|
@ -8,7 +8,10 @@ set(unittest-includes ${unittest-includes}
|
|||
features/cellular/framework/common/util
|
||||
../features/cellular/framework/common
|
||||
../features/cellular/framework/AT
|
||||
../features/cellular/framework/device
|
||||
../features/frameworks/mbed-client-randlib/mbed-client-randlib
|
||||
../drivers
|
||||
../hal
|
||||
)
|
||||
|
||||
# Source files
|
||||
|
@ -33,4 +36,17 @@ set(unittest-test-sources
|
|||
stubs/FileHandle_stub.cpp
|
||||
stubs/mbed_assert_stub.c
|
||||
stubs/CellularDevice_stub.cpp
|
||||
stubs/NetworkStack_stub.cpp
|
||||
stubs/AT_CellularContext_stub.cpp
|
||||
stubs/Semaphore_stub.cpp
|
||||
stubs/UARTSerial_stub.cpp
|
||||
stubs/SerialBase_stub.cpp
|
||||
stubs/CellularStateMachine_stub.cpp
|
||||
)
|
||||
|
||||
# defines
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDEVICE_SERIAL=1 -DDEVICE_INTERRUPTIN=1 -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_APN=NULL -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_USERNAME=NULL -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_PASSWORD=NULL -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_PLMN=NULL -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_SIM_PIN=NULL")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DMDMTXD=NC -DMDMRXD=NC -DMBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE=115200")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DDEVICE_SERIAL=1 -DDEVICE_INTERRUPTIN=1 -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_APN=NULL -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_USERNAME=NULL -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_PASSWORD=NULL -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_PLMN=NULL -DMBED_CONF_NSAPI_DEFAULT_CELLULAR_SIM_PIN=NULL")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMDMTXD=NC -DMDMRXD=NC -DMBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE=115200")
|
||||
|
||||
|
|
|
@ -46,54 +46,12 @@ protected:
|
|||
{
|
||||
}
|
||||
};
|
||||
// *INDENT-ON*
|
||||
class my_stack : public AT_CellularStack {
|
||||
public:
|
||||
my_stack(ATHandler &atHandler) : AT_CellularStack(atHandler, 1, IPV4_STACK) {}
|
||||
virtual int get_max_socket_count()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
virtual int get_max_packet_size()
|
||||
{
|
||||
return 200;
|
||||
}
|
||||
virtual bool is_protocol_supported(nsapi_protocol_t protocol)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual nsapi_error_t socket_close_impl(int sock_id)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
virtual nsapi_error_t create_socket_impl(CellularSocket *socket)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size)
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class my_AT_CN : public AT_CellularNetwork {
|
||||
public:
|
||||
my_AT_CN(ATHandler &atHandler) : AT_CellularNetwork(atHandler) {}
|
||||
virtual ~my_AT_CN() {}
|
||||
NetworkStack *get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
return new my_stack(get_at_handler());
|
||||
} else {
|
||||
return _stack;
|
||||
}
|
||||
}
|
||||
virtual AT_CellularNetwork::RegistrationMode has_registration(RegistrationType reg_type)
|
||||
{
|
||||
if (reg_type == C_GREG) {
|
||||
|
@ -105,27 +63,12 @@ public:
|
|||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
if (requested_stack == IPV4_STACK || requested_stack == DEFAULT_STACK) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class my_AT_CNipv6 : public AT_CellularNetwork {
|
||||
public:
|
||||
my_AT_CNipv6(ATHandler &atHandler) : AT_CellularNetwork(atHandler) {}
|
||||
virtual ~my_AT_CNipv6() {}
|
||||
NetworkStack *get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
return new my_stack(get_at_handler());
|
||||
} else {
|
||||
return _stack;
|
||||
}
|
||||
}
|
||||
virtual AT_CellularNetwork::RegistrationMode has_registration(RegistrationType reg_type)
|
||||
{
|
||||
if (reg_type == C_GREG) {
|
||||
|
@ -137,13 +80,6 @@ public:
|
|||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
if (requested_stack == IPV6_STACK || requested_stack == DEFAULT_STACK) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
static int network_cb_count;
|
||||
|
@ -163,256 +99,6 @@ TEST_F(TestAT_CellularNetwork, Create)
|
|||
delete cn;
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_init)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
AT_CellularNetwork cn(at);
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.init());
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_NO_MEMORY;
|
||||
EXPECT_TRUE(NSAPI_ERROR_NO_MEMORY == cn.init());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_credentials)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork *cnn = new AT_CellularNetwork(at);
|
||||
delete cnn;
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, NULL));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, NULL, NULL));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, NULL, "passwd"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, "user", NULL));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, "user"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", NULL));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", NULL, NULL));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", NULL, "passwd"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", "user", NULL));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", "user"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", "user", "passwd"));
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_activate_context)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
my_AT_CN my_cn(at);
|
||||
my_AT_CNipv6 my_cnipv6(at);
|
||||
|
||||
// get_context return true and new context created. But now stack and so error.
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == cn.activate_context());
|
||||
|
||||
// get_context return true and new context created, also do_user_authentication called with success.
|
||||
// But now stack and so error.
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == cn.activate_context());
|
||||
|
||||
// get_context return true and new context created, also do_user_authentication called with failure.
|
||||
ATHandler_stub::resp_stop_success_count = 2;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_AUTH_FAILURE == my_cn.activate_context());
|
||||
|
||||
// get_context return true and new context created, also do_user_authentication called with success.
|
||||
// Now there is stack.
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::resp_stop_success_count = kResp_stop_count_default;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.activate_context());
|
||||
|
||||
// get_context return true and new context created, test delete context
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::resp_stop_success_count = kResp_stop_count_default;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.activate_context());
|
||||
|
||||
|
||||
|
||||
// get_context pdp type gives zero len, fails with no stack
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::read_string_index = 1;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"";
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == cn.activate_context());
|
||||
|
||||
// get_context pdp type gives proper type, apn reading fails
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::read_string_index = 1;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"IPV6";
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_NO_CONNECTION == cn.activate_context());
|
||||
|
||||
// get_context pdp type gives proper type, apn does not match, now other contexts so new one created
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"internet";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IP";
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_credentials("apn", CellularNetwork::CHAP, "user", "passwd"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.activate_context());
|
||||
|
||||
// get_context pdp type gives proper type, apn match
|
||||
ATHandler_stub::resp_info_true_counter = 2; // set to 2 so cgact will give that this context is active
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"internet";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IPV4V6";
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_stack_type(IPV4_STACK));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_credentials("internet"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.activate_context());
|
||||
|
||||
// get_context pdp type gives proper type, apn match
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"internet";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IPV6";
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cnipv6.set_stack_type(IPV6_STACK));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cnipv6.set_credentials("internet"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cnipv6.activate_context());
|
||||
|
||||
// get_context pdp type gives proper type, apn match
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"internet";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IPV4V6";
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_stack_type(DEFAULT_STACK));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_credentials("internet"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.activate_context());
|
||||
|
||||
// get_context pdp type gives proper type, apn match
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"internet";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IPV4V6";
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cnipv6.set_stack_type(DEFAULT_STACK));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cnipv6.set_credentials("internet"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cnipv6.activate_context());
|
||||
|
||||
// get_context pdp type gives proper type, apn match
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"internet";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IPV6";
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cnipv6.set_stack_type(DEFAULT_STACK));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cnipv6.set_credentials("internet"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cnipv6.activate_context());
|
||||
|
||||
// get_context pdp type gives proper type, apn match
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::read_string_index = 2;
|
||||
ATHandler_stub::read_string_table[0] = (char *)"internet";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"IP";
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_stack_type(DEFAULT_STACK));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_credentials("internet"));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.activate_context());
|
||||
|
||||
// get_context pdp type gives proper type, apn match. Test Delete the created context.
|
||||
ATHandler_stub::resp_info_true_counter = 0;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::int_value = 1;
|
||||
//ATHandler_stub::nsapi_error_ok_counter = 2;
|
||||
ATHandler_stub::resp_stop_success_count = 2;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_credentials(NULL, NULL, NULL));
|
||||
EXPECT_TRUE(NSAPI_ERROR_NO_CONNECTION == my_cn.activate_context());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_connect)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
// no stack so will fail
|
||||
cn.attach(&network_cb);
|
||||
network_cb_count = 0;
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == cn.connect("APN", "a", "b"));
|
||||
EXPECT_TRUE(NSAPI_STATUS_DISCONNECTED == cn.get_connection_status());
|
||||
EXPECT_TRUE(network_cb_count == 2);
|
||||
|
||||
network_cb_count = 0;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
|
||||
EXPECT_TRUE(NSAPI_ERROR_NO_CONNECTION == cn.connect("APN"));
|
||||
EXPECT_TRUE(network_cb_count == 2);
|
||||
EXPECT_TRUE(NSAPI_STATUS_DISCONNECTED == cn.get_connection_status());
|
||||
|
||||
my_AT_CN my_cn(at);
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
cn.set_stack_type(IPV4_STACK);
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.connect());
|
||||
EXPECT_TRUE(network_cb_count == 2);
|
||||
EXPECT_TRUE(NSAPI_STATUS_GLOBAL_UP == my_cn.get_connection_status());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_disconnect)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.disconnect());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_stack)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
my_AT_CN my_cn(at);
|
||||
my_stack *mystack = (my_stack *)my_cn.get_stack();
|
||||
EXPECT_TRUE(mystack);
|
||||
delete mystack;
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_registration)
|
||||
{
|
||||
EventQueue que;
|
||||
|
@ -674,130 +360,6 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_detach)
|
|||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
|
||||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.detach());
|
||||
|
||||
// connect so we can test callback in detach
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
cn.set_stack_type(IPV4_STACK);
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.connect());
|
||||
EXPECT_TRUE(NSAPI_STATUS_GLOBAL_UP == cn.get_connection_status());
|
||||
// attach callback
|
||||
cn.attach(&network_cb);
|
||||
network_cb_count = 0;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.detach());
|
||||
EXPECT_TRUE(network_cb_count == 1);
|
||||
EXPECT_TRUE(NSAPI_STATUS_DISCONNECTED == cn.get_connection_status());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_rate_control)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
int ur = -1;
|
||||
CellularNetwork::RateControlExceptionReports reports = CellularNetwork::NotAllowedToBeSent;
|
||||
CellularNetwork::RateControlUplinkTimeUnit timeUnit = CellularNetwork::Unrestricted;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
|
||||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_rate_control(reports, timeUnit, ur));
|
||||
EXPECT_TRUE(reports == CellularNetwork::NotAllowedToBeSent);
|
||||
EXPECT_TRUE(timeUnit == CellularNetwork::Unrestricted);
|
||||
EXPECT_TRUE(ur == -1);
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::int_value = 1;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_rate_control(reports, timeUnit, ur));
|
||||
EXPECT_TRUE(reports == CellularNetwork::AllowedToBeSent);
|
||||
EXPECT_TRUE(timeUnit == CellularNetwork::Minute);
|
||||
EXPECT_TRUE(ur == 1);
|
||||
|
||||
// test second if in get_rate_control
|
||||
reports = CellularNetwork::NotAllowedToBeSent;
|
||||
timeUnit = CellularNetwork::Unrestricted;
|
||||
ur = -1;
|
||||
|
||||
ATHandler_stub::int_count = 1;
|
||||
ATHandler_stub::int_valid_count_table[0] = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_rate_control(reports, timeUnit, ur));
|
||||
EXPECT_TRUE(reports == CellularNetwork::NotAllowedToBeSent);
|
||||
EXPECT_TRUE(timeUnit == CellularNetwork::Unrestricted);
|
||||
EXPECT_TRUE(ur == -1);
|
||||
|
||||
// test second if in get_rate_control
|
||||
ATHandler_stub::int_count = 2;
|
||||
ATHandler_stub::int_valid_count_table[0] = 1;
|
||||
ATHandler_stub::int_valid_count_table[1] = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_rate_control(reports, timeUnit, ur));
|
||||
EXPECT_TRUE(reports == CellularNetwork::AllowedToBeSent);
|
||||
EXPECT_TRUE(timeUnit == CellularNetwork::Unrestricted);
|
||||
EXPECT_TRUE(ur == -1);
|
||||
|
||||
// test third if in get_rate_control
|
||||
ATHandler_stub::int_count = 3;
|
||||
ATHandler_stub::int_valid_count_table[0] = 3;
|
||||
ATHandler_stub::int_valid_count_table[1] = 1;
|
||||
ATHandler_stub::int_valid_count_table[2] = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_rate_control(reports, timeUnit, ur));
|
||||
EXPECT_TRUE(reports == CellularNetwork::AllowedToBeSent);
|
||||
EXPECT_TRUE(timeUnit == CellularNetwork::Day);
|
||||
EXPECT_TRUE(ur == -1);
|
||||
|
||||
ATHandler_stub::int_count = 4;
|
||||
ATHandler_stub::int_valid_count_table[0] = 5;
|
||||
ATHandler_stub::int_valid_count_table[1] = 3;
|
||||
ATHandler_stub::int_valid_count_table[2] = 1;
|
||||
ATHandler_stub::int_valid_count_table[3] = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_rate_control(reports, timeUnit, ur));
|
||||
EXPECT_TRUE(reports == CellularNetwork::AllowedToBeSent);
|
||||
EXPECT_TRUE(timeUnit == CellularNetwork::Day);
|
||||
EXPECT_TRUE(ur == 5);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_apn_backoff_timer)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
int time = -1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
|
||||
EXPECT_TRUE(NSAPI_ERROR_PARAMETER == cn.get_apn_backoff_timer(time));
|
||||
EXPECT_TRUE(time == -1);
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
EXPECT_TRUE(NSAPI_ERROR_PARAMETER == cn.get_apn_backoff_timer(time));
|
||||
EXPECT_TRUE(time == -1);
|
||||
|
||||
ATHandler_stub::resp_info_true_counter = 0;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
cn.set_credentials("internet", NULL, NULL);
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_apn_backoff_timer(time));
|
||||
EXPECT_TRUE(time == -1);
|
||||
|
||||
ATHandler_stub::resp_info_true_counter = 0;
|
||||
ATHandler_stub::bool_value = true;
|
||||
ATHandler_stub::int_value = 55;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
cn.set_credentials("internet", NULL, NULL);
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_apn_backoff_timer(time));
|
||||
EXPECT_TRUE(time == 55);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_ip_address)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
EXPECT_TRUE(!cn.get_ip_address());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_access_technology)
|
||||
|
@ -896,103 +458,12 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_ciot_optimization_con
|
|||
pref = CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE;
|
||||
ATHandler_stub::int_value = 1;
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
|
||||
ATHandler_stub::nsapi_error_ok_counter = 0;
|
||||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_ciot_optimization_config(sup, pref));
|
||||
EXPECT_TRUE(sup == CellularNetwork::SUPPORTED_UE_OPT_NO_SUPPORT);
|
||||
EXPECT_TRUE(pref == CellularNetwork::PREFERRED_UE_OPT_NO_PREFERENCE);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_stack_type)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
EXPECT_TRUE(NSAPI_ERROR_PARAMETER == cn.set_stack_type(IPV4_STACK));
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_stack_type(DEFAULT_STACK));
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_stack_type)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
EXPECT_TRUE(DEFAULT_STACK == cn.get_stack_type());
|
||||
|
||||
my_AT_CN my_cn(at);
|
||||
EXPECT_TRUE(DEFAULT_STACK == my_cn.get_stack_type());
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_stack_type(IPV4_STACK));
|
||||
EXPECT_TRUE(DEFAULT_STACK == my_cn.get_stack_type());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_pdpcontext_params)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
CellularNetwork::pdpContextList_t list;
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
|
||||
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_pdpcontext_params(list));
|
||||
|
||||
// don't got to while loop
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
ATHandler_stub::resp_info_true_counter = 0;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_pdpcontext_params(list));
|
||||
EXPECT_TRUE(NULL == list.get_head());
|
||||
|
||||
// go to while loop and check values
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::resp_info_true_counter = 1;
|
||||
ATHandler_stub::int_count = 9;
|
||||
ATHandler_stub::int_valid_count_table[8] = 1;
|
||||
ATHandler_stub::int_valid_count_table[7] = 2;
|
||||
ATHandler_stub::int_valid_count_table[6] = 3;
|
||||
ATHandler_stub::int_valid_count_table[5] = 4;
|
||||
ATHandler_stub::int_valid_count_table[4] = 5;
|
||||
ATHandler_stub::int_valid_count_table[3] = 6;
|
||||
ATHandler_stub::int_valid_count_table[2] = 7;
|
||||
ATHandler_stub::int_valid_count_table[1] = 8;
|
||||
ATHandler_stub::int_valid_count_table[0] = 9;
|
||||
|
||||
ATHandler_stub::read_string_index = 7;
|
||||
ATHandler_stub::read_string_table[6] = (char *)"internet";
|
||||
ATHandler_stub::read_string_table[5] = (char *)"1.2.3.4.5.6.7.8.9.10.11.112.13.14.15.16.1.2.3.44.55.6.7.8.9.10.11.12.13.14.15.16";
|
||||
ATHandler_stub::read_string_table[4] = (char *)"23.33.44.1.2.3.55.123.225.34.11.1.0.0.123.234";
|
||||
ATHandler_stub::read_string_table[3] = (char *)"1.2.3.4";
|
||||
ATHandler_stub::read_string_table[2] = (char *)"0.255.0.255";
|
||||
ATHandler_stub::read_string_table[1] = (char *)"25.66.77.88";
|
||||
ATHandler_stub::read_string_table[0] = (char *)"004.003.002.001";
|
||||
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_pdpcontext_params(list));
|
||||
CellularNetwork::pdpcontext_params_t *params = list.get_head();
|
||||
EXPECT_TRUE(params != NULL);
|
||||
EXPECT_TRUE(params->next == NULL);
|
||||
EXPECT_TRUE(params->cid == 1);
|
||||
EXPECT_TRUE(params->bearer_id == 2);
|
||||
EXPECT_TRUE(params->im_signalling_flag == 3);
|
||||
EXPECT_TRUE(params->lipa_indication == 4);
|
||||
EXPECT_TRUE(params->ipv4_mtu == 5);
|
||||
EXPECT_TRUE(params->wlan_offload == 6);
|
||||
EXPECT_TRUE(params->local_addr_ind == 7);
|
||||
EXPECT_TRUE(params->non_ip_mtu == 8);
|
||||
EXPECT_TRUE(params->serving_plmn_rate_control_value == 9);
|
||||
EXPECT_TRUE(strcmp(params->apn, "internet") == 0);
|
||||
EXPECT_TRUE(strcmp(params->local_addr, "102:304:506:708:90A:B70:D0E:F10") == 0);
|
||||
EXPECT_TRUE(strcmp(params->local_subnet_mask, "102:32C:3706:708:90A:B0C:D0E:F10") == 0);
|
||||
EXPECT_TRUE(strcmp(params->gateway_addr, "1721:2C01:203:377B:E122:B01:000:7BEA") == 0);
|
||||
EXPECT_TRUE(strcmp(params->dns_primary_addr, "1.2.3.4") == 0);
|
||||
EXPECT_TRUE(strcmp(params->dns_secondary_addr, "0.255.0.255") == 0);
|
||||
EXPECT_TRUE(strcmp(params->p_cscf_prim_addr, "25.66.77.88") == 0);
|
||||
EXPECT_TRUE(strcmp(params->p_cscf_sec_addr, "004.003.002.001") == 0);
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_extended_signal_quality)
|
||||
{
|
||||
EventQueue que;
|
||||
|
@ -1132,8 +603,6 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_attach)
|
|||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
network_cb_count = 0;
|
||||
cn.attach(&network_cb);
|
||||
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == cn.connect());
|
||||
EXPECT_TRUE(network_cb_count == 2); // check that attached callback was called twice
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_get_connection_status)
|
||||
|
@ -1147,32 +616,6 @@ TEST_F(TestAT_CellularNetwork, test_get_connection_status)
|
|||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
network_cb_count = 0;
|
||||
cn.attach(&network_cb);
|
||||
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == cn.connect());
|
||||
EXPECT_TRUE(network_cb_count == 2); // check that attached callback was called twice
|
||||
EXPECT_TRUE(NSAPI_STATUS_DISCONNECTED == cn.get_connection_status());
|
||||
|
||||
my_AT_CN my_cn(at);
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::bool_value = false;
|
||||
cn.set_stack_type(IPV4_STACK);
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.connect());
|
||||
EXPECT_TRUE(network_cb_count == 2);
|
||||
EXPECT_TRUE(NSAPI_STATUS_GLOBAL_UP == my_cn.get_connection_status());
|
||||
}
|
||||
|
||||
TEST_F(TestAT_CellularNetwork, test_set_blocking)
|
||||
{
|
||||
EventQueue que;
|
||||
FileHandle_stub fh1;
|
||||
ATHandler at(&fh1, que, 0, ",");
|
||||
|
||||
AT_CellularNetwork cn(at);
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_blocking(false));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_blocking(true));
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_blocking(false));
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_blocking(true));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ set(unittest-includes ${unittest-includes}
|
|||
# Source files
|
||||
set(unittest-sources
|
||||
../features/cellular/framework/AT/AT_CellularNetwork.cpp
|
||||
../features/cellular/framework/AT/AT_CellularStack.cpp
|
||||
../features/cellular/framework/common/CellularUtil.cpp
|
||||
)
|
||||
|
||||
|
@ -25,8 +24,6 @@ set(unittest-test-sources
|
|||
stubs/AT_CellularBase_stub.cpp
|
||||
stubs/EventQueue_stub.cpp
|
||||
stubs/FileHandle_stub.cpp
|
||||
stubs/NetworkInterface_stub.cpp
|
||||
stubs/NetworkStack_stub.cpp
|
||||
stubs/us_ticker_stub.cpp
|
||||
stubs/mbed_assert_stub.c
|
||||
stubs/SocketAddress_stub.cpp
|
||||
|
|
|
@ -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 "AT_CellularContext.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
|
||||
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)
|
||||
{
|
||||
_stack = NULL;
|
||||
_ip_stack_type = DEFAULT_STACK;
|
||||
_authentication_type = CellularContext::CHAP;
|
||||
_connect_status = NSAPI_STATUS_DISCONNECTED;
|
||||
_is_context_active = false;
|
||||
_is_context_activated = false;
|
||||
_apn = apn;
|
||||
_uname = MBED_CONF_NSAPI_DEFAULT_CELLULAR_USERNAME;
|
||||
_pwd = MBED_CONF_NSAPI_DEFAULT_CELLULAR_PASSWORD;
|
||||
_status_cb = NULL;
|
||||
_cid = -1;
|
||||
_new_context_set = false;
|
||||
_next = NULL;
|
||||
}
|
||||
|
||||
AT_CellularContext::~AT_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
void AT_CellularContext::set_file_handle(FileHandle *fh)
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::connect()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::set_device_ready()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::set_sim_ready()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::register_to_network()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::attach_to_network()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::check_operation(nsapi_error_t err, ContextOperation op)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
uint32_t AT_CellularContext::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 AT_CellularContext::is_connected()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
NetworkStack *AT_CellularContext::get_stack()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *AT_CellularContext::get_ip_address()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void AT_CellularContext::attach(Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::set_blocking(bool blocking)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void AT_CellularContext::set_plmn(const char *plmn)
|
||||
{
|
||||
}
|
||||
|
||||
void AT_CellularContext::set_sim_pin(const char *sim_pin)
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::connect(const char *sim_pin, const char *apn, const char *uname,
|
||||
const char *pwd)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void AT_CellularContext::set_credentials(const char *apn, const char *uname, const char *pwd)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const char *AT_CellularContext::get_netmask()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *AT_CellularContext::get_gateway()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool AT_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
nsapi_ip_stack_t AT_CellularContext::get_stack_type()
|
||||
{
|
||||
return IPV4V6_STACK;
|
||||
}
|
||||
|
||||
nsapi_ip_stack_t AT_CellularContext::string_to_stack_type(const char *pdp_type)
|
||||
{
|
||||
return IPV4V6_STACK;
|
||||
}
|
||||
|
||||
// PDP Context handling
|
||||
nsapi_error_t AT_CellularContext::delete_current_context()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::do_user_authentication()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
bool AT_CellularContext::get_context()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AT_CellularContext::set_new_context(int cid)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::do_activate_context()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void AT_CellularContext::do_connect()
|
||||
{
|
||||
}
|
||||
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
nsapi_error_t AT_CellularContext::open_data_channel()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
|
||||
{
|
||||
}
|
||||
|
||||
#endif //#if NSAPI_PPP_AVAILABLE
|
||||
|
||||
nsapi_error_t AT_CellularContext::disconnect()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::get_apn_backoff_timer(int &backoff_timer)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::get_rate_control(
|
||||
CellularContext::RateControlExceptionReports &reports,
|
||||
CellularContext::RateControlUplinkTimeUnit &timeUnit, int &uplinkRate)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::get_pdpcontext_params(pdpContextList_t ¶ms_list)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
// Called by CellularDevice for network and cellular device changes
|
||||
void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
|
||||
{
|
||||
}
|
||||
|
||||
void AT_CellularContext::call_network_cb(nsapi_connection_status_t status)
|
||||
{
|
||||
}
|
|
@ -33,49 +33,6 @@ AT_CellularNetwork::~AT_CellularNetwork()
|
|||
{
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::init()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn,
|
||||
const char *username, const char *password)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn,
|
||||
AuthenticationType type, const char *username, const char *password)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::connect(const char *apn,
|
||||
const char *username, const char *password)
|
||||
{
|
||||
return connect();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::connect()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::activate_context()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::open_data_channel()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::disconnect()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::attach(Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
}
|
||||
|
@ -85,16 +42,6 @@ nsapi_connection_status_t AT_CellularNetwork::get_connection_status() const
|
|||
return NSAPI_STATUS_LOCAL_UP;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_blocking(bool blocking)
|
||||
{
|
||||
return NSAPI_ERROR_OK;;
|
||||
}
|
||||
|
||||
nsapi_ip_stack_t AT_CellularNetwork::string_to_stack_type(const char *pdp_type)
|
||||
{
|
||||
return IPV4_STACK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bool urc_on)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
|
@ -126,7 +73,7 @@ AT_CellularNetwork::RegistrationMode AT_CellularNetwork::has_registration(Regist
|
|||
return RegistrationModeDisable;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_attach(int timeout)
|
||||
nsapi_error_t AT_CellularNetwork::set_attach()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
@ -141,36 +88,6 @@ nsapi_error_t AT_CellularNetwork::detach()
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_apn_backoff_timer(int &backoffTime)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
NetworkStack *AT_CellularNetwork::get_stack()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *AT_CellularNetwork::get_ip_address()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_stack_type(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_ip_stack_t AT_CellularNetwork::get_stack_type()
|
||||
{
|
||||
return IPV4_STACK;
|
||||
}
|
||||
|
||||
bool AT_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::urc_no_carrier()
|
||||
{
|
||||
|
||||
|
@ -203,19 +120,6 @@ nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_rate_control(
|
||||
CellularNetwork::RateControlExceptionReports &reports,
|
||||
CellularNetwork::RateControlUplinkTimeUnit &timeUnit, int &uplinkRate)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_pdpcontext_params(pdpContextList_t ¶ms_list)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_extended_signal_quality(int &rxlev, int &ber, int &rscp, int &ecno, int &rsrq, int &rsrp)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
|
@ -241,10 +145,7 @@ nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_nam
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::do_user_authentication()
|
||||
bool AT_CellularNetwork::is_active_context()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -26,14 +26,54 @@ MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
|
|||
return NULL;
|
||||
}
|
||||
|
||||
CellularDevice::CellularDevice() : _network_ref_count(0), _sms_ref_count(0), _power_ref_count(0), _sim_ref_count(0),
|
||||
_info_ref_count(0)
|
||||
CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0),_power_ref_count(0), _sim_ref_count(0),
|
||||
_info_ref_count(0), _fh(fh), _queue(5 * EVENTS_EVENT_SIZE), _state_machine(0), _nw(0)
|
||||
{
|
||||
}
|
||||
|
||||
events::EventQueue *CellularDevice::get_queue() const
|
||||
CellularDevice::~CellularDevice()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
events::EventQueue *CellularDevice::get_queue()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CellularDevice::set_plmn(char const*)
|
||||
{
|
||||
}
|
||||
|
||||
void CellularDevice::set_sim_pin(char const*)
|
||||
{
|
||||
}
|
||||
|
||||
CellularContext *CellularDevice::get_context_list() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::set_device_ready()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::set_sim_ready()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::register_to_network()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::attach_to_network()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 "CellularStateMachine.h"
|
||||
#include "CellularDevice.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
CellularStateMachine::CellularStateMachine(CellularDevice &device, events::EventQueue &queue) :
|
||||
_cellularDevice(device), _queue(queue)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CellularStateMachine::~CellularStateMachine()
|
||||
{
|
||||
}
|
||||
|
||||
void CellularStateMachine::stop()
|
||||
{
|
||||
}
|
||||
|
||||
void CellularStateMachine::set_sim_pin(const char *sim_pin)
|
||||
{
|
||||
}
|
||||
|
||||
void CellularStateMachine::set_plmn(const char *plmn)
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t CellularStateMachine::run_to_state(CellularStateMachine::CellularState state)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
bool CellularStateMachine::get_current_status(CellularStateMachine::CellularState ¤t_state, CellularStateMachine::CellularState &target_state)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularStateMachine::start_dispatch()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void CellularStateMachine::set_cellular_callback(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 "SerialBase.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
SerialBase::SerialBase(PinName tx, PinName rx, int baud)
|
||||
{
|
||||
}
|
||||
|
||||
SerialBase::~SerialBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SerialBase::baud(int baudrate)
|
||||
{
|
||||
}
|
||||
|
||||
void SerialBase::format(int bits, Parity parity, int stop_bits)
|
||||
{
|
||||
}
|
||||
|
||||
int SerialBase::readable()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SerialBase::writeable()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SerialBase::attach(Callback<void()> func, IrqType type)
|
||||
{
|
||||
}
|
||||
|
||||
void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type)
|
||||
{
|
||||
}
|
||||
|
||||
int SerialBase::_base_getc()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SerialBase::_base_putc(int c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SerialBase::send_break()
|
||||
{
|
||||
}
|
||||
|
||||
void SerialBase::lock()
|
||||
{
|
||||
}
|
||||
|
||||
void SerialBase:: unlock()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* 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 "UARTSerial.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
||||
UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) : SerialBase(tx, rx, baud)
|
||||
{
|
||||
}
|
||||
|
||||
UARTSerial::~UARTSerial()
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t UARTSerial::read(void *buffer, size_t length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t UARTSerial::write(const void *buffer, size_t length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
off_t UARTSerial::seek(off_t offset, int whence)
|
||||
{
|
||||
return -ESPIPE;
|
||||
}
|
||||
|
||||
int UARTSerial::close()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UARTSerial::dcd_irq()
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::set_baud(int baud)
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::set_data_carrier_detect(PinName dcd_pin, bool active_high)
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::set_format(int bits, Parity parity, int stop_bits)
|
||||
{
|
||||
}
|
||||
|
||||
int UARTSerial::isatty()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int UARTSerial::sync()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UARTSerial::sigio(Callback<void()> func)
|
||||
{
|
||||
}
|
||||
|
||||
ssize_t UARTSerial::write_unbuffered(const char *buf_ptr, size_t length)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool UARTSerial::hup() const
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::wake()
|
||||
{
|
||||
}
|
||||
|
||||
short UARTSerial::poll(short events) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UARTSerial::lock()
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::unlock()
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::api_lock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::api_unlock(void)
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::rx_irq(void)
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::tx_irq(void)
|
||||
{
|
||||
}
|
||||
|
||||
void UARTSerial::wait_ms(uint32_t millisec)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -25,6 +25,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct gpio_irq_s {
|
||||
uint32_t ch;
|
||||
};
|
||||
|
||||
struct serial_s {
|
||||
int x;
|
||||
};
|
||||
|
||||
#include "gpio_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -39,11 +39,10 @@
|
|||
|
||||
static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
static CellularDevice *device;
|
||||
static EventQueue queue(8 * EVENTS_EVENT_SIZE);
|
||||
|
||||
static void create_device()
|
||||
{
|
||||
device = new CELLULAR_DEVICE(queue);
|
||||
device = new CELLULAR_DEVICE(&cellular_serial);
|
||||
TEST_ASSERT(device != NULL);
|
||||
}
|
||||
|
||||
|
@ -52,32 +51,26 @@ static void open_close_interfaces()
|
|||
CellularNetwork *nw = device->open_network(&cellular_serial);
|
||||
TEST_ASSERT(nw != NULL);
|
||||
device->close_network();
|
||||
nw = device->open_network(NULL);
|
||||
TEST_ASSERT(nw == NULL);
|
||||
|
||||
CellularSIM *sim = device->open_sim(&cellular_serial);
|
||||
TEST_ASSERT(sim != NULL);
|
||||
device->close_sim();
|
||||
sim = device->open_sim(NULL);
|
||||
TEST_ASSERT(sim == NULL);
|
||||
|
||||
CellularInformation *info = device->open_information(&cellular_serial);
|
||||
TEST_ASSERT(info != NULL);
|
||||
device->close_information();
|
||||
info = device->open_information(NULL);
|
||||
TEST_ASSERT(info == NULL);
|
||||
|
||||
CellularPower *power = device->open_power(&cellular_serial);
|
||||
TEST_ASSERT(power != NULL);
|
||||
device->close_power();
|
||||
power = device->open_power(NULL);
|
||||
TEST_ASSERT(power == NULL);
|
||||
|
||||
CellularSMS *sms = device->open_sms(&cellular_serial);
|
||||
TEST_ASSERT(sms != NULL);
|
||||
device->close_sms();
|
||||
sms = device->open_sms(NULL);
|
||||
TEST_ASSERT(sms == NULL);
|
||||
|
||||
CellularContext *ctx = device->create_context();
|
||||
TEST_ASSERT(ctx != NULL);
|
||||
device->delete_context(ctx);
|
||||
}
|
||||
|
||||
static void other_methods()
|
||||
|
@ -86,8 +79,6 @@ static void other_methods()
|
|||
device->set_timeout(5000);
|
||||
device->modem_debug_on(true);
|
||||
device->modem_debug_on(false);
|
||||
NetworkStack *stack = device->get_stack();
|
||||
TEST_ASSERT(stack == NULL);
|
||||
|
||||
CellularNetwork *nw = device->open_network(&cellular_serial);
|
||||
TEST_ASSERT(nw != NULL);
|
||||
|
@ -96,8 +87,6 @@ static void other_methods()
|
|||
device->set_timeout(5000);
|
||||
device->modem_debug_on(true);
|
||||
device->modem_debug_on(false);
|
||||
stack = device->get_stack();
|
||||
TEST_ASSERT(stack != NULL);
|
||||
}
|
||||
|
||||
static void delete_device()
|
||||
|
|
|
@ -39,46 +39,30 @@
|
|||
|
||||
|
||||
#include "AT_CellularInformation.h"
|
||||
#include "CellularConnectionFSM.h"
|
||||
#include "CellularContext.h"
|
||||
#include "CellularDevice.h"
|
||||
#include "../../cellular_tests_common.h"
|
||||
|
||||
#define SIM_TIMEOUT (180*1000)
|
||||
|
||||
static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
static EventQueue queue(2 * EVENTS_EVENT_SIZE);
|
||||
static CellularConnectionFSM cellular;
|
||||
static CellularConnectionFSM::CellularState cellular_target_state;
|
||||
static rtos::Semaphore fsm_semaphore(0);
|
||||
|
||||
static bool fsm_callback(int state, int next_state)
|
||||
{
|
||||
if (next_state == CellularConnectionFSM::STATE_SIM_PIN) {
|
||||
TEST_ASSERT(fsm_semaphore.release() == osOK);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static CellularContext *ctx;
|
||||
|
||||
static void init_to_sim_state()
|
||||
{
|
||||
cellular.set_serial(&cellular_serial);
|
||||
TEST_ASSERT(cellular.init() == NSAPI_ERROR_OK);
|
||||
#if defined (MDMRTS) && defined (MDMCTS)
|
||||
cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
ctx = CellularContext::get_default_instance();
|
||||
TEST_ASSERT(ctx != NULL);
|
||||
ctx->set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
#ifdef MBED_CONF_APP_APN
|
||||
ctx->set_credentials(MBED_CONF_APP_APN);
|
||||
#endif
|
||||
cellular.set_callback(&fsm_callback);
|
||||
TEST_ASSERT(cellular.start_dispatch() == NSAPI_ERROR_OK);
|
||||
cellular_target_state = CellularConnectionFSM::STATE_SIM_PIN;
|
||||
TEST_ASSERT(cellular.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(fsm_semaphore.wait(SIM_TIMEOUT) == 1);
|
||||
TEST_ASSERT(ctx->set_sim_ready() == NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
static void test_information_interface()
|
||||
{
|
||||
CellularInformation *info = cellular.get_device()->open_information(&cellular_serial);
|
||||
CellularDevice *dev = CellularDevice::get_default_instance();
|
||||
|
||||
CellularInformation *info = dev->open_information();
|
||||
const int kbuf_size = 100;
|
||||
char *buf = (char *)malloc(sizeof(char) * kbuf_size);
|
||||
char *buf = new char[kbuf_size];
|
||||
|
||||
TEST_ASSERT(info->get_manufacturer(buf, kbuf_size) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(info->get_model(buf, kbuf_size) == NSAPI_ERROR_OK);
|
||||
|
@ -96,9 +80,9 @@ static void test_information_interface()
|
|||
err = info->get_serial_number(buf, kbuf_size, CellularInformation::SVN);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_UNSUPPORTED || err == NSAPI_ERROR_OK);
|
||||
|
||||
cellular.get_device()->close_information();
|
||||
dev->close_information();
|
||||
|
||||
free(buf);
|
||||
delete [] buf;
|
||||
}
|
||||
|
||||
using namespace utest::v1;
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_ADV_WISE_1570) || defined(TARGET_MTB_ADV_WISE_1570)
|
||||
#error [NOT_SUPPORTED] target MTB_ADV_WISE_1570 is too unstable for network tests, IoT network is unstable
|
||||
#endif
|
||||
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
@ -38,65 +42,30 @@
|
|||
#include "mbed.h"
|
||||
|
||||
#include "AT_CellularNetwork.h"
|
||||
#include "CellularConnectionFSM.h"
|
||||
#include "CellularContext.h"
|
||||
#include "CellularDevice.h"
|
||||
#include "../../cellular_tests_common.h"
|
||||
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
|
||||
|
||||
#define NETWORK_TIMEOUT (180*1000)
|
||||
|
||||
static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
static EventQueue queue(8 * EVENTS_EVENT_SIZE);
|
||||
static rtos::Semaphore network_semaphore(0);
|
||||
static CellularConnectionFSM cellular;
|
||||
static CellularConnectionFSM::CellularState cellular_target_state;
|
||||
static CELLULAR_DEVICE *device;
|
||||
static CellularContext *ctx;
|
||||
static CellularDevice *device;
|
||||
static CellularNetwork *nw;
|
||||
|
||||
|
||||
static bool fsm_callback(int state, int next_state)
|
||||
{
|
||||
if (next_state == cellular_target_state) {
|
||||
TEST_ASSERT(network_semaphore.release() == osOK);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// test methods that are already run in state machine (CellularConnectionFSM) but as it might change
|
||||
// we wan't to run these 'manually' also
|
||||
static void test_network_interface_fsm()
|
||||
{
|
||||
#if defined (MDMRTS) && defined (MDMCTS)
|
||||
cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
#endif
|
||||
device = new CELLULAR_DEVICE(queue);
|
||||
TEST_ASSERT(device != NULL);
|
||||
|
||||
CellularNetwork *nw = device->open_network(&cellular_serial);
|
||||
TEST_ASSERT(nw != NULL);
|
||||
TEST_ASSERT(nw->init() == NSAPI_ERROR_OK);
|
||||
|
||||
delete device;
|
||||
device = NULL;
|
||||
}
|
||||
|
||||
static void init_network_interface()
|
||||
{
|
||||
cellular.set_serial(&cellular_serial);
|
||||
TEST_ASSERT(cellular.init() == NSAPI_ERROR_OK);
|
||||
cellular.set_callback(&fsm_callback);
|
||||
TEST_ASSERT(cellular.start_dispatch() == NSAPI_ERROR_OK);
|
||||
cellular.set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
ctx = CellularContext::get_default_instance();
|
||||
TEST_ASSERT(ctx != NULL);
|
||||
ctx->set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
#ifdef MBED_CONF_APP_APN
|
||||
CellularNetwork *network = cellular.get_network();
|
||||
TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN) == NSAPI_ERROR_OK);
|
||||
ctx->set_credentials(MBED_CONF_APP_APN);
|
||||
#endif
|
||||
cellular_target_state = CellularConnectionFSM::STATE_REGISTERING_NETWORK;
|
||||
TEST_ASSERT(cellular.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1);
|
||||
}
|
||||
TEST_ASSERT(ctx->register_to_network() == NSAPI_ERROR_OK);
|
||||
|
||||
device = CellularDevice::get_default_instance();
|
||||
TEST_ASSERT(device != NULL);
|
||||
}
|
||||
|
||||
static bool get_network_registration(CellularNetwork::RegistrationType type,
|
||||
CellularNetwork::RegistrationStatus &status, bool &is_registered)
|
||||
|
@ -149,8 +118,8 @@ static void nw_callback(nsapi_event_t ev, intptr_t intptr)
|
|||
|
||||
static void test_network_registration()
|
||||
{
|
||||
cellular.get_device()->set_timeout(10 * 1000);
|
||||
nw = cellular.get_network();
|
||||
device->set_timeout(10 * 1000);
|
||||
nw = device->open_network();
|
||||
TEST_ASSERT(nw != NULL);
|
||||
|
||||
nw->attach(&nw_callback);
|
||||
|
@ -194,97 +163,22 @@ static void test_attach()
|
|||
TEST_ASSERT(status == CellularNetwork::Attached);
|
||||
}
|
||||
|
||||
static void test_activate_context()
|
||||
{
|
||||
TEST_ASSERT(nw->activate_context() == NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
static void test_connect()
|
||||
{
|
||||
TEST_ASSERT(nw->connect() == NSAPI_ERROR_OK);
|
||||
char count = 0;
|
||||
while ((nw->get_connection_status() != NSAPI_STATUS_GLOBAL_UP) && (count++ < 60)) {
|
||||
wait(1);
|
||||
}
|
||||
nsapi_connection_status_t st = nw->get_connection_status();
|
||||
TEST_ASSERT(st == NSAPI_STATUS_GLOBAL_UP);
|
||||
}
|
||||
|
||||
static void test_credentials()
|
||||
{
|
||||
nsapi_error_t err = nw->set_credentials(NULL, "username", "pass");
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
err = nw->set_credentials("internet", "user", NULL);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
err = nw->set_credentials("internet", CellularNetwork::NOAUTH, "user", "pass");
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
TEST_ASSERT(nw->set_credentials("internet", NULL, "pass") == NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
static void test_other()
|
||||
{
|
||||
const char *devi = CELLULAR_STRINGIFY(CELLULAR_DEVICE);
|
||||
TEST_ASSERT(nw->get_3gpp_error() == 0);
|
||||
|
||||
CellularNetwork::RateControlExceptionReports reports;
|
||||
CellularNetwork::RateControlUplinkTimeUnit timeUnit;
|
||||
int uplinkRate;
|
||||
// can't test values as they are optional
|
||||
nsapi_error_t err = nw->get_rate_control(reports, timeUnit, uplinkRate);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
|
||||
if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0 && strcmp(devi, "SARA4_PPP") != 0) { // QUECTEL_BG96 does not give any specific reason for device error
|
||||
if (err == NSAPI_ERROR_DEVICE_ERROR) {
|
||||
TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem
|
||||
((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem
|
||||
}
|
||||
}
|
||||
|
||||
uplinkRate = -1;
|
||||
err = nw->get_apn_backoff_timer(uplinkRate);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR || err == NSAPI_ERROR_PARAMETER);
|
||||
if (err == NSAPI_ERROR_DEVICE_ERROR) {
|
||||
if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "TELIT_HE910") != 0 && strcmp(devi, "SARA4_PPP") != 0) { // QUECTEL_BG96 does not give any specific reason for device error
|
||||
TEST_ASSERT(((AT_CellularNetwork *)nw)->get_device_error().errCode == 100 && // 100 == unknown command for modem
|
||||
((AT_CellularNetwork *)nw)->get_device_error().errType == 3); // 3 == CME error from the modem
|
||||
}
|
||||
} else if (err == NSAPI_ERROR_PARAMETER) {
|
||||
TEST_ASSERT(uplinkRate == -1);
|
||||
} else {
|
||||
TEST_ASSERT(uplinkRate >= 0);
|
||||
}
|
||||
|
||||
err = nw->set_access_technology(CellularNetwork::RAT_GSM);
|
||||
nsapi_error_t err = nw->set_access_technology(CellularNetwork::RAT_GSM);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
|
||||
// scanning of operators requires some delay before operation is allowed(seen with WISE_1570)
|
||||
wait(5);
|
||||
// scanning of operators might take a long time
|
||||
cellular.get_device()->set_timeout(240 * 1000);
|
||||
device->set_timeout(240 * 1000);
|
||||
CellularNetwork::operList_t operators;
|
||||
int uplinkRate = -1;
|
||||
TEST_ASSERT(nw->scan_plmn(operators, uplinkRate) == NSAPI_ERROR_OK);
|
||||
cellular.get_device()->set_timeout(10 * 1000);
|
||||
|
||||
|
||||
// all current targets support IPV4
|
||||
nsapi_ip_stack_t stack_type = IPV4_STACK;
|
||||
TEST_ASSERT(nw->set_stack_type(stack_type) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(nw->get_stack_type() == stack_type);
|
||||
|
||||
CellularNetwork::pdpContextList_t params_list;
|
||||
err = nw->get_pdpcontext_params(params_list);
|
||||
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
|
||||
if (err == NSAPI_ERROR_DEVICE_ERROR) {
|
||||
if (strcmp(devi, "TELIT_HE910") != 0) { // TELIT_HE910 just gives an error and no specific error number so we can't know is this real error or that modem/network does not support the command
|
||||
TEST_ASSERT((((AT_CellularNetwork *)nw)->get_device_error().errType == 3) && // 3 == CME error from the modem
|
||||
((((AT_CellularNetwork *)nw)->get_device_error().errCode == 100) || // 100 == unknown command for modem
|
||||
(((AT_CellularNetwork *)nw)->get_device_error().errCode == 50))); // 50 == incorrect parameters // seen in wise_1570 for not supported commands
|
||||
}
|
||||
} else {
|
||||
// should have some values, only not optional are apn and bearer id
|
||||
CellularNetwork::pdpcontext_params_t *params = params_list.get_head();
|
||||
TEST_ASSERT(params->bearer_id >= 0)
|
||||
}
|
||||
device->set_timeout(10 * 1000);
|
||||
|
||||
int rxlev = -1, ber = -1, rscp = -1, ecno = -1, rsrq = -1, rsrp = -1;
|
||||
err = nw->get_extended_signal_quality(rxlev, ber, rscp, ecno, rsrq, rsrp);
|
||||
|
@ -328,8 +222,6 @@ static void test_other()
|
|||
nsapi_connection_status_t st = nw->get_connection_status();
|
||||
TEST_ASSERT(st == NSAPI_STATUS_DISCONNECTED);
|
||||
|
||||
TEST_ASSERT(nw->set_blocking(true) == NSAPI_ERROR_OK);
|
||||
|
||||
#ifndef TARGET_UBLOX_C027 // AT command is supported, but excluded as it runs out of memory easily (there can be very many operator names)
|
||||
if (strcmp(devi, "QUECTEL_BG96") != 0 && strcmp(devi, "SARA4_PPP") != 0) {
|
||||
// QUECTEL_BG96 timeouts with this one, tested with 3 minute timeout
|
||||
|
@ -378,15 +270,6 @@ static void test_other()
|
|||
}
|
||||
}
|
||||
|
||||
static void test_disconnect()
|
||||
{
|
||||
nsapi_connection_status_t st = nw->get_connection_status();
|
||||
TEST_ASSERT(st == NSAPI_STATUS_GLOBAL_UP);
|
||||
TEST_ASSERT(nw->disconnect() == NSAPI_ERROR_OK);
|
||||
// wait to process URC's, received after disconnect
|
||||
rtos::ThisThread::sleep_for(500);
|
||||
}
|
||||
|
||||
static void test_detach()
|
||||
{
|
||||
// in PPP mode there is NO CARRIER waiting so flush it out
|
||||
|
@ -412,17 +295,11 @@ static utest::v1::status_t greentea_failure_handler(const Case *const source, co
|
|||
}
|
||||
|
||||
static Case cases[] = {
|
||||
Case("CellularNetwork state machine methods", test_network_interface_fsm, greentea_failure_handler),
|
||||
Case("CellularNetwork init", init_network_interface, greentea_failure_handler),
|
||||
Case("CellularNetwork test registering", test_network_registration, greentea_failure_handler),
|
||||
Case("CellularNetwork test attach", test_attach, greentea_failure_handler),
|
||||
Case("CellularNetwork test activate pdp context", test_activate_context, greentea_failure_handler),
|
||||
Case("CellularNetwork test other functions", test_other, greentea_failure_handler),
|
||||
Case("CellularNetwork test connect", test_connect, greentea_failure_handler),
|
||||
Case("CellularNetwork test credentials", test_credentials, greentea_failure_handler),
|
||||
Case("CellularNetwork test disconnect", test_disconnect, greentea_failure_handler),
|
||||
Case("CellularNetwork test detach", test_detach, greentea_failure_handler)
|
||||
|
||||
};
|
||||
|
||||
static utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
|
|
|
@ -44,9 +44,7 @@
|
|||
|
||||
#define NETWORK_TIMEOUT (180*1000)
|
||||
|
||||
static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
static CELLULAR_DEVICE *cellular_device;
|
||||
static EventQueue queue(2 * EVENTS_EVENT_SIZE);
|
||||
static CellularDevice *cellular_device;
|
||||
|
||||
static void urc_callback()
|
||||
{
|
||||
|
@ -74,9 +72,9 @@ static void wait_for_power(CellularPower *pwr)
|
|||
static void test_power_interface()
|
||||
{
|
||||
const char *devi = CELLULAR_STRINGIFY(CELLULAR_DEVICE);
|
||||
cellular_device = new CELLULAR_DEVICE(queue);
|
||||
cellular_device->set_timeout(5000);
|
||||
CellularPower *pwr = cellular_device->open_power(&cellular_serial);
|
||||
cellular_device = CellularDevice::get_default_instance();
|
||||
cellular_device->set_timeout(9000);
|
||||
CellularPower *pwr = cellular_device->open_power();
|
||||
TEST_ASSERT(pwr != NULL);
|
||||
|
||||
nsapi_error_t err = pwr->on();
|
||||
|
@ -89,6 +87,7 @@ static void test_power_interface()
|
|||
TEST_ASSERT(err == NSAPI_ERROR_OK);
|
||||
wait_for_power(pwr);
|
||||
|
||||
wait(1);
|
||||
err = pwr->opt_power_save_mode(0, 0);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
|
||||
if (err == NSAPI_ERROR_DEVICE_ERROR) {
|
||||
|
@ -98,6 +97,7 @@ static void test_power_interface()
|
|||
}
|
||||
}
|
||||
|
||||
wait(1);
|
||||
err = pwr->opt_receive_period(0, CellularPower::EDRXEUTRAN_NB_S1_mode, 3);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_DEVICE_ERROR);
|
||||
if (err == NSAPI_ERROR_DEVICE_ERROR) {
|
||||
|
@ -109,6 +109,7 @@ static void test_power_interface()
|
|||
|
||||
err = pwr->off();
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
|
||||
}
|
||||
|
||||
using namespace utest::v1;
|
||||
|
|
|
@ -37,86 +37,40 @@
|
|||
|
||||
#include "mbed.h"
|
||||
|
||||
#include "CellularConnectionFSM.h"
|
||||
#include "CellularContext.h"
|
||||
#include "CellularDevice.h"
|
||||
#include "CellularSIM.h"
|
||||
#include "../../cellular_tests_common.h"
|
||||
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
|
||||
|
||||
#define NETWORK_TIMEOUT (180*1000)
|
||||
|
||||
static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
static EventQueue queue(8 * EVENTS_EVENT_SIZE);
|
||||
static rtos::Semaphore network_semaphore(0);
|
||||
static CellularConnectionFSM cellular;
|
||||
static CellularConnectionFSM::CellularState cellular_target_state;
|
||||
static CellularContext *ctx;
|
||||
static CellularDevice *device;
|
||||
|
||||
static char *get_rand_string(char *str, size_t size)
|
||||
static void init_to_device_ready_state()
|
||||
{
|
||||
const char charset[] = "0123456789";
|
||||
if (size) {
|
||||
--size;
|
||||
for (size_t n = 0; n < size; n++) {
|
||||
int key = rand() % (int)(sizeof charset - 1);
|
||||
str[n] = charset[key];
|
||||
}
|
||||
str[size] = '\0';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
ctx = CellularContext::get_default_instance();
|
||||
TEST_ASSERT(ctx != NULL);
|
||||
TEST_ASSERT(ctx->set_device_ready() == NSAPI_ERROR_OK);
|
||||
|
||||
static bool fsm_callback(int state, int next_state)
|
||||
{
|
||||
if (next_state == CellularConnectionFSM::STATE_SIM_PIN) {
|
||||
TEST_ASSERT(network_semaphore.release() == osOK);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void init_to_sim_state()
|
||||
{
|
||||
cellular.set_serial(&cellular_serial);
|
||||
TEST_ASSERT(cellular.init() == NSAPI_ERROR_OK);
|
||||
#if defined (MDMRTS) && defined (MDMCTS)
|
||||
cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
#endif
|
||||
cellular.set_callback(&fsm_callback);
|
||||
TEST_ASSERT(cellular.start_dispatch() == NSAPI_ERROR_OK);
|
||||
cellular_target_state = CellularConnectionFSM::STATE_SIM_PIN;
|
||||
TEST_ASSERT(cellular.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1);
|
||||
device = CellularDevice::get_default_instance();
|
||||
TEST_ASSERT(device != NULL);
|
||||
}
|
||||
|
||||
static void test_sim_interface()
|
||||
{
|
||||
CellularSIM *sim = cellular.get_sim();
|
||||
CellularSIM *sim = device->open_sim();
|
||||
TEST_ASSERT(sim != NULL);
|
||||
|
||||
// set SIM at time out to 3000
|
||||
cellular.get_device()->set_timeout(3000);
|
||||
// set SIM at time out to 9000
|
||||
device->set_timeout(9000);
|
||||
wait(4); // we need to wait for some time so that SIM interface is working in all modules.
|
||||
// 1. test set_pin
|
||||
nsapi_error_t err = sim->set_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
MBED_ASSERT(err == NSAPI_ERROR_OK);
|
||||
|
||||
// 2. test change pin
|
||||
char pin[5];
|
||||
int sanity_count = 0;
|
||||
while (strcmp(get_rand_string(pin, 5), MBED_CONF_APP_CELLULAR_SIM_PIN) == 0) {
|
||||
sanity_count++;
|
||||
TEST_ASSERT(sanity_count < 50);
|
||||
};
|
||||
|
||||
// change pin and change it back
|
||||
wait(1);
|
||||
err = sim->change_pin(MBED_CONF_APP_CELLULAR_SIM_PIN, pin);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
|
||||
wait(1);
|
||||
err = sim->change_pin(pin, MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
|
||||
// 3. test set_pin_query
|
||||
// 2. test set_pin_query
|
||||
wait(1);
|
||||
err = sim->set_pin_query(MBED_CONF_APP_CELLULAR_SIM_PIN, false);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
|
@ -126,14 +80,14 @@ static void test_sim_interface()
|
|||
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
|
||||
|
||||
wait(1);
|
||||
// 4. test get_sim_state
|
||||
// 3. test get_sim_state
|
||||
CellularSIM::SimState state;
|
||||
err = sim->get_sim_state(state);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(state == CellularSIM::SimStateReady);
|
||||
|
||||
wait(1);
|
||||
// 5. test get_imsi
|
||||
// 4. test get_imsi
|
||||
char imsi[16] = {0};
|
||||
err = sim->get_imsi(imsi);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK);
|
||||
|
@ -149,7 +103,7 @@ static utest::v1::status_t greentea_failure_handler(const Case *const source, co
|
|||
}
|
||||
|
||||
static Case cases[] = {
|
||||
Case("CellularSIM init", init_to_sim_state, greentea_failure_handler),
|
||||
Case("CellularSIM init", init_to_device_ready_state, greentea_failure_handler),
|
||||
Case("CellularSIM test interface", test_sim_interface, greentea_failure_handler)
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@
|
|||
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TARGET_ADV_WISE_1570) || defined(TARGET_MTB_ADV_WISE_1570)
|
||||
#error [NOT_SUPPORTED] target MTB_ADV_WISE_1570 does not have SMS functionality
|
||||
#endif
|
||||
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
|
@ -40,59 +42,43 @@
|
|||
#include "mbed.h"
|
||||
|
||||
#include "AT_CellularSMS.h"
|
||||
#include "CellularConnectionFSM.h"
|
||||
#include "CellularContext.h"
|
||||
#include "CellularDevice.h"
|
||||
#include "../../cellular_tests_common.h"
|
||||
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
|
||||
|
||||
#define NETWORK_TIMEOUT (600*1000)
|
||||
|
||||
#define SIM_BUSY 314
|
||||
static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
static EventQueue queue(8 * EVENTS_EVENT_SIZE);
|
||||
static rtos::Semaphore network_semaphore(0);
|
||||
static CellularConnectionFSM *cellularConnectionFSM;
|
||||
static CellularConnectionFSM::CellularState cellular_target_state;
|
||||
static CellularContext *ctx;
|
||||
static CellularDevice *device;
|
||||
static CellularSMS *sms;
|
||||
static char service_center_address[SMS_MAX_PHONE_NUMBER_SIZE];
|
||||
static int service_address_type;
|
||||
|
||||
static bool cellular_status(int state, int next_state)
|
||||
static void create_context()
|
||||
{
|
||||
if (cellular_target_state == state) {
|
||||
(void)network_semaphore.release();
|
||||
return false; // return false -> state machine is halted
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void createFSM()
|
||||
{
|
||||
#if defined (MDMRTS) && defined (MDMCTS)
|
||||
cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
#endif
|
||||
cellularConnectionFSM = new CellularConnectionFSM();
|
||||
cellularConnectionFSM->set_serial(&cellular_serial);
|
||||
cellularConnectionFSM->set_callback(&cellular_status);
|
||||
|
||||
TEST_ASSERT(cellularConnectionFSM->init() == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(cellularConnectionFSM->start_dispatch() == NSAPI_ERROR_OK);
|
||||
cellularConnectionFSM->set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
|
||||
CellularDevice *device = cellularConnectionFSM->get_device();
|
||||
device = new CELLULAR_DEVICE(&cellular_serial);
|
||||
TEST_ASSERT(device != NULL);
|
||||
device->set_timeout(30000);
|
||||
|
||||
device->set_timeout(9000);
|
||||
ctx = device->create_context();
|
||||
TEST_ASSERT(ctx != NULL);
|
||||
ctx->set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
#ifdef MBED_CONF_APP_APN
|
||||
ctx->set_credentials(MBED_CONF_APP_APN);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void store_service_center_address()
|
||||
{
|
||||
// Frist we need to go SIM_PIN state to make sure that we can get service address and device ready to accept AT commands
|
||||
createFSM();
|
||||
cellular_target_state = CellularConnectionFSM::STATE_SIM_PIN;
|
||||
TEST_ASSERT(cellularConnectionFSM->continue_to_state(cellular_target_state) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1); // cellular network searching may take several minutes
|
||||
// First we need to go SIM_PIN state to make sure that we can get service address and device ready to accept AT commands
|
||||
create_context();
|
||||
TEST_ASSERT(ctx->set_sim_ready() == NSAPI_ERROR_OK);
|
||||
wait(1);
|
||||
delete device; // will also delete context
|
||||
|
||||
delete cellularConnectionFSM;
|
||||
cellularConnectionFSM = NULL;
|
||||
wait(3); // some modems needs more time access sim
|
||||
|
||||
ATHandler *at_init = new ATHandler(&cellular_serial, queue, 30000, "\r");
|
||||
at_init->cmd_start("AT+CSCA?");
|
||||
|
@ -114,50 +100,60 @@ static void init()
|
|||
{
|
||||
// First store current service address
|
||||
store_service_center_address();
|
||||
create_context();
|
||||
|
||||
createFSM();
|
||||
CellularNetwork *network = cellularConnectionFSM->get_network();
|
||||
|
||||
TEST_ASSERT(network != NULL);
|
||||
TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN, NULL, NULL) == NSAPI_ERROR_OK);
|
||||
|
||||
cellular_target_state = CellularConnectionFSM::STATE_REGISTERING_NETWORK;
|
||||
TEST_ASSERT(cellularConnectionFSM->continue_to_state(cellular_target_state) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1); // cellular network searching may take several minutes
|
||||
|
||||
sms = cellularConnectionFSM->get_device()->open_sms(&cellular_serial);
|
||||
TEST_ASSERT(ctx->register_to_network() == NSAPI_ERROR_OK);
|
||||
sms = device->open_sms(&cellular_serial);
|
||||
TEST_ASSERT(sms != NULL);
|
||||
|
||||
wait(3);
|
||||
wait(3); // some modems needs more time access sim
|
||||
}
|
||||
|
||||
static void test_sms_initialize_text_mode()
|
||||
{
|
||||
TEST_ASSERT(sms->initialize(CellularSMS::CellularSMSMmodeText) == NSAPI_ERROR_OK);
|
||||
nsapi_error_t err = sms->initialize(CellularSMS::CellularSMSMmodeText);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || (err == NSAPI_ERROR_DEVICE_ERROR &&
|
||||
((AT_CellularSMS *)sms)->get_device_error().errCode == SIM_BUSY));
|
||||
|
||||
}
|
||||
|
||||
static void test_sms_initialize_pdu_mode()
|
||||
{
|
||||
TEST_ASSERT(sms->initialize(CellularSMS::CellularSMSMmodePDU) == NSAPI_ERROR_OK);
|
||||
nsapi_error_t err = sms->initialize(CellularSMS::CellularSMSMmodePDU);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || (err == NSAPI_ERROR_DEVICE_ERROR &&
|
||||
((AT_CellularSMS *)sms)->get_device_error().errCode == SIM_BUSY));
|
||||
}
|
||||
|
||||
static void test_set_cscs()
|
||||
{
|
||||
TEST_ASSERT(sms->set_cscs("IRA") == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(sms->set_cscs("UCS2") == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(sms->set_cscs("GSM") == NSAPI_ERROR_OK);
|
||||
nsapi_error_t err = sms->set_cscs("IRA");
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || (err == NSAPI_ERROR_DEVICE_ERROR &&
|
||||
((AT_CellularSMS *)sms)->get_device_error().errCode == SIM_BUSY));
|
||||
err = sms->set_cscs("UCS2");
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || (err == NSAPI_ERROR_DEVICE_ERROR &&
|
||||
((AT_CellularSMS *)sms)->get_device_error().errCode == SIM_BUSY));
|
||||
err = sms->set_cscs("GSM");
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || (err == NSAPI_ERROR_DEVICE_ERROR &&
|
||||
((AT_CellularSMS *)sms)->get_device_error().errCode == SIM_BUSY));
|
||||
}
|
||||
|
||||
static void test_set_csca()
|
||||
{
|
||||
TEST_ASSERT(sms->set_csca("55555", 129) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(sms->set_csca("+35855555", 145) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(sms->set_csca(service_center_address, service_address_type) == NSAPI_ERROR_OK);
|
||||
nsapi_error_t err = sms->set_csca("55555", 129);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || (err == NSAPI_ERROR_DEVICE_ERROR &&
|
||||
((AT_CellularSMS *)sms)->get_device_error().errCode == SIM_BUSY));
|
||||
err = sms->set_csca("+35855555", 145);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || (err == NSAPI_ERROR_DEVICE_ERROR &&
|
||||
((AT_CellularSMS *)sms)->get_device_error().errCode == SIM_BUSY));
|
||||
err = sms->set_csca(service_center_address, service_address_type);
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || (err == NSAPI_ERROR_DEVICE_ERROR &&
|
||||
((AT_CellularSMS *)sms)->get_device_error().errCode == SIM_BUSY));
|
||||
}
|
||||
|
||||
static void test_set_cpms_me()
|
||||
{
|
||||
TEST_ASSERT(sms->set_cpms("ME", "ME", "ME") == NSAPI_ERROR_OK);
|
||||
nsapi_error_t err = sms->set_cpms("ME", "ME", "ME");
|
||||
TEST_ASSERT(err == NSAPI_ERROR_OK || (err == NSAPI_ERROR_DEVICE_ERROR &&
|
||||
((AT_CellularSMS *)sms)->get_device_error().errCode == SIM_BUSY));
|
||||
}
|
||||
|
||||
#ifdef MBED_CONF_APP_CELLULAR_PHONE_NUMBER
|
||||
|
@ -224,7 +220,6 @@ static void test_set_extra_sim_wait_time_1000()
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
static utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
|
||||
|
@ -233,7 +228,6 @@ static utest::v1::status_t greentea_failure_handler(const Case *const source, co
|
|||
return STATUS_ABORT;
|
||||
}
|
||||
|
||||
|
||||
static Case cases[] = {
|
||||
Case("CellularSMS init", init, greentea_failure_handler),
|
||||
Case("CellularSMS test ME for storage", test_set_cpms_me, greentea_failure_handler),
|
||||
|
@ -256,9 +250,6 @@ static Case cases[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(600, "default_auto");
|
||||
|
|
|
@ -30,13 +30,17 @@
|
|||
#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build.
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_ADV_WISE_1570) || defined(TARGET_MTB_ADV_WISE_1570)
|
||||
#error [NOT_SUPPORTED] target MTB_ADV_WISE_1570 is too unstable for network tests, IoT network is unstable
|
||||
#endif
|
||||
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "unity.h"
|
||||
#include "utest.h"
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
#include "CellularConnectionFSM.h"
|
||||
#include "CellularContext.h"
|
||||
|
||||
#if MBED_CONF_CELLULAR_USE_APN_LOOKUP || MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP
|
||||
#include "APN_db.h"
|
||||
|
@ -48,13 +52,9 @@
|
|||
#define SOCKET_TIMEOUT (30*1000)
|
||||
|
||||
#define ECHO_SERVER_NAME "echo.mbedcloudtesting.com"
|
||||
#define ECHO_SERVER_UDP_PORT 7
|
||||
|
||||
static CellularConnectionFSM::CellularState cellular_target_state;
|
||||
static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
static rtos::Semaphore network_semaphore(0);
|
||||
static CellularConnectionFSM cellular;
|
||||
#define ECHO_SERVER_UDP_PORT 8877
|
||||
|
||||
static CellularContext *ctx;
|
||||
static SocketAddress echo_server_addr;
|
||||
static rtos::EventFlags eventFlags;
|
||||
|
||||
|
@ -141,37 +141,20 @@ private:
|
|||
bool _rx_pending;
|
||||
};
|
||||
|
||||
static void network_callback(nsapi_event_t ev, intptr_t ptr)
|
||||
{
|
||||
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
|
||||
if (ptr == NSAPI_STATUS_GLOBAL_UP) {
|
||||
TEST_ASSERT(network_semaphore.release() == osOK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void udp_network_stack()
|
||||
{
|
||||
cellular.set_serial(&cellular_serial);
|
||||
TEST_ASSERT(cellular.init() == NSAPI_ERROR_OK);
|
||||
#if defined (MDMRTS) && defined (MDMCTS)
|
||||
cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
#endif
|
||||
cellular.attach(&network_callback);
|
||||
TEST_ASSERT(cellular.start_dispatch() == NSAPI_ERROR_OK);
|
||||
cellular.set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
ctx = CellularContext::get_default_instance();
|
||||
TEST_ASSERT(ctx != NULL);
|
||||
ctx->set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
#ifdef MBED_CONF_APP_APN
|
||||
CellularNetwork *network = cellular.get_network();
|
||||
TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD) == NSAPI_ERROR_OK);
|
||||
ctx->set_credentials(MBED_CONF_APP_APN, MBED_CONF_APP_USERNAME, MBED_CONF_APP_PASSWORD);
|
||||
#endif
|
||||
cellular_target_state = CellularConnectionFSM::STATE_CONNECTED;
|
||||
TEST_ASSERT(cellular.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1);
|
||||
TEST_ASSERT(ctx->connect() == NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
static void udp_gethostbyname()
|
||||
{
|
||||
TEST_ASSERT(cellular.get_network()->gethostbyname(ECHO_SERVER_NAME, &echo_server_addr) == 0);
|
||||
TEST_ASSERT(ctx->gethostbyname(ECHO_SERVER_NAME, &echo_server_addr) == 0);
|
||||
tr_info("Echo server IP: %s", echo_server_addr.get_ip_address());
|
||||
echo_server_addr.set_port(7);
|
||||
}
|
||||
|
@ -179,7 +162,7 @@ static void udp_gethostbyname()
|
|||
static void udp_socket_send_receive()
|
||||
{
|
||||
EchoSocket echo_socket(4);
|
||||
TEST_ASSERT(echo_socket.open(cellular.get_network()) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(echo_socket.open(ctx) == NSAPI_ERROR_OK);
|
||||
echo_socket.set_blocking(true);
|
||||
echo_socket.set_timeout(SOCKET_TIMEOUT);
|
||||
echo_socket.test_sendto();
|
||||
|
@ -193,7 +176,7 @@ static void udp_socket_send_receive_async()
|
|||
TEST_ASSERT(!(eventFlags.clear(async_flag) & osFlagsError));
|
||||
|
||||
EchoSocket echo_socket(4);
|
||||
TEST_ASSERT(echo_socket.open(cellular.get_network()) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(echo_socket.open(ctx) == NSAPI_ERROR_OK);
|
||||
echo_socket.set_async(async_flag);
|
||||
echo_socket.test_sendto();
|
||||
echo_socket.test_recvfrom();
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
},
|
||||
"target_overrides": {
|
||||
"*": {
|
||||
"nsapi.dns-response-wait-time": 30000,
|
||||
"ppp-cell-iface.apn-lookup": false,
|
||||
"cellular.use-apn-lookup": false,
|
||||
"target.features_add": ["LWIP"],
|
||||
|
|
|
@ -1,364 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 "CellularTargets.h"
|
||||
#ifdef CELLULAR_DEVICE
|
||||
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
#include "nsapi_ppp.h"
|
||||
#endif
|
||||
|
||||
#include "CellularConnectionFSM.h"
|
||||
#include "CellularDevice.h"
|
||||
|
||||
#include "EasyCellularConnection.h"
|
||||
#include "CellularLog.h"
|
||||
#include "mbed_wait_api.h"
|
||||
|
||||
#if USE_APN_LOOKUP
|
||||
#include "APN_db.h"
|
||||
#endif //USE_APN_LOOKUP
|
||||
|
||||
namespace mbed {
|
||||
|
||||
bool EasyCellularConnection::cellular_status(int state, int next_state)
|
||||
{
|
||||
tr_info("cellular_status: %s ==> %s", _cellularConnectionFSM->get_state_string((CellularConnectionFSM::CellularState)state),
|
||||
_cellularConnectionFSM->get_state_string((CellularConnectionFSM::CellularState)next_state));
|
||||
|
||||
if (_target_state == state) {
|
||||
tr_info("Target state reached: %s", _cellularConnectionFSM->get_state_string(_target_state));
|
||||
(void)_cellularSemaphore.release();
|
||||
return false; // return false -> state machine is halted
|
||||
}
|
||||
|
||||
// only in case of an error or when connected is reached state and next_state can be the same.
|
||||
// Release semaphore to return application instead of waiting for semaphore to complete.
|
||||
if (state == next_state) {
|
||||
tr_error("cellular_status: state and next_state are same, release semaphore as this is an error in state machine");
|
||||
_stm_error = true;
|
||||
(void)_cellularSemaphore.release();
|
||||
return false; // return false -> state machine is halted
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void EasyCellularConnection::network_callback(nsapi_event_t ev, intptr_t ptr)
|
||||
{
|
||||
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
|
||||
if (ptr == NSAPI_STATUS_GLOBAL_UP) {
|
||||
_is_connected = true;
|
||||
} else {
|
||||
_is_connected = false;
|
||||
}
|
||||
}
|
||||
if (_status_cb) {
|
||||
_status_cb(ev, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
EasyCellularConnection::EasyCellularConnection(bool debug) :
|
||||
_is_connected(false), _is_initialized(false), _stm_error(false),
|
||||
_target_state(CellularConnectionFSM::STATE_POWER_ON),
|
||||
_cellularSerial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE), _cellularSemaphore(0),
|
||||
_cellularConnectionFSM(0), _credentials_err(NSAPI_ERROR_OK), _status_cb(0)
|
||||
{
|
||||
tr_info("EasyCellularConnection()");
|
||||
#if USE_APN_LOOKUP
|
||||
_credentials_set = false;
|
||||
#endif // #if USE_APN_LOOKUP
|
||||
modem_debug_on(debug);
|
||||
}
|
||||
|
||||
EasyCellularConnection::~EasyCellularConnection()
|
||||
{
|
||||
if (_cellularConnectionFSM) {
|
||||
_cellularConnectionFSM->set_callback(NULL);
|
||||
_cellularConnectionFSM->attach(NULL);
|
||||
delete _cellularConnectionFSM;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::init()
|
||||
{
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
_stm_error = false;
|
||||
if (!_is_initialized) {
|
||||
#if defined (MDMRTS) && defined (MDMCTS)
|
||||
_cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
#endif
|
||||
_cellularConnectionFSM = new CellularConnectionFSM();
|
||||
_cellularConnectionFSM->set_serial(&_cellularSerial);
|
||||
_cellularConnectionFSM->set_callback(callback(this, &EasyCellularConnection::cellular_status));
|
||||
|
||||
err = _cellularConnectionFSM->init();
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
err = _cellularConnectionFSM->start_dispatch();
|
||||
_cellularConnectionFSM->attach(callback(this, &EasyCellularConnection::network_callback));
|
||||
}
|
||||
_is_initialized = true;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void EasyCellularConnection::set_credentials(const char *apn, const char *uname, const char *pwd)
|
||||
{
|
||||
if (apn && strlen(apn) > 0) {
|
||||
_credentials_err = init();
|
||||
|
||||
if (_credentials_err) {
|
||||
return;
|
||||
}
|
||||
CellularNetwork *network = _cellularConnectionFSM->get_network();
|
||||
if (network) {
|
||||
_credentials_err = network->set_credentials(apn, uname, pwd);
|
||||
#if USE_APN_LOOKUP
|
||||
if (_credentials_err == NSAPI_ERROR_OK) {
|
||||
_credentials_set = true;
|
||||
}
|
||||
#endif // #if USE_APN_LOOKUP
|
||||
} else {
|
||||
//if get_network() returns NULL it means there was not enough memory for
|
||||
//an AT_CellularNetwork element during CellularConnectionFSM initialization
|
||||
tr_error("There was not enough memory during CellularConnectionFSM initialization");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EasyCellularConnection::set_sim_pin(const char *sim_pin)
|
||||
{
|
||||
if (sim_pin && strlen(sim_pin) > 0) {
|
||||
if (!_cellularConnectionFSM) {
|
||||
_credentials_err = init();
|
||||
|
||||
if (_credentials_err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_cellularConnectionFSM->set_sim_pin(sim_pin);
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
|
||||
{
|
||||
if (_is_connected) {
|
||||
return NSAPI_ERROR_IS_CONNECTED;
|
||||
}
|
||||
|
||||
set_credentials(apn, uname, pwd);
|
||||
if (_credentials_err) {
|
||||
return _credentials_err;
|
||||
}
|
||||
|
||||
if (sim_pin) {
|
||||
set_sim_pin(sim_pin);
|
||||
}
|
||||
|
||||
return connect();
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::check_connect()
|
||||
{
|
||||
if (_is_connected) {
|
||||
return NSAPI_ERROR_IS_CONNECTED;
|
||||
}
|
||||
|
||||
// there was an error while setting credentials but it's a void function so check error here...
|
||||
if (_credentials_err) {
|
||||
return _credentials_err;
|
||||
}
|
||||
|
||||
nsapi_error_t err = init();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::connect()
|
||||
{
|
||||
nsapi_error_t err = check_connect();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
#if USE_APN_LOOKUP
|
||||
if (!_credentials_set) {
|
||||
_target_state = CellularConnectionFSM::STATE_SIM_PIN;
|
||||
err = _cellularConnectionFSM->continue_to_state(_target_state);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
int sim_wait = _cellularSemaphore.wait(60 * 1000); // reserve 60 seconds to access to SIM
|
||||
if (sim_wait != 1 || _stm_error) {
|
||||
tr_error("NO SIM ACCESS");
|
||||
err = NSAPI_ERROR_NO_CONNECTION;
|
||||
} else {
|
||||
char imsi[MAX_IMSI_LENGTH + 1];
|
||||
wait(1); // need to wait to access SIM in some modems
|
||||
err = _cellularConnectionFSM->get_sim()->get_imsi(imsi);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
const char *apn_config = apnconfig(imsi);
|
||||
if (apn_config) {
|
||||
const char *apn = _APN_GET(apn_config);
|
||||
const char *uname = _APN_GET(apn_config);
|
||||
const char *pwd = _APN_GET(apn_config);
|
||||
tr_info("Looked up APN %s", apn);
|
||||
err = _cellularConnectionFSM->get_network()->set_credentials(apn, uname, pwd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (err) {
|
||||
tr_error("APN lookup failed");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif // USE_APN_LOOKUP
|
||||
|
||||
_target_state = CellularConnectionFSM::STATE_CONNECTED;
|
||||
err = _cellularConnectionFSM->continue_to_state(_target_state);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
int ret_wait = _cellularSemaphore.wait(10 * 60 * 1000); // cellular network searching may take several minutes
|
||||
if (ret_wait != 1 || _stm_error) {
|
||||
tr_info("No cellular connection");
|
||||
err = NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::disconnect()
|
||||
{
|
||||
_credentials_err = NSAPI_ERROR_OK;
|
||||
_is_connected = false;
|
||||
_is_initialized = false;
|
||||
_stm_error = false;
|
||||
#if USE_APN_LOOKUP
|
||||
_credentials_set = false;
|
||||
#endif // #if USE_APN_LOOKUP
|
||||
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
if (_cellularConnectionFSM && _cellularConnectionFSM->get_network()) {
|
||||
err = _cellularConnectionFSM->get_network()->disconnect();
|
||||
}
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
delete _cellularConnectionFSM;
|
||||
_cellularConnectionFSM = NULL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
bool EasyCellularConnection::is_connected()
|
||||
{
|
||||
return _is_connected;
|
||||
}
|
||||
|
||||
const char *EasyCellularConnection::get_ip_address()
|
||||
{
|
||||
if (_cellularConnectionFSM) {
|
||||
CellularNetwork *network = _cellularConnectionFSM->get_network();
|
||||
if (!network) {
|
||||
return NULL;
|
||||
}
|
||||
return _cellularConnectionFSM->get_network()->get_ip_address();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *EasyCellularConnection::get_netmask()
|
||||
{
|
||||
if (_cellularConnectionFSM) {
|
||||
CellularNetwork *network = _cellularConnectionFSM->get_network();
|
||||
if (!network) {
|
||||
return NULL;
|
||||
}
|
||||
return network->get_netmask();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *EasyCellularConnection::get_gateway()
|
||||
{
|
||||
if (_cellularConnectionFSM) {
|
||||
CellularNetwork *network = _cellularConnectionFSM->get_network();
|
||||
if (!network) {
|
||||
return NULL;
|
||||
}
|
||||
return network->get_gateway();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void EasyCellularConnection::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
_status_cb = status_cb;
|
||||
}
|
||||
|
||||
void EasyCellularConnection::modem_debug_on(bool on)
|
||||
{
|
||||
if (_cellularConnectionFSM) {
|
||||
CellularDevice *dev = _cellularConnectionFSM->get_device();
|
||||
if (dev) {
|
||||
dev->modem_debug_on(on);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EasyCellularConnection::set_plmn(const char *plmn)
|
||||
{
|
||||
if (plmn && strlen(plmn) > 0) {
|
||||
if (!_cellularConnectionFSM) {
|
||||
_credentials_err = init();
|
||||
|
||||
if (_credentials_err) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_cellularConnectionFSM->set_plmn(plmn);
|
||||
}
|
||||
}
|
||||
|
||||
NetworkStack *EasyCellularConnection::get_stack()
|
||||
{
|
||||
if (_cellularConnectionFSM) {
|
||||
return _cellularConnectionFSM->get_stack();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CellularDevice *EasyCellularConnection::get_device()
|
||||
{
|
||||
return _cellularConnectionFSM->get_device();
|
||||
}
|
||||
|
||||
UARTSerial *EasyCellularConnection::get_serial()
|
||||
{
|
||||
return &_cellularSerial;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // CELLULAR_DEVICE
|
|
@ -1,190 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 EASY_CELLULAR_CONNECTION_H
|
||||
#define EASY_CELLULAR_CONNECTION_H
|
||||
|
||||
#include "CellularConnectionFSM.h"
|
||||
#if defined(CELLULAR_DEVICE) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "netsocket/CellularBase.h"
|
||||
|
||||
#define USE_APN_LOOKUP (MBED_CONF_CELLULAR_USE_APN_LOOKUP || (NSAPI_PPP_AVAILABLE && MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP))
|
||||
|
||||
namespace mbed {
|
||||
|
||||
/** EasyCellularConnection class
|
||||
*
|
||||
* Simplified adapter for cellular connection
|
||||
*/
|
||||
class EasyCellularConnection: public CellularBase {
|
||||
|
||||
public:
|
||||
EasyCellularConnection(bool debug = false);
|
||||
virtual ~EasyCellularConnection();
|
||||
|
||||
public:
|
||||
/** Set the Cellular network credentials
|
||||
*
|
||||
* Please check documentation of connect() for default behaviour of APN settings.
|
||||
*
|
||||
* @param apn Access point name
|
||||
* @param uname optionally, Username
|
||||
* @param pwd optionally, password
|
||||
*/
|
||||
virtual void set_credentials(const char *apn, const char *uname = 0,
|
||||
const char *pwd = 0);
|
||||
|
||||
/** Set the pin code for SIM card
|
||||
*
|
||||
* @param sim_pin PIN for the SIM card
|
||||
*/
|
||||
virtual void set_sim_pin(const char *sim_pin);
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to connect to a Cellular network.
|
||||
*
|
||||
* @param sim_pin PIN for the SIM card
|
||||
* @param apn optionally, access point name
|
||||
* @param uname optionally, Username
|
||||
* @param pwd optionally, password
|
||||
* @return NSAPI_ERROR_OK on success, or negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0,
|
||||
const char *uname = 0,
|
||||
const char *pwd = 0);
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to connect to a Cellular network.
|
||||
* If the SIM requires a PIN, and it is not set/invalid, NSAPI_ERROR_AUTH_ERROR is returned.
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success, or negative error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t connect();
|
||||
|
||||
/** Stop the interface
|
||||
*
|
||||
* @return 0 on success, or error code on failure
|
||||
*/
|
||||
virtual nsapi_error_t disconnect();
|
||||
|
||||
/** Check if the connection is currently established or not
|
||||
*
|
||||
* @return true/false If the cellular module have successfully acquired a carrier and is
|
||||
* connected to an external packet data network using PPP, isConnected()
|
||||
* API returns true and false otherwise.
|
||||
*/
|
||||
virtual bool is_connected();
|
||||
|
||||
/** Get the local IP address
|
||||
*
|
||||
* @return Null-terminated representation of the local IP address
|
||||
* or null if no IP address has been received
|
||||
*/
|
||||
virtual const char *get_ip_address();
|
||||
|
||||
/** Get the local network mask
|
||||
*
|
||||
* @return Null-terminated representation of the local network mask
|
||||
* or null if no network mask has been received
|
||||
*/
|
||||
virtual const char *get_netmask();
|
||||
|
||||
/** Get the local gateways
|
||||
*
|
||||
* @return Null-terminated representation of the local gateway
|
||||
* or null if no network mask has been received
|
||||
*/
|
||||
virtual const char *get_gateway();
|
||||
|
||||
/** Register callback for status reporting
|
||||
*
|
||||
* The specified status callback function will be called on status changes
|
||||
* on the network. The parameters on the callback are the event type and
|
||||
* event-type dependent reason parameter.
|
||||
*
|
||||
* @param status_cb The callback for status changes
|
||||
*/
|
||||
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||
|
||||
/** Turn modem debug traces on
|
||||
*
|
||||
* @param on set true to enable debug traces
|
||||
*/
|
||||
void modem_debug_on(bool on);
|
||||
|
||||
/** Sets the operator plmn which is used when registering to a network specified by plmn. If plmn is not set then automatic
|
||||
* registering is used when registering to a cellular network.
|
||||
*
|
||||
* @param plmn operator in numeric format. See more from 3GPP TS 27.007 chapter 7.3.
|
||||
*/
|
||||
void set_plmn(const char *plmn);
|
||||
|
||||
/** Get the cellular device from the cellular state machine
|
||||
*
|
||||
* @return cellular device
|
||||
*/
|
||||
CellularDevice *get_device();
|
||||
|
||||
/** Get the UART serial file handle used by cellular subsystem
|
||||
*
|
||||
* @return address of cellular UART serial
|
||||
*/
|
||||
UARTSerial *get_serial();
|
||||
|
||||
protected:
|
||||
|
||||
/** Provide access to the NetworkStack object
|
||||
*
|
||||
* @return The underlying NetworkStack object
|
||||
*/
|
||||
virtual NetworkStack *get_stack();
|
||||
|
||||
private:
|
||||
/** Callback for cellular status changes
|
||||
*
|
||||
* @return true to continue state machine
|
||||
*/
|
||||
bool cellular_status(int state, int next_state);
|
||||
void network_callback(nsapi_event_t ev, intptr_t ptr);
|
||||
nsapi_error_t init();
|
||||
nsapi_error_t check_connect();
|
||||
|
||||
bool _is_connected;
|
||||
bool _is_initialized;
|
||||
bool _stm_error;
|
||||
#if USE_APN_LOOKUP
|
||||
bool _credentials_set;
|
||||
#endif // #if USE_APN_LOOKUP
|
||||
CellularConnectionFSM::CellularState _target_state;
|
||||
|
||||
UARTSerial _cellularSerial;
|
||||
rtos::Semaphore _cellularSemaphore;
|
||||
CellularConnectionFSM *_cellularConnectionFSM;
|
||||
nsapi_error_t _credentials_err;
|
||||
Callback<void(nsapi_event_t, intptr_t)> _status_cb;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // CELLULAR_DEVICE || DOXYGEN
|
||||
|
||||
#endif // EASY_CELLULAR_CONNECTION_H
|
||||
|
||||
/** @}*/
|
|
@ -0,0 +1,252 @@
|
|||
/*
|
||||
* 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 _CELLULARCONTEXT_H_
|
||||
#define _CELLULARCONTEXT_H_
|
||||
|
||||
#include "CellularBase.h"
|
||||
#include "CellularDevice.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class CellularContext : public CellularBase {
|
||||
|
||||
public:
|
||||
// max simultaneous PDP contexts active
|
||||
static const int PDP_CONTEXT_COUNT = 4;
|
||||
|
||||
/* authentication type when activating or modifying the pdp context */
|
||||
enum AuthenticationType {
|
||||
NOAUTH = 0,
|
||||
PAP,
|
||||
CHAP
|
||||
};
|
||||
|
||||
/* whether the additional exception reports are allowed to be sent when the maximum uplink rate is reached */
|
||||
enum RateControlExceptionReports {
|
||||
NotAllowedToBeSent = 0,
|
||||
AllowedToBeSent
|
||||
};
|
||||
|
||||
/* specifies the time unit to be used for the maximum uplink rate */
|
||||
enum RateControlUplinkTimeUnit {
|
||||
Unrestricted = 0,
|
||||
Minute,
|
||||
Hour,
|
||||
Day,
|
||||
Week
|
||||
};
|
||||
|
||||
/* PDP Context information */
|
||||
struct pdpcontext_params_t {
|
||||
char apn[MAX_ACCESSPOINT_NAME_LENGTH + 1];
|
||||
char local_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char local_subnet_mask[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char gateway_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char dns_primary_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char dns_secondary_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char p_cscf_prim_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char p_cscf_sec_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
int cid;
|
||||
int bearer_id;
|
||||
int im_signalling_flag;
|
||||
int lipa_indication;
|
||||
int ipv4_mtu;
|
||||
int wlan_offload;
|
||||
int local_addr_ind;
|
||||
int non_ip_mtu;
|
||||
int serving_plmn_rate_control_value;
|
||||
pdpcontext_params_t *next;
|
||||
|
||||
pdpcontext_params_t()
|
||||
{
|
||||
apn[0] = '\0';
|
||||
local_addr[0] = '\0';
|
||||
local_subnet_mask[0] = '\0';
|
||||
gateway_addr[0] = '\0';
|
||||
dns_primary_addr[0] = '\0';
|
||||
dns_secondary_addr[0] = '\0';
|
||||
p_cscf_prim_addr[0] = '\0';
|
||||
p_cscf_sec_addr[0] = '\0';
|
||||
cid = -1;
|
||||
bearer_id = -1;
|
||||
im_signalling_flag = -1;
|
||||
lipa_indication = -1;
|
||||
ipv4_mtu = -1;
|
||||
wlan_offload = -1;
|
||||
local_addr_ind = -1;
|
||||
non_ip_mtu = -1;
|
||||
serving_plmn_rate_control_value = -1;
|
||||
next = NULL;
|
||||
}
|
||||
};
|
||||
typedef CellularList<pdpcontext_params_t> pdpContextList_t;
|
||||
|
||||
// pointer for next item when used as a linked list
|
||||
CellularContext *_next;
|
||||
protected:
|
||||
// friend of CellularDevice so that it's the only way to close/delete this class.
|
||||
friend class CellularDevice;
|
||||
virtual ~CellularContext() {}
|
||||
|
||||
public: // from NetworkInterface
|
||||
virtual nsapi_error_t set_blocking(bool blocking) = 0;
|
||||
virtual NetworkStack *get_stack() = 0;
|
||||
virtual const char *get_ip_address() = 0;
|
||||
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb) = 0;
|
||||
virtual nsapi_error_t connect() = 0;
|
||||
virtual nsapi_error_t disconnect() = 0;
|
||||
|
||||
// from CellularBase
|
||||
virtual void set_plmn(const char *plmn) = 0;
|
||||
virtual void set_sim_pin(const char *sim_pin) = 0;
|
||||
virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0, const char *uname = 0,
|
||||
const char *pwd = 0) = 0;
|
||||
virtual void set_credentials(const char *apn, const char *uname = 0, const char *pwd = 0) = 0;
|
||||
virtual const char *get_netmask() = 0;
|
||||
virtual const char *get_gateway() = 0;
|
||||
virtual bool is_connected() = 0;
|
||||
static CellularContext *get_default_instance();
|
||||
|
||||
|
||||
// Operations, can be sync/async. Also Connect() is this kind of operations, inherited from NetworkInterface above.
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Power on the device and does the initializations for communication with the modem..
|
||||
* By default this API is synchronous. API can be set to asynchronous with method set_blocking(...).
|
||||
* In synchronous and asynchronous mode application can get result in from callback which is set with
|
||||
* attach(...)
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on case of memory failure
|
||||
*/
|
||||
virtual nsapi_error_t set_device_ready() = 0;
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to open the sim.
|
||||
* By default this API is synchronous. API can be set to asynchronous with method set_blocking(...).
|
||||
* In synchronous and asynchronous mode application can get result in from callback which is set with
|
||||
* attach(...)
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on case of memory failure
|
||||
*/
|
||||
virtual nsapi_error_t set_sim_ready() = 0;
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to register the device to cellular network.
|
||||
* By default this API is synchronous. API can be set to asynchronous with method set_blocking(...).
|
||||
* In synchronous and asynchronous mode application can get result in from callback which is set with
|
||||
* attach(...)
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on case of memory failure
|
||||
*/
|
||||
virtual nsapi_error_t register_to_network() = 0;
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to attach the device to cellular network.
|
||||
* By default this API is synchronous. API can be set to asynchronous with method set_blocking(...).
|
||||
* In synchronous and asynchronous mode application can get result in from callback which is set with
|
||||
* attach(...)
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on case of memory failure
|
||||
*/
|
||||
virtual nsapi_error_t attach_to_network() = 0;
|
||||
|
||||
// PDP Context specific functions
|
||||
|
||||
/** Get APN rate control.
|
||||
*
|
||||
* @remark optional params are not updated if not received from network, so use good defaults
|
||||
* @param reports Additional exception reports at maximum rate reached are allowed to be sent [optional]
|
||||
* @param time_unit Uplink time unit with values 0=unrestricted, 1=minute, 2=hour, 3=day, 4=week [optional]
|
||||
* @param uplink_rate Maximum number of messages per timeUnit [optional]
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_DEVICE_ERROR on case of failure
|
||||
*/
|
||||
virtual nsapi_error_t get_rate_control(CellularContext::RateControlExceptionReports &reports,
|
||||
CellularContext::RateControlUplinkTimeUnit &time_unit, int &uplink_rate) = 0;
|
||||
|
||||
/** Get the relevant information for an active non secondary PDP context.
|
||||
*
|
||||
* @remark optional params are not updated if not received from network.
|
||||
* @param params_list reference to linked list, which is filled on successful call
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on memory failure
|
||||
* NSAPI_ERROR_DEVICE_ERROR on other failures
|
||||
*/
|
||||
virtual nsapi_error_t get_pdpcontext_params(pdpContextList_t ¶ms_list) = 0;
|
||||
|
||||
/** Get backoff timer value
|
||||
*
|
||||
* @param backoff_timer Backoff timer value associated with PDP APN in seconds
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_PARAMETER if no access point is set or found when activating context
|
||||
* NSAPI_ERROR_DEVICE_ERROR on failure
|
||||
*/
|
||||
virtual nsapi_error_t get_apn_backoff_timer(int &backoff_timer) = 0;
|
||||
|
||||
/** Set the file handle used to communicate with the modem. Can be used to change default file handle.
|
||||
*
|
||||
* @param fh file handle for communicating with the modem
|
||||
*/
|
||||
virtual void set_file_handle(FileHandle *fh) = 0;
|
||||
|
||||
protected: // Device specific implementations might need these so protected
|
||||
enum ContextOperation {
|
||||
OP_INVALID = -1,
|
||||
OP_DEVICE_READY = 0,
|
||||
OP_SIM_READY = 1,
|
||||
OP_REGISTER = 2,
|
||||
OP_ATTACH = 3,
|
||||
OP_CONNECT = 4,
|
||||
OP_MAX = 5
|
||||
};
|
||||
|
||||
/** Status callback function will be called on status changes on the network or CellularDevice
|
||||
* by the CellularDevice.
|
||||
*
|
||||
* @param ev event type
|
||||
* @param ptr event-type dependent reason parameter
|
||||
*/
|
||||
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr) = 0;
|
||||
|
||||
// member variables needed in target override methods
|
||||
NetworkStack *_stack; // must be pointer because of PPP
|
||||
nsapi_ip_stack_t _ip_stack_type;
|
||||
CellularContext::AuthenticationType _authentication_type;
|
||||
nsapi_connection_status_t _connect_status;
|
||||
cell_callback_data_t _cb_data;
|
||||
Callback<void(nsapi_event_t, intptr_t)> _status_cb;
|
||||
int _cid;
|
||||
bool _new_context_set;
|
||||
bool _is_context_active;
|
||||
bool _is_context_activated; // did we activate the context
|
||||
const char *_apn;
|
||||
const char *_uname;
|
||||
const char *_pwd;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
|
||||
#endif /* _CELLULARCONTEXT_H_ */
|
|
@ -19,11 +19,7 @@
|
|||
#define CELLULAR_DEVICE_H_
|
||||
|
||||
#include "CellularTargets.h"
|
||||
#include "EventQueue.h"
|
||||
#include "nsapi_types.h"
|
||||
#include "PlatformMutex.h"
|
||||
|
||||
class NetworkStack;
|
||||
#include "CellularStateMachine.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -32,8 +28,12 @@ class CellularSMS;
|
|||
class CellularSIM;
|
||||
class CellularInformation;
|
||||
class CellularNetwork;
|
||||
class CellularContext;
|
||||
class FileHandle;
|
||||
|
||||
const int MAX_PIN_SIZE = 8;
|
||||
const int MAX_PLMN_SIZE = 16;
|
||||
|
||||
/**
|
||||
* Class CellularDevice
|
||||
*
|
||||
|
@ -50,55 +50,144 @@ public:
|
|||
*/
|
||||
static CellularDevice *get_default_instance();
|
||||
|
||||
/** Get event queue that can be chained to main event queue. EventQueue is created in get_default_instance() or
|
||||
* given to CELLULAR_DEVICE (for example TELIT_HE910 class).
|
||||
* @return event queue
|
||||
*/
|
||||
virtual events::EventQueue *get_queue() const;
|
||||
|
||||
/** Default constructor
|
||||
*
|
||||
* @param fh File handle used in communication with the modem.
|
||||
*/
|
||||
CellularDevice();
|
||||
CellularDevice(FileHandle *fh);
|
||||
|
||||
/** virtual Destructor
|
||||
*/
|
||||
virtual ~CellularDevice() {}
|
||||
virtual ~CellularDevice();
|
||||
|
||||
/** Creates a new CellularContext interface.
|
||||
*
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle. If null then the default
|
||||
* file handle is used.
|
||||
* @param apn access point to use with context, can be null.
|
||||
*
|
||||
* @return new instance of class CellularContext or NULL in case of failure
|
||||
*
|
||||
*/
|
||||
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL) = 0;
|
||||
|
||||
/** Deletes the given CellularContext instance
|
||||
*
|
||||
* @param context CellularContext to delete
|
||||
*/
|
||||
virtual void delete_context(CellularContext *context) = 0;
|
||||
|
||||
/** Stop the current operation. Operations: set_device_ready, set_sim_ready, register_to_network, attach_to_network
|
||||
*
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/** Get event queue that can be chained to main event queue.
|
||||
* @return event queue
|
||||
*/
|
||||
virtual events::EventQueue *get_queue();
|
||||
|
||||
/** Set the pin code for SIM card
|
||||
*
|
||||
* @param sim_pin PIN for the SIM card
|
||||
*/
|
||||
void set_sim_pin(const char *sim_pin);
|
||||
|
||||
/** Plmn to use when registering to cellular network.
|
||||
* If plmn is set then registering is forced to this plmn. If plmn is not set then automatic
|
||||
* registering is used when registering to a cellular network. Does not start any operations.
|
||||
*
|
||||
* @param plmn plmn used when registering to cellular network
|
||||
*/
|
||||
void set_plmn(const char *plmn);
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Power on the device and does the initializations for communication with the modem..
|
||||
* By default this API is synchronous. API can be set to asynchronous with method set_blocking(...).
|
||||
* In synchronous and asynchronous mode application can get result in from callback which is set with
|
||||
* attach(...)
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on case of memory failure
|
||||
*/
|
||||
nsapi_error_t set_device_ready();
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to open the sim.
|
||||
* By default this API is synchronous. API can be set to asynchronous with method set_blocking(...).
|
||||
* In synchronous and asynchronous mode application can get result in from callback which is set with
|
||||
* attach(...)
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on case of memory failure
|
||||
*/
|
||||
nsapi_error_t set_sim_ready();
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to register the device to cellular network.
|
||||
* By default this API is synchronous. API can be set to asynchronous with method set_blocking(...).
|
||||
* In synchronous and asynchronous mode application can get result in from callback which is set with
|
||||
* attach(...)
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on case of memory failure
|
||||
*/
|
||||
nsapi_error_t register_to_network();
|
||||
|
||||
/** Start the interface
|
||||
*
|
||||
* Attempts to attach the device to cellular network.
|
||||
* By default this API is synchronous. API can be set to asynchronous with method set_blocking(...).
|
||||
* In synchronous and asynchronous mode application can get result in from callback which is set with
|
||||
* attach(...)
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on case of memory failure
|
||||
*/
|
||||
nsapi_error_t attach_to_network();
|
||||
|
||||
public:
|
||||
/** Create new CellularNetwork interface.
|
||||
*
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle.
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle. If null then the default
|
||||
* file handle is used.
|
||||
* @return New instance of interface CellularNetwork.
|
||||
*/
|
||||
virtual CellularNetwork *open_network(FileHandle *fh) = 0;
|
||||
virtual CellularNetwork *open_network(FileHandle *fh = NULL) = 0;
|
||||
|
||||
/** Create new CellularSMS interface.
|
||||
*
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle.
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle. If null then the default
|
||||
* file handle is used.
|
||||
* @return New instance of interface CellularSMS.
|
||||
*/
|
||||
virtual CellularSMS *open_sms(FileHandle *fh) = 0;
|
||||
virtual CellularSMS *open_sms(FileHandle *fh = NULL) = 0;
|
||||
|
||||
/** Create new CellularPower interface.
|
||||
*
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle.
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle. If null then the default
|
||||
* file handle is used.
|
||||
* @return New instance of interface CellularPower.
|
||||
*/
|
||||
virtual CellularPower *open_power(FileHandle *fh) = 0;
|
||||
virtual CellularPower *open_power(FileHandle *fh = NULL) = 0;
|
||||
|
||||
/** Create new CellularSIM interface.
|
||||
*
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle.
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle. If null then the default
|
||||
* file handle is used.
|
||||
* @return New instance of interface CellularSIM.
|
||||
*/
|
||||
virtual CellularSIM *open_sim(FileHandle *fh) = 0;
|
||||
virtual CellularSIM *open_sim(FileHandle *fh = NULL) = 0;
|
||||
|
||||
/** Create new CellularInformation interface.
|
||||
*
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle.
|
||||
* @param fh file handle used in communication to modem. Can be for example UART handle. If null then the default
|
||||
* file handle is used.
|
||||
* @return New instance of interface CellularInformation.
|
||||
*/
|
||||
virtual CellularInformation *open_information(FileHandle *fh) = 0;
|
||||
virtual CellularInformation *open_information(FileHandle *fh = NULL) = 0;
|
||||
|
||||
/** Closes the opened CellularNetwork by deleting the CellularNetwork instance.
|
||||
*/
|
||||
|
@ -132,28 +221,47 @@ public:
|
|||
*/
|
||||
virtual void modem_debug_on(bool on) = 0;
|
||||
|
||||
/** Get network stack.
|
||||
*
|
||||
* @return network stack
|
||||
*/
|
||||
virtual NetworkStack *get_stack() = 0;
|
||||
|
||||
/** Initialize cellular module must be called right after module is ready.
|
||||
* For example, when multiple modules are supported in a single AT driver this function detects
|
||||
* and adapts to an actual module at runtime.
|
||||
*
|
||||
* @param fh file handle used in communication to modem.
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
virtual nsapi_error_t init_module(FileHandle *fh) = 0;
|
||||
virtual nsapi_error_t init_module() = 0;
|
||||
|
||||
/** Get the linked list of CellularContext instances
|
||||
*
|
||||
* @return Pointer to first item in linked list
|
||||
*/
|
||||
virtual CellularContext *get_context_list() const;
|
||||
|
||||
protected:
|
||||
friend class AT_CellularNetwork;
|
||||
friend class AT_CellularContext;
|
||||
|
||||
/** Cellular callback to be attached to Network and CellularStateMachine classes.
|
||||
* CellularContext calls this when in PPP mode to provide network changes.
|
||||
* This method will broadcast to every interested classes:
|
||||
* CellularContext (might be many) and CellularStateMachine if available.
|
||||
*/
|
||||
void cellular_callback(nsapi_event_t ev, intptr_t ptr);
|
||||
|
||||
int _network_ref_count;
|
||||
int _sms_ref_count;
|
||||
int _power_ref_count;
|
||||
int _sim_ref_count;
|
||||
int _info_ref_count;
|
||||
FileHandle *_fh;
|
||||
events::EventQueue _queue;
|
||||
CellularStateMachine *_state_machine;
|
||||
private:
|
||||
nsapi_error_t start_state_machine(CellularStateMachine::CellularState target_state);
|
||||
nsapi_error_t create_state_machine();
|
||||
|
||||
CellularNetwork *_nw;
|
||||
char _sim_pin[MAX_PIN_SIZE + 1];
|
||||
char _plmn[MAX_PLMN_SIZE + 1];
|
||||
PlatformMutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
#ifndef CELLULAR_NETWORK_H_
|
||||
#define CELLULAR_NETWORK_H_
|
||||
|
||||
#include "NetworkInterface.h"
|
||||
#include "CellularList.h"
|
||||
#include "Callback.h"
|
||||
#include "nsapi_types.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -35,7 +36,7 @@ const int MAX_OPERATOR_NAME_SHORT = 8;
|
|||
*
|
||||
* An abstract interface for connecting to a network and getting information from it.
|
||||
*/
|
||||
class CellularNetwork : public NetworkInterface {
|
||||
class CellularNetwork {
|
||||
protected:
|
||||
// friend of CellularDevice so that it's the only way to close/delete this class.
|
||||
friend class CellularDevice;
|
||||
|
@ -77,7 +78,8 @@ public:
|
|||
RegisteredSMSOnlyRoaming,
|
||||
AttachedEmergencyOnly,
|
||||
RegisteredCSFBNotPreferredHome,
|
||||
RegisteredCSFBNotPreferredRoaming = 10
|
||||
RegisteredCSFBNotPreferredRoaming,
|
||||
AlreadyRegistered = 11 // our our definition when modem says that we are not registered but we have active PDP Context
|
||||
};
|
||||
|
||||
/* Network registration type */
|
||||
|
@ -94,28 +96,6 @@ public:
|
|||
Attached,
|
||||
};
|
||||
|
||||
/* whether the additional exception reports are allowed to be sent when the maximum uplink rate is reached */
|
||||
enum RateControlExceptionReports {
|
||||
NotAllowedToBeSent = 0,
|
||||
AllowedToBeSent
|
||||
};
|
||||
|
||||
/* specifies the time unit to be used for the maximum uplink rate */
|
||||
enum RateControlUplinkTimeUnit {
|
||||
Unrestricted = 0,
|
||||
Minute,
|
||||
Hour,
|
||||
Day,
|
||||
Week
|
||||
};
|
||||
|
||||
/* authentication type when activating or modifying the pdp context */
|
||||
enum AuthenticationType {
|
||||
NOAUTH = 0,
|
||||
PAP,
|
||||
CHAP
|
||||
};
|
||||
|
||||
enum RadioAccessTechnology {
|
||||
RAT_GSM,
|
||||
RAT_GSM_COMPACT,
|
||||
|
@ -159,51 +139,6 @@ public:
|
|||
|
||||
typedef CellularList<operator_t> operList_t;
|
||||
|
||||
/* PDP Context information */
|
||||
struct pdpcontext_params_t {
|
||||
char apn[MAX_ACCESSPOINT_NAME_LENGTH + 1];
|
||||
char local_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char local_subnet_mask[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char gateway_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char dns_primary_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char dns_secondary_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char p_cscf_prim_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
char p_cscf_sec_addr[MAX_IPV6_ADDR_IN_IPV4LIKE_DOTTED_FORMAT + 1];
|
||||
int cid;
|
||||
int bearer_id;
|
||||
int im_signalling_flag;
|
||||
int lipa_indication;
|
||||
int ipv4_mtu;
|
||||
int wlan_offload;
|
||||
int local_addr_ind;
|
||||
int non_ip_mtu;
|
||||
int serving_plmn_rate_control_value;
|
||||
pdpcontext_params_t *next;
|
||||
|
||||
pdpcontext_params_t()
|
||||
{
|
||||
apn[0] = '\0';
|
||||
local_addr[0] = '\0';
|
||||
local_subnet_mask[0] = '\0';
|
||||
gateway_addr[0] = '\0';
|
||||
dns_primary_addr[0] = '\0';
|
||||
dns_secondary_addr[0] = '\0';
|
||||
p_cscf_prim_addr[0] = '\0';
|
||||
p_cscf_sec_addr[0] = '\0';
|
||||
cid = -1;
|
||||
bearer_id = -1;
|
||||
im_signalling_flag = -1;
|
||||
lipa_indication = -1;
|
||||
ipv4_mtu = -1;
|
||||
wlan_offload = -1;
|
||||
local_addr_ind = -1;
|
||||
non_ip_mtu = -1;
|
||||
serving_plmn_rate_control_value = -1;
|
||||
next = NULL;
|
||||
}
|
||||
};
|
||||
typedef CellularList<pdpcontext_params_t> pdpContextList_t;
|
||||
|
||||
struct operator_names_t {
|
||||
char numeric[MAX_OPERATOR_NAME_SHORT + 1];
|
||||
char alpha[MAX_OPERATOR_NAME_LONG + 1];
|
||||
|
@ -248,14 +183,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/** Does all the needed initializations that can fail
|
||||
*
|
||||
* @remark must be called immediately after constructor.
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on memory failure
|
||||
*/
|
||||
virtual nsapi_error_t init() = 0;
|
||||
|
||||
/** Request registering to network.
|
||||
*
|
||||
* @param plmn format is in numeric format or 0 for automatic network registration
|
||||
|
@ -286,38 +213,12 @@ public:
|
|||
virtual nsapi_error_t set_registration_urc(RegistrationType type, bool on) = 0;
|
||||
|
||||
|
||||
/** Set the cellular network APN and credentials
|
||||
*
|
||||
* @param apn Optional name of the network to connect to
|
||||
* @param username Optional username for the APN
|
||||
* @param password Optional password fot the APN
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on memory failure
|
||||
*/
|
||||
virtual nsapi_error_t set_credentials(const char *apn,
|
||||
const char *username = 0, const char *password = 0) = 0;
|
||||
|
||||
/** Set the cellular network APN and credentials
|
||||
*
|
||||
* @param apn Name of the network to connect to
|
||||
* @param type Authentication type to use
|
||||
* @param username Optional username for the APN
|
||||
* @param password Optional password fot the APN
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on memory failure
|
||||
*/
|
||||
virtual nsapi_error_t set_credentials(const char *apn, AuthenticationType type,
|
||||
const char *username = 0, const char *password = 0) = 0;
|
||||
|
||||
/** Request attach to network.
|
||||
*
|
||||
* @deprecated Parameter timeout will be deprecated. Use mbed-os/features/cellular/framework/API/CellularDevice.h set_timeout instead.
|
||||
* @param timeout milliseconds to wait for attach response
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_DEVICE_ERROR on failure
|
||||
*/
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.9", "Parameter timeout will be deprecated. Use mbed-os/features/cellular/framework/API/CellularDevice.h set_timeout instead.")
|
||||
virtual nsapi_error_t set_attach(int timeout = 10 * 1000) = 0;
|
||||
virtual nsapi_error_t set_attach() = 0;
|
||||
|
||||
/** Request attach status from network.
|
||||
*
|
||||
|
@ -334,27 +235,6 @@ public:
|
|||
*/
|
||||
virtual nsapi_error_t detach() = 0;
|
||||
|
||||
/** Get APN rate control.
|
||||
*
|
||||
* @remark optional params are not updated if not received from network, so use good defaults
|
||||
* @param reports Additional exception reports at maximum rate reached are allowed to be sent [optional]
|
||||
* @param time_unit Uplink time unit with values 0=unrestricted, 1=minute, 2=hour, 3=day, 4=week [optional]
|
||||
* @param uplink_rate Maximum number of messages per timeUnit [optional]
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_DEVICE_ERROR on case of failure
|
||||
*/
|
||||
virtual nsapi_error_t get_rate_control(CellularNetwork::RateControlExceptionReports &reports,
|
||||
CellularNetwork::RateControlUplinkTimeUnit &time_unit, int &uplink_rate) = 0;
|
||||
|
||||
/** Get backoff timer value
|
||||
*
|
||||
* @param backoff_timer Backoff timer value associated with PDP APN in seconds
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_PARAMETER if no access point is set or found when activating context
|
||||
* NSAPI_ERROR_DEVICE_ERROR on failure
|
||||
*/
|
||||
virtual nsapi_error_t get_apn_backoff_timer(int &backoff_timer) = 0;
|
||||
|
||||
/** Sets radio access technology.
|
||||
*
|
||||
* @param rat Radio access technology
|
||||
|
@ -395,70 +275,6 @@ public:
|
|||
virtual nsapi_error_t get_ciot_optimization_config(Supported_UE_Opt &supported_opt,
|
||||
Preferred_UE_Opt &preferred_opt) = 0;
|
||||
|
||||
/** Start the interface. Attempts to connect to a cellular network.
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_CONNECTION if fails to find suitable context to activate or activation failed (if not already activated)
|
||||
* NSAPI_ERROR_UNSUPPORTED if NetworkStack was not found or cellular device does not support authentication
|
||||
* NSAPI_ERROR_AUTH_FAILURE if password and username were provided and authentication to network failed
|
||||
* Also if PPP mode
|
||||
* NSAPI_ERROR_DEVICE_ERROR on failure and check more error from nsapi_ppp_connect(...)
|
||||
*/
|
||||
virtual nsapi_error_t connect() = 0;
|
||||
|
||||
/** Start the interface. Attempts to connect to a cellular network.
|
||||
*
|
||||
* @param apn Optional name of the network to connect to
|
||||
* @param username Optional username for your APN
|
||||
* @param password Optional password for your APN
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_CONNECTION if fails to find suitable context to activate or activation failed (if not already activated)
|
||||
* NSAPI_ERROR_UNSUPPORTED if NetworkStack was not found
|
||||
* NSAPI_ERROR_AUTH_FAILURE if password and username were provided and authentication to network failed
|
||||
* NSAPI_ERROR_NO_MEMORY on memory failure
|
||||
* Also if PPP mode
|
||||
* NSAPI_ERROR_DEVICE_ERROR on failure and check more error from nsapi_ppp_connect(...)
|
||||
*/
|
||||
virtual nsapi_error_t connect(const char *apn,
|
||||
const char *username = 0, const char *password = 0) = 0;
|
||||
|
||||
/** Finds the correct PDP context and activates it. If correct PDP context is not found, one is created.
|
||||
* Given APN (or not given) and stack type (IPv4/IPv6/dual) are influencing when finding the PDP context.
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_CONNECTION if fails to find suitable context to activate or activation failed (if not already activated)
|
||||
* NSAPI_ERROR_UNSUPPORTED if NetworkStack was not found
|
||||
* NSAPI_ERROR_AUTH_FAILURE if password and username were provided and authentication to network failed
|
||||
*/
|
||||
virtual nsapi_error_t activate_context() = 0;
|
||||
|
||||
/**
|
||||
* Set the pdn type to be used
|
||||
*
|
||||
* @param stack_type the stack type to be used.
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_PARAMETER if modem does not support the given stack_type
|
||||
*/
|
||||
virtual nsapi_error_t set_stack_type(nsapi_ip_stack_t stack_type) = 0;
|
||||
|
||||
/**
|
||||
* Get the pdn type in use
|
||||
*
|
||||
* @return stack type
|
||||
*/
|
||||
virtual nsapi_ip_stack_t get_stack_type() = 0;
|
||||
|
||||
/** Get the relevant information for an active non secondary PDP context.
|
||||
*
|
||||
* @remark optional params are not updated if not received from network.
|
||||
* @param params_list reference to linked list, which is filled on successful call
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_NO_MEMORY on memory failure
|
||||
* NSAPI_ERROR_DEVICE_ERROR on other failures
|
||||
*/
|
||||
virtual nsapi_error_t get_pdpcontext_params(pdpContextList_t ¶ms_list) = 0;
|
||||
|
||||
/** Get extended signal quality parameters.
|
||||
*
|
||||
* @param rxlev signal strength level
|
||||
|
@ -511,14 +327,6 @@ public:
|
|||
*/
|
||||
virtual nsapi_connection_status_t get_connection_status() const = 0;
|
||||
|
||||
/** Set blocking status of connect() which by default should be blocking
|
||||
*
|
||||
* @param blocking true if connect is blocking
|
||||
* @return NSAPI_ERROR_OK
|
||||
* if PPP mode check errors from nsapi_ppp_set_blocking(...)
|
||||
*/
|
||||
virtual nsapi_error_t set_blocking(bool blocking) = 0;
|
||||
|
||||
/** Read operator names
|
||||
*
|
||||
* @param op_names on successful return contains linked list of operator names.
|
||||
|
@ -528,6 +336,12 @@ public:
|
|||
*/
|
||||
virtual nsapi_error_t get_operator_names(operator_names_list &op_names) = 0;
|
||||
|
||||
/** Check if there is any PDP context active
|
||||
*
|
||||
* @return true is any context is active, false otherwise or in case of error
|
||||
*/
|
||||
virtual bool is_active_context() = 0;
|
||||
|
||||
/** Gets current network registration parameters:
|
||||
* type, status, access technology, cell_id, lac, active_time, periodic_tau.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,911 @@
|
|||
/*
|
||||
* 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 "AT_CellularContext.h"
|
||||
#include "AT_CellularNetwork.h"
|
||||
#include "AT_CellularStack.h"
|
||||
#include "CellularLog.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "CellularSIM.h"
|
||||
#include "UARTSerial.h"
|
||||
#include "mbed_wait_api.h"
|
||||
|
||||
#define NETWORK_TIMEOUT 30 * 60 * 1000 // 30 minutes
|
||||
#define DEVICE_TIMEOUT 5 * 60 * 1000 // 5 minutes
|
||||
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
#include "nsapi_ppp.h"
|
||||
#endif
|
||||
|
||||
#define USE_APN_LOOKUP (MBED_CONF_CELLULAR_USE_APN_LOOKUP || (NSAPI_PPP_AVAILABLE && MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP))
|
||||
|
||||
#if USE_APN_LOOKUP
|
||||
#include "APN_db.h"
|
||||
#endif //USE_APN_LOOKUP
|
||||
|
||||
using namespace mbed_cellular_util;
|
||||
using namespace mbed;
|
||||
|
||||
AT_CellularContext::AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
|
||||
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);
|
||||
_stack = NULL;
|
||||
_ip_stack_type = DEFAULT_STACK;
|
||||
_authentication_type = CellularContext::CHAP;
|
||||
_connect_status = NSAPI_STATUS_DISCONNECTED;
|
||||
_is_context_active = false;
|
||||
_is_context_activated = false;
|
||||
_apn = apn;
|
||||
_uname = NULL;
|
||||
_pwd = NULL;
|
||||
_status_cb = NULL;
|
||||
_cid = -1;
|
||||
_new_context_set = false;
|
||||
_next = NULL;
|
||||
}
|
||||
|
||||
AT_CellularContext::~AT_CellularContext()
|
||||
{
|
||||
(void)disconnect();
|
||||
|
||||
if (_nw) {
|
||||
_device->close_network();
|
||||
}
|
||||
}
|
||||
|
||||
void AT_CellularContext::set_file_handle(FileHandle *fh)
|
||||
{
|
||||
_fh = fh;
|
||||
_at.set_file_handle(_fh);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::connect()
|
||||
{
|
||||
if (_is_connected) {
|
||||
return NSAPI_ERROR_IS_CONNECTED;
|
||||
}
|
||||
nsapi_error_t err = _device->attach_to_network();
|
||||
_cb_data.error = check_operation(err, OP_CONNECT);
|
||||
|
||||
if (_is_blocking) {
|
||||
if (_cb_data.error == NSAPI_ERROR_OK || _cb_data.error == NSAPI_ERROR_ALREADY) {
|
||||
do_connect();
|
||||
}
|
||||
} else {
|
||||
if (_cb_data.error == NSAPI_ERROR_ALREADY) {
|
||||
// device is already attached, to be async we must use queue to connect and give proper callbacks
|
||||
int id = _device->get_queue()->call_in(0, this, &AT_CellularContext::do_connect);
|
||||
if (id == 0) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return _cb_data.error;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::set_device_ready()
|
||||
{
|
||||
nsapi_error_t err = _device->set_device_ready();
|
||||
return check_operation(err, OP_DEVICE_READY);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::set_sim_ready()
|
||||
{
|
||||
nsapi_error_t err = _device->set_sim_ready();
|
||||
return check_operation(err, OP_SIM_READY);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::register_to_network()
|
||||
{
|
||||
nsapi_error_t err = _device->register_to_network();
|
||||
return check_operation(err, OP_REGISTER);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::attach_to_network()
|
||||
{
|
||||
nsapi_error_t err = _device->attach_to_network();
|
||||
return check_operation(err, OP_ATTACH);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::check_operation(nsapi_error_t err, ContextOperation op)
|
||||
{
|
||||
_current_op = op;
|
||||
if (err == NSAPI_ERROR_IN_PROGRESS || err == NSAPI_ERROR_OK) {
|
||||
if (_is_blocking) {
|
||||
int sema_err = _semaphore.wait(get_timeout_for_operation(op)); // cellular network searching may take several minutes
|
||||
if (sema_err != 1) {
|
||||
tr_warning("No cellular connection");
|
||||
return NSAPI_ERROR_TIMEOUT;
|
||||
}
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
uint32_t AT_CellularContext::get_timeout_for_operation(ContextOperation op) const
|
||||
{
|
||||
uint32_t timeout = NETWORK_TIMEOUT; // default timeout is 30 minutes as registration and attach may take time
|
||||
if (op == OP_SIM_READY || op == OP_DEVICE_READY) {
|
||||
timeout = DEVICE_TIMEOUT; // use 5 minutes for device ready and sim
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
bool AT_CellularContext::is_connected()
|
||||
{
|
||||
return _is_connected;
|
||||
}
|
||||
|
||||
NetworkStack *AT_CellularContext::get_stack()
|
||||
{
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
// use lwIP/PPP if modem does not have IP stack
|
||||
if (!_stack) {
|
||||
_stack = nsapi_ppp_get_stack();
|
||||
}
|
||||
#endif
|
||||
return _stack;
|
||||
}
|
||||
|
||||
const char *AT_CellularContext::get_netmask()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *AT_CellularContext::get_gateway()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *AT_CellularContext::get_ip_address()
|
||||
{
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
return nsapi_ppp_get_ip_addr(_at.get_file_handle());
|
||||
#else
|
||||
if (!_stack) {
|
||||
_stack = get_stack();
|
||||
}
|
||||
if (_stack) {
|
||||
return _stack->get_ip_address();
|
||||
}
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AT_CellularContext::attach(Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
_status_cb = status_cb;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::set_blocking(bool blocking)
|
||||
{
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
err = nsapi_ppp_set_blocking(blocking);
|
||||
#endif
|
||||
_is_blocking = blocking;
|
||||
return err;
|
||||
}
|
||||
|
||||
void AT_CellularContext::set_plmn(const char *plmn)
|
||||
{
|
||||
_device->set_plmn(plmn);
|
||||
}
|
||||
|
||||
void AT_CellularContext::set_sim_pin(const char *sim_pin)
|
||||
{
|
||||
_device->set_sim_pin(sim_pin);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::connect(const char *sim_pin, const char *apn, const char *uname,
|
||||
const char *pwd)
|
||||
{
|
||||
set_sim_pin(sim_pin);
|
||||
set_credentials(apn, uname, pwd);
|
||||
return connect();
|
||||
}
|
||||
|
||||
void AT_CellularContext::set_credentials(const char *apn, const char *uname, const char *pwd)
|
||||
{
|
||||
_apn = apn;
|
||||
_uname = uname;
|
||||
_pwd = pwd;
|
||||
}
|
||||
|
||||
bool AT_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
if (stack_type == _ip_stack_type) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_ip_stack_t AT_CellularContext::get_stack_type()
|
||||
{
|
||||
return _ip_stack_type;
|
||||
}
|
||||
|
||||
nsapi_ip_stack_t AT_CellularContext::string_to_stack_type(const char *pdp_type)
|
||||
{
|
||||
nsapi_ip_stack_t stack = DEFAULT_STACK;
|
||||
int len = strlen(pdp_type);
|
||||
|
||||
if (len == 6 && memcmp(pdp_type, "IPV4V6", len) == 0) {
|
||||
stack = IPV4V6_STACK;
|
||||
} else if (len == 4 && memcmp(pdp_type, "IPV6", len) == 0) {
|
||||
stack = IPV6_STACK;
|
||||
} else if (len == 2 && memcmp(pdp_type, "IP", len) == 0) {
|
||||
stack = IPV4_STACK;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
// PDP Context handling
|
||||
nsapi_error_t AT_CellularContext::delete_current_context()
|
||||
{
|
||||
tr_info("Delete context %d", _cid);
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+CGDCONT=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
_cid = -1;
|
||||
_new_context_set = false;
|
||||
}
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::do_user_authentication()
|
||||
{
|
||||
// if user has defined user name and password we need to call CGAUTH before activating or modifying context
|
||||
if (_pwd && _uname) {
|
||||
if (!is_supported(AT_CGAUTH)) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
_at.cmd_start("AT+CGAUTH=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(_authentication_type);
|
||||
_at.write_string(_uname);
|
||||
_at.write_string(_pwd);
|
||||
_at.cmd_stop_read_resp();
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
return NSAPI_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
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:");
|
||||
_cid = -1;
|
||||
int cid_max = 0; // needed when creating new context
|
||||
char apn[MAX_ACCESSPOINT_NAME_LENGTH];
|
||||
int apn_len = 0;
|
||||
|
||||
bool modem_supports_ipv6 = stack_type_supported(IPV6_STACK);
|
||||
bool modem_supports_ipv4 = stack_type_supported(IPV4_STACK);
|
||||
|
||||
while (_at.info_resp()) {
|
||||
int cid = _at.read_int();
|
||||
if (cid > cid_max) {
|
||||
cid_max = cid;
|
||||
}
|
||||
char pdp_type_from_context[10];
|
||||
int pdp_type_len = _at.read_string(pdp_type_from_context, sizeof(pdp_type_from_context) - 1);
|
||||
if (pdp_type_len > 0) {
|
||||
apn_len = _at.read_string(apn, sizeof(apn) - 1);
|
||||
if (apn_len >= 0) {
|
||||
if (_apn && (strcmp(apn, _apn) != 0)) {
|
||||
continue;
|
||||
}
|
||||
nsapi_ip_stack_t pdp_stack = string_to_stack_type(pdp_type_from_context);
|
||||
// Accept dual PDP context for IPv4/IPv6 only modems
|
||||
if (pdp_stack != DEFAULT_STACK && (stack_type_supported(pdp_stack) || pdp_stack == IPV4V6_STACK)) {
|
||||
if (_ip_stack_type_requested == IPV4_STACK) {
|
||||
if (pdp_stack == IPV4_STACK || pdp_stack == IPV4V6_STACK) {
|
||||
_ip_stack_type = _ip_stack_type_requested;
|
||||
_cid = cid;
|
||||
break;
|
||||
}
|
||||
} else if (_ip_stack_type_requested == IPV6_STACK) {
|
||||
if (pdp_stack == IPV6_STACK || pdp_stack == IPV4V6_STACK) {
|
||||
_ip_stack_type = _ip_stack_type_requested;
|
||||
_cid = cid;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// requested dual stack or stack is not specified
|
||||
// If dual PDP need to check for IPV4 or IPV6 modem support. Prefer IPv6.
|
||||
if (pdp_stack == IPV4V6_STACK) {
|
||||
if (modem_supports_ipv6) {
|
||||
_ip_stack_type = IPV6_STACK;
|
||||
_cid = cid;
|
||||
break;
|
||||
} else if (modem_supports_ipv4) {
|
||||
_ip_stack_type = IPV4_STACK;
|
||||
_cid = cid;
|
||||
break;
|
||||
}
|
||||
// If PDP is IPV4 or IPV6 they are already checked if supported
|
||||
} else {
|
||||
_ip_stack_type = pdp_stack;
|
||||
_cid = cid;
|
||||
|
||||
if (pdp_stack == IPV6_STACK) {
|
||||
break;
|
||||
}
|
||||
if (pdp_stack == IPV4_STACK && !modem_supports_ipv6) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
if (_cid == -1) { // no suitable context was found so create a new one
|
||||
if (!set_new_context(cid_max + 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// save the apn
|
||||
if (apn_len > 0 && !_apn) {
|
||||
memcpy(_found_apn, apn, apn_len + 1);
|
||||
}
|
||||
|
||||
tr_debug("Context id %d", _cid);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AT_CellularContext::set_new_context(int cid)
|
||||
{
|
||||
nsapi_ip_stack_t tmp_stack = _ip_stack_type_requested;
|
||||
|
||||
if (tmp_stack == DEFAULT_STACK) {
|
||||
bool modem_supports_ipv6 = stack_type_supported(IPV6_STACK);
|
||||
bool modem_supports_ipv4 = stack_type_supported(IPV4_STACK);
|
||||
|
||||
if (modem_supports_ipv6 && modem_supports_ipv4) {
|
||||
tmp_stack = IPV4V6_STACK;
|
||||
} else if (modem_supports_ipv6) {
|
||||
tmp_stack = IPV6_STACK;
|
||||
} else if (modem_supports_ipv4) {
|
||||
tmp_stack = IPV4_STACK;
|
||||
}
|
||||
}
|
||||
|
||||
char pdp_type[8 + 1] = {0};
|
||||
|
||||
switch (tmp_stack) {
|
||||
case IPV4_STACK:
|
||||
strncpy(pdp_type, "IP", sizeof(pdp_type));
|
||||
break;
|
||||
case IPV6_STACK:
|
||||
strncpy(pdp_type, "IPV6", sizeof(pdp_type));
|
||||
break;
|
||||
case IPV4V6_STACK:
|
||||
strncpy(pdp_type, "IPV6", sizeof(pdp_type)); // try first IPV6 and then fall-back to IPv4
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//apn: "If the value is null or omitted, then the subscription value will be requested."
|
||||
bool success = false;
|
||||
_at.cmd_start("AT+CGDCONT=");
|
||||
_at.write_int(cid);
|
||||
_at.write_string(pdp_type);
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop_read_resp();
|
||||
success = (_at.get_last_error() == NSAPI_ERROR_OK);
|
||||
|
||||
// Fall back to ipv4
|
||||
if (!success && tmp_stack == IPV4V6_STACK) {
|
||||
_at.clear_error();
|
||||
tmp_stack = IPV4_STACK;
|
||||
_at.cmd_start("AT+FCLASS=0;+CGDCONT=");
|
||||
_at.write_int(cid);
|
||||
_at.write_string("IP");
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop_read_resp();
|
||||
success = (_at.get_last_error() == NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
_ip_stack_type = tmp_stack;
|
||||
_cid = cid;
|
||||
_new_context_set = true;
|
||||
tr_info("New PDP context id %d was created", _cid);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::do_activate_context()
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
|
||||
// try to find or create context with suitable stack
|
||||
if (get_context()) {
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
_at.unlock();
|
||||
// in PPP we don't activate any context but leave it to PPP stack
|
||||
return err;
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
// try to authenticate user before activating or modifying context
|
||||
err = do_user_authentication();
|
||||
} else {
|
||||
err = NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
_at.unlock();
|
||||
tr_error("Failed to activate network context! (%d)", err);
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
return err;
|
||||
}
|
||||
|
||||
// do check for stack to validate that we have support for stack
|
||||
if (!get_stack()) {
|
||||
_at.unlock();
|
||||
tr_error("No cellular stack!");
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
_is_context_active = false;
|
||||
_is_context_activated = false;
|
||||
_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_id == _cid && context_activation_state == 1) {
|
||||
_is_context_active = true;
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
if (!_is_context_active) {
|
||||
tr_info("Activate PDP context %d", _cid);
|
||||
_at.cmd_start("AT+CGACT=1,");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
_is_context_activated = true;
|
||||
}
|
||||
}
|
||||
|
||||
err = (_at.get_last_error() == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
// If new PDP context was created and failed to activate, delete it
|
||||
if (err != NSAPI_ERROR_OK && _new_context_set) {
|
||||
delete_current_context();
|
||||
} else if (err == NSAPI_ERROR_OK) {
|
||||
_is_context_active = true;
|
||||
}
|
||||
|
||||
_at.unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void AT_CellularContext::do_connect()
|
||||
{
|
||||
call_network_cb(NSAPI_STATUS_CONNECTING);
|
||||
|
||||
if (!_is_context_active) {
|
||||
_cb_data.error = do_activate_context();
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
// in PPP mode we did not activate any context, just searched the correct _cid
|
||||
if (_status_cb) {
|
||||
_status_cb((nsapi_event_t)CellularActivatePDPContext, (intptr_t )&_cb_data);
|
||||
}
|
||||
#endif // !NSAPI_PPP_AVAILABLE
|
||||
}
|
||||
|
||||
if (_cb_data.error != NSAPI_ERROR_OK) {
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
_is_connected = false;
|
||||
return;
|
||||
}
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
if (_cb_data.error == NSAPI_ERROR_OK) {
|
||||
_at.lock();
|
||||
_cb_data.error = open_data_channel();
|
||||
_at.unlock();
|
||||
if (_cb_data.error != NSAPI_ERROR_OK) {
|
||||
tr_error("Failed to open data channel!");
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
_is_connected = false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
_is_connected = true;
|
||||
call_network_cb(NSAPI_STATUS_GLOBAL_UP);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
nsapi_error_t AT_CellularContext::open_data_channel()
|
||||
{
|
||||
tr_info("Open data channel in PPP mode");
|
||||
if (is_supported(AT_CGDATA)) {
|
||||
_at.cmd_start("AT+CGDATA=\"PPP\",");
|
||||
_at.write_int(_cid);
|
||||
} else {
|
||||
MBED_ASSERT(_cid >= 0 && _cid <= 99);
|
||||
_at.cmd_start("ATD*99***");
|
||||
_at.use_delimiter(false);
|
||||
_at.write_int(_cid);
|
||||
_at.write_string("#", false);
|
||||
_at.use_delimiter(true);
|
||||
}
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("CONNECT", true);
|
||||
if (_at.get_last_error()) {
|
||||
tr_error("Failed to CONNECT");
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
_at.set_is_filehandle_usable(false);
|
||||
|
||||
/* Initialize PPP
|
||||
* If blocking: mbed_ppp_init() is a blocking call, it will block until
|
||||
connected, or timeout after 30 seconds*/
|
||||
return nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularContext::ppp_status_cb), _uname, _pwd, _ip_stack_type);
|
||||
}
|
||||
|
||||
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);
|
||||
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
|
||||
_is_connected = true;
|
||||
} else {
|
||||
_is_connected = false;
|
||||
}
|
||||
|
||||
_connect_status = (nsapi_connection_status_t)ptr;
|
||||
|
||||
// call device's callback, it will broadcast this to here (cellular_callback)
|
||||
_device->cellular_callback(ev, ptr);
|
||||
}
|
||||
|
||||
#endif //#if NSAPI_PPP_AVAILABLE
|
||||
|
||||
nsapi_error_t AT_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!");
|
||||
// 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
|
||||
// will set the correct sigio and nonblocking
|
||||
_at.lock();
|
||||
_at.set_file_handle(_at.get_file_handle());
|
||||
_at.set_is_filehandle_usable(true);
|
||||
//_at.sync(); // consume extra characters after ppp disconnect, also it may take a while until modem listens AT commands
|
||||
_at.unlock();
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
_at.lock();
|
||||
|
||||
// deactivate a context only if we have activated
|
||||
if (_is_context_activated) {
|
||||
_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.cmd_start("AT+CGACT=0,");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
}
|
||||
}
|
||||
|
||||
if (!_at.get_last_error()) {
|
||||
_is_connected = false;
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
}
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::get_apn_backoff_timer(int &backoff_timer)
|
||||
{
|
||||
// If apn is set
|
||||
if (_apn) {
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CABTRDP=");
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+CABTRDP:");
|
||||
if (_at.info_resp()) {
|
||||
_at.skip_param();
|
||||
backoff_timer = _at.read_int();
|
||||
}
|
||||
_at.resp_stop();
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::get_rate_control(
|
||||
CellularContext::RateControlExceptionReports &reports,
|
||||
CellularContext::RateControlUplinkTimeUnit &timeUnit, int &uplinkRate)
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CGAPNRC=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+CGAPNRC:");
|
||||
_at.read_int();
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
bool comma_found = true;
|
||||
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;
|
||||
}
|
||||
|
||||
if (comma_found && next_element >= 0) {
|
||||
timeUnit = (RateControlUplinkTimeUnit)next_element;
|
||||
tr_debug("time %d", timeUnit);
|
||||
next_element = _at.read_int();
|
||||
} else {
|
||||
comma_found = false;
|
||||
}
|
||||
|
||||
if (comma_found && next_element >= 0) {
|
||||
uplinkRate = next_element;
|
||||
tr_debug("rate %d", uplinkRate);
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::get_pdpcontext_params(pdpContextList_t ¶ms_list)
|
||||
{
|
||||
const int ipv6_subnet_size = 128;
|
||||
const int max_ipv6_size = 64;
|
||||
char *ipv6_and_subnetmask = new char[ipv6_subnet_size];
|
||||
char *temp = new char[max_ipv6_size];
|
||||
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CGCONTRDP=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+CGCONTRDP:");
|
||||
pdpcontext_params_t *params = NULL;
|
||||
while (_at.info_resp()) { // response can be zero or many +CGDCONT lines
|
||||
params = params_list.add_new();
|
||||
params->cid = _at.read_int();
|
||||
params->bearer_id = _at.read_int();
|
||||
_at.read_string(params->apn, sizeof(params->apn));
|
||||
|
||||
// rest are optional params
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->local_addr, sizeof(params->local_addr), params->local_subnet_mask, sizeof(params->local_subnet_mask));
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->gateway_addr, sizeof(params->gateway_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->gateway_addr, sizeof(params->gateway_addr), temp, max_ipv6_size);
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->dns_primary_addr, sizeof(params->dns_primary_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->dns_primary_addr, sizeof(params->dns_primary_addr), temp, max_ipv6_size);
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->dns_secondary_addr, sizeof(params->dns_secondary_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->dns_secondary_addr, sizeof(params->dns_secondary_addr), temp, max_ipv6_size);
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->p_cscf_prim_addr, sizeof(params->p_cscf_prim_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->p_cscf_prim_addr, sizeof(params->p_cscf_prim_addr), temp, max_ipv6_size);
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->p_cscf_sec_addr, sizeof(params->p_cscf_sec_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->p_cscf_sec_addr, sizeof(params->p_cscf_sec_addr), temp, max_ipv6_size);
|
||||
|
||||
params->im_signalling_flag = _at.read_int();
|
||||
params->lipa_indication = _at.read_int();
|
||||
params->ipv4_mtu = _at.read_int();
|
||||
params->wlan_offload = _at.read_int();
|
||||
params->local_addr_ind = _at.read_int();
|
||||
params->non_ip_mtu = _at.read_int();
|
||||
params->serving_plmn_rate_control_value = _at.read_int();
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
delete [] temp;
|
||||
delete [] ipv6_and_subnetmask;
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
// Called by CellularDevice for network and cellular device changes
|
||||
void AT_CellularContext::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* 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);
|
||||
#if USE_APN_LOOKUP
|
||||
if (st == CellularSIMStatusChanged && data->status_data == CellularSIM::SimStateReady &&
|
||||
_cb_data.error == NSAPI_ERROR_OK) {
|
||||
if (!_apn) {
|
||||
char imsi[MAX_IMSI_LENGTH + 1];
|
||||
wait(1); // need to wait to access SIM in some modems
|
||||
_cb_data.error = _device->open_sim()->get_imsi(imsi);
|
||||
if (_cb_data.error == NSAPI_ERROR_OK) {
|
||||
const char *apn_config = apnconfig(imsi);
|
||||
if (apn_config) {
|
||||
const char *apn = _APN_GET(apn_config);
|
||||
const char *uname = _APN_GET(apn_config);
|
||||
const char *pwd = _APN_GET(apn_config);
|
||||
tr_info("Looked up APN %s", apn);
|
||||
set_credentials(apn, uname, pwd);
|
||||
}
|
||||
} else {
|
||||
tr_error("APN lookup failed");
|
||||
_device->stop();
|
||||
if (_is_blocking) {
|
||||
// operation failed, release semaphore
|
||||
_semaphore.release();
|
||||
}
|
||||
}
|
||||
_device->close_sim();
|
||||
}
|
||||
}
|
||||
#endif // USE_APN_LOOKUP
|
||||
|
||||
if (!_nw && st == CellularDeviceReady && data->error == NSAPI_ERROR_OK) {
|
||||
_nw = _device->open_network(_fh);
|
||||
}
|
||||
|
||||
if (_is_blocking) {
|
||||
if (data->error != NSAPI_ERROR_OK) {
|
||||
// operation failed, release semaphore
|
||||
_semaphore.release();
|
||||
} else {
|
||||
if ((st == CellularDeviceReady && _current_op == OP_DEVICE_READY) ||
|
||||
(st == CellularSIMStatusChanged && _current_op == OP_SIM_READY &&
|
||||
data->status_data == CellularSIM::SimStateReady)) {
|
||||
// target reached, release semaphore
|
||||
_semaphore.release();
|
||||
} else if (st == CellularRegistrationStatusChanged && (data->status_data == CellularNetwork::RegisteredHomeNetwork ||
|
||||
data->status_data == CellularNetwork::RegisteredRoaming || data->status_data == CellularNetwork::AlreadyRegistered) && _current_op == OP_REGISTER) {
|
||||
// target reached, release semaphore
|
||||
_semaphore.release();
|
||||
} else if (st == CellularAttachNetwork && (_current_op == OP_ATTACH || _current_op == OP_CONNECT) &&
|
||||
data->status_data == CellularNetwork::Attached) {
|
||||
// target reached, release semaphore
|
||||
_semaphore.release();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// non blocking
|
||||
if (st == CellularAttachNetwork && _current_op == OP_CONNECT && data->error == NSAPI_ERROR_OK &&
|
||||
data->status_data == CellularNetwork::Attached) {
|
||||
// forward to application
|
||||
if (_status_cb) {
|
||||
_status_cb(ev, ptr);
|
||||
}
|
||||
do_connect();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tr_debug("AT_CellularContext::cellular_callback, network_callback called with 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) {
|
||||
_cb_data.error = NSAPI_ERROR_OK;
|
||||
_semaphore.release();
|
||||
} else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
|
||||
_cb_data.error = NSAPI_ERROR_NO_CONNECTION;
|
||||
_semaphore.release();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// forward to application
|
||||
if (_status_cb) {
|
||||
_status_cb(ev, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void AT_CellularContext::call_network_cb(nsapi_connection_status_t status)
|
||||
{
|
||||
if (_connect_status != status) {
|
||||
_connect_status = status;
|
||||
if (_status_cb) {
|
||||
_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _connect_status);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* 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 AT_CELLULARCONTEXT_H_
|
||||
#define AT_CELLULARCONTEXT_H_
|
||||
|
||||
#include "CellularContext.h"
|
||||
#include "AT_CellularBase.h"
|
||||
#include "Semaphore.h"
|
||||
|
||||
const int MAX_APN_LENGTH = 63 + 1;
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class AT_CellularContext : public CellularContext, public AT_CellularBase {
|
||||
public:
|
||||
AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn = 0);
|
||||
virtual ~AT_CellularContext();
|
||||
|
||||
// from CellularBase/NetworkInterface
|
||||
virtual nsapi_error_t set_blocking(bool blocking);
|
||||
virtual NetworkStack *get_stack();
|
||||
virtual const char *get_ip_address();
|
||||
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||
virtual nsapi_error_t connect();
|
||||
virtual nsapi_error_t disconnect();
|
||||
virtual bool is_connected();
|
||||
// from CellularBase
|
||||
virtual void set_plmn(const char *plmn);
|
||||
virtual void set_sim_pin(const char *sim_pin);
|
||||
virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0, const char *uname = 0,
|
||||
const char *pwd = 0);
|
||||
virtual void set_credentials(const char *apn, const char *uname = 0, const char *pwd = 0);
|
||||
virtual const char *get_netmask();
|
||||
virtual const char *get_gateway();
|
||||
|
||||
// from CellularContext
|
||||
virtual nsapi_error_t get_pdpcontext_params(pdpContextList_t ¶ms_list);
|
||||
virtual nsapi_error_t get_rate_control(CellularContext::RateControlExceptionReports &reports,
|
||||
CellularContext::RateControlUplinkTimeUnit &time_unit, int &uplink_rate);
|
||||
virtual nsapi_error_t get_apn_backoff_timer(int &backoff_timer);
|
||||
virtual nsapi_error_t set_device_ready();
|
||||
virtual nsapi_error_t set_sim_ready();
|
||||
virtual nsapi_error_t register_to_network();
|
||||
virtual nsapi_error_t attach_to_network();
|
||||
virtual void set_file_handle(FileHandle *fh);
|
||||
|
||||
protected:
|
||||
virtual void cellular_callback(nsapi_event_t ev, intptr_t ptr);
|
||||
|
||||
/** Does the authentication for the PDP Context if user name and password are provided.
|
||||
* Can be overridden by the modem target if 3GPP default implementation if not an option
|
||||
*
|
||||
* @return NSAPI_ERROR_OK if no credentials provided or authentication was successful
|
||||
* NSAPI_ERROR_AUTH_FAILURE if authentication failed
|
||||
* NSAPI_ERROR_DEVICE_ERROR if communication with the modemm failed
|
||||
*/
|
||||
virtual nsapi_error_t do_user_authentication();
|
||||
|
||||
/** Activates PDP context or in PPP mode opens data channel.
|
||||
* Can be overridden by the modem target if 3GPP default implementation if not an option
|
||||
*/
|
||||
virtual void do_connect();
|
||||
|
||||
/** Check if modem supports the given stack type. Can be overridden by the modem.
|
||||
*
|
||||
* @return true if supported
|
||||
*/
|
||||
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
|
||||
|
||||
/** Get the operation specific timeout. Used in synchronous mode when setting the maximum
|
||||
* waiting time. Modem specific implementation can override this to provide different timeouts.
|
||||
*
|
||||
* @param op current operation
|
||||
* @return timeout in milliseconds
|
||||
*/
|
||||
virtual uint32_t get_timeout_for_operation(ContextOperation op) const;
|
||||
|
||||
/** Helper method to call callback function if it is provided
|
||||
*
|
||||
* @param status connection status which is parameter in callback function
|
||||
*/
|
||||
void call_network_cb(nsapi_connection_status_t status);
|
||||
|
||||
private:
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
nsapi_error_t open_data_channel();
|
||||
void ppp_status_cb(nsapi_event_t ev, intptr_t ptr);
|
||||
#endif // #if NSAPI_PPP_AVAILABLE
|
||||
nsapi_error_t do_activate_context();
|
||||
bool set_new_context(int cid);
|
||||
bool get_context();
|
||||
nsapi_error_t delete_current_context();
|
||||
nsapi_ip_stack_t string_to_stack_type(const char *pdp_type);
|
||||
nsapi_ip_stack_t get_stack_type();
|
||||
nsapi_error_t check_operation(nsapi_error_t err, ContextOperation op);
|
||||
|
||||
private:
|
||||
nsapi_ip_stack_t _ip_stack_type_requested;
|
||||
bool _is_connected;
|
||||
bool _is_blocking;
|
||||
ContextOperation _current_op;
|
||||
char _found_apn[MAX_APN_LENGTH];
|
||||
CellularDevice *_device;
|
||||
CellularNetwork *_nw;
|
||||
FileHandle *_fh;
|
||||
rtos::Semaphore _semaphore;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // AT_CELLULARCONTEXT_H_
|
|
@ -21,27 +21,49 @@
|
|||
#include "AT_CellularPower.h"
|
||||
#include "AT_CellularSIM.h"
|
||||
#include "AT_CellularSMS.h"
|
||||
#include "AT_CellularContext.h"
|
||||
#include "AT_CellularStack.h"
|
||||
#include "CellularLog.h"
|
||||
#include "ATHandler.h"
|
||||
#include "UARTSerial.h"
|
||||
#include "FileHandle.h"
|
||||
|
||||
using namespace events;
|
||||
using namespace mbed;
|
||||
|
||||
#define DEFAULT_AT_TIMEOUT 1000 // at default timeout in milliseconds
|
||||
|
||||
AT_CellularDevice::AT_CellularDevice(EventQueue &queue) :
|
||||
_atHandlers(0), _network(0), _sms(0), _sim(0), _power(0), _information(0), _queue(queue),
|
||||
_default_timeout(DEFAULT_AT_TIMEOUT), _modem_debug_on(false)
|
||||
AT_CellularDevice::AT_CellularDevice(FileHandle *fh) : CellularDevice(fh), _atHandlers(0), _network(0), _sms(0),
|
||||
_sim(0), _power(0), _information(0), _context_list(0), _default_timeout(DEFAULT_AT_TIMEOUT),
|
||||
_modem_debug_on(false)
|
||||
{
|
||||
}
|
||||
|
||||
AT_CellularDevice::~AT_CellularDevice()
|
||||
{
|
||||
delete _state_machine;
|
||||
|
||||
// make sure that all is deleted even if somewhere close was not called and reference counting is messed up.
|
||||
_network_ref_count = 1;
|
||||
_sms_ref_count = 1;
|
||||
_power_ref_count = 1;
|
||||
_sim_ref_count = 1;
|
||||
_info_ref_count = 1;
|
||||
|
||||
close_network();
|
||||
close_sms();
|
||||
close_power();
|
||||
close_sim();
|
||||
close_information();
|
||||
|
||||
AT_CellularContext* curr = _context_list;
|
||||
AT_CellularContext* next;
|
||||
while (curr) {
|
||||
next = (AT_CellularContext*)curr->_next;
|
||||
delete curr;
|
||||
curr = next;
|
||||
}
|
||||
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
while (atHandler) {
|
||||
ATHandler *old = atHandler;
|
||||
|
@ -50,16 +72,11 @@ AT_CellularDevice::~AT_CellularDevice()
|
|||
}
|
||||
}
|
||||
|
||||
events::EventQueue *AT_CellularDevice::get_queue() const
|
||||
{
|
||||
return &_queue;
|
||||
}
|
||||
|
||||
// each parser is associated with one filehandle (that is UART)
|
||||
ATHandler *AT_CellularDevice::get_at_handler(FileHandle *fileHandle)
|
||||
{
|
||||
if (!fileHandle) {
|
||||
return NULL;
|
||||
fileHandle = _fh;
|
||||
}
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
while (atHandler) {
|
||||
|
@ -107,6 +124,58 @@ void AT_CellularDevice::release_at_handler(ATHandler *at_handler)
|
|||
}
|
||||
}
|
||||
|
||||
CellularContext *AT_CellularDevice::get_context_list() const
|
||||
{
|
||||
return _context_list;
|
||||
}
|
||||
|
||||
CellularContext *AT_CellularDevice::create_context(FileHandle *fh, const char *apn)
|
||||
{
|
||||
ATHandler *atHandler = get_at_handler(fh);
|
||||
if (atHandler) {
|
||||
AT_CellularContext *ctx = create_context_impl(*atHandler, apn);
|
||||
AT_CellularContext* curr = _context_list;
|
||||
|
||||
if (_context_list == NULL) {
|
||||
_context_list = ctx;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
AT_CellularContext* prev;
|
||||
while (curr) {
|
||||
prev = curr;
|
||||
curr = (AT_CellularContext*)curr->_next;
|
||||
}
|
||||
|
||||
prev->_next = ctx;
|
||||
return ctx;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AT_CellularContext *AT_CellularDevice::create_context_impl(ATHandler &at, const char *apn)
|
||||
{
|
||||
return new AT_CellularContext(at, this, apn);
|
||||
}
|
||||
|
||||
void AT_CellularDevice::delete_context(CellularContext *context)
|
||||
{
|
||||
AT_CellularContext* curr = _context_list;
|
||||
AT_CellularContext* prev = NULL;
|
||||
while (curr) {
|
||||
if (curr == context) {
|
||||
if (prev == NULL) {
|
||||
_context_list = (AT_CellularContext*)curr->_next;
|
||||
} else {
|
||||
prev->_next = curr->_next;
|
||||
}
|
||||
}
|
||||
prev = curr;
|
||||
curr = (AT_CellularContext*)curr->_next;
|
||||
}
|
||||
delete (AT_CellularContext*)context;
|
||||
}
|
||||
|
||||
CellularNetwork *AT_CellularDevice::open_network(FileHandle *fh)
|
||||
{
|
||||
if (!_network) {
|
||||
|
@ -278,7 +347,7 @@ void AT_CellularDevice::set_timeout(int timeout)
|
|||
}
|
||||
}
|
||||
|
||||
uint16_t AT_CellularDevice::get_send_delay()
|
||||
uint16_t AT_CellularDevice::get_send_delay() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -294,15 +363,7 @@ void AT_CellularDevice::modem_debug_on(bool on)
|
|||
}
|
||||
}
|
||||
|
||||
NetworkStack *AT_CellularDevice::get_stack()
|
||||
{
|
||||
if (!_network) {
|
||||
return NULL;
|
||||
}
|
||||
return _network->get_stack();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularDevice::init_module(FileHandle *fh)
|
||||
nsapi_error_t AT_CellularDevice::init_module()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ class AT_CellularNetwork;
|
|||
class AT_CellularPower;
|
||||
class AT_CellularSIM;
|
||||
class AT_CellularSMS;
|
||||
class AT_CellularContext;
|
||||
|
||||
/**
|
||||
* Class AT_CellularDevice
|
||||
|
@ -37,33 +38,21 @@ class AT_CellularSMS;
|
|||
*/
|
||||
class AT_CellularDevice : public CellularDevice {
|
||||
public:
|
||||
AT_CellularDevice(events::EventQueue &queue);
|
||||
AT_CellularDevice(FileHandle *fh);
|
||||
virtual ~AT_CellularDevice();
|
||||
|
||||
protected:
|
||||
ATHandler *_atHandlers;
|
||||
virtual CellularContext *create_context(FileHandle *fh = NULL, const char *apn = NULL);
|
||||
virtual void delete_context(CellularContext *context);
|
||||
|
||||
ATHandler *get_at_handler(FileHandle *fh);
|
||||
virtual CellularNetwork *open_network(FileHandle *fh = NULL);
|
||||
|
||||
/** Releases the given at_handler. If last reference to at_hander then it's deleted.
|
||||
*
|
||||
* @param at_handler
|
||||
*/
|
||||
void release_at_handler(ATHandler *at_handler);
|
||||
virtual CellularSMS *open_sms(FileHandle *fh = NULL);
|
||||
|
||||
public: // CellularDevice
|
||||
virtual CellularPower *open_power(FileHandle *fh = NULL);
|
||||
|
||||
virtual events::EventQueue *get_queue() const;
|
||||
virtual CellularSIM *open_sim(FileHandle *fh = NULL);
|
||||
|
||||
virtual CellularNetwork *open_network(FileHandle *fh);
|
||||
|
||||
virtual CellularSMS *open_sms(FileHandle *fh);
|
||||
|
||||
virtual CellularPower *open_power(FileHandle *fh);
|
||||
|
||||
virtual CellularSIM *open_sim(FileHandle *fh);
|
||||
|
||||
virtual CellularInformation *open_information(FileHandle *fh);
|
||||
virtual CellularInformation *open_information(FileHandle *fh = NULL);
|
||||
|
||||
virtual void close_network();
|
||||
|
||||
|
@ -77,15 +66,31 @@ public: // CellularDevice
|
|||
|
||||
virtual void set_timeout(int timeout);
|
||||
|
||||
virtual uint16_t get_send_delay();
|
||||
virtual uint16_t get_send_delay() const;
|
||||
|
||||
virtual void modem_debug_on(bool on);
|
||||
|
||||
virtual NetworkStack *get_stack();
|
||||
virtual nsapi_error_t init_module();
|
||||
|
||||
virtual nsapi_error_t init_module(FileHandle *fh);
|
||||
ATHandler *_atHandlers;
|
||||
|
||||
ATHandler *get_at_handler(FileHandle *fh);
|
||||
|
||||
/** Releases the given at_handler. If last reference to at_hander then it's deleted.
|
||||
*
|
||||
* @param at_handler
|
||||
*/
|
||||
void release_at_handler(ATHandler *at_handler);
|
||||
|
||||
/** Creates new instance of AT_CellularContext or if overridden, modem specific implementation.
|
||||
*
|
||||
* @param at ATHandler reference for communication with the modem.
|
||||
* @param apn access point to use with context
|
||||
* @return new instance of class AT_CellularContext
|
||||
*
|
||||
*/
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
|
||||
|
||||
protected:
|
||||
/** Create new instance of AT_CellularNetwork or if overridden, modem specific implementation.
|
||||
*
|
||||
* @param at ATHandler reference for communication with the modem.
|
||||
|
@ -121,14 +126,14 @@ protected:
|
|||
*/
|
||||
virtual AT_CellularInformation *open_information_impl(ATHandler &at);
|
||||
|
||||
virtual CellularContext *get_context_list() const;
|
||||
|
||||
AT_CellularNetwork *_network;
|
||||
AT_CellularSMS *_sms;
|
||||
AT_CellularSIM *_sim;
|
||||
AT_CellularPower *_power;
|
||||
AT_CellularInformation *_information;
|
||||
|
||||
protected:
|
||||
events::EventQueue &_queue;
|
||||
AT_CellularContext *_context_list;
|
||||
int _default_timeout;
|
||||
bool _modem_debug_on;
|
||||
};
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include "AT_CellularNetwork.h"
|
||||
#include "nsapi_ppp.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "CellularLog.h"
|
||||
#include "CellularCommon.h"
|
||||
|
@ -39,20 +38,34 @@ static const at_reg_t at_reg[] = {
|
|||
};
|
||||
|
||||
AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(atHandler),
|
||||
_stack(NULL), _apn(NULL), _uname(NULL), _pwd(NULL), _ip_stack_type_requested(DEFAULT_STACK),
|
||||
_ip_stack_type(DEFAULT_STACK), _cid(-1), _connection_status_cb(NULL), _op_act(RAT_UNKNOWN),
|
||||
_authentication_type(CHAP), _connect_status(NSAPI_STATUS_DISCONNECTED), _new_context_set(false),
|
||||
_is_context_active(false)
|
||||
_connection_status_cb(NULL), _op_act(RAT_UNKNOWN), _connect_status(NSAPI_STATUS_DISCONNECTED)
|
||||
{
|
||||
|
||||
_urc_funcs[C_EREG] = callback(this, &AT_CellularNetwork::urc_cereg);
|
||||
_urc_funcs[C_GREG] = callback(this, &AT_CellularNetwork::urc_cgreg);
|
||||
_urc_funcs[C_REG] = callback(this, &AT_CellularNetwork::urc_creg);
|
||||
|
||||
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
|
||||
if (has_registration((RegistrationType)type) != RegistrationModeDisable) {
|
||||
_at.set_urc_handler(at_reg[type].urc_prefix, _urc_funcs[type]);
|
||||
}
|
||||
}
|
||||
|
||||
_at.set_urc_handler("NO CARRIER", callback(this, &AT_CellularNetwork::urc_no_carrier));
|
||||
// additional urc to get better disconnect info for application. Not critical.
|
||||
_at.set_urc_handler("+CGEV:", callback(this, &AT_CellularNetwork::urc_cgev));
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CGEREP=1");// discard unsolicited result codes when MT TE link is reserved (e.g. in on line data mode); otherwise forward them directly to the TE
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.unlock();
|
||||
}
|
||||
|
||||
AT_CellularNetwork::~AT_CellularNetwork()
|
||||
{
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
(void)disconnect();
|
||||
#else
|
||||
delete _stack;
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CGEREP=0");// buffer unsolicited result codes in the MT; if MT result code buffer is full, the oldest ones can be discarded. No codes are forwarded to the TE
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.unlock();
|
||||
|
||||
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
|
||||
if (has_registration((RegistrationType)type) != RegistrationModeDisable) {
|
||||
|
@ -62,42 +75,6 @@ AT_CellularNetwork::~AT_CellularNetwork()
|
|||
|
||||
_at.remove_urc_handler("NO CARRIER");
|
||||
_at.remove_urc_handler("+CGEV:");
|
||||
free_credentials();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::init()
|
||||
{
|
||||
_urc_funcs[C_EREG] = callback(this, &AT_CellularNetwork::urc_cereg);
|
||||
_urc_funcs[C_GREG] = callback(this, &AT_CellularNetwork::urc_cgreg);
|
||||
_urc_funcs[C_REG] = callback(this, &AT_CellularNetwork::urc_creg);
|
||||
|
||||
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
|
||||
if (has_registration((RegistrationType)type) != RegistrationModeDisable) {
|
||||
if (_at.set_urc_handler(at_reg[type].urc_prefix, _urc_funcs[type]) != NSAPI_ERROR_OK) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _at.set_urc_handler("NO CARRIER", callback(this, &AT_CellularNetwork::urc_no_carrier));
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::free_credentials()
|
||||
{
|
||||
if (_uname) {
|
||||
free(_uname);
|
||||
_uname = NULL;
|
||||
}
|
||||
|
||||
if (_pwd) {
|
||||
free(_pwd);
|
||||
_pwd = NULL;
|
||||
}
|
||||
|
||||
if (_apn) {
|
||||
free(_apn);
|
||||
_apn = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::urc_no_carrier()
|
||||
|
@ -160,17 +137,22 @@ void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
|
|||
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;
|
||||
if (reg_params._act != _reg_params._act) {
|
||||
_reg_params._act = reg_params._act;
|
||||
_connection_status_cb((nsapi_event_t)CellularRadioAccessTechnologyChanged, _reg_params._act);
|
||||
data.status_data = reg_params._act;
|
||||
_connection_status_cb((nsapi_event_t)CellularRadioAccessTechnologyChanged, (intptr_t)&data);
|
||||
}
|
||||
if (reg_params._status != _reg_params._status) {
|
||||
_reg_params._status = reg_params._status;
|
||||
_connection_status_cb((nsapi_event_t)CellularRegistrationStatusChanged, _reg_params._status);
|
||||
data.status_data = reg_params._status;
|
||||
_connection_status_cb((nsapi_event_t)CellularRegistrationStatusChanged, (intptr_t)&data);
|
||||
}
|
||||
if (reg_params._cell_id != -1 && reg_params._cell_id != _reg_params._cell_id) {
|
||||
_reg_params._cell_id = reg_params._cell_id;
|
||||
_connection_status_cb((nsapi_event_t)CellularCellIDChanged, _reg_params._cell_id);
|
||||
data.status_data = reg_params._cell_id;
|
||||
_connection_status_cb((nsapi_event_t)CellularCellIDChanged, (intptr_t)&data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,278 +175,6 @@ void AT_CellularNetwork::urc_cgreg()
|
|||
read_reg_params_and_compare(C_GREG);
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn,
|
||||
const char *username, const char *password)
|
||||
{
|
||||
free_credentials();
|
||||
|
||||
size_t len;
|
||||
if (apn && (len = strlen(apn)) > 0) {
|
||||
_apn = (char *)malloc(len * sizeof(char) + 1);
|
||||
if (_apn) {
|
||||
memcpy(_apn, apn, len + 1);
|
||||
} else {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (username && (len = strlen(username)) > 0) {
|
||||
if (!is_supported(AT_CGAUTH)) { // APN authentication is needed with username/password
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
_uname = (char *)malloc(len * sizeof(char) + 1);
|
||||
if (_uname) {
|
||||
memcpy(_uname, username, len + 1);
|
||||
} else {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (password && (len = strlen(password)) > 0) {
|
||||
_pwd = (char *)malloc(len * sizeof(char) + 1);
|
||||
if (_pwd) {
|
||||
memcpy(_pwd, password, len + 1);
|
||||
} else {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn,
|
||||
AuthenticationType type, const char *username, const char *password)
|
||||
{
|
||||
nsapi_error_t err = set_credentials(apn, username, password);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
_authentication_type = type;
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::connect(const char *apn,
|
||||
const char *username, const char *password)
|
||||
{
|
||||
nsapi_error_t err = set_credentials(apn, username, password);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return connect();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::delete_current_context()
|
||||
{
|
||||
tr_info("Delete context %d", _cid);
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+CGDCONT=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
_cid = -1;
|
||||
_new_context_set = false;
|
||||
}
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::activate_context()
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
|
||||
// try to find or create context with suitable stack
|
||||
if (!get_context()) {
|
||||
err = NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
_at.unlock();
|
||||
tr_error("Failed to activate network context! (%d)", err);
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
// do check for stack to validate that we have support for stack
|
||||
_stack = get_stack();
|
||||
if (!_stack) {
|
||||
tr_error("No cellular stack!");
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
_is_context_active = false;
|
||||
_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_id == _cid && context_activation_state == 1) {
|
||||
_is_context_active = true;
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
if (!_is_context_active) {
|
||||
// authenticate before activating or modifying context
|
||||
nsapi_error_t err = do_user_authentication();
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
tr_error("Cellular authentication failed!");
|
||||
return err;
|
||||
}
|
||||
|
||||
tr_info("Activate PDP context %d", _cid);
|
||||
_at.cmd_start("AT+CGACT=1,");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
}
|
||||
|
||||
err = (_at.get_last_error() == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
// If new PDP context was created and failed to activate, delete it
|
||||
if (err != NSAPI_ERROR_OK && _new_context_set) {
|
||||
delete_current_context();
|
||||
} else if (err == NSAPI_ERROR_OK) {
|
||||
_is_context_active = true;
|
||||
}
|
||||
|
||||
_at.unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::connect()
|
||||
{
|
||||
call_network_cb(NSAPI_STATUS_CONNECTING);
|
||||
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
if (!_is_context_active) {
|
||||
err = activate_context();
|
||||
}
|
||||
if (err) {
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
return err;
|
||||
}
|
||||
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
_at.lock();
|
||||
err = open_data_channel();
|
||||
_at.unlock();
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
tr_error("Failed to open data channel!");
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
// additional urc to get better disconnect info for application. Not critical so not returning an error in case of failure
|
||||
err = _at.set_urc_handler("+CGEV:", callback(this, &AT_CellularNetwork::urc_cgev));
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CGEREP=1");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.unlock();
|
||||
}
|
||||
|
||||
call_network_cb(NSAPI_STATUS_GLOBAL_UP);
|
||||
#endif
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::open_data_channel()
|
||||
{
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
tr_info("Open data channel in PPP mode");
|
||||
if (is_supported(AT_CGDATA)) {
|
||||
_at.cmd_start("AT+CGDATA=\"PPP\",");
|
||||
_at.write_int(_cid);
|
||||
} else {
|
||||
MBED_ASSERT(_cid >= 0 && _cid <= 99);
|
||||
_at.cmd_start("ATD*99***");
|
||||
_at.use_delimiter(false);
|
||||
_at.write_int(_cid);
|
||||
_at.write_string("#", false);
|
||||
_at.use_delimiter(true);
|
||||
}
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("CONNECT", true);
|
||||
if (_at.get_last_error()) {
|
||||
tr_error("Failed to CONNECT");
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
_at.set_is_filehandle_usable(false);
|
||||
|
||||
/* Initialize PPP
|
||||
* If blocking: mbed_ppp_init() is a blocking call, it will block until
|
||||
connected, or timeout after 30 seconds*/
|
||||
return nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularNetwork::ppp_status_cb), NULL, NULL, _ip_stack_type);
|
||||
#else
|
||||
return NSAPI_ERROR_OK;
|
||||
#endif // #if NSAPI_PPP_AVAILABLE
|
||||
}
|
||||
|
||||
/**
|
||||
* User initiated disconnect
|
||||
*
|
||||
* Disconnects from PPP connection only and brings down the underlying network
|
||||
* interface
|
||||
*/
|
||||
nsapi_error_t AT_CellularNetwork::disconnect()
|
||||
{
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
nsapi_error_t err = nsapi_ppp_disconnect(_at.get_file_handle());
|
||||
// after ppp disconnect if we wan't to use same at handler we need to set filehandle again to athandler so it
|
||||
// will set the correct sigio and nonblocking
|
||||
_at.lock();
|
||||
_at.set_file_handle(_at.get_file_handle());
|
||||
_at.set_is_filehandle_usable(true);
|
||||
_at.unlock();
|
||||
return err;
|
||||
#else
|
||||
_at.lock();
|
||||
|
||||
_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();
|
||||
|
||||
// 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 && (_reg_params._act < RAT_E_UTRAN || active_contexts_count > 1)) {
|
||||
_at.cmd_start("AT+CGACT=0,");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
}
|
||||
|
||||
_at.restore_at_timeout();
|
||||
|
||||
_at.remove_urc_handler("+CGEV:");
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
|
||||
return _at.unlock_return_error();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::call_network_cb(nsapi_connection_status_t status)
|
||||
{
|
||||
if (_connect_status != status) {
|
||||
|
@ -485,224 +195,6 @@ nsapi_connection_status_t AT_CellularNetwork::get_connection_status() const
|
|||
return _connect_status;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_blocking(bool blocking)
|
||||
{
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
return nsapi_ppp_set_blocking(blocking);
|
||||
#else
|
||||
return NSAPI_ERROR_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
void AT_CellularNetwork::ppp_status_cb(nsapi_event_t event, intptr_t parameter)
|
||||
{
|
||||
_connect_status = (nsapi_connection_status_t)parameter;
|
||||
|
||||
if (_connection_status_cb) {
|
||||
_connection_status_cb(event, parameter);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::do_user_authentication()
|
||||
{
|
||||
// if user has defined user name and password we need to call CGAUTH before activating or modifying context
|
||||
if (_pwd && _uname) {
|
||||
if (!is_supported(AT_CGAUTH)) {
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
_at.cmd_start("AT+CGAUTH=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(_authentication_type);
|
||||
_at.write_string(_uname);
|
||||
_at.write_string(_pwd);
|
||||
_at.cmd_stop_read_resp();
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
return NSAPI_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
bool AT_CellularNetwork::set_new_context(int cid)
|
||||
{
|
||||
nsapi_ip_stack_t tmp_stack = _ip_stack_type_requested;
|
||||
|
||||
if (tmp_stack == DEFAULT_STACK) {
|
||||
bool modem_supports_ipv6 = get_modem_stack_type(IPV6_STACK);
|
||||
bool modem_supports_ipv4 = get_modem_stack_type(IPV4_STACK);
|
||||
|
||||
if (modem_supports_ipv6 && modem_supports_ipv4) {
|
||||
tmp_stack = IPV4V6_STACK;
|
||||
} else if (modem_supports_ipv6) {
|
||||
tmp_stack = IPV6_STACK;
|
||||
} else if (modem_supports_ipv4) {
|
||||
tmp_stack = IPV4_STACK;
|
||||
}
|
||||
}
|
||||
|
||||
char pdp_type[8 + 1] = {0};
|
||||
|
||||
switch (tmp_stack) {
|
||||
case IPV4_STACK:
|
||||
strncpy(pdp_type, "IP", sizeof(pdp_type));
|
||||
break;
|
||||
case IPV6_STACK:
|
||||
strncpy(pdp_type, "IPV6", sizeof(pdp_type));
|
||||
break;
|
||||
case IPV4V6_STACK:
|
||||
strncpy(pdp_type, "IPV6", sizeof(pdp_type)); // try first IPV6 and then fall-back to IPv4
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//apn: "If the value is null or omitted, then the subscription value will be requested."
|
||||
bool success = false;
|
||||
_at.cmd_start("AT+CGDCONT=");
|
||||
_at.write_int(cid);
|
||||
_at.write_string(pdp_type);
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop_read_resp();
|
||||
success = (_at.get_last_error() == NSAPI_ERROR_OK);
|
||||
|
||||
// Fall back to ipv4
|
||||
if (!success && tmp_stack == IPV4V6_STACK) {
|
||||
tmp_stack = IPV4_STACK;
|
||||
_at.clear_error();
|
||||
_at.cmd_start("AT+FCLASS=0;+CGDCONT=");
|
||||
_at.write_int(cid);
|
||||
_at.write_string("IP");
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop_read_resp();
|
||||
success = (_at.get_last_error() == NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
_ip_stack_type = tmp_stack;
|
||||
_cid = cid;
|
||||
_new_context_set = true;
|
||||
tr_info("New PDP context id %d was created", _cid);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool AT_CellularNetwork::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:");
|
||||
_cid = -1;
|
||||
int cid_max = 0; // needed when creating new context
|
||||
char apn[MAX_ACCESSPOINT_NAME_LENGTH];
|
||||
int apn_len = 0;
|
||||
|
||||
bool modem_supports_ipv6 = get_modem_stack_type(IPV6_STACK);
|
||||
bool modem_supports_ipv4 = get_modem_stack_type(IPV4_STACK);
|
||||
|
||||
while (_at.info_resp()) {
|
||||
int cid = _at.read_int();
|
||||
if (cid > cid_max) {
|
||||
cid_max = cid;
|
||||
}
|
||||
char pdp_type_from_context[10];
|
||||
int pdp_type_len = _at.read_string(pdp_type_from_context, sizeof(pdp_type_from_context) - 1);
|
||||
if (pdp_type_len > 0) {
|
||||
apn_len = _at.read_string(apn, sizeof(apn) - 1);
|
||||
if (apn_len >= 0) {
|
||||
if (_apn && (strcmp(apn, _apn) != 0)) {
|
||||
continue;
|
||||
}
|
||||
nsapi_ip_stack_t pdp_stack = string_to_stack_type(pdp_type_from_context);
|
||||
// Accept dual PDP context for IPv4/IPv6 only modems
|
||||
if (pdp_stack != DEFAULT_STACK && (get_modem_stack_type(pdp_stack) || pdp_stack == IPV4V6_STACK)) {
|
||||
if (_ip_stack_type_requested == IPV4_STACK) {
|
||||
if (pdp_stack == IPV4_STACK || pdp_stack == IPV4V6_STACK) {
|
||||
_ip_stack_type = _ip_stack_type_requested;
|
||||
_cid = cid;
|
||||
break;
|
||||
}
|
||||
} else if (_ip_stack_type_requested == IPV6_STACK) {
|
||||
if (pdp_stack == IPV6_STACK || pdp_stack == IPV4V6_STACK) {
|
||||
_ip_stack_type = _ip_stack_type_requested;
|
||||
_cid = cid;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// requested dual stack or stack is not specified
|
||||
// If dual PDP need to check for IPV4 or IPV6 modem support. Prefer IPv6.
|
||||
if (pdp_stack == IPV4V6_STACK) {
|
||||
if (modem_supports_ipv6) {
|
||||
_ip_stack_type = IPV6_STACK;
|
||||
_cid = cid;
|
||||
break;
|
||||
} else if (modem_supports_ipv4) {
|
||||
_ip_stack_type = IPV4_STACK;
|
||||
_cid = cid;
|
||||
break;
|
||||
}
|
||||
// If PDP is IPV4 or IPV6 they are already checked if supported
|
||||
} else {
|
||||
_ip_stack_type = pdp_stack;
|
||||
_cid = cid;
|
||||
|
||||
if (pdp_stack == IPV6_STACK) {
|
||||
break;
|
||||
}
|
||||
if (pdp_stack == IPV4_STACK && !modem_supports_ipv6) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
if (_cid == -1) { // no suitable context was found so create a new one
|
||||
if (!set_new_context(cid_max + 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// save the apn
|
||||
if (apn_len > 0 && !_apn) {
|
||||
_apn = (char *)malloc(apn_len * sizeof(char) + 1);
|
||||
if (_apn) {
|
||||
memcpy(_apn, apn, apn_len + 1);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
tr_debug("Context id %d", _cid);
|
||||
return true;
|
||||
}
|
||||
|
||||
nsapi_ip_stack_t AT_CellularNetwork::string_to_stack_type(const char *pdp_type)
|
||||
{
|
||||
nsapi_ip_stack_t stack = DEFAULT_STACK;
|
||||
int len = strlen(pdp_type);
|
||||
|
||||
if (len == 6 && memcmp(pdp_type, "IPV4V6", len) == 0) {
|
||||
stack = IPV4V6_STACK;
|
||||
} else if (len == 4 && memcmp(pdp_type, "IPV6", len) == 0) {
|
||||
stack = IPV6_STACK;
|
||||
} else if (len == 2 && memcmp(pdp_type, "IP", len) == 0) {
|
||||
stack = IPV4_STACK;
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bool urc_on)
|
||||
{
|
||||
int index = (int)type;
|
||||
|
@ -758,7 +250,7 @@ nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn)
|
|||
}
|
||||
} else {
|
||||
tr_debug("Manual network registration to %s", plmn);
|
||||
_at.cmd_start("AT+COPS=4,2,");
|
||||
_at.cmd_start("AT+COPS=1,2,");
|
||||
_at.write_string(plmn);
|
||||
_at.cmd_stop_read_resp();
|
||||
}
|
||||
|
@ -815,7 +307,7 @@ AT_CellularNetwork::RegistrationMode AT_CellularNetwork::has_registration(Regist
|
|||
return RegistrationModeLAC;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_attach(int /*timeout*/)
|
||||
nsapi_error_t AT_CellularNetwork::set_attach()
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
|
@ -863,76 +355,6 @@ nsapi_error_t AT_CellularNetwork::detach()
|
|||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_apn_backoff_timer(int &backoff_timer)
|
||||
{
|
||||
// If apn is set
|
||||
if (_apn) {
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CABTRDP=");
|
||||
_at.write_string(_apn);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+CABTRDP:");
|
||||
if (_at.info_resp()) {
|
||||
_at.skip_param();
|
||||
backoff_timer = _at.read_int();
|
||||
}
|
||||
_at.resp_stop();
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
NetworkStack *AT_CellularNetwork::get_stack()
|
||||
{
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
// use lwIP/PPP if modem does not have IP stack
|
||||
if (!_stack) {
|
||||
_stack = nsapi_ppp_get_stack();
|
||||
}
|
||||
#endif
|
||||
return _stack;
|
||||
}
|
||||
|
||||
const char *AT_CellularNetwork::get_ip_address()
|
||||
{
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
return nsapi_ppp_get_ip_addr(_at.get_file_handle());
|
||||
#else
|
||||
if (!_stack) {
|
||||
_stack = get_stack();
|
||||
}
|
||||
if (_stack) {
|
||||
return _stack->get_ip_address();
|
||||
}
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_stack_type(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
if (get_modem_stack_type(stack_type)) {
|
||||
_ip_stack_type_requested = stack_type;
|
||||
return NSAPI_ERROR_OK;
|
||||
} else {
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_ip_stack_t AT_CellularNetwork::get_stack_type()
|
||||
{
|
||||
return _ip_stack_type;
|
||||
}
|
||||
|
||||
bool AT_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
if (requested_stack == _ip_stack_type) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
|
@ -966,15 +388,6 @@ nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount
|
|||
while (_at.info_elem('(')) {
|
||||
|
||||
op = operators.add_new();
|
||||
if (!op) {
|
||||
tr_warn("Could not allocate new operator");
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
operators.delete_all();
|
||||
opsCount = 0;
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
op->op_status = (operator_t::Status)_at.read_int();
|
||||
_at.read_string(op->op_long, sizeof(op->op_long));
|
||||
_at.read_string(op->op_short, sizeof(op->op_short));
|
||||
|
@ -1001,10 +414,11 @@ nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount
|
|||
nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(Supported_UE_Opt supported_opt,
|
||||
Preferred_UE_Opt preferred_opt)
|
||||
{
|
||||
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CCIOTOPT=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(0); // disable urc
|
||||
_at.write_int(supported_opt);
|
||||
_at.write_int(preferred_opt);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
@ -1032,138 +446,6 @@ nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt
|
|||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_rate_control(
|
||||
CellularNetwork::RateControlExceptionReports &reports,
|
||||
CellularNetwork::RateControlUplinkTimeUnit &timeUnit, int &uplinkRate)
|
||||
{
|
||||
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CGAPNRC=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+CGAPNRC:");
|
||||
_at.read_int();
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
bool comma_found = true;
|
||||
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;
|
||||
}
|
||||
|
||||
if (comma_found && next_element >= 0) {
|
||||
timeUnit = (RateControlUplinkTimeUnit)next_element;
|
||||
tr_debug("time %d", timeUnit);
|
||||
next_element = _at.read_int();
|
||||
} else {
|
||||
comma_found = false;
|
||||
}
|
||||
|
||||
if (comma_found && next_element >= 0) {
|
||||
uplinkRate = next_element;
|
||||
tr_debug("rate %d", uplinkRate);
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_pdpcontext_params(pdpContextList_t ¶ms_list)
|
||||
{
|
||||
const int ipv6_subnet_size = 128;
|
||||
const int max_ipv6_size = 64;
|
||||
char *ipv6_and_subnetmask = (char *)malloc(ipv6_subnet_size);
|
||||
if (!ipv6_and_subnetmask) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
char *temp = (char *)malloc(max_ipv6_size);
|
||||
if (!temp) {
|
||||
free(ipv6_and_subnetmask);
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start("AT+CGCONTRDP=");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop();
|
||||
|
||||
_at.resp_start("+CGCONTRDP:");
|
||||
pdpcontext_params_t *params = NULL;
|
||||
while (_at.info_resp()) { // response can be zero or many +CGDCONT lines
|
||||
params = params_list.add_new();
|
||||
if (!params) {
|
||||
tr_warn("Could not allocate new pdpcontext_params_t");
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
params_list.delete_all();
|
||||
free(temp);
|
||||
free(ipv6_and_subnetmask);
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
params->cid = _at.read_int();
|
||||
params->bearer_id = _at.read_int();
|
||||
_at.read_string(params->apn, sizeof(params->apn));
|
||||
|
||||
// rest are optional params
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->local_addr, sizeof(params->local_addr), params->local_subnet_mask, sizeof(params->local_subnet_mask));
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->gateway_addr, sizeof(params->gateway_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->gateway_addr, sizeof(params->gateway_addr), temp, max_ipv6_size);
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->dns_primary_addr, sizeof(params->dns_primary_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->dns_primary_addr, sizeof(params->dns_primary_addr), temp, max_ipv6_size);
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->dns_secondary_addr, sizeof(params->dns_secondary_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->dns_secondary_addr, sizeof(params->dns_secondary_addr), temp, max_ipv6_size);
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->p_cscf_prim_addr, sizeof(params->p_cscf_prim_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->p_cscf_prim_addr, sizeof(params->p_cscf_prim_addr), temp, max_ipv6_size);
|
||||
ipv6_and_subnetmask[0] = '\0';
|
||||
temp[0] = '\0';
|
||||
|
||||
_at.read_string(ipv6_and_subnetmask, ipv6_subnet_size);
|
||||
separate_ip_addresses(ipv6_and_subnetmask, params->p_cscf_sec_addr, sizeof(params->p_cscf_sec_addr), temp, max_ipv6_size);
|
||||
prefer_ipv6(params->p_cscf_sec_addr, sizeof(params->p_cscf_sec_addr), temp, max_ipv6_size);
|
||||
|
||||
params->im_signalling_flag = _at.read_int();
|
||||
params->lipa_indication = _at.read_int();
|
||||
params->ipv4_mtu = _at.read_int();
|
||||
params->wlan_offload = _at.read_int();
|
||||
params->local_addr_ind = _at.read_int();
|
||||
params->non_ip_mtu = _at.read_int();
|
||||
params->serving_plmn_rate_control_value = _at.read_int();
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
free(temp);
|
||||
free(ipv6_and_subnetmask);
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_extended_signal_quality(int &rxlev, int &ber, int &rscp, int &ecno, int &rsrq, int &rsrp)
|
||||
{
|
||||
_at.lock();
|
||||
|
@ -1256,13 +538,6 @@ nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_nam
|
|||
operator_names_t *names = NULL;
|
||||
while (_at.info_resp()) {
|
||||
names = op_names.add_new();
|
||||
if (!names) {
|
||||
tr_warn("Could not allocate new operator_names_t");
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
op_names.delete_all();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
_at.read_string(names->numeric, sizeof(names->numeric));
|
||||
_at.read_string(names->alpha, sizeof(names->alpha));
|
||||
}
|
||||
|
@ -1271,6 +546,29 @@ nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_nam
|
|||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
bool AT_CellularNetwork::is_active_context()
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
bool active_found = false;
|
||||
// read active contexts
|
||||
_at.cmd_start("AT+CGACT?");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+CGACT:");
|
||||
while (_at.info_resp()) {
|
||||
(void)_at.read_int(); // discard context id
|
||||
if (_at.read_int() == 1) { // check state
|
||||
tr_debug("Found active context");
|
||||
active_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
|
||||
return active_found;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_registration_params(registration_params_t ®_params)
|
||||
{
|
||||
reg_params = _reg_params;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "CellularNetwork.h"
|
||||
#include "AT_CellularBase.h"
|
||||
#include "NetworkStack.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -33,7 +32,7 @@ namespace mbed {
|
|||
/**
|
||||
* Class AT_CellularNetwork
|
||||
*
|
||||
* Class for connecting to a network and getting information from it.
|
||||
* Class for attaching to a network and getting information from it.
|
||||
*/
|
||||
class AT_CellularNetwork : public CellularNetwork, public AT_CellularBase {
|
||||
|
||||
|
@ -44,52 +43,22 @@ public:
|
|||
// declare friend so it can access stack
|
||||
friend class AT_CellularDevice;
|
||||
|
||||
public: // NetworkInterface
|
||||
|
||||
virtual nsapi_error_t set_credentials(const char *apn,
|
||||
const char *username = 0, const char *password = 0);
|
||||
|
||||
virtual nsapi_error_t set_credentials(const char *apn, AuthenticationType type,
|
||||
const char *username = 0, const char *password = 0);
|
||||
|
||||
virtual nsapi_error_t connect(const char *apn,
|
||||
const char *username = 0, const char *password = 0);
|
||||
|
||||
virtual nsapi_error_t connect();
|
||||
|
||||
virtual nsapi_error_t disconnect();
|
||||
|
||||
protected:
|
||||
virtual NetworkStack *get_stack();
|
||||
|
||||
public: // CellularNetwork
|
||||
virtual nsapi_error_t init();
|
||||
|
||||
virtual nsapi_error_t activate_context();
|
||||
|
||||
virtual nsapi_error_t set_registration(const char *plmn = 0);
|
||||
|
||||
virtual nsapi_error_t get_network_registering_mode(NWRegisteringMode &mode);
|
||||
|
||||
virtual nsapi_error_t set_attach(int timeout = 10 * 1000);
|
||||
virtual nsapi_error_t set_attach();
|
||||
|
||||
virtual nsapi_error_t get_attach(AttachStatus &status);
|
||||
|
||||
virtual nsapi_error_t detach();
|
||||
|
||||
virtual nsapi_error_t get_rate_control(CellularNetwork::RateControlExceptionReports &reports,
|
||||
CellularNetwork::RateControlUplinkTimeUnit &time_unit, int &uplink_rate);
|
||||
|
||||
virtual nsapi_error_t get_apn_backoff_timer(int &backoff_timer);
|
||||
|
||||
virtual void attach(Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||
|
||||
virtual nsapi_connection_status_t get_connection_status() const;
|
||||
|
||||
virtual nsapi_error_t set_blocking(bool blocking);
|
||||
|
||||
virtual const char *get_ip_address();
|
||||
|
||||
virtual nsapi_error_t set_access_technology(RadioAccessTechnology rat);
|
||||
|
||||
virtual nsapi_error_t scan_plmn(operList_t &operators, int &ops_count);
|
||||
|
@ -100,12 +69,6 @@ public: // CellularNetwork
|
|||
virtual nsapi_error_t get_ciot_optimization_config(Supported_UE_Opt &supported_opt,
|
||||
Preferred_UE_Opt &preferred_opt);
|
||||
|
||||
virtual nsapi_error_t set_stack_type(nsapi_ip_stack_t stack_type);
|
||||
|
||||
virtual nsapi_ip_stack_t get_stack_type();
|
||||
|
||||
virtual nsapi_error_t get_pdpcontext_params(pdpContextList_t ¶ms_list);
|
||||
|
||||
virtual nsapi_error_t get_extended_signal_quality(int &rxlev, int &ber, int &rscp, int &ecno, int &rsrq, int &rsrp);
|
||||
|
||||
virtual nsapi_error_t get_signal_quality(int &rssi, int &ber);
|
||||
|
@ -118,17 +81,13 @@ public: // CellularNetwork
|
|||
|
||||
virtual nsapi_error_t get_operator_names(operator_names_list &op_names);
|
||||
|
||||
virtual bool is_active_context();
|
||||
|
||||
virtual nsapi_error_t get_registration_params(registration_params_t ®_params);
|
||||
|
||||
virtual nsapi_error_t get_registration_params(RegistrationType type, registration_params_t ®_params);
|
||||
protected:
|
||||
|
||||
/** Check if modem supports the given stack type.
|
||||
*
|
||||
* @return true if supported
|
||||
*/
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
/** Check if modem supports given registration type.
|
||||
*
|
||||
* @param reg_type enum RegistrationType
|
||||
|
@ -149,13 +108,6 @@ protected:
|
|||
*/
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat);
|
||||
|
||||
/** APN user authentication
|
||||
*
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
* NSAPI_ERROR_UNSUPPORTED on authentication not supported by cellular device
|
||||
* NSAPI_ERROR_AUTH_FAILURE on authentication to network failed
|
||||
*/
|
||||
virtual nsapi_error_t do_user_authentication();
|
||||
private:
|
||||
// "NO CARRIER" urc
|
||||
void urc_no_carrier();
|
||||
|
@ -164,19 +116,6 @@ private:
|
|||
void urc_cgreg();
|
||||
void urc_cgev();
|
||||
|
||||
nsapi_ip_stack_t string_to_stack_type(const char *pdp_type);
|
||||
|
||||
void free_credentials();
|
||||
|
||||
nsapi_error_t open_data_channel();
|
||||
bool get_context();
|
||||
bool set_new_context(int cid);
|
||||
|
||||
nsapi_error_t delete_current_context();
|
||||
|
||||
// calls network callback only if status was changed, updates local connection status
|
||||
void call_network_cb(nsapi_connection_status_t status);
|
||||
|
||||
void read_reg_params_and_compare(RegistrationType type);
|
||||
void read_reg_params(registration_params_t ®_params);
|
||||
|
||||
|
@ -185,27 +124,15 @@ private:
|
|||
// Returns periodic tau(Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element) in seconds
|
||||
int calculate_periodic_tau(const char *periodic_tau_string, int periodic_tau_length);
|
||||
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
void ppp_status_cb(nsapi_event_t, intptr_t);
|
||||
#endif
|
||||
// calls network callback only if status was changed, updates local connection status
|
||||
void call_network_cb(nsapi_connection_status_t status);
|
||||
|
||||
protected:
|
||||
NetworkStack *_stack;
|
||||
char *_apn;
|
||||
char *_uname;
|
||||
char *_pwd;
|
||||
nsapi_ip_stack_t _ip_stack_type_requested;
|
||||
nsapi_ip_stack_t _ip_stack_type;
|
||||
int _cid;
|
||||
|
||||
Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
|
||||
RadioAccessTechnology _op_act;
|
||||
AuthenticationType _authentication_type;
|
||||
nsapi_connection_status_t _connect_status;
|
||||
bool _new_context_set;
|
||||
bool _is_context_active;
|
||||
|
||||
registration_params_t _reg_params;
|
||||
|
||||
mbed::Callback<void()> _urc_funcs[C_MAX];
|
||||
};
|
||||
|
||||
|
|
|
@ -294,11 +294,8 @@ char *AT_CellularSMS::create_pdu(const char *phone_number, const char *message,
|
|||
// message 7-bit padded and it will be converted to hex so it will take twice as much space
|
||||
totalPDULength += (message_length - (message_length / 8)) * 2;
|
||||
|
||||
char *pdu = (char *)calloc(totalPDULength, sizeof(char));
|
||||
if (!pdu) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *pdu = new char[totalPDULength];
|
||||
memset(pdu, 0, totalPDULength);
|
||||
int x = 0;
|
||||
// See more how to create PDU from 3GPP specification 23040
|
||||
// first two define that we use service center number which is set with +CSCA
|
||||
|
@ -386,7 +383,7 @@ char *AT_CellularSMS::create_pdu(const char *phone_number, const char *message,
|
|||
// we might need to send zero length sms
|
||||
if (message_length) {
|
||||
if (pack_7_bit_gsm_and_hex(message, message_length, pdu + x, paddingBits) == 0) {
|
||||
free(pdu);
|
||||
delete [] pdu;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -501,7 +498,7 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const c
|
|||
_at.cmd_start(ESC);
|
||||
_at.cmd_stop();
|
||||
_at.unlock();
|
||||
free(pdu_str);
|
||||
delete [] pdu_str;
|
||||
return msg_write_len;
|
||||
}
|
||||
|
||||
|
@ -511,7 +508,7 @@ nsapi_size_or_error_t AT_CellularSMS::send_sms(const char *phone_number, const c
|
|||
_at.resp_start("+CMGS:");
|
||||
_at.resp_stop();
|
||||
}
|
||||
free(pdu_str);
|
||||
delete [] pdu_str;
|
||||
remaining_len -= concatenated_sms_length;
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
return _at.unlock_return_error();
|
||||
|
@ -667,7 +664,8 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t *sms, char *buf, char
|
|||
msg_len = _at.read_int();
|
||||
if (msg_len > 0) {
|
||||
pduSize = msg_len * 2 + 20; // *2 as it's hex encoded and +20 as service center number is not included in size given by CMGR
|
||||
pdu = (char *)calloc(pduSize, sizeof(char));
|
||||
pdu = new char[pduSize];
|
||||
memset(pdu, 0, pduSize);
|
||||
if (!pdu) {
|
||||
_at.resp_stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
|
@ -678,12 +676,12 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms(sms_info_t *sms, char *buf, char
|
|||
if (msg_len >= 0) { // we need to allow zero length messages
|
||||
index += msg_len;
|
||||
} else {
|
||||
free(pdu);
|
||||
delete [] pdu;
|
||||
_at.resp_stop();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
free(pdu);
|
||||
delete [] pdu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1062,7 +1060,8 @@ nsapi_error_t AT_CellularSMS::list_messages()
|
|||
_at.skip_param(2); // <stat>,[<alpha>]
|
||||
length = _at.read_int();
|
||||
length = length * 2 + 20; // *2 as it's hex encoded and +20 as service center number is not included in size given by CMGL
|
||||
pdu = (char *)calloc(length, sizeof(char));
|
||||
pdu = new char[length];
|
||||
memset(pdu, 0, length);
|
||||
if (!pdu) {
|
||||
delete info;
|
||||
_at.resp_stop();
|
||||
|
@ -1086,7 +1085,7 @@ nsapi_error_t AT_CellularSMS::list_messages()
|
|||
delete info;
|
||||
info = NULL;
|
||||
}
|
||||
free(pdu);
|
||||
delete [] pdu;
|
||||
pdu = NULL;
|
||||
}
|
||||
|
||||
|
@ -1194,7 +1193,7 @@ uint16_t AT_CellularSMS::pack_7_bit_gsm_and_hex(const char *str, uint16_t len, c
|
|||
return 0;
|
||||
}
|
||||
// convert to 7bit gsm first
|
||||
char *gsm_str = (char *)malloc(len);
|
||||
char *gsm_str = new char[len];
|
||||
if (!gsm_str) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1236,7 +1235,7 @@ uint16_t AT_CellularSMS::pack_7_bit_gsm_and_hex(const char *str, uint16_t len, c
|
|||
i++;
|
||||
}
|
||||
|
||||
free(gsm_str);
|
||||
delete [] gsm_str;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -21,17 +21,34 @@
|
|||
#include <stdint.h>
|
||||
#include "nsapi_types.h"
|
||||
|
||||
struct cell_callback_data_t {
|
||||
nsapi_error_t error; /* possible error code */
|
||||
int status_data; /* cellular_event_status related enum or other info in int format. Check cellular_event_status comments.*/
|
||||
bool final_try; /* This flag is true if state machine is used and this was the last try. State machine does goes to idle. */
|
||||
|
||||
cell_callback_data_t()
|
||||
{
|
||||
error = NSAPI_ERROR_OK;
|
||||
status_data = -1;
|
||||
final_try = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Cellular specific event changes.
|
||||
* Connect and disconnect are handled via NSAPI_EVENT_CONNECTION_STATUS_CHANGE
|
||||
* All enum types have struct *cell_callback_data_t in intptr_t with possible error code in cell_callback_data_t.error.
|
||||
* Most enum values also have some enum in cell_callback_data_t.enumeration, check comments below.
|
||||
*/
|
||||
typedef enum cellular_event_status {
|
||||
CellularDeviceReady = NSAPI_EVENT_CELLULAR_STATUS_BASE, /* Modem is powered and ready to receive commands. No additional info in callback intptr_t. */
|
||||
CellularSIMStatusChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 1, /* SIM state changed, call SIM state. enum SimState as additional info callback intptr_t. See enum SimState in ../API/CellularSIM.h */
|
||||
CellularRegistrationStatusChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 2, /* Registering status changed. enum RegistrationStatus as additional info callback intptr_t. See enum RegistrationStatus in ../API/CellularNetwork.h */
|
||||
CellularRegistrationTypeChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 3, /* Registration type changed. enum RegistrationType as additional info callback intptr_t. See enum RegistrationType in ../API/CellularNetwork.h */
|
||||
CellularCellIDChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 4, /* Network Cell ID have changed. int cellid as additional info callback intptr_t. */
|
||||
CellularRadioAccessTechnologyChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 5, /* Network roaming status have changed. enum RadioAccessTechnology as additional info callback intptr_t. See enum RadioAccessTechnology in ../API/CellularNetwork.h */
|
||||
CellularDeviceReady = NSAPI_EVENT_CELLULAR_STATUS_BASE, /* Modem is powered and ready to receive commands. cell_callback_data_t.status_data will be -1 */
|
||||
CellularSIMStatusChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 1, /* SIM state changed. cell_callback_data_t.status_data will be enum SimState. See enum SimState in ../API/CellularSIM.h*/
|
||||
CellularRegistrationStatusChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 2, /* Registering status changed. cell_callback_data_t.status_data will be enum RegistrationStatus. See enum RegistrationStatus in ../API/CellularNetwork.h*/
|
||||
CellularRegistrationTypeChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 3, /* Registration type changed. cell_callback_data_t.status_data will be enum RegistrationType. See enum RegistrationType in ../API/CellularNetwork.h*/
|
||||
CellularCellIDChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 4, /* Network Cell ID have changed. cell_callback_data_t.status_data will be int cellid*/
|
||||
CellularRadioAccessTechnologyChanged = NSAPI_EVENT_CELLULAR_STATUS_BASE + 5, /* Network roaming status have changed. cell_callback_data_t.status_data will be enum RadioAccessTechnology See enum RadioAccessTechnology in ../API/CellularNetwork.h*/
|
||||
CellularAttachNetwork = NSAPI_EVENT_CELLULAR_STATUS_BASE + 6, /* cell_callback_data_t.status_data will be enum AttachStatus. See enum AttachStatus in ../API/CellularNetwork.h */
|
||||
CellularActivatePDPContext = NSAPI_EVENT_CELLULAR_STATUS_BASE + 7, /* NSAPI_ERROR_OK in cell_callback_data_t.error on successfully PDP Context activated or negative error */
|
||||
} cellular_connection_status_t;
|
||||
|
||||
#endif // CELLULAR_COMMON_
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 "CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
#ifdef CELLULAR_DEVICE
|
||||
MBED_WEAK CellularContext *CellularContext::get_default_instance()
|
||||
{
|
||||
// Uses default APN, uname, password from mbed_app.json
|
||||
static CellularDevice *dev = CellularDevice::get_default_instance();
|
||||
if (!dev) {
|
||||
return NULL;
|
||||
}
|
||||
static CellularContext *context = dev->create_context();
|
||||
return context;
|
||||
}
|
||||
#else
|
||||
MBED_WEAK CellularContext *CellularContext::get_default_instance()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif // CELLULAR_DEVICE
|
||||
|
||||
} // namespace mbed
|
|
@ -16,8 +16,13 @@
|
|||
*/
|
||||
|
||||
#include "CellularDevice.h"
|
||||
#include "EventQueue.h"
|
||||
#include "CellularContext.h"
|
||||
#include "CellularSIM.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "CellularLog.h"
|
||||
#include "CellularTargets.h"
|
||||
#include "EventQueue.h"
|
||||
#include "UARTSerial.h"
|
||||
|
||||
#ifdef CELLULAR_DEVICE
|
||||
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
|
||||
|
@ -28,8 +33,14 @@ namespace mbed {
|
|||
#ifdef CELLULAR_DEVICE
|
||||
MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
|
||||
{
|
||||
static events::EventQueue event_queue(4 * EVENTS_EVENT_SIZE);
|
||||
static CELLULAR_DEVICE device(event_queue);
|
||||
static UARTSerial serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
#if DEVICE_SERIAL_FC
|
||||
if (MDMRTS != NC && MDMCTS != NC) {
|
||||
tr_info("_USING flow control, MDMRTS: %d MDMCTS: %d", MDMRTS, MDMCTS);
|
||||
serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
}
|
||||
#endif
|
||||
static CELLULAR_DEVICE device(&serial);
|
||||
return &device;
|
||||
}
|
||||
#else
|
||||
|
@ -39,14 +50,151 @@ MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
|
|||
}
|
||||
#endif // CELLULAR_DEVICE
|
||||
|
||||
CellularDevice::CellularDevice() : _network_ref_count(0), _sms_ref_count(0), _power_ref_count(0), _sim_ref_count(0),
|
||||
_info_ref_count(0)
|
||||
CellularDevice::CellularDevice(FileHandle *fh) : _network_ref_count(0), _sms_ref_count(0), _power_ref_count(0), _sim_ref_count(0),
|
||||
_info_ref_count(0), _fh(fh), _queue(5 * EVENTS_EVENT_SIZE), _state_machine(0), _nw(0)
|
||||
{
|
||||
set_sim_pin(NULL);
|
||||
set_plmn(NULL);
|
||||
}
|
||||
|
||||
CellularDevice::~CellularDevice()
|
||||
{
|
||||
}
|
||||
|
||||
events::EventQueue *CellularDevice::get_queue() const
|
||||
void CellularDevice::stop()
|
||||
{
|
||||
MBED_ASSERT(_state_machine);
|
||||
_state_machine->stop();
|
||||
}
|
||||
|
||||
events::EventQueue *CellularDevice::get_queue()
|
||||
{
|
||||
return &_queue;
|
||||
}
|
||||
|
||||
CellularContext *CellularDevice::get_context_list() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CellularDevice::set_sim_pin(const char *sim_pin)
|
||||
{
|
||||
if (sim_pin) {
|
||||
strncpy(_sim_pin, sim_pin, sizeof(_sim_pin));
|
||||
_sim_pin[sizeof(_sim_pin) - 1] = '\0';
|
||||
} else {
|
||||
memset(_sim_pin, 0, sizeof(_sim_pin));
|
||||
}
|
||||
}
|
||||
|
||||
void CellularDevice::set_plmn(const char *plmn)
|
||||
{
|
||||
if (plmn) {
|
||||
strncpy(_plmn, plmn, sizeof(_plmn));
|
||||
_plmn[sizeof(_plmn) - 1] = '\0';
|
||||
} else {
|
||||
memset(_plmn, 0, sizeof(_plmn));
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::set_device_ready()
|
||||
{
|
||||
return start_state_machine(CellularStateMachine::STATE_DEVICE_READY);
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::set_sim_ready()
|
||||
{
|
||||
return start_state_machine(CellularStateMachine::STATE_SIM_PIN);
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::register_to_network()
|
||||
{
|
||||
return start_state_machine(CellularStateMachine::STATE_REGISTERING_NETWORK);
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::attach_to_network()
|
||||
{
|
||||
return start_state_machine(CellularStateMachine::STATE_ATTACHING_NETWORK);
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::create_state_machine()
|
||||
{
|
||||
if (!_state_machine) {
|
||||
_state_machine = new CellularStateMachine(*this, *get_queue());
|
||||
_state_machine->set_cellular_callback(callback(this, &CellularDevice::cellular_callback));
|
||||
return _state_machine->start_dispatch();
|
||||
}
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularDevice::start_state_machine(CellularStateMachine::CellularState target_state)
|
||||
{
|
||||
_mutex.lock();
|
||||
nsapi_error_t err = create_state_machine();
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
CellularStateMachine::CellularState current_state, targeted_state;
|
||||
|
||||
bool is_running = _state_machine->get_current_status(current_state, targeted_state);
|
||||
|
||||
if (current_state >= target_state) { // can stm be in this state but failed?
|
||||
_mutex.unlock();
|
||||
return NSAPI_ERROR_ALREADY;
|
||||
} else if (is_running && targeted_state >= target_state) {
|
||||
_mutex.unlock();
|
||||
return NSAPI_ERROR_IN_PROGRESS;
|
||||
}
|
||||
|
||||
err = _state_machine->run_to_state(target_state);
|
||||
_mutex.unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
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);
|
||||
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
|
||||
_state_machine->cellular_event_changed(ev, ptr);
|
||||
}
|
||||
|
||||
if (cell_ev == CellularDeviceReady && ptr_data->error == NSAPI_ERROR_OK) {
|
||||
// Here we can create mux and give new filehandles as mux reserves the one what was in use.
|
||||
// if mux we would need to set new filehandle:_state_machine->set_filehandle( get fh from mux);
|
||||
_nw = open_network(_fh);
|
||||
// Attach to network so we can get update status from the network
|
||||
_nw->attach(callback(this, &CellularDevice::cellular_callback));
|
||||
if (strlen(_plmn)) {
|
||||
_state_machine->set_plmn(_plmn);
|
||||
}
|
||||
} else if (cell_ev == CellularSIMStatusChanged && ptr_data->error == NSAPI_ERROR_OK &&
|
||||
ptr_data->status_data == CellularSIM::SimStatePinNeeded) {
|
||||
if (strlen(_sim_pin)) {
|
||||
_state_machine->set_sim_pin(_sim_pin);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tr_debug("Device: network_callback called with event: %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) {
|
||||
_state_machine->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// broadcast network and cellular changes to state machine and CellularContext.
|
||||
CellularContext *curr = get_context_list();
|
||||
while (curr) {
|
||||
curr->cellular_callback(ev, ptr);
|
||||
curr = curr->_next;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -15,17 +15,17 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "CellularConnectionFSM.h"
|
||||
|
||||
#ifdef CELLULAR_DEVICE
|
||||
#include "CellularStateMachine.h"
|
||||
#include "CellularDevice.h"
|
||||
#include "CellularPower.h"
|
||||
#include "CellularSIM.h"
|
||||
#include "CellularLog.h"
|
||||
#include "Thread.h"
|
||||
#include "UARTSerial.h"
|
||||
|
||||
#ifndef MBED_TRACE_MAX_LEVEL
|
||||
#define MBED_TRACE_MAX_LEVEL TRACE_LEVEL_INFO
|
||||
#endif
|
||||
#include "CellularLog.h"
|
||||
#include "CellularCommon.h"
|
||||
#include "CellularDevice.h"
|
||||
#include "CellularUtil.h"
|
||||
|
||||
// timeout to wait for AT responses
|
||||
#define TIMEOUT_POWER_ON (1*1000)
|
||||
|
@ -39,14 +39,17 @@
|
|||
|
||||
#define RETRY_COUNT_DEFAULT 3
|
||||
|
||||
const int STM_STOPPED = -99;
|
||||
|
||||
namespace mbed {
|
||||
|
||||
CellularConnectionFSM::CellularConnectionFSM() :
|
||||
_serial(0), _state(STATE_INIT), _next_state(_state), _status_callback(0), _event_status_cb(0), _network(0), _power(0), _sim(0),
|
||||
_queue(8 * EVENTS_EVENT_SIZE), _queue_thread(0), _cellularDevice(0), _retry_count(0), _event_timeout(-1),
|
||||
_at_queue(0), _event_id(0), _plmn(0), _command_success(false), _plmn_network_found(false)
|
||||
CellularStateMachine::CellularStateMachine(CellularDevice &device, events::EventQueue &queue) :
|
||||
_cellularDevice(device), _state(STATE_INIT), _next_state(_state), _target_state(_state),
|
||||
_event_status_cb(0), _network(0), _power(0), _sim(0), _queue(queue), _queue_thread(0), _sim_pin(0),
|
||||
_retry_count(0), _event_timeout(-1), _event_id(-1), _plmn(0), _command_success(false),
|
||||
_plmn_network_found(false), _is_retry(false), _cb_data(), _current_event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE),
|
||||
_active_context(false)
|
||||
{
|
||||
memset(_sim_pin, 0, sizeof(_sim_pin));
|
||||
#if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0
|
||||
_start_time = 0;
|
||||
#else
|
||||
|
@ -65,97 +68,59 @@ CellularConnectionFSM::CellularConnectionFSM() :
|
|||
_retry_timeout_array[7] = 128; // if around two minutes was not enough then let's wait much longer
|
||||
_retry_timeout_array[8] = 600;
|
||||
_retry_timeout_array[9] = TIMEOUT_NETWORK_MAX;
|
||||
_retry_array_length = MAX_RETRY_ARRAY_SIZE;
|
||||
_retry_array_length = RETRY_ARRAY_SIZE;
|
||||
}
|
||||
|
||||
CellularConnectionFSM::~CellularConnectionFSM()
|
||||
CellularStateMachine::~CellularStateMachine()
|
||||
{
|
||||
stop();
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::stop()
|
||||
void CellularStateMachine::reset()
|
||||
{
|
||||
_queue.cancel(_event_id);
|
||||
_queue.break_dispatch();
|
||||
_state = STATE_INIT;
|
||||
_event_timeout = -1;
|
||||
_event_id = -1;
|
||||
_plmn_network_found = false;
|
||||
_is_retry = false;
|
||||
_active_context = false;
|
||||
enter_to_state(STATE_INIT);
|
||||
}
|
||||
|
||||
void CellularStateMachine::stop()
|
||||
{
|
||||
if (_queue_thread) {
|
||||
_queue.break_dispatch();
|
||||
_queue_thread->terminate();
|
||||
delete _queue_thread;
|
||||
_queue_thread = NULL;
|
||||
}
|
||||
|
||||
if (_at_queue) {
|
||||
_at_queue->chain(NULL);
|
||||
_at_queue = NULL;
|
||||
}
|
||||
|
||||
reset();
|
||||
_event_id = STM_STOPPED;
|
||||
if (_power) {
|
||||
_cellularDevice->close_power();
|
||||
_cellularDevice.close_power();
|
||||
_power = NULL;
|
||||
}
|
||||
|
||||
if (_network) {
|
||||
_cellularDevice->close_network();
|
||||
_network = NULL;
|
||||
}
|
||||
|
||||
if (_sim) {
|
||||
_cellularDevice->close_sim();
|
||||
_cellularDevice.close_sim();
|
||||
_sim = NULL;
|
||||
}
|
||||
|
||||
_state = STATE_INIT;
|
||||
_next_state = _state;
|
||||
if (_network) {
|
||||
_cellularDevice.close_network();
|
||||
_network = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t CellularConnectionFSM::init()
|
||||
bool CellularStateMachine::power_on()
|
||||
{
|
||||
tr_info("CELLULAR_DEVICE: %s", CELLULAR_STRINGIFY(CELLULAR_DEVICE));
|
||||
_cellularDevice = CellularDevice::get_default_instance();
|
||||
if (!_cellularDevice) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
_power = _cellularDevice->open_power(_serial);
|
||||
if (!_power) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
_network = _cellularDevice->open_network(_serial);
|
||||
if (!_network) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
_sim = _cellularDevice->open_sim(_serial);
|
||||
if (!_sim) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
_at_queue = _cellularDevice->get_queue();
|
||||
if (!_at_queue) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
_at_queue->chain(&_queue);
|
||||
|
||||
_retry_count = 0;
|
||||
_state = STATE_INIT;
|
||||
_next_state = STATE_INIT;
|
||||
|
||||
return _network->init();
|
||||
}
|
||||
|
||||
bool CellularConnectionFSM::power_on()
|
||||
{
|
||||
nsapi_error_t err = _power->on();
|
||||
if (err != NSAPI_ERROR_OK && err != NSAPI_ERROR_UNSUPPORTED) {
|
||||
_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.");
|
||||
err = _power->off();
|
||||
if (err != NSAPI_ERROR_OK && err != NSAPI_ERROR_UNSUPPORTED) {
|
||||
_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!");
|
||||
}
|
||||
return false;
|
||||
|
@ -163,46 +128,49 @@ bool CellularConnectionFSM::power_on()
|
|||
return true;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::set_sim_pin(const char *sim_pin)
|
||||
void CellularStateMachine::set_sim_pin(const char *sim_pin)
|
||||
{
|
||||
strncpy(_sim_pin, sim_pin, sizeof(_sim_pin));
|
||||
_sim_pin[sizeof(_sim_pin) - 1] = '\0';
|
||||
_sim_pin = sim_pin;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::set_plmn(const char *plmn)
|
||||
void CellularStateMachine::set_plmn(const char *plmn)
|
||||
{
|
||||
_plmn = plmn;
|
||||
}
|
||||
|
||||
bool CellularConnectionFSM::open_sim()
|
||||
bool CellularStateMachine::open_sim()
|
||||
{
|
||||
if (!_sim) {
|
||||
// can only fail with allocation with new and then it's critical error
|
||||
_sim = _cellularDevice.open_sim();
|
||||
}
|
||||
|
||||
CellularSIM::SimState state = CellularSIM::SimStateUnknown;
|
||||
// wait until SIM is readable
|
||||
// here you could add wait(secs) if you know start delay of your SIM
|
||||
if (_sim->get_sim_state(state) != NSAPI_ERROR_OK) {
|
||||
_cb_data.error = _sim->get_sim_state(state);
|
||||
if (_cb_data.error != NSAPI_ERROR_OK) {
|
||||
tr_info("Waiting for SIM (err while reading)...");
|
||||
if (_event_status_cb) {
|
||||
_event_status_cb((nsapi_event_t)CellularSIMStatusChanged, state);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// report current state so callback can set sim pin if needed
|
||||
if (_event_status_cb) {
|
||||
_event_status_cb((nsapi_event_t)CellularSIMStatusChanged, state);
|
||||
_cb_data.status_data = state;
|
||||
_event_status_cb((nsapi_event_t)CellularSIMStatusChanged, (intptr_t)&_cb_data);
|
||||
}
|
||||
|
||||
if (state == CellularSIM::SimStatePinNeeded) {
|
||||
if (strlen(_sim_pin)) {
|
||||
tr_info("SIM pin required, entering pin");
|
||||
nsapi_error_t err = _sim->set_pin(_sim_pin);
|
||||
if (err) {
|
||||
tr_error("SIM pin set failed with: %d, bailing out...", err);
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
// No sim pin provided even it's needed, stop state machine
|
||||
tr_error("PIN required but No SIM pin provided.");
|
||||
_retry_count = MAX_RETRY_ARRAY_SIZE;
|
||||
_retry_count = RETRY_ARRAY_SIZE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +178,7 @@ bool CellularConnectionFSM::open_sim()
|
|||
return state == CellularSIM::SimStateReady;
|
||||
}
|
||||
|
||||
bool CellularConnectionFSM::is_registered()
|
||||
bool CellularStateMachine::is_registered()
|
||||
{
|
||||
CellularNetwork::RegistrationStatus status;
|
||||
bool is_registered = false;
|
||||
|
@ -224,18 +192,20 @@ bool CellularConnectionFSM::is_registered()
|
|||
}
|
||||
}
|
||||
|
||||
return is_registered;
|
||||
_cb_data.status_data = status;
|
||||
return is_registered || _active_context;
|
||||
}
|
||||
|
||||
bool CellularConnectionFSM::get_network_registration(CellularNetwork::RegistrationType type,
|
||||
CellularNetwork::RegistrationStatus &status, bool &is_registered)
|
||||
bool CellularStateMachine::get_network_registration(CellularNetwork::RegistrationType type,
|
||||
CellularNetwork::RegistrationStatus &status, bool &is_registered)
|
||||
{
|
||||
is_registered = false;
|
||||
bool is_roaming = false;
|
||||
CellularNetwork::registration_params_t reg_params;
|
||||
nsapi_error_t err = _network->get_registration_params(type, reg_params);
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
if (err != NSAPI_ERROR_UNSUPPORTED) {
|
||||
_cb_data.error = _network->get_registration_params(type, reg_params);
|
||||
|
||||
if (_cb_data.error != NSAPI_ERROR_OK) {
|
||||
if (_cb_data.error != NSAPI_ERROR_UNSUPPORTED) {
|
||||
tr_warn("Get network registration failed (type %d)!", type);
|
||||
}
|
||||
return false;
|
||||
|
@ -243,19 +213,19 @@ bool CellularConnectionFSM::get_network_registration(CellularNetwork::Registrati
|
|||
status = reg_params._status;
|
||||
switch (status) {
|
||||
case CellularNetwork::RegisteredRoaming:
|
||||
is_roaming = true;
|
||||
is_roaming = true;// @suppress("No break at end of case")
|
||||
// fall-through
|
||||
case CellularNetwork::RegisteredHomeNetwork:
|
||||
is_registered = true;
|
||||
break;
|
||||
case CellularNetwork::RegisteredSMSOnlyRoaming:
|
||||
is_roaming = true;
|
||||
is_roaming = true;// @suppress("No break at end of case")
|
||||
// fall-through
|
||||
case CellularNetwork::RegisteredSMSOnlyHome:
|
||||
tr_warn("SMS only network registration!");
|
||||
break;
|
||||
case CellularNetwork::RegisteredCSFBNotPreferredRoaming:
|
||||
is_roaming = true;
|
||||
is_roaming = true; // @suppress("No break at end of case")
|
||||
// fall-through
|
||||
case CellularNetwork::RegisteredCSFBNotPreferredHome:
|
||||
tr_warn("Not preferred network registration!");
|
||||
|
@ -278,31 +248,36 @@ bool CellularConnectionFSM::get_network_registration(CellularNetwork::Registrati
|
|||
return true;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::report_failure(const char *msg)
|
||||
void CellularStateMachine::report_failure(const char *msg)
|
||||
{
|
||||
tr_error("Cellular network failed: %s", msg);
|
||||
if (_status_callback) {
|
||||
_status_callback(_state, _next_state);
|
||||
tr_error("Cellular stm failed with: %s", msg);
|
||||
|
||||
_event_id = -1;
|
||||
if (_event_status_cb) {
|
||||
_cb_data.final_try = true;
|
||||
_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));
|
||||
}
|
||||
|
||||
const char *CellularConnectionFSM::get_state_string(CellularState state)
|
||||
const char *CellularStateMachine::get_state_string(CellularState state) const
|
||||
{
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
static const char *strings[] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Manual registering", "Attaching network", "Activating PDP Context", "Connecting network", "Connected"};
|
||||
static const char *strings[STATE_MAX_FSM_STATE] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Manual registering", "Attaching network"};
|
||||
return strings[state];
|
||||
#else
|
||||
return NULL;
|
||||
#endif // #if MBED_CONF_MBED_TRACE_ENABLE
|
||||
}
|
||||
|
||||
bool CellularConnectionFSM::is_registered_to_plmn()
|
||||
bool CellularStateMachine::is_registered_to_plmn()
|
||||
{
|
||||
int format;
|
||||
CellularNetwork::operator_t op;
|
||||
|
||||
nsapi_error_t err = _network->get_operator_params(format, op);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
_cb_data.error = _network->get_operator_params(format, op);
|
||||
if (_cb_data.error == NSAPI_ERROR_OK) {
|
||||
if (format == 2) {
|
||||
// great, numeric format we can do comparison for that
|
||||
if (strcmp(op.op_num, _plmn) == 0) {
|
||||
|
@ -313,8 +288,8 @@ bool CellularConnectionFSM::is_registered_to_plmn()
|
|||
|
||||
// format was alpha, get operator names to do the comparing
|
||||
CellularNetwork::operator_names_list names_list;
|
||||
nsapi_error_t err = _network->get_operator_names(names_list);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
_cb_data.error = _network->get_operator_names(names_list);
|
||||
if (_cb_data.error == NSAPI_ERROR_OK) {
|
||||
CellularNetwork::operator_names_t *op_names = names_list.get_head();
|
||||
bool found_match = false;
|
||||
while (op_names) {
|
||||
|
@ -344,64 +319,38 @@ bool CellularConnectionFSM::is_registered_to_plmn()
|
|||
return false;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularConnectionFSM::continue_from_state(CellularState state)
|
||||
{
|
||||
tr_info("Continue state from %s to %s", get_state_string((CellularConnectionFSM::CellularState)_state),
|
||||
get_state_string((CellularConnectionFSM::CellularState)state));
|
||||
_state = state;
|
||||
_next_state = state;
|
||||
_retry_count = 0;
|
||||
if (!_queue.call_in(0, callback(this, &CellularConnectionFSM::event))) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularConnectionFSM::continue_to_state(CellularState state)
|
||||
{
|
||||
MBED_ASSERT(_cellularDevice);
|
||||
_retry_count = 0;
|
||||
if (state < _state) {
|
||||
_state = state;
|
||||
} else {
|
||||
// update next state so that we don't continue from previous state
|
||||
_state = _next_state;
|
||||
}
|
||||
if (!_queue.call_in(0, callback(this, &CellularConnectionFSM::event))) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::enter_to_state(CellularState state)
|
||||
void CellularStateMachine::enter_to_state(CellularState state)
|
||||
{
|
||||
_next_state = state;
|
||||
_retry_count = 0;
|
||||
_command_success = false;
|
||||
_cb_data.error = NSAPI_ERROR_OK;
|
||||
_cb_data.status_data = -1;
|
||||
_cb_data.final_try = false;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::retry_state_or_fail()
|
||||
void CellularStateMachine::retry_state_or_fail()
|
||||
{
|
||||
if (++_retry_count < MAX_RETRY_ARRAY_SIZE) {
|
||||
tr_debug("Retry State %s, retry %d/%d", get_state_string(_state), _retry_count, MAX_RETRY_ARRAY_SIZE);
|
||||
if (++_retry_count < RETRY_ARRAY_SIZE) {
|
||||
tr_debug("Retry State %s, retry %d/%d", get_state_string(_state), _retry_count, RETRY_ARRAY_SIZE);
|
||||
_event_timeout = _retry_timeout_array[_retry_count];
|
||||
_is_retry = true;
|
||||
} else {
|
||||
report_failure(get_state_string(_state));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::state_init()
|
||||
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);
|
||||
_cellularDevice.set_timeout(TIMEOUT_POWER_ON);
|
||||
tr_info("Cellular state init (timeout %d ms)", TIMEOUT_POWER_ON);
|
||||
nsapi_error_t err = _power->is_device_ready();
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
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);
|
||||
enter_to_state(STATE_POWER_ON);
|
||||
|
@ -411,9 +360,9 @@ void CellularConnectionFSM::state_init()
|
|||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::state_power_on()
|
||||
void CellularStateMachine::state_power_on()
|
||||
{
|
||||
_cellularDevice->set_timeout(TIMEOUT_POWER_ON);
|
||||
_cellularDevice.set_timeout(TIMEOUT_POWER_ON);
|
||||
tr_info("Cellular power ON (timeout %d ms)", TIMEOUT_POWER_ON);
|
||||
if (power_on()) {
|
||||
enter_to_state(STATE_DEVICE_READY);
|
||||
|
@ -423,44 +372,52 @@ void CellularConnectionFSM::state_power_on()
|
|||
}
|
||||
}
|
||||
|
||||
bool CellularConnectionFSM::device_ready()
|
||||
bool CellularStateMachine::device_ready()
|
||||
{
|
||||
if (_cellularDevice->init_module(_serial) != NSAPI_ERROR_OK) {
|
||||
tr_info("Cellular device ready");
|
||||
if (_cellularDevice.init_module() != NSAPI_ERROR_OK) {
|
||||
return false;
|
||||
}
|
||||
tr_info("Cellular device ready");
|
||||
if (_event_status_cb) {
|
||||
_event_status_cb((nsapi_event_t)CellularDeviceReady, 0);
|
||||
_event_status_cb((nsapi_event_t)CellularDeviceReady, (intptr_t)&_cb_data);
|
||||
}
|
||||
_power->remove_device_ready_urc_cb(mbed::callback(this, &CellularConnectionFSM::ready_urc_cb));
|
||||
_cellularDevice->close_power();
|
||||
_power->remove_device_ready_urc_cb(mbed::callback(this, &CellularStateMachine::ready_urc_cb));
|
||||
_cellularDevice.close_power();
|
||||
_power = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::state_device_ready()
|
||||
void CellularStateMachine::state_device_ready()
|
||||
{
|
||||
_cellularDevice->set_timeout(TIMEOUT_POWER_ON);
|
||||
if (_power->set_at_mode() == NSAPI_ERROR_OK) {
|
||||
_cellularDevice.set_timeout(TIMEOUT_POWER_ON);
|
||||
_cb_data.error = _power->set_at_mode();
|
||||
if (_cb_data.error == NSAPI_ERROR_OK) {
|
||||
if (device_ready()) {
|
||||
enter_to_state(STATE_SIM_PIN);
|
||||
} else {
|
||||
retry_state_or_fail();
|
||||
}
|
||||
} else {
|
||||
if (_retry_count == 0) {
|
||||
(void)_power->set_device_ready_urc_cb(mbed::callback(this, &CellularConnectionFSM::ready_urc_cb));
|
||||
_power->set_device_ready_urc_cb(mbed::callback(this, &CellularStateMachine::ready_urc_cb));
|
||||
}
|
||||
retry_state_or_fail();
|
||||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::state_sim_pin()
|
||||
void CellularStateMachine::state_sim_pin()
|
||||
{
|
||||
_cellularDevice->set_timeout(TIMEOUT_SIM_PIN);
|
||||
_cellularDevice.set_timeout(TIMEOUT_SIM_PIN);
|
||||
tr_info("Sim state (timeout %d ms)", TIMEOUT_SIM_PIN);
|
||||
if (open_sim()) {
|
||||
if (!_network) {
|
||||
_network = _cellularDevice.open_network();
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
|
||||
if (!_network->set_registration_urc((CellularNetwork::RegistrationType)type, true)) {
|
||||
_cb_data.error = _network->set_registration_urc((CellularNetwork::RegistrationType)type, true);
|
||||
if (!_cb_data.error) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
@ -469,6 +426,9 @@ void CellularConnectionFSM::state_sim_pin()
|
|||
retry_state_or_fail();
|
||||
return;
|
||||
}
|
||||
|
||||
_active_context = false;
|
||||
_active_context = _network->is_active_context(); // check if context was already activated
|
||||
if (_plmn) {
|
||||
enter_to_state(STATE_MANUAL_REGISTERING_NETWORK);
|
||||
} else {
|
||||
|
@ -479,134 +439,186 @@ void CellularConnectionFSM::state_sim_pin()
|
|||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::state_registering()
|
||||
void CellularStateMachine::state_registering()
|
||||
{
|
||||
_cellularDevice->set_timeout(TIMEOUT_NETWORK);
|
||||
_cellularDevice.set_timeout(TIMEOUT_NETWORK);
|
||||
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);
|
||||
// we are already registered, go to attach
|
||||
enter_to_state(STATE_ATTACHING_NETWORK);
|
||||
} else {
|
||||
_cellularDevice->set_timeout(TIMEOUT_REGISTRATION);
|
||||
_cellularDevice.set_timeout(TIMEOUT_REGISTRATION);
|
||||
if (!_command_success) {
|
||||
_command_success = (_network->set_registration() == NSAPI_ERROR_OK);
|
||||
_cb_data.error = _network->set_registration();
|
||||
_command_success = (_cb_data.error == NSAPI_ERROR_OK);
|
||||
}
|
||||
retry_state_or_fail();
|
||||
}
|
||||
}
|
||||
|
||||
// only used when _plmn is set
|
||||
void CellularConnectionFSM::state_manual_registering_network()
|
||||
void CellularStateMachine::state_manual_registering_network()
|
||||
{
|
||||
_cellularDevice->set_timeout(TIMEOUT_REGISTRATION);
|
||||
_cellularDevice.set_timeout(TIMEOUT_REGISTRATION);
|
||||
tr_info("state_manual_registering_network");
|
||||
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);
|
||||
_plmn_network_found = true;
|
||||
enter_to_state(STATE_ATTACHING_NETWORK);
|
||||
} else {
|
||||
if (!_command_success) {
|
||||
_command_success = (_network->set_registration(_plmn) == NSAPI_ERROR_OK);
|
||||
_cb_data.error = _network->set_registration(_plmn);
|
||||
_command_success = (_cb_data.error == NSAPI_ERROR_OK);
|
||||
}
|
||||
retry_state_or_fail();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::state_attaching()
|
||||
void CellularStateMachine::state_attaching()
|
||||
{
|
||||
_cellularDevice->set_timeout(TIMEOUT_CONNECT);
|
||||
if (_network->set_attach() == NSAPI_ERROR_OK) {
|
||||
_cellularDevice->close_sim();
|
||||
_cellularDevice.set_timeout(TIMEOUT_CONNECT);
|
||||
_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;
|
||||
enter_to_state(STATE_ACTIVATING_PDP_CONTEXT);
|
||||
if (_event_status_cb) {
|
||||
_cb_data.status_data = CellularNetwork::Attached;
|
||||
_event_status_cb(_current_event, (intptr_t)&_cb_data);
|
||||
}
|
||||
} else {
|
||||
retry_state_or_fail();
|
||||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::state_activating_pdp_context()
|
||||
void CellularStateMachine::continue_from_state(CellularState state)
|
||||
{
|
||||
_cellularDevice->set_timeout(TIMEOUT_CONNECT);
|
||||
tr_info("Activate PDP Context (timeout %d ms)", TIMEOUT_CONNECT);
|
||||
if (_network->activate_context() == NSAPI_ERROR_OK) {
|
||||
// when using modems stack connect is synchronous
|
||||
_next_state = STATE_CONNECTING_NETWORK;
|
||||
_mutex.lock();
|
||||
tr_info("Continue state from %s to %s", get_state_string((CellularStateMachine::CellularState)_state),
|
||||
get_state_string((CellularStateMachine::CellularState)state));
|
||||
_state = state;
|
||||
enter_to_state(state);
|
||||
_event_id = _queue.call_in(0, this, &CellularStateMachine::event);
|
||||
if (!_event_id) {
|
||||
_event_id = -1;
|
||||
_cb_data.error = NSAPI_ERROR_NO_MEMORY;
|
||||
report_failure("Failed to call queue.");
|
||||
stop();
|
||||
}
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
nsapi_error_t CellularStateMachine::run_to_state(CellularStateMachine::CellularState state)
|
||||
{
|
||||
_mutex.lock();
|
||||
// call pre_event via queue so that it's in same thread and it's safe to decisions
|
||||
int id = _queue.call_in(0, this, &CellularStateMachine::pre_event, state);
|
||||
if (!id) {
|
||||
stop();
|
||||
_mutex.unlock();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
_mutex.unlock();
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
} else {
|
||||
retry_state_or_fail();
|
||||
// wanted state is already / will be achieved, return without launching new event
|
||||
return;
|
||||
}
|
||||
// if _event_id is -1 it means that new event is not going to be launched so we must launch new event
|
||||
if (_event_id == -1) {
|
||||
if (!_cb_data.final_try) {
|
||||
// update next state so that we don't continue from previous state if state machine was paused and then started again.
|
||||
// but only if earlier try did not finish to failure, then we must continue from that state
|
||||
_state = _next_state;
|
||||
}
|
||||
enter_to_state(_next_state);
|
||||
_event_id = _queue.call_in(0, this, &CellularStateMachine::event);
|
||||
if (!_event_id) {
|
||||
_event_id = -1;
|
||||
report_failure("Failed to call queue.");
|
||||
stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::state_connect_to_network()
|
||||
bool CellularStateMachine::get_current_status(CellularStateMachine::CellularState ¤t_state, CellularStateMachine::CellularState &target_state)
|
||||
{
|
||||
_cellularDevice->set_timeout(TIMEOUT_CONNECT);
|
||||
tr_info("Connect to cellular network (timeout %d ms)", TIMEOUT_CONNECT);
|
||||
if (_network->connect() == NSAPI_ERROR_OK) {
|
||||
_cellularDevice->set_timeout(TIMEOUT_NETWORK);
|
||||
tr_debug("Connected to cellular network, set at timeout (timeout %d ms)", TIMEOUT_NETWORK);
|
||||
// when using modems stack connect is synchronous
|
||||
_next_state = STATE_CONNECTED;
|
||||
} else {
|
||||
retry_state_or_fail();
|
||||
}
|
||||
bool is_running;
|
||||
_mutex.lock();
|
||||
current_state = _state;
|
||||
target_state = _target_state;
|
||||
is_running = _event_id != -1;
|
||||
_mutex.unlock();
|
||||
return is_running;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::state_connected()
|
||||
{
|
||||
_cellularDevice->set_timeout(TIMEOUT_NETWORK);
|
||||
tr_debug("Cellular ready! (timeout %d ms)", TIMEOUT_NETWORK);
|
||||
if (_status_callback) {
|
||||
_status_callback(_state, _next_state);
|
||||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::event()
|
||||
void CellularStateMachine::event()
|
||||
{
|
||||
tr_debug("CellularStateMachine::event(): %s", get_state_string(_state));
|
||||
_event_timeout = -1;
|
||||
_is_retry = false;
|
||||
|
||||
switch (_state) {
|
||||
case STATE_INIT:
|
||||
_current_event = (nsapi_event_t)CellularDeviceReady;
|
||||
state_init();
|
||||
break;
|
||||
case STATE_POWER_ON:
|
||||
_current_event = (nsapi_event_t)CellularDeviceReady;
|
||||
state_power_on();
|
||||
break;
|
||||
case STATE_DEVICE_READY:
|
||||
_current_event = (nsapi_event_t)CellularDeviceReady;
|
||||
state_device_ready();
|
||||
break;
|
||||
case STATE_SIM_PIN:
|
||||
_current_event = (nsapi_event_t)CellularSIMStatusChanged;
|
||||
state_sim_pin();
|
||||
break;
|
||||
case STATE_REGISTERING_NETWORK:
|
||||
_current_event = (nsapi_event_t)CellularRegistrationStatusChanged;
|
||||
state_registering();
|
||||
break;
|
||||
case STATE_MANUAL_REGISTERING_NETWORK:
|
||||
_current_event = (nsapi_event_t)CellularRegistrationStatusChanged;
|
||||
state_manual_registering_network();
|
||||
break;
|
||||
case STATE_ATTACHING_NETWORK:
|
||||
_current_event = (nsapi_event_t)CellularAttachNetwork;
|
||||
state_attaching();
|
||||
break;
|
||||
case STATE_ACTIVATING_PDP_CONTEXT:
|
||||
state_activating_pdp_context();
|
||||
break;
|
||||
case STATE_CONNECTING_NETWORK:
|
||||
state_connect_to_network();
|
||||
break;
|
||||
case STATE_CONNECTED:
|
||||
state_connected();
|
||||
break;
|
||||
default:
|
||||
MBED_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
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((CellularConnectionFSM::CellularState)_state),
|
||||
get_state_string((CellularConnectionFSM::CellularState)_next_state));
|
||||
if (_status_callback) {
|
||||
if (!_status_callback(_state, _next_state)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
tr_info("Cellular state from %s to %s", get_state_string((CellularStateMachine::CellularState)_state),
|
||||
get_state_string((CellularStateMachine::CellularState)_next_state));
|
||||
} else {
|
||||
tr_info("Cellular event in %d seconds", _event_timeout);
|
||||
}
|
||||
|
@ -614,23 +626,20 @@ void CellularConnectionFSM::event()
|
|||
if (_event_timeout == -1) {
|
||||
_event_timeout = 0;
|
||||
}
|
||||
_event_id = _queue.call_in(_event_timeout * 1000, callback(this, &CellularConnectionFSM::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!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t CellularConnectionFSM::start_dispatch()
|
||||
nsapi_error_t CellularStateMachine::start_dispatch()
|
||||
{
|
||||
MBED_ASSERT(!_queue_thread);
|
||||
|
||||
_queue_thread = new rtos::Thread(osPriorityNormal, 2048, NULL, "cellular_fsm");
|
||||
if (!_queue_thread) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
_queue_thread = new rtos::Thread(osPriorityNormal, 2048, NULL, "stm_queue");
|
||||
if (_queue_thread->start(callback(&_queue, &events::EventQueue::dispatch_forever)) != osOK) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
|
@ -639,34 +648,24 @@ nsapi_error_t CellularConnectionFSM::start_dispatch()
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::set_serial(UARTSerial *serial)
|
||||
void CellularStateMachine::set_cellular_callback(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
_serial = serial;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::set_callback(mbed::Callback<bool(int, int)> status_callback)
|
||||
{
|
||||
_status_callback = status_callback;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
MBED_ASSERT(_network);
|
||||
_event_status_cb = status_cb;
|
||||
if (status_cb) {
|
||||
_network->attach(callback(this, &CellularConnectionFSM::network_callback));
|
||||
} else {
|
||||
_network->attach(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr)
|
||||
void CellularStateMachine::cellular_event_changed(nsapi_event_t ev, intptr_t ptr)
|
||||
{
|
||||
tr_info("FSM: network_callback called with event: %d, intptr: %d, _state: %s", ev, ptr, get_state_string(_state));
|
||||
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
|
||||
if (ptr == CellularNetwork::RegisteredHomeNetwork || ptr == CellularNetwork::RegisteredRoaming) {
|
||||
if ((data->status_data == CellularNetwork::RegisteredHomeNetwork || data->status_data == CellularNetwork::RegisteredRoaming) && data->error == NSAPI_ERROR_OK) {
|
||||
if (_plmn) {
|
||||
if (is_registered_to_plmn()) {
|
||||
if (!_plmn_network_found) {
|
||||
|
@ -681,52 +680,25 @@ void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_event_status_cb) {
|
||||
_event_status_cb(ev, ptr);
|
||||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::ready_urc_cb()
|
||||
void CellularStateMachine::ready_urc_cb()
|
||||
{
|
||||
tr_debug("Device ready URC func called");
|
||||
if (_state == STATE_DEVICE_READY && _power->set_at_mode() == NSAPI_ERROR_OK) {
|
||||
tr_debug("State was STATE_DEVICE_READY and at mode ready, cancel state and move to next");
|
||||
_queue.cancel(_event_id);
|
||||
if (device_ready()) {
|
||||
_queue.cancel(_event_id);
|
||||
continue_from_state(STATE_SIM_PIN);
|
||||
} else {
|
||||
continue_from_state(STATE_DEVICE_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
events::EventQueue *CellularConnectionFSM::get_queue()
|
||||
void CellularStateMachine::set_retry_timeout_array(uint16_t timeout[], int array_len)
|
||||
{
|
||||
return &_queue;
|
||||
}
|
||||
|
||||
CellularNetwork *CellularConnectionFSM::get_network()
|
||||
{
|
||||
return _network;
|
||||
}
|
||||
|
||||
CellularDevice *CellularConnectionFSM::get_device()
|
||||
{
|
||||
return _cellularDevice;
|
||||
}
|
||||
|
||||
CellularSIM *CellularConnectionFSM::get_sim()
|
||||
{
|
||||
return _sim;
|
||||
}
|
||||
|
||||
NetworkStack *CellularConnectionFSM::get_stack()
|
||||
{
|
||||
return _cellularDevice->get_stack();
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::set_retry_timeout_array(uint16_t timeout[], int array_len)
|
||||
{
|
||||
_retry_array_length = array_len > MAX_RETRY_ARRAY_SIZE ? MAX_RETRY_ARRAY_SIZE : array_len;
|
||||
_retry_array_length = array_len > RETRY_ARRAY_SIZE ? RETRY_ARRAY_SIZE : array_len;
|
||||
|
||||
for (int i = 0; i < _retry_array_length; i++) {
|
||||
_retry_timeout_array[i] = timeout[i];
|
||||
|
@ -735,4 +707,3 @@ void CellularConnectionFSM::set_retry_timeout_array(uint16_t timeout[], int arra
|
|||
|
||||
} // namespace
|
||||
|
||||
#endif // CELLULAR_DEVICE
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Arm Limited and affiliates.
|
||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -14,39 +14,43 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef _CELLULAR_STATEMACHINE_H_
|
||||
#define _CELLULAR_STATEMACHINE_H_
|
||||
|
||||
#ifndef _CELLULAR_CONNECTION_FSM_H
|
||||
#define _CELLULAR_CONNECTION_FSM_H
|
||||
|
||||
#include "CellularTargets.h"
|
||||
#if defined(CELLULAR_DEVICE) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "UARTSerial.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "EventQueue.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#include "CellularNetwork.h"
|
||||
#include "CellularPower.h"
|
||||
#include "CellularSIM.h"
|
||||
#include "CellularCommon.h"
|
||||
#include "PlatformMutex.h"
|
||||
|
||||
namespace rtos {
|
||||
class Thread;
|
||||
}
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class CellularPower;
|
||||
class CellularSIM;
|
||||
class CellularDevice;
|
||||
|
||||
const int PIN_SIZE = 8;
|
||||
const int MAX_RETRY_ARRAY_SIZE = 10;
|
||||
const int RETRY_ARRAY_SIZE = 10;
|
||||
|
||||
/** CellularConnectionFSM class
|
||||
/** CellularStateMachine class
|
||||
*
|
||||
* Finite State Machine for connecting to cellular network
|
||||
* Finite State Machine for attaching to cellular network. Used by CellularDevice.
|
||||
*/
|
||||
class CellularConnectionFSM {
|
||||
public:
|
||||
CellularConnectionFSM();
|
||||
virtual ~CellularConnectionFSM();
|
||||
class CellularStateMachine {
|
||||
private:
|
||||
// friend of CellularDevice so that it's the only way to close/delete this class.
|
||||
friend class CellularDevice;
|
||||
friend class AT_CellularDevice;
|
||||
/** Constructor
|
||||
*
|
||||
* @param device reference to CellularDevice
|
||||
* @param queue reference to queue used in state transitions
|
||||
*/
|
||||
CellularStateMachine(CellularDevice &device, events::EventQueue &queue);
|
||||
~CellularStateMachine();
|
||||
|
||||
public:
|
||||
/** Cellular connection states
|
||||
*/
|
||||
enum CellularState {
|
||||
|
@ -57,75 +61,32 @@ public:
|
|||
STATE_REGISTERING_NETWORK,
|
||||
STATE_MANUAL_REGISTERING_NETWORK,
|
||||
STATE_ATTACHING_NETWORK,
|
||||
STATE_ACTIVATING_PDP_CONTEXT,
|
||||
STATE_CONNECTING_NETWORK,
|
||||
STATE_CONNECTED
|
||||
STATE_MAX_FSM_STATE
|
||||
};
|
||||
|
||||
public:
|
||||
/** Initialize cellular device
|
||||
* @remark Must be called before any other methods
|
||||
* @return see nsapi_error_t, 0 on success
|
||||
*/
|
||||
nsapi_error_t init();
|
||||
|
||||
/** Set serial connection for cellular device
|
||||
* @param serial UART driver
|
||||
*/
|
||||
void set_serial(UARTSerial *serial);
|
||||
|
||||
/** Set callback for state update
|
||||
* @param status_callback function to call on state changes
|
||||
*/
|
||||
void set_callback(mbed::Callback<bool(int, int)> status_callback);
|
||||
|
||||
/** Register callback for status reporting
|
||||
/** Register cellular specific for status changes
|
||||
*
|
||||
* The specified status callback function will be called on status changes
|
||||
* on the network. The parameters on the callback are the event type and
|
||||
* event-type dependent reason parameter.
|
||||
* The specified status callback function will be called on device status changes.
|
||||
* The parameters on the callback are the event type and event-type dependent reason parameter.
|
||||
*
|
||||
* @param status_cb The callback for status changes
|
||||
*/
|
||||
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||
|
||||
/** Get event queue that can be chained to main event queue (or use start_dispatch)
|
||||
* @return event queue
|
||||
*/
|
||||
events::EventQueue *get_queue();
|
||||
void set_cellular_callback(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||
|
||||
/** Start event queue dispatching
|
||||
* @return see nsapi_error_t, 0 on success
|
||||
*/
|
||||
nsapi_error_t start_dispatch();
|
||||
|
||||
/** Stop event queue dispatching and close cellular interfaces. After calling stop(), init() must be called
|
||||
* before any other methods.
|
||||
/** Stop event queue dispatching and close cellular interfaces.
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/** Get cellular network interface
|
||||
* @return network interface, NULL on failure
|
||||
*/
|
||||
CellularNetwork *get_network();
|
||||
|
||||
/** Get cellular device interface
|
||||
* @return device interface, NULL on failure
|
||||
*/
|
||||
CellularDevice *get_device();
|
||||
|
||||
/** Get cellular sim interface. SIM interface is released when moving from STATE_ATTACHING_NETWORK to STATE_ACTIVATING_PDP_CONTEXT.
|
||||
* After SIM interface is closed, this method returns NULL, and any instances fetched using this method are invalid.
|
||||
* SIM interface can be created again using CellularDevice, which you can get with the method get_device().
|
||||
* @return sim interface, NULL on failure
|
||||
*/
|
||||
CellularSIM *get_sim();
|
||||
|
||||
/** Change cellular connection to the target state
|
||||
* @param state to continue. Default is to connect.
|
||||
/** Runs state machine to connected state unless callback method set with set_state_callback return false to stop.
|
||||
*
|
||||
* @return see nsapi_error_t, 0 on success
|
||||
*/
|
||||
nsapi_error_t continue_to_state(CellularState state = STATE_CONNECTED);
|
||||
nsapi_error_t run_to_state(CellularState state);
|
||||
|
||||
/** Set cellular device SIM PIN code
|
||||
* @param sim_pin PIN code
|
||||
|
@ -152,8 +113,27 @@ public:
|
|||
* @param state state which is returned in string format
|
||||
* @return string format of the given state
|
||||
*/
|
||||
const char *get_state_string(CellularState state);
|
||||
const char *get_state_string(CellularState state) const;
|
||||
|
||||
/** Get the current status of the state machine. Thread safe.
|
||||
*
|
||||
* @param current_state
|
||||
* @param target_state
|
||||
* @return true if state machine is running, false is not
|
||||
*
|
||||
*/
|
||||
bool get_current_status(CellularStateMachine::CellularState ¤t_state, CellularStateMachine::CellularState &target_state);
|
||||
|
||||
/** CellularDevice updates about network events and cellular events
|
||||
*
|
||||
* @param ev Event type
|
||||
* @param ptr Event type specific data
|
||||
*/
|
||||
void cellular_event_changed(nsapi_event_t ev, intptr_t ptr);
|
||||
|
||||
/** Reset the state machine to init state. After reset state machine can be used again to run to wanted state.
|
||||
*/
|
||||
void reset();
|
||||
private:
|
||||
bool power_on();
|
||||
bool open_sim();
|
||||
|
@ -169,54 +149,46 @@ private:
|
|||
void state_registering();
|
||||
void state_manual_registering_network();
|
||||
void state_attaching();
|
||||
void state_activating_pdp_context();
|
||||
void state_connect_to_network();
|
||||
void state_connected();
|
||||
void enter_to_state(CellularState state);
|
||||
void retry_state_or_fail();
|
||||
void network_callback(nsapi_event_t ev, intptr_t ptr);
|
||||
nsapi_error_t continue_from_state(CellularState state);
|
||||
void continue_from_state(CellularState state);
|
||||
bool is_registered_to_plmn();
|
||||
|
||||
private:
|
||||
friend class EasyCellularConnection;
|
||||
NetworkStack *get_stack();
|
||||
|
||||
private:
|
||||
void report_failure(const char *msg);
|
||||
void event();
|
||||
void ready_urc_cb();
|
||||
void pre_event(CellularState state);
|
||||
|
||||
UARTSerial *_serial;
|
||||
CellularDevice &_cellularDevice;
|
||||
CellularState _state;
|
||||
CellularState _next_state;
|
||||
CellularState _target_state;
|
||||
|
||||
Callback<bool(int, int)> _status_callback;
|
||||
Callback<void(nsapi_event_t, intptr_t)> _event_status_cb;
|
||||
|
||||
CellularNetwork *_network;
|
||||
CellularPower *_power;
|
||||
CellularSIM *_sim;
|
||||
events::EventQueue _queue;
|
||||
events::EventQueue &_queue;
|
||||
rtos::Thread *_queue_thread;
|
||||
CellularDevice *_cellularDevice;
|
||||
char _sim_pin[PIN_SIZE + 1];
|
||||
|
||||
const char *_sim_pin;
|
||||
int _retry_count;
|
||||
int _start_time;
|
||||
int _event_timeout;
|
||||
|
||||
uint16_t _retry_timeout_array[MAX_RETRY_ARRAY_SIZE];
|
||||
uint16_t _retry_timeout_array[RETRY_ARRAY_SIZE];
|
||||
int _retry_array_length;
|
||||
events::EventQueue *_at_queue;
|
||||
char _st_string[20];
|
||||
int _event_id;
|
||||
const char *_plmn;
|
||||
bool _command_success;
|
||||
bool _plmn_network_found;
|
||||
bool _is_retry;
|
||||
cell_callback_data_t _cb_data;
|
||||
nsapi_event_t _current_event;
|
||||
bool _active_context; // Is there any active context?
|
||||
PlatformMutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // CELLULAR_DEVICE || DOXYGEN
|
||||
|
||||
#endif // _CELLULAR_CONNECTION_FSM_H
|
||||
#endif /* _CELLULAR_STATEMACHINE_H_ */
|
|
@ -17,16 +17,18 @@
|
|||
|
||||
#include "GEMALTO_CINTERION_CellularNetwork.h"
|
||||
#include "GEMALTO_CINTERION_Module.h"
|
||||
#include "AT_CellularInformation.h"
|
||||
#include "GEMALTO_CINTERION_CellularContext.h"
|
||||
#include "GEMALTO_CINTERION.h"
|
||||
#include "AT_CellularInformation.h"
|
||||
#include "CellularLog.h"
|
||||
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
||||
const uint16_t RESPONSE_TO_SEND_DELAY = 100; // response-to-send delay in milliseconds at bit-rate over 9600
|
||||
|
||||
GEMALTO_CINTERION::GEMALTO_CINTERION(EventQueue &queue) : AT_CellularDevice(queue)
|
||||
GEMALTO_CINTERION::GEMALTO_CINTERION(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -39,9 +41,14 @@ AT_CellularNetwork *GEMALTO_CINTERION::open_network_impl(ATHandler &at)
|
|||
return new GEMALTO_CINTERION_CellularNetwork(at);
|
||||
}
|
||||
|
||||
nsapi_error_t GEMALTO_CINTERION::init_module(FileHandle *fh)
|
||||
AT_CellularContext *GEMALTO_CINTERION::create_context_impl(ATHandler &at, const char *apn)
|
||||
{
|
||||
CellularInformation *information = open_information(fh);
|
||||
return new GEMALTO_CINTERION_CellularContext(at, this, apn);
|
||||
}
|
||||
|
||||
nsapi_error_t GEMALTO_CINTERION::init_module()
|
||||
{
|
||||
CellularInformation *information = open_information();
|
||||
if (!information) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
@ -55,7 +62,7 @@ nsapi_error_t GEMALTO_CINTERION::init_module(FileHandle *fh)
|
|||
return GEMALTO_CINTERION_Module::detect_model(model);
|
||||
}
|
||||
|
||||
uint16_t GEMALTO_CINTERION::get_send_delay()
|
||||
uint16_t GEMALTO_CINTERION::get_send_delay() const
|
||||
{
|
||||
return RESPONSE_TO_SEND_DELAY;
|
||||
}
|
||||
|
|
|
@ -25,15 +25,15 @@ namespace mbed {
|
|||
class GEMALTO_CINTERION : public AT_CellularDevice {
|
||||
public:
|
||||
|
||||
GEMALTO_CINTERION(events::EventQueue &queue);
|
||||
GEMALTO_CINTERION(FileHandle *fh);
|
||||
virtual ~GEMALTO_CINTERION();
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
|
||||
public: // CellularDevice
|
||||
virtual nsapi_error_t init_module(FileHandle *fh);
|
||||
virtual uint16_t get_send_delay();
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
|
||||
public:
|
||||
virtual nsapi_error_t init_module();
|
||||
virtual uint16_t get_send_delay() const;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 "GEMALTO_CINTERION_CellularContext.h"
|
||||
#include "GEMALTO_CINTERION_CellularStack.h"
|
||||
#include "GEMALTO_CINTERION_Module.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
GEMALTO_CINTERION_CellularContext::GEMALTO_CINTERION_CellularContext(ATHandler &at, CellularDevice *device,
|
||||
const char *apn) : AT_CellularContext(at, device, apn)
|
||||
{
|
||||
}
|
||||
|
||||
GEMALTO_CINTERION_CellularContext::~GEMALTO_CINTERION_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
NetworkStack *GEMALTO_CINTERION_CellularContext::get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
_stack = new GEMALTO_CINTERION_CellularStack(_at, _apn, _cid, _ip_stack_type);
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
|
||||
bool GEMALTO_CINTERION_CellularContext::stack_type_supported(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
if (GEMALTO_CINTERION_Module::get_model() == GEMALTO_CINTERION_Module::ModelBGS2) {
|
||||
return (requested_stack == IPV4_STACK);
|
||||
}
|
||||
return (requested_stack == IPV4_STACK || requested_stack == IPV6_STACK);
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 GEMALTO_CINTERION_CELLULARCONTEXT_H_
|
||||
#define GEMALTO_CINTERION_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class GEMALTO_CINTERION_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
GEMALTO_CINTERION_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
|
||||
virtual ~GEMALTO_CINTERION_CellularContext();
|
||||
|
||||
protected:
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
virtual NetworkStack *get_stack();
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
virtual bool stack_type_supported(nsapi_ip_stack_t requested_stack);
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // GEMALTO_CINTERION_CELLULARCONTEXT_H_
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
|
||||
#include "GEMALTO_CINTERION_CellularNetwork.h"
|
||||
#include "GEMALTO_CINTERION_CellularStack.h"
|
||||
#include "GEMALTO_CINTERION_Module.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
@ -29,24 +28,6 @@ GEMALTO_CINTERION_CellularNetwork::~GEMALTO_CINTERION_CellularNetwork()
|
|||
{
|
||||
}
|
||||
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
NetworkStack *GEMALTO_CINTERION_CellularNetwork::get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
_stack = new GEMALTO_CINTERION_CellularStack(_at, _apn, _cid, _ip_stack_type);
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
|
||||
bool GEMALTO_CINTERION_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
if (GEMALTO_CINTERION_Module::get_model() == GEMALTO_CINTERION_Module::ModelBGS2) {
|
||||
return (requested_stack == IPV4_STACK);
|
||||
}
|
||||
return (requested_stack == IPV4_STACK || requested_stack == IPV6_STACK);
|
||||
}
|
||||
|
||||
AT_CellularNetwork::RegistrationMode GEMALTO_CINTERION_CellularNetwork::has_registration(RegistrationType reg_type)
|
||||
{
|
||||
if (GEMALTO_CINTERION_Module::get_model() == GEMALTO_CINTERION_Module::ModelEMS31) {
|
||||
|
|
|
@ -28,14 +28,7 @@ public:
|
|||
virtual ~GEMALTO_CINTERION_CellularNetwork();
|
||||
|
||||
protected:
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
virtual NetworkStack *get_stack();
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
|
||||
virtual RegistrationMode has_registration(RegistrationType reg_type);
|
||||
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opsAct);
|
||||
};
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ void GEMALTO_CINTERION_CellularStack::urc_sis()
|
|||
int urc_code = _at.read_int();
|
||||
CellularSocket *sock = find_socket(sock_id);
|
||||
if (sock) {
|
||||
// Currently only UDP is supported so there is need to handle only some error codes here,
|
||||
// and others are detected on sendto/recvfrom responses.
|
||||
if (urc_code == 5) { // The service is ready to use (ELS61 and EMS31).
|
||||
if (sock->_cb) {
|
||||
sock->started = true;
|
||||
|
@ -163,9 +165,7 @@ nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_close_impl(int sock_id)
|
|||
_at.write_int(sock_id);
|
||||
_at.write_string("srvType");
|
||||
_at.write_string("none");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
_at.restore_at_timeout();
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "SARA4_PPP.h"
|
||||
#include "SARA4_PPP_CellularNetwork.h"
|
||||
#include "SARA4_PPP_CellularPower.h"
|
||||
#include "SARA4_PPP_CellularContext.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
@ -28,7 +29,7 @@ static const AT_CellularBase::SupportedFeature unsupported_features[] = {
|
|||
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
|
||||
};
|
||||
|
||||
SARA4_PPP::SARA4_PPP(EventQueue &queue) : AT_CellularDevice(queue)
|
||||
SARA4_PPP::SARA4_PPP(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
AT_CellularBase::set_unsupported_features(unsupported_features);
|
||||
}
|
||||
|
@ -47,3 +48,7 @@ AT_CellularPower *SARA4_PPP::open_power_impl(ATHandler &at)
|
|||
return new SARA4_PPP_CellularPower(at);
|
||||
}
|
||||
|
||||
AT_CellularContext *SARA4_PPP::create_context_impl(ATHandler &at, const char *apn)
|
||||
{
|
||||
return new SARA4_PPP_CellularContext(at, this, apn);
|
||||
}
|
||||
|
|
|
@ -25,12 +25,13 @@ namespace mbed {
|
|||
class SARA4_PPP : public AT_CellularDevice {
|
||||
|
||||
public:
|
||||
SARA4_PPP(events::EventQueue &queue);
|
||||
SARA4_PPP(FileHandle *fh);
|
||||
virtual ~SARA4_PPP();
|
||||
|
||||
public: // CellularDevice
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
virtual AT_CellularPower *open_power_impl(ATHandler &at);
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 "SARA4_PPP_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
SARA4_PPP_CellularContext::SARA4_PPP_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
|
||||
AT_CellularContext(at, device, apn)
|
||||
{
|
||||
}
|
||||
|
||||
SARA4_PPP_CellularContext::~SARA4_PPP_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
bool SARA4_PPP_CellularContext::stack_type_supported(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
return requested_stack == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 SARA4_PPP_CELLULARCONTEXT_H_
|
||||
#define SARA4_PPP_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class SARA4_PPP_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
SARA4_PPP_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
|
||||
virtual ~SARA4_PPP_CellularContext();
|
||||
|
||||
protected:
|
||||
virtual bool stack_type_supported(nsapi_ip_stack_t requested_stack);
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // SARA4_PPP_CELLULARCONTEXT_H_
|
|
@ -27,11 +27,6 @@ SARA4_PPP_CellularNetwork::~SARA4_PPP_CellularNetwork()
|
|||
{
|
||||
}
|
||||
|
||||
bool SARA4_PPP_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
return requested_stack == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
AT_CellularNetwork::RegistrationMode SARA4_PPP_CellularNetwork::has_registration(RegistrationType reg_type)
|
||||
{
|
||||
return (reg_type == C_REG || reg_type == C_GREG) ? RegistrationModeLAC : RegistrationModeDisable;
|
||||
|
|
|
@ -28,8 +28,6 @@ public:
|
|||
virtual ~SARA4_PPP_CellularNetwork();
|
||||
|
||||
protected:
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
virtual RegistrationMode has_registration(RegistrationType rat);
|
||||
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "QUECTEL_BC95_CellularNetwork.h"
|
||||
#include "QUECTEL_BC95_CellularPower.h"
|
||||
#include "QUECTEL_BC95_CellularSIM.h"
|
||||
|
||||
#include "QUECTEL_BC95_CellularContext.h"
|
||||
#include "QUECTEL_BC95.h"
|
||||
|
||||
#define CONNECT_DELIM "\r\n"
|
||||
|
@ -36,7 +36,7 @@ static const AT_CellularBase::SupportedFeature unsupported_features[] = {
|
|||
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
|
||||
};
|
||||
|
||||
QUECTEL_BC95::QUECTEL_BC95(EventQueue &queue) : AT_CellularDevice(queue)
|
||||
QUECTEL_BC95::QUECTEL_BC95(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
AT_CellularBase::set_unsupported_features(unsupported_features);
|
||||
}
|
||||
|
@ -59,3 +59,8 @@ AT_CellularSIM *QUECTEL_BC95::open_sim_impl(ATHandler &at)
|
|||
{
|
||||
return new QUECTEL_BC95_CellularSIM(at);
|
||||
}
|
||||
|
||||
AT_CellularContext *QUECTEL_BC95::create_context_impl(ATHandler &at, const char *apn)
|
||||
{
|
||||
return new QUECTEL_BC95_CellularContext(at, this, apn);
|
||||
}
|
||||
|
|
|
@ -24,13 +24,14 @@ namespace mbed {
|
|||
|
||||
class QUECTEL_BC95 : public AT_CellularDevice {
|
||||
public:
|
||||
QUECTEL_BC95(events::EventQueue &queue);
|
||||
QUECTEL_BC95(FileHandle *fh);
|
||||
virtual ~QUECTEL_BC95();
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
virtual AT_CellularPower *open_power_impl(ATHandler &at);
|
||||
virtual AT_CellularSIM *open_sim_impl(ATHandler &at);
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
|
||||
|
||||
public: // NetworkInterface
|
||||
void handle_urc(FileHandle *fh);
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 "QUECTEL_BC95_CellularContext.h"
|
||||
#include "QUECTEL_BC95_CellularStack.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
QUECTEL_BC95_CellularContext::QUECTEL_BC95_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
|
||||
AT_CellularContext(at, device, apn)
|
||||
{
|
||||
}
|
||||
|
||||
QUECTEL_BC95_CellularContext::~QUECTEL_BC95_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
NetworkStack *QUECTEL_BC95_CellularContext::get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
_stack = new QUECTEL_BC95_CellularStack(_at, _cid, _ip_stack_type);
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
|
||||
bool QUECTEL_BC95_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
return stack_type == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 QUECTEL_BC95_CELLULARCONTEXT_H_
|
||||
#define QUECTEL_BC95_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class QUECTEL_BC95_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
QUECTEL_BC95_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
|
||||
virtual ~QUECTEL_BC95_CellularContext();
|
||||
|
||||
protected:
|
||||
virtual NetworkStack *get_stack();
|
||||
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // QUECTEL_BC95_CELLULARCONTEXT_H_
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
|
||||
#include "QUECTEL_BC95_CellularNetwork.h"
|
||||
#include "QUECTEL_BC95_CellularStack.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
|
@ -29,19 +28,6 @@ QUECTEL_BC95_CellularNetwork::~QUECTEL_BC95_CellularNetwork()
|
|||
{
|
||||
}
|
||||
|
||||
NetworkStack *QUECTEL_BC95_CellularNetwork::get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
_stack = new QUECTEL_BC95_CellularStack(_at, _cid, _ip_stack_type);
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
|
||||
bool QUECTEL_BC95_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
return requested_stack == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
AT_CellularNetwork::RegistrationMode QUECTEL_BC95_CellularNetwork::has_registration(RegistrationType reg_tech)
|
||||
{
|
||||
return (reg_tech == C_EREG) ? RegistrationModeLAC : RegistrationModeDisable;
|
||||
|
|
|
@ -28,12 +28,7 @@ public:
|
|||
virtual ~QUECTEL_BC95_CellularNetwork();
|
||||
|
||||
protected:
|
||||
virtual NetworkStack *get_stack();
|
||||
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
virtual RegistrationMode has_registration(RegistrationType reg_type);
|
||||
};
|
||||
} // namespace mbed
|
||||
|
|
|
@ -15,9 +15,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "QUECTEL/BG96/QUECTEL_BG96.h"
|
||||
#include "QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h"
|
||||
#include "QUECTEL/BG96/QUECTEL_BG96_CellularStack.h"
|
||||
#include "QUECTEL_BG96.h"
|
||||
#include "QUECTEL_BG96_CellularNetwork.h"
|
||||
#include "QUECTEL_BG96_CellularStack.h"
|
||||
#include "QUECTEL_BG96_CellularSIM.h"
|
||||
#include "QUECTEL_BG96_CellularPower.h"
|
||||
#include "QUECTEL_BG96_CellularContext.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
@ -34,7 +37,7 @@ static const AT_CellularBase::SupportedFeature unsupported_features[] = {
|
|||
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
|
||||
};
|
||||
|
||||
QUECTEL_BG96::QUECTEL_BG96(EventQueue &queue) : AT_CellularDevice(queue)
|
||||
QUECTEL_BG96::QUECTEL_BG96(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
AT_CellularBase::set_unsupported_features(unsupported_features);
|
||||
}
|
||||
|
@ -47,3 +50,19 @@ AT_CellularNetwork *QUECTEL_BG96::open_network_impl(ATHandler &at)
|
|||
{
|
||||
return new QUECTEL_BG96_CellularNetwork(at);
|
||||
}
|
||||
|
||||
AT_CellularSIM *QUECTEL_BG96::open_sim_impl(ATHandler &at)
|
||||
{
|
||||
return new QUECTEL_BG96_CellularSIM(at);
|
||||
}
|
||||
|
||||
AT_CellularPower *QUECTEL_BG96::open_power_impl(ATHandler &at)
|
||||
{
|
||||
return new QUECTEL_BG96_CellularPower(at);
|
||||
}
|
||||
|
||||
AT_CellularContext *QUECTEL_BG96::create_context_impl(ATHandler &at, const char *apn)
|
||||
{
|
||||
return new QUECTEL_BG96_CellularContext(at, this, apn);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,13 +24,15 @@ namespace mbed {
|
|||
|
||||
class QUECTEL_BG96 : public AT_CellularDevice {
|
||||
public:
|
||||
QUECTEL_BG96(events::EventQueue &queue);
|
||||
QUECTEL_BG96(FileHandle *fh);
|
||||
virtual ~QUECTEL_BG96();
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
|
||||
public: // NetworkInterface
|
||||
virtual AT_CellularSIM *open_sim_impl(ATHandler &at);
|
||||
virtual AT_CellularPower *open_power_impl(ATHandler &at);
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
|
||||
public:
|
||||
void handle_urc(FileHandle *fh);
|
||||
};
|
||||
} // namespace mbed
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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 "QUECTEL_BG96_CellularContext.h"
|
||||
#include "QUECTEL_BG96_CellularStack.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
QUECTEL_BG96_CellularContext::QUECTEL_BG96_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
|
||||
AT_CellularContext(at, device, apn)
|
||||
{
|
||||
}
|
||||
|
||||
QUECTEL_BG96_CellularContext::~QUECTEL_BG96_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
bool QUECTEL_BG96_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
if (stack_type == IPV4_STACK) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NetworkStack *QUECTEL_BG96_CellularContext::get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
_stack = new QUECTEL_BG96_CellularStack(_at, _cid, _ip_stack_type);
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BG96_CellularContext::do_user_authentication()
|
||||
{
|
||||
if (_pwd && _uname) {
|
||||
_at.cmd_start("AT+QICSGP=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(1); // IPv4
|
||||
_at.write_string(_apn);
|
||||
_at.write_string(_uname);
|
||||
_at.write_string(_pwd);
|
||||
_at.write_int(_authentication_type);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
return NSAPI_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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 QUECTEL_BG96_CELLULARCONTEXT_H_
|
||||
#define QUECTEL_BG96_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class QUECTEL_BG96_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
QUECTEL_BG96_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
|
||||
virtual ~QUECTEL_BG96_CellularContext();
|
||||
|
||||
protected:
|
||||
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
|
||||
virtual NetworkStack *get_stack();
|
||||
virtual nsapi_error_t do_user_authentication();
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // QUECTEL_BG96_CELLULARCONTEXT_H_
|
|
@ -28,23 +28,6 @@ QUECTEL_BG96_CellularNetwork::~QUECTEL_BG96_CellularNetwork()
|
|||
{
|
||||
}
|
||||
|
||||
bool QUECTEL_BG96_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
if (requested_stack == IPV4_STACK) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
NetworkStack *QUECTEL_BG96_CellularNetwork::get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
_stack = new QUECTEL_BG96_CellularStack(_at, _cid, _ip_stack_type);
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct)
|
||||
{
|
||||
_at.lock();
|
||||
|
@ -89,22 +72,3 @@ nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(RadioAcce
|
|||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_BG96_CellularNetwork::do_user_authentication()
|
||||
{
|
||||
if (_pwd && _uname) {
|
||||
_at.cmd_start("AT+QICSGP=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(1); // IPv4
|
||||
_at.write_string(_apn);
|
||||
_at.write_string(_uname);
|
||||
_at.write_string(_pwd);
|
||||
_at.write_int(_authentication_type);
|
||||
_at.cmd_stop_read_resp();
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
return NSAPI_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
|
|
@ -28,13 +28,7 @@ public:
|
|||
virtual ~QUECTEL_BG96_CellularNetwork();
|
||||
|
||||
protected:
|
||||
virtual NetworkStack *get_stack();
|
||||
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
virtual nsapi_error_t do_user_authentication();
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "QUECTEL/UG96/QUECTEL_UG96.h"
|
||||
#include "QUECTEL/UG96/QUECTEL_UG96_CellularNetwork.h"
|
||||
#include "QUECTEL/UG96/QUECTEL_UG96_CellularPower.h"
|
||||
#include "QUECTEL_UG96.h"
|
||||
#include "QUECTEL_UG96_CellularNetwork.h"
|
||||
#include "QUECTEL_UG96_CellularPower.h"
|
||||
#include "QUECTEL_UG96_CellularContext.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
@ -29,7 +30,7 @@ using namespace events;
|
|||
#define MAX_STARTUP_TRIALS 5
|
||||
#define MAX_RESET_TRIALS 5
|
||||
|
||||
QUECTEL_UG96::QUECTEL_UG96(EventQueue &queue) : AT_CellularDevice(queue)
|
||||
QUECTEL_UG96::QUECTEL_UG96(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -46,3 +47,8 @@ AT_CellularPower *QUECTEL_UG96::open_power_impl(ATHandler &at)
|
|||
{
|
||||
return new QUECTEL_UG96_CellularPower(at);
|
||||
}
|
||||
|
||||
AT_CellularContext *QUECTEL_UG96::create_context_impl(ATHandler &at, const char *apn)
|
||||
{
|
||||
return new QUECTEL_UG96_CellularContext(at, this, apn);
|
||||
}
|
||||
|
|
|
@ -32,12 +32,13 @@ namespace mbed {
|
|||
|
||||
class QUECTEL_UG96 : public AT_CellularDevice {
|
||||
public:
|
||||
QUECTEL_UG96(events::EventQueue &queue);
|
||||
QUECTEL_UG96(FileHandle *fh);
|
||||
virtual ~QUECTEL_UG96();
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
virtual AT_CellularPower *open_power_impl(ATHandler &at);
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
|
||||
|
||||
public: // NetworkInterface
|
||||
void handle_urc(FileHandle *fh);
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 "QUECTEL_UG96_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
QUECTEL_UG96_CellularContext::QUECTEL_UG96_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
|
||||
AT_CellularContext(at, device, apn)
|
||||
{
|
||||
}
|
||||
|
||||
QUECTEL_UG96_CellularContext::~QUECTEL_UG96_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
bool QUECTEL_UG96_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
return stack_type == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_UG96_CellularContext::do_user_authentication()
|
||||
{
|
||||
if (_pwd && _uname) {
|
||||
_at.cmd_start("AT+QICSGP=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(1); // context type 1=IPv4
|
||||
_at.write_string(_apn);
|
||||
_at.write_string(_uname);
|
||||
_at.write_string(_pwd);
|
||||
_at.write_int(_authentication_type);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
return NSAPI_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 QUECTEL_UG96_CELLULARCONTEXT_H_
|
||||
#define QUECTEL_UG96_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class QUECTEL_UG96_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
QUECTEL_UG96_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
|
||||
virtual ~QUECTEL_UG96_CellularContext();
|
||||
|
||||
protected:
|
||||
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
|
||||
virtual nsapi_error_t do_user_authentication();
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // QUECTEL_UG96_CELLULARCONTEXT_H_
|
|
@ -15,7 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "QUECTEL/UG96/QUECTEL_UG96_CellularNetwork.h"
|
||||
#include "QUECTEL_UG96_CellularNetwork.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
|
@ -27,11 +27,6 @@ QUECTEL_UG96_CellularNetwork::~QUECTEL_UG96_CellularNetwork()
|
|||
{
|
||||
}
|
||||
|
||||
bool QUECTEL_UG96_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
return requested_stack == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
AT_CellularNetwork::RegistrationMode QUECTEL_UG96_CellularNetwork::has_registration(RegistrationType reg_type)
|
||||
{
|
||||
return (reg_type == C_REG || reg_type == C_GREG) ? RegistrationModeLAC : RegistrationModeDisable;
|
||||
|
@ -42,24 +37,3 @@ nsapi_error_t QUECTEL_UG96_CellularNetwork::set_access_technology_impl(RadioAcce
|
|||
_op_act = RAT_UNKNOWN;
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t QUECTEL_UG96_CellularNetwork::do_user_authentication()
|
||||
{
|
||||
if (_pwd && _uname) {
|
||||
_at.cmd_start("AT+QICSGP=");
|
||||
_at.write_int(_cid);
|
||||
_at.write_int(1); // context type 1=IPv4
|
||||
_at.write_string(_apn);
|
||||
_at.write_string(_uname);
|
||||
_at.write_string(_pwd);
|
||||
_at.write_int(_authentication_type);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
return NSAPI_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
|
|
@ -28,13 +28,8 @@ public:
|
|||
virtual ~QUECTEL_UG96_CellularNetwork();
|
||||
|
||||
protected:
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
virtual RegistrationMode has_registration(RegistrationType rat);
|
||||
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
|
||||
virtual nsapi_error_t do_user_authentication();
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "TELIT_HE910.h"
|
||||
#include "TELIT_HE910_CellularPower.h"
|
||||
#include "TELIT_HE910_CellularNetwork.h"
|
||||
#include "TELIT_HE910_CellularContext.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
@ -28,7 +29,7 @@ static const AT_CellularBase::SupportedFeature unsupported_features[] = {
|
|||
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
|
||||
};
|
||||
|
||||
TELIT_HE910::TELIT_HE910(EventQueue &queue) : AT_CellularDevice(queue)
|
||||
TELIT_HE910::TELIT_HE910(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
AT_CellularBase::set_unsupported_features(unsupported_features);
|
||||
}
|
||||
|
@ -47,7 +48,12 @@ AT_CellularPower *TELIT_HE910::open_power_impl(ATHandler &at)
|
|||
return new TELIT_HE910_CellularPower(at);
|
||||
}
|
||||
|
||||
uint16_t TELIT_HE910::get_send_delay()
|
||||
AT_CellularContext *TELIT_HE910::create_context_impl(ATHandler &at, const char *apn)
|
||||
{
|
||||
return new TELIT_HE910_CellularContext(at, this, apn);
|
||||
}
|
||||
|
||||
uint16_t TELIT_HE910::get_send_delay() const
|
||||
{
|
||||
return DEFAULT_DELAY_BETWEEN_AT_COMMANDS;
|
||||
}
|
||||
|
|
|
@ -27,15 +27,16 @@ namespace mbed {
|
|||
|
||||
class TELIT_HE910 : public AT_CellularDevice {
|
||||
public:
|
||||
TELIT_HE910(events::EventQueue &queue);
|
||||
TELIT_HE910(FileHandle *fh);
|
||||
virtual ~TELIT_HE910();
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
virtual AT_CellularPower *open_power_impl(ATHandler &at);
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
|
||||
|
||||
public: // from CellularDevice
|
||||
virtual uint16_t get_send_delay();
|
||||
virtual uint16_t get_send_delay() const;
|
||||
};
|
||||
} // namespace mbed
|
||||
#endif /* CELLULAR_TARGETS_TELIT_HE910_TELIT_HE910_H_ */
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 "TELIT_HE910_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
TELIT_HE910_CellularContext::TELIT_HE910_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
|
||||
AT_CellularContext(at, device, apn)
|
||||
{
|
||||
}
|
||||
|
||||
TELIT_HE910_CellularContext::~TELIT_HE910_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
bool TELIT_HE910_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
return stack_type == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 TELIT_HE910_CELLULARCONTEXT_H_
|
||||
#define TELIT_HE910_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class TELIT_HE910_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
TELIT_HE910_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
|
||||
virtual ~TELIT_HE910_CellularContext();
|
||||
|
||||
protected:
|
||||
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // TELIT_HE910_CELLULARCONTEXT_H_
|
|
@ -27,11 +27,6 @@ TELIT_HE910_CellularNetwork::~TELIT_HE910_CellularNetwork()
|
|||
{
|
||||
}
|
||||
|
||||
bool TELIT_HE910_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
return requested_stack == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
AT_CellularNetwork::RegistrationMode TELIT_HE910_CellularNetwork::has_registration(RegistrationType reg_type)
|
||||
{
|
||||
return (reg_type == C_REG || reg_type == C_GREG) ? RegistrationModeLAC : RegistrationModeDisable;
|
||||
|
|
|
@ -28,11 +28,7 @@ public:
|
|||
virtual ~TELIT_HE910_CellularNetwork();
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
virtual RegistrationMode has_registration(RegistrationType rat);
|
||||
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
};
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "UBLOX_AT.h"
|
||||
#include "UBLOX_AT_CellularNetwork.h"
|
||||
#include "UBLOX_AT_CellularPower.h"
|
||||
#include "UBLOX_AT_CellularContext.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
@ -29,7 +30,7 @@ static const AT_CellularBase::SupportedFeature unsupported_features[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
UBLOX_AT::UBLOX_AT(EventQueue &queue) : AT_CellularDevice(queue)
|
||||
UBLOX_AT::UBLOX_AT(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
#ifdef TARGET_UBLOX_C030_R410M
|
||||
AT_CellularBase::set_unsupported_features(unsupported_features);
|
||||
|
@ -49,3 +50,8 @@ AT_CellularPower *UBLOX_AT::open_power_impl(ATHandler &at)
|
|||
{
|
||||
return new UBLOX_AT_CellularPower(at);
|
||||
}
|
||||
|
||||
AT_CellularContext *UBLOX_AT::create_context_impl(ATHandler &at, const char *apn)
|
||||
{
|
||||
return new UBLOX_AT_CellularContext(at, this, apn);
|
||||
}
|
||||
|
|
|
@ -24,13 +24,13 @@ namespace mbed {
|
|||
|
||||
class UBLOX_AT : public AT_CellularDevice {
|
||||
public:
|
||||
UBLOX_AT(events::EventQueue &queue);
|
||||
UBLOX_AT(FileHandle *fh);
|
||||
virtual ~UBLOX_AT();
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
virtual AT_CellularPower *open_power_impl(ATHandler &at);
|
||||
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
|
||||
public: // NetworkInterface
|
||||
void handle_urc(FileHandle *fh);
|
||||
};
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* 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 "UBLOX_AT_CellularContext.h"
|
||||
#include "UBLOX_AT_CellularStack.h"
|
||||
#include "APN_db.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
UBLOX_AT_CellularContext::UBLOX_AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
|
||||
AT_CellularContext(at, device, apn)
|
||||
{
|
||||
// The authentication to use
|
||||
_auth = NSAPI_SECURITY_UNKNOWN;
|
||||
}
|
||||
|
||||
UBLOX_AT_CellularContext::~UBLOX_AT_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
NetworkStack *UBLOX_AT_CellularContext::get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
_stack = new UBLOX_AT_CellularStack(_at, _cid, _ip_stack_type);
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
|
||||
bool UBLOX_AT_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
return stack_type == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
void UBLOX_AT_CellularContext::do_connect()
|
||||
{
|
||||
_at.lock();
|
||||
_cb_data.error = NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
// Attempt to establish a connection
|
||||
#ifdef TARGET_UBLOX_C030_R410M
|
||||
_cb_data.error = NSAPI_ERROR_OK;
|
||||
#else
|
||||
_cb_data.error = open_data_channel();
|
||||
#endif
|
||||
if (_cb_data.error != NSAPI_ERROR_OK) {
|
||||
// If new PSD context was created and failed to activate, delete it
|
||||
if (_new_context_set) {
|
||||
disconnect_modem_stack();
|
||||
}
|
||||
_connect_status = NSAPI_STATUS_DISCONNECTED;
|
||||
} else {
|
||||
_connect_status = NSAPI_STATUS_GLOBAL_UP;
|
||||
}
|
||||
_at.unlock();
|
||||
|
||||
if (_status_cb) {
|
||||
call_network_cb(_connect_status);
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularContext::open_data_channel()
|
||||
{
|
||||
bool success = false;
|
||||
int active = 0;
|
||||
char * config = NULL;
|
||||
nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION;
|
||||
char imsi[MAX_IMSI_LENGTH+1];
|
||||
|
||||
// do check for stack to validate that we have support for stack
|
||||
_stack = get_stack();
|
||||
if (!_stack) {
|
||||
return err;
|
||||
}
|
||||
|
||||
_at.cmd_start("AT+UPSND=" PROFILE ",8");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+UPSND:");
|
||||
_at.read_int();
|
||||
_at.read_int();
|
||||
active = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
if (active == 0) {
|
||||
// If the caller hasn't entered an APN, try to find it
|
||||
if (_apn == NULL) {
|
||||
err = get_imsi(imsi);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
config = (char*)apnconfig(imsi);
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to connect
|
||||
do {
|
||||
get_next_credentials(&config);
|
||||
if(_uname && _pwd) {
|
||||
_auth = (*_uname && *_pwd) ? _auth : NSAPI_SECURITY_NONE;
|
||||
} else {
|
||||
_auth = NSAPI_SECURITY_NONE;
|
||||
}
|
||||
success = activate_profile(_apn, _uname, _pwd);
|
||||
} while (!success && config && *config);
|
||||
} else {
|
||||
// If the profile is already active, we're good
|
||||
success = true;
|
||||
}
|
||||
|
||||
err = (_at.get_last_error() == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
bool UBLOX_AT_CellularContext::activate_profile(const char* apn,
|
||||
const char* username,
|
||||
const char* password)
|
||||
{
|
||||
bool activated = false;
|
||||
bool success = false;
|
||||
|
||||
// Set up the APN
|
||||
if (apn) {
|
||||
success = false;
|
||||
_at.cmd_start("AT+UPSD=0,1,");
|
||||
_at.write_string(apn);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
// Set up the UserName
|
||||
if (success && username) {
|
||||
success = false;
|
||||
_at.cmd_start("AT+UPSD=" PROFILE ",2,");
|
||||
_at.write_string(username);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
// Set up the Password
|
||||
if (success && password) {
|
||||
success = false;
|
||||
_at.cmd_start("AT+UPSD=" PROFILE ",3,");
|
||||
_at.write_string(password);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
_at.cmd_start("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
// Set up the authentication protocol
|
||||
// 0 = none
|
||||
// 1 = PAP (Password Authentication Protocol)
|
||||
// 2 = CHAP (Challenge Handshake Authentication Protocol)
|
||||
for (int protocol = nsapi_security_to_modem_security(NSAPI_SECURITY_NONE);
|
||||
success && (protocol <= nsapi_security_to_modem_security(NSAPI_SECURITY_CHAP)); protocol++) {
|
||||
if ((_auth == NSAPI_SECURITY_UNKNOWN) || (nsapi_security_to_modem_security(_auth) == protocol)) {
|
||||
_at.cmd_start("AT+UPSD=0,6,");
|
||||
_at.write_int(protocol);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
// Activate, wait upto 30 seconds for the connection to be made
|
||||
_at.set_at_timeout(30000);
|
||||
_at.cmd_start("AT+UPSDA=0,3");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
_at.restore_at_timeout();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
activated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activated;
|
||||
}
|
||||
|
||||
// Convert nsapi_security_t to the modem security numbers
|
||||
int UBLOX_AT_CellularContext::nsapi_security_to_modem_security(nsapi_security_t nsapi_security)
|
||||
{
|
||||
int modem_security = 3;
|
||||
|
||||
switch (nsapi_security) {
|
||||
case NSAPI_SECURITY_NONE:
|
||||
modem_security = 0;
|
||||
break;
|
||||
case NSAPI_SECURITY_PAP:
|
||||
modem_security = 1;
|
||||
break;
|
||||
case NSAPI_SECURITY_CHAP:
|
||||
modem_security = 2;
|
||||
break;
|
||||
case NSAPI_SECURITY_UNKNOWN:
|
||||
modem_security = 3;
|
||||
break;
|
||||
default:
|
||||
modem_security = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
return modem_security;
|
||||
}
|
||||
|
||||
// Disconnect the on board IP stack of the modem.
|
||||
bool UBLOX_AT_CellularContext::disconnect_modem_stack()
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (get_ip_address() != NULL) {
|
||||
_at.cmd_start("AT+UPSDA=" PROFILE ",4");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
_at.resp_stop();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularContext::get_imsi(char* imsi)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CIMI");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
int len = _at.read_string(imsi, MAX_IMSI_LENGTH);
|
||||
if (len > 0) {
|
||||
imsi[len] = '\0';
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
// Get the next set of credentials, based on IMSI.
|
||||
void UBLOX_AT_CellularContext::get_next_credentials(char ** config)
|
||||
{
|
||||
if (*config) {
|
||||
_apn = _APN_GET(*config);
|
||||
_uname = _APN_GET(*config);
|
||||
_pwd = _APN_GET(*config);
|
||||
}
|
||||
}
|
||||
|
||||
const char *UBLOX_AT_CellularContext::get_gateway()
|
||||
{
|
||||
return get_ip_address();
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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 UBLOX_AT_CELLULARCONTEXT_H_
|
||||
#define UBLOX_AT_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_AT_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
UBLOX_AT_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
|
||||
virtual ~UBLOX_AT_CellularContext();
|
||||
|
||||
virtual void do_connect();
|
||||
virtual const char *get_gateway();
|
||||
|
||||
protected:
|
||||
virtual NetworkStack *get_stack();
|
||||
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
|
||||
|
||||
private:
|
||||
|
||||
/** Length of IMSI buffer.
|
||||
*/
|
||||
static const int MAX_IMSI_LENGTH = 15;
|
||||
|
||||
/** The type of authentication to use.
|
||||
*/
|
||||
nsapi_security_t _auth;
|
||||
|
||||
/** Connect the on board IP stack of the modem.
|
||||
*
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
nsapi_error_t open_data_channel();
|
||||
|
||||
/** Activate one of the on-board modem's connection profiles.
|
||||
*
|
||||
* @param apn The APN to use.
|
||||
* @param username The user name to use.
|
||||
* @param password The password to use.
|
||||
* @param auth The authentication method to use
|
||||
* (NSAPI_SECURITY_NONE, NSAPI_SECURITY_PAP,
|
||||
* NSAPI_SECURITY_CHAP or NSAPI_SECURITY_UNKNOWN).
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool activate_profile(const char* apn, const char* username, const char* password);
|
||||
|
||||
/** Convert nsapi_security_t to the modem security numbers.
|
||||
*
|
||||
* @param nsapi_security Security protocol.
|
||||
* @return Modem security numbers.
|
||||
*/
|
||||
int nsapi_security_to_modem_security(nsapi_security_t nsapi_security);
|
||||
|
||||
/** Disconnect the on board IP stack of the modem.
|
||||
*
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool disconnect_modem_stack();
|
||||
|
||||
/** Read IMSI of modem.
|
||||
*/
|
||||
nsapi_error_t get_imsi(char* imsi);
|
||||
|
||||
/** Get the next set of credentials from the database.
|
||||
*/
|
||||
void get_next_credentials(char ** config);
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // UBLOX_AT_CELLULARCONTEXT_H_
|
|
@ -16,15 +16,12 @@
|
|||
*/
|
||||
|
||||
#include "UBLOX_AT_CellularNetwork.h"
|
||||
#include "UBLOX_AT_CellularStack.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
UBLOX_AT_CellularNetwork::UBLOX_AT_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler)
|
||||
{
|
||||
_op_act = RAT_UNKNOWN;
|
||||
// The authentication to use
|
||||
_auth = NSAPI_SECURITY_UNKNOWN;
|
||||
}
|
||||
|
||||
UBLOX_AT_CellularNetwork::~UBLOX_AT_CellularNetwork()
|
||||
|
@ -34,19 +31,6 @@ UBLOX_AT_CellularNetwork::~UBLOX_AT_CellularNetwork()
|
|||
}
|
||||
}
|
||||
|
||||
NetworkStack *UBLOX_AT_CellularNetwork::get_stack()
|
||||
{
|
||||
if (!_stack) {
|
||||
_stack = new UBLOX_AT_CellularStack(_at, _cid, _ip_stack_type);
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
|
||||
bool UBLOX_AT_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
return requested_stack == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
AT_CellularNetwork::RegistrationMode UBLOX_AT_CellularNetwork::has_registration(RegistrationType reg_type)
|
||||
{
|
||||
return (reg_type == C_REG || reg_type == C_GREG) ? RegistrationModeLAC : RegistrationModeDisable;
|
||||
|
@ -85,230 +69,3 @@ nsapi_error_t UBLOX_AT_CellularNetwork::set_access_technology_impl(RadioAccessTe
|
|||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::connect()
|
||||
{
|
||||
_at.lock();
|
||||
nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
// Attempt to establish a connection
|
||||
#ifdef TARGET_UBLOX_C030_R410M
|
||||
err = NSAPI_ERROR_OK;
|
||||
#else
|
||||
err = open_data_channel();
|
||||
#endif
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
// If new PSD context was created and failed to activate, delete it
|
||||
if (_new_context_set) {
|
||||
disconnect_modem_stack();
|
||||
}
|
||||
_connect_status = NSAPI_STATUS_DISCONNECTED;
|
||||
} else {
|
||||
_connect_status = NSAPI_STATUS_GLOBAL_UP;
|
||||
}
|
||||
_at.unlock();
|
||||
|
||||
if (_connection_status_cb) {
|
||||
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, _connect_status);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::open_data_channel()
|
||||
{
|
||||
bool success = false;
|
||||
int active = 0;
|
||||
char *config = NULL;
|
||||
nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION;
|
||||
char imsi[MAX_IMSI_LENGTH + 1];
|
||||
|
||||
// do check for stack to validate that we have support for stack
|
||||
_stack = get_stack();
|
||||
if (!_stack) {
|
||||
return err;
|
||||
}
|
||||
|
||||
_at.cmd_start("AT+UPSND=" PROFILE ",8");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+UPSND:");
|
||||
_at.read_int();
|
||||
_at.read_int();
|
||||
active = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
if (active == 0) {
|
||||
// If the caller hasn't entered an APN, try to find it
|
||||
if (_apn == NULL) {
|
||||
err = get_imsi(imsi);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
config = (char *)apnconfig(imsi);
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to connect
|
||||
do {
|
||||
get_next_credentials(&config);
|
||||
if (_uname && _pwd) {
|
||||
_auth = (*_uname && *_pwd) ? _auth : NSAPI_SECURITY_NONE;
|
||||
} else {
|
||||
_auth = NSAPI_SECURITY_NONE;
|
||||
}
|
||||
success = activate_profile(_apn, _uname, _pwd);
|
||||
} while (!success && config && *config);
|
||||
} else {
|
||||
// If the profile is already active, we're good
|
||||
success = true;
|
||||
}
|
||||
|
||||
err = (_at.get_last_error() == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
bool UBLOX_AT_CellularNetwork::activate_profile(const char *apn,
|
||||
const char *username,
|
||||
const char *password)
|
||||
{
|
||||
bool activated = false;
|
||||
bool success = false;
|
||||
|
||||
// Set up the APN
|
||||
if (apn) {
|
||||
success = false;
|
||||
_at.cmd_start("AT+UPSD=0,1,");
|
||||
_at.write_string(apn);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
// Set up the UserName
|
||||
if (success && username) {
|
||||
success = false;
|
||||
_at.cmd_start("AT+UPSD=" PROFILE ",2,");
|
||||
_at.write_string(username);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
// Set up the Password
|
||||
if (success && password) {
|
||||
success = false;
|
||||
_at.cmd_start("AT+UPSD=" PROFILE ",3,");
|
||||
_at.write_string(password);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
_at.cmd_start("AT+UPSD=" PROFILE ",7,\"0.0.0.0\"");
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
// Set up the authentication protocol
|
||||
// 0 = none
|
||||
// 1 = PAP (Password Authentication Protocol)
|
||||
// 2 = CHAP (Challenge Handshake Authentication Protocol)
|
||||
for (int protocol = nsapi_security_to_modem_security(NSAPI_SECURITY_NONE);
|
||||
success && (protocol <= nsapi_security_to_modem_security(NSAPI_SECURITY_CHAP)); protocol++) {
|
||||
if ((_auth == NSAPI_SECURITY_UNKNOWN) || (nsapi_security_to_modem_security(_auth) == protocol)) {
|
||||
_at.cmd_start("AT+UPSD=0,6,");
|
||||
_at.write_int(protocol);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
// Activate, wait upto 30 seconds for the connection to be made
|
||||
_at.set_at_timeout(30000);
|
||||
_at.cmd_start("AT+UPSDA=0,3");
|
||||
_at.cmd_stop_read_resp();
|
||||
_at.restore_at_timeout();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
activated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activated;
|
||||
}
|
||||
|
||||
// Convert nsapi_security_t to the modem security numbers
|
||||
int UBLOX_AT_CellularNetwork::nsapi_security_to_modem_security(nsapi_security_t nsapi_security)
|
||||
{
|
||||
int modem_security = 3;
|
||||
|
||||
switch (nsapi_security) {
|
||||
case NSAPI_SECURITY_NONE:
|
||||
modem_security = 0;
|
||||
break;
|
||||
case NSAPI_SECURITY_PAP:
|
||||
modem_security = 1;
|
||||
break;
|
||||
case NSAPI_SECURITY_CHAP:
|
||||
modem_security = 2;
|
||||
break;
|
||||
case NSAPI_SECURITY_UNKNOWN:
|
||||
modem_security = 3;
|
||||
break;
|
||||
default:
|
||||
modem_security = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
return modem_security;
|
||||
}
|
||||
|
||||
// Disconnect the on board IP stack of the modem.
|
||||
bool UBLOX_AT_CellularNetwork::disconnect_modem_stack()
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (get_ip_address() != NULL) {
|
||||
_at.cmd_start("AT+UPSDA=" PROFILE ",4");
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
nsapi_error_t UBLOX_AT_CellularNetwork::get_imsi(char *imsi)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CIMI");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start();
|
||||
int len = _at.read_string(imsi, MAX_IMSI_LENGTH);
|
||||
if (len > 0) {
|
||||
imsi[len] = '\0';
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
// Get the next set of credentials, based on IMSI.
|
||||
void UBLOX_AT_CellularNetwork::get_next_credentials(char **config)
|
||||
{
|
||||
if (*config) {
|
||||
_apn = _APN_GET(*config);
|
||||
_uname = _APN_GET(*config);
|
||||
_pwd = _APN_GET(*config);
|
||||
}
|
||||
}
|
||||
|
||||
const char *UBLOX_AT_CellularNetwork::get_gateway()
|
||||
{
|
||||
return get_ip_address();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#define UBLOX_AT_CELLULAR_NETWORK_H_
|
||||
|
||||
#include "AT_CellularNetwork.h"
|
||||
#include "APN_db.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
|
@ -28,67 +27,9 @@ public:
|
|||
UBLOX_AT_CellularNetwork(ATHandler &atHandler);
|
||||
virtual ~UBLOX_AT_CellularNetwork();
|
||||
|
||||
virtual nsapi_error_t connect();
|
||||
|
||||
virtual const char *get_gateway();
|
||||
|
||||
protected:
|
||||
virtual NetworkStack *get_stack();
|
||||
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
virtual RegistrationMode has_registration(RegistrationType rat);
|
||||
|
||||
private:
|
||||
|
||||
/** Length of IMSI buffer.
|
||||
*/
|
||||
static const int MAX_IMSI_LENGTH = 15;
|
||||
|
||||
/** The type of authentication to use.
|
||||
*/
|
||||
nsapi_security_t _auth;
|
||||
|
||||
/** Connect the on board IP stack of the modem.
|
||||
*
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
nsapi_error_t open_data_channel();
|
||||
|
||||
/** Activate one of the on-board modem's connection profiles.
|
||||
*
|
||||
* @param apn The APN to use.
|
||||
* @param username The user name to use.
|
||||
* @param password The password to use.
|
||||
* @param auth The authentication method to use
|
||||
* (NSAPI_SECURITY_NONE, NSAPI_SECURITY_PAP,
|
||||
* NSAPI_SECURITY_CHAP or NSAPI_SECURITY_UNKNOWN).
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool activate_profile(const char *apn, const char *username, const char *password);
|
||||
|
||||
/** Convert nsapi_security_t to the modem security numbers.
|
||||
*
|
||||
* @param nsapi_security Security protocol.
|
||||
* @return Modem security numbers.
|
||||
*/
|
||||
int nsapi_security_to_modem_security(nsapi_security_t nsapi_security);
|
||||
|
||||
/** Disconnect the on board IP stack of the modem.
|
||||
*
|
||||
* @return True if successful, otherwise false.
|
||||
*/
|
||||
bool disconnect_modem_stack();
|
||||
|
||||
/** Read IMSI of modem.
|
||||
*/
|
||||
nsapi_error_t get_imsi(char *imsi);
|
||||
|
||||
/** Get the next set of credentials from the database.
|
||||
*/
|
||||
void get_next_credentials(char **config);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -193,12 +193,9 @@ nsapi_size_or_error_t UBLOX_AT_CellularStack::socket_sendto_impl(CellularSocket
|
|||
const void *data, nsapi_size_t size)
|
||||
{
|
||||
int sent_len = 0;
|
||||
uint8_t ch = 0, cont = 50;
|
||||
|
||||
pollfh fhs;
|
||||
fhs.fh = _at.get_file_handle();
|
||||
fhs.events = POLLIN;
|
||||
int pollCount;
|
||||
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
if (size > UBLOX_MAX_PACKET_SIZE) {
|
||||
|
@ -210,7 +207,7 @@ nsapi_size_or_error_t UBLOX_AT_CellularStack::socket_sendto_impl(CellularSocket
|
|||
_at.write_int(address.get_port());
|
||||
_at.write_int(size);
|
||||
_at.cmd_stop();
|
||||
pollCount = poll(&fhs, 1, 50);
|
||||
(void)poll(&fhs, 1, 50);
|
||||
_at.write_bytes((uint8_t *)data, size);
|
||||
|
||||
_at.resp_start("+USOST:");
|
||||
|
@ -235,7 +232,7 @@ nsapi_size_or_error_t UBLOX_AT_CellularStack::socket_sendto_impl(CellularSocket
|
|||
_at.write_int(socket->id);
|
||||
_at.write_int(blk);
|
||||
_at.cmd_stop();
|
||||
pollCount = poll(&fhs, 1, 50);
|
||||
(void)poll(&fhs, 1, 50);
|
||||
_at.write_bytes((uint8_t *)buf, blk);
|
||||
|
||||
_at.resp_start("+USOWR:");
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "UBLOX_PPP.h"
|
||||
#include "UBLOX_PPP_CellularNetwork.h"
|
||||
#include "UBLOX_PPP_CellularPower.h"
|
||||
#include "UBLOX_PPP_CellularContext.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
@ -29,7 +30,7 @@ static const AT_CellularBase::SupportedFeature unsupported_features[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
UBLOX_PPP::UBLOX_PPP(EventQueue &queue) : AT_CellularDevice(queue)
|
||||
UBLOX_PPP::UBLOX_PPP(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
#ifdef TARGET_UBLOX_C027
|
||||
AT_CellularBase::set_unsupported_features(unsupported_features);
|
||||
|
@ -49,3 +50,8 @@ AT_CellularPower *UBLOX_PPP::open_power_impl(ATHandler &at)
|
|||
{
|
||||
return new UBLOX_PPP_CellularPower(at);
|
||||
}
|
||||
|
||||
AT_CellularContext *UBLOX_PPP::create_context_impl(ATHandler &at, const char *apn)
|
||||
{
|
||||
return new UBLOX_PPP_CellularContext(at, this, apn);
|
||||
}
|
||||
|
|
|
@ -24,16 +24,13 @@ namespace mbed {
|
|||
|
||||
class UBLOX_PPP : public AT_CellularDevice {
|
||||
public:
|
||||
UBLOX_PPP(events::EventQueue &queue);
|
||||
UBLOX_PPP(FileHandle *fh);
|
||||
virtual ~UBLOX_PPP();
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
virtual AT_CellularPower *open_power_impl(ATHandler &at);
|
||||
};
|
||||
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.9", "This API will be deprecated, Use UBLOX_PPP instead of UBLOX_LISA_U.")
|
||||
class UBLOX_LISA_U : public UBLOX_PPP {
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 "UBLOX_PPP_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
UBLOX_PPP_CellularContext::UBLOX_PPP_CellularContext(ATHandler &at, CellularDevice *device, const char *apn) :
|
||||
AT_CellularContext(at, device, apn)
|
||||
{
|
||||
}
|
||||
|
||||
UBLOX_PPP_CellularContext::~UBLOX_PPP_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
bool UBLOX_PPP_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
|
||||
{
|
||||
return stack_type == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 UBLOX_PPP_CELLULARCONTEXT_H_
|
||||
#define UBLOX_PPP_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UBLOX_PPP_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
UBLOX_PPP_CellularContext(ATHandler &at, CellularDevice *device, const char *apn);
|
||||
virtual ~UBLOX_PPP_CellularContext();
|
||||
|
||||
protected:
|
||||
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // UBLOX_PPP_CELLULARCONTEXT_H_
|
|
@ -27,11 +27,6 @@ UBLOX_PPP_CellularNetwork::~UBLOX_PPP_CellularNetwork()
|
|||
{
|
||||
}
|
||||
|
||||
bool UBLOX_PPP_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
|
||||
{
|
||||
return requested_stack == IPV4_STACK ? true : false;
|
||||
}
|
||||
|
||||
AT_CellularNetwork::RegistrationMode UBLOX_PPP_CellularNetwork::has_registration(RegistrationType reg_type)
|
||||
{
|
||||
return (reg_type == C_REG || reg_type == C_GREG) ? RegistrationModeLAC : RegistrationModeDisable;
|
||||
|
|
|
@ -28,17 +28,10 @@ public:
|
|||
virtual ~UBLOX_PPP_CellularNetwork();
|
||||
|
||||
protected:
|
||||
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
|
||||
|
||||
virtual RegistrationMode has_registration(RegistrationType rat);
|
||||
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
};
|
||||
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.9", "This API will be deprecated, Use UBLOX_PPP_CellularNetwork instead of UBLOX_LISA_U_CellularNetwork.")
|
||||
class UBLOX_LISA_U_CellularNetwork : public UBLOX_PPP_CellularNetwork {
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_PPP_CELLULAR_NETWORK_H_
|
||||
|
|
|
@ -34,10 +34,6 @@ public: //from CellularPower
|
|||
virtual nsapi_error_t off();
|
||||
};
|
||||
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.9", "This API will be deprecated, Use UBLOX_PPP_CellularPower instead of UBLOX_LISA_U_CellularPower.")
|
||||
class UBLOX_LISA_U_CellularPower : public UBLOX_PPP_CellularPower {
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // UBLOX_PPP_CELLULARPOWER_H_
|
||||
|
|
|
@ -45,6 +45,12 @@ public:
|
|||
virtual void set_credentials(const char *apn, const char *uname = 0,
|
||||
const char *pwd = 0) = 0;
|
||||
|
||||
/** Set the plmn. PLMN controls to what network device registers.
|
||||
*
|
||||
* @param plmn user to force what network to register.
|
||||
*/
|
||||
virtual void set_plmn(const char *plmn) = 0;
|
||||
|
||||
/** Set the PIN code for SIM card.
|
||||
*
|
||||
* @param sim_pin PIN for the SIM card.
|
||||
|
|
|
@ -129,7 +129,9 @@ MBED_WEAK NetworkInterface *NetworkInterface::get_target_default_instance()
|
|||
#ifdef MBED_CONF_NSAPI_DEFAULT_CELLULAR_SIM_PIN
|
||||
cellular->set_sim_pin(MBED_CONF_NSAPI_DEFAULT_CELLULAR_SIM_PIN);
|
||||
#endif
|
||||
|
||||
#ifdef MBED_CONF_NSAPI_DEFAULT_CELLULAR_PLMN
|
||||
cellular->set_plmn(MBED_CONF_NSAPI_DEFAULT_CELLULAR_PLMN);
|
||||
#endif
|
||||
return cellular;
|
||||
}
|
||||
#elif defined(MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE)
|
||||
|
|
|
@ -60,10 +60,14 @@ void OnboardCellularInterface::modem_power_down()
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // CELLULAR_DEVICE
|
||||
|
||||
#ifdef ONBOARD_CELLULAR_INTERFACE_AVAILABLE
|
||||
#ifdef CELLULAR_DEVICE
|
||||
MBED_WEAK CellularBase *CellularBase::get_target_default_instance()
|
||||
{
|
||||
return CellularContext::get_default_instance();
|
||||
}
|
||||
#elif defined ONBOARD_CELLULAR_INTERFACE_AVAILABLE
|
||||
MBED_WEAK CellularBase *CellularBase::get_target_default_instance()
|
||||
{
|
||||
static OnboardCellularInterface cellular;
|
||||
|
|
|
@ -16,9 +16,41 @@
|
|||
#ifndef ONBOARD_CELLULAR_INTERFACE_
|
||||
#define ONBOARD_CELLULAR_INTERFACE_
|
||||
|
||||
#include "EasyCellularConnection.h"
|
||||
#include "CellularContext.h"
|
||||
#ifdef CELLULAR_DEVICE
|
||||
typedef mbed::EasyCellularConnection OnboardCellularInterface;
|
||||
using namespace mbed;
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.9", "This API will be deprecated, use CellularBase::get_default_instance() instead.")
|
||||
class OnboardCellularInterface : public CellularBase
|
||||
{
|
||||
public:
|
||||
OnboardCellularInterface() {
|
||||
context = CellularContext::get_default_instance();
|
||||
MBED_ASSERT(context != NULL);
|
||||
}
|
||||
public: // from NetworkInterface
|
||||
virtual nsapi_error_t set_blocking(bool blocking) {return context->set_blocking(blocking);}
|
||||
virtual NetworkStack *get_stack() {return context->get_stack();}
|
||||
virtual const char *get_ip_address() {return context->get_ip_address();}
|
||||
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb) {context->attach(status_cb);}
|
||||
virtual nsapi_error_t connect() {return context->connect();}
|
||||
virtual nsapi_error_t disconnect() {return context->disconnect();}
|
||||
|
||||
// from CellularBase
|
||||
virtual void set_plmn(const char *plmn) {context->set_plmn(plmn);}
|
||||
virtual void set_sim_pin(const char *sim_pin) {context->set_sim_pin(sim_pin);}
|
||||
virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0, const char *uname = 0,
|
||||
const char *pwd = 0)
|
||||
{return context->connect(sim_pin, apn, uname, pwd);}
|
||||
virtual void set_credentials(const char *apn, const char *uname = 0, const char *pwd = 0)
|
||||
{context->set_credentials(apn, uname, pwd);}
|
||||
virtual const char *get_netmask() {return context->get_netmask();}
|
||||
virtual const char *get_gateway() {return context->get_gateway();}
|
||||
virtual bool is_connected() {return context->is_connected();}
|
||||
|
||||
private:
|
||||
CellularContext *context;
|
||||
};
|
||||
|
||||
#define ONBOARD_CELLULAR_INTERFACE_AVAILABLE
|
||||
#elif MODEM_ON_BOARD && MODEM_ON_BOARD_UART && NSAPI_PPP_AVAILABLE
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"default-wifi-ssid": null,
|
||||
"default-wifi-password": null,
|
||||
"default-wifi-security": "NONE",
|
||||
"default-cellular-plmn": null,
|
||||
"default-cellular-sim-pin": null,
|
||||
"default-cellular-apn": null,
|
||||
"default-cellular-username": null,
|
||||
|
|
|
@ -261,6 +261,8 @@ typedef enum {
|
|||
P_73 = WAKE,
|
||||
P_74 = NC,
|
||||
P_75 = NC,
|
||||
MDMRTS = NC,
|
||||
MDMCTS = NC,
|
||||
|
||||
} PinName;
|
||||
|
||||
|
|
Loading…
Reference in New Issue