Separated context activation from connect, increased stack size to 2048 to avoid stack underflows and changed connection callback call.

pull/6496/head
Teppo Järvelin 2018-03-20 10:53:00 +02:00
parent f0026e4c48
commit 89843246ac
6 changed files with 101 additions and 78 deletions

View File

@ -175,7 +175,7 @@ bool CellularConnectionFSM::open_sim()
}
if (_event_status_cb) {
_event_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularSIMStatusChanged);
_event_status_cb((nsapi_event_t)CellularSIMStatusChanged, state);
}
return state == CellularSIM::SimStateReady;
@ -302,6 +302,8 @@ bool CellularConnectionFSM::is_automatic_registering()
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;
@ -370,7 +372,7 @@ bool CellularConnectionFSM::device_ready()
{
tr_info("Cellular device ready");
if (_event_status_cb) {
_event_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularDeviceReady);
_event_status_cb((nsapi_event_t)CellularDeviceReady, 0);
}
_power->remove_device_ready_urc_cb(mbed::callback(this, &CellularConnectionFSM::ready_urc_cb));
@ -505,6 +507,8 @@ void CellularConnectionFSM::event()
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;
@ -529,7 +533,7 @@ nsapi_error_t CellularConnectionFSM::start_dispatch()
{
MBED_ASSERT(!_queue_thread);
_queue_thread = new rtos::Thread(osPriorityNormal, 1024);
_queue_thread = new rtos::Thread(osPriorityNormal, 2048);
if (!_queue_thread) {
stop();
return NSAPI_ERROR_NO_MEMORY;
@ -562,14 +566,9 @@ void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr)
{
tr_debug("FSM: network_callback called with event: %d, intptr: %d", ev, ptr);
if (ev == NSAPI_EVENT_CELLULAR_STATUS_CHANGE) {
if (ptr == CellularRegistrationStatusChanged && _state == STATE_REGISTERING_NETWORK) {
// check for registration status
if (is_registered()) {
_queue.cancel(_eventID);
continue_from_state(STATE_ATTACHING_NETWORK);
}
}
if ((cellular_connection_status_t)ev == CellularRegistrationStatusChanged && ptr == CellularNetwork::RegisteredHomeNetwork && _state == STATE_REGISTERING_NETWORK) {
_queue.cancel(_eventID);
continue_from_state(STATE_ATTACHING_NETWORK);
}
if (_event_status_cb) {
@ -579,7 +578,7 @@ void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr)
void CellularConnectionFSM::ready_urc_cb()
{
tr_info("Device ready URC func called");
tr_debug("Device ready URC func called");
if (_state == STATE_DEVICE_READY && _power->set_at_mode() == NSAPI_ERROR_OK) {
tr_info("State was STATE_DEVICE_READY and at mode ready, cancel state and move to next");
_queue.cancel(_eventID);

View File

@ -358,6 +358,13 @@ public:
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 zero on success
*/
virtual nsapi_error_t activate_context() = 0;
/**
* Set the pdn type to be used
*

View File

@ -42,7 +42,7 @@ AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(a
_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), _cell_id(-1), _connect_status(NSAPI_STATUS_DISCONNECTED), _new_context_set(false),
_reg_status(NotRegistered), _current_act(RAT_UNKNOWN)
_is_context_active(false), _reg_status(NotRegistered), _current_act(RAT_UNKNOWN)
{
}
@ -100,14 +100,17 @@ void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
if (_at.get_last_error() == NSAPI_ERROR_OK && _connection_status_cb) {
tr_debug("stat: %d, lac: %d, cellID: %d, act: %d", reg_status, lac, cell_id, act);
if (act != -1 && (RadioAccessTechnology)act != _current_act) {
_current_act = (RadioAccessTechnology)act;
_connection_status_cb((nsapi_event_t)CellularRadioAccessTechnologyChanged, _current_act);
}
if (reg_status != _reg_status) {
_connection_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularRegistrationStatusChanged);
_reg_status = reg_status;
_connection_status_cb((nsapi_event_t)CellularRegistrationStatusChanged, _reg_status);
}
if (cell_id != -1 && cell_id != _cell_id) {
_connection_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularCellIDChanged);
}
if (act != -1 && (RadioAccessTechnology)act != _current_act) {
_connection_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularRadioAccessTechnologyChanged);
_cell_id = cell_id;
_connection_status_cb((nsapi_event_t)CellularCellIDChanged, _cell_id);
}
}
}
@ -206,15 +209,10 @@ nsapi_error_t AT_CellularNetwork::delete_current_context()
return _at.get_last_error();
}
nsapi_error_t AT_CellularNetwork::connect()
nsapi_error_t AT_CellularNetwork::activate_context()
{
_at.lock();
_connect_status = NSAPI_STATUS_CONNECTING;
if (_connection_status_cb) {
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING);
}
nsapi_error_t err = set_context_to_be_activated();
if (err != NSAPI_ERROR_OK) {
_at.unlock();
@ -228,18 +226,58 @@ nsapi_error_t AT_CellularNetwork::connect()
return err;
}
err = open_data_channel();
if (err != NSAPI_ERROR_OK) {
// do check for stack to validate that we have support for stack
_stack = get_stack();
if (!_stack) {
return err;
}
// If new PDP context was created and failed to activate, delete it
if (_new_context_set) {
delete_current_context();
_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();
_at.unlock();
if (!_is_context_active) {
tr_info("Activate PDP context");
_at.cmd_start("AT+CGACT=1,");
_at.write_int(_cid);
_at.cmd_stop();
_at.resp_start();
_at.resp_stop();
}
tr_error("Failed to open data channel!");
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();
}
_at.unlock();
return err;
}
nsapi_error_t AT_CellularNetwork::connect()
{
_connect_status = NSAPI_STATUS_CONNECTING;
if (_connection_status_cb) {
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING);
}
nsapi_error_t err = NSAPI_ERROR_OK;
if (!_is_context_active) {
err = activate_context();
}
if (err) {
_connect_status = NSAPI_STATUS_DISCONNECTED;
if (_connection_status_cb) {
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED);
@ -248,9 +286,19 @@ nsapi_error_t AT_CellularNetwork::connect()
return err;
}
#if NSAPI_PPP_AVAILABLE
_at.lock();
err = open_data_channel();
_at.unlock();
#if !NSAPI_PPP_AVAILABLE
if (err != NSAPI_ERROR_OK) {
tr_error("Failed to open data channel!");
_connect_status = NSAPI_STATUS_DISCONNECTED;
if (_connection_status_cb) {
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED);
}
return err;
}
#else
_connect_status = NSAPI_STATUS_GLOBAL_UP;
if (_connection_status_cb) {
_connection_status_cb(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_GLOBAL_UP);
@ -262,9 +310,6 @@ nsapi_error_t AT_CellularNetwork::connect()
nsapi_error_t AT_CellularNetwork::open_data_channel()
{
//old way: _at.send("ATD*99***%d#", _cid) && _at.recv("CONNECT");
nsapi_error_t err = NSAPI_ERROR_NO_CONNECTION;
#if NSAPI_PPP_AVAILABLE
tr_info("Open data channel in PPP mode");
_at.cmd_start("AT+CGDATA=\"PPP\",");
_at.write_int(_cid);
@ -277,41 +322,7 @@ nsapi_error_t AT_CellularNetwork::open_data_channel()
/* Initialize PPP
* If blocking: mbed_ppp_init() is a blocking call, it will block until
connected, or timeout after 30 seconds*/
err = nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularNetwork::ppp_status_cb), _uname, _pwd, _ip_stack_type);
#else
// do check for stack to validate that we have support for stack
_stack = get_stack();
if (!_stack) {
return err;
}
bool 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;
tr_debug("PDP context %d is active.", _cid);
break;
}
}
_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();
_at.resp_start();
_at.resp_stop();
}
err = (_at.get_last_error() == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION;
#endif
return err;
return nsapi_ppp_connect(_at.get_file_handle(), callback(this, &AT_CellularNetwork::ppp_status_cb), NULL, NULL, _ip_stack_type);
}
/**
@ -695,6 +706,7 @@ nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type,
int lac = -1, cell_id = -1, act = -1;
read_reg_params(type, status, lac, cell_id, act);
_at.resp_stop();
_reg_status = status;
if (cell_id != -1) {
_cell_id = cell_id;

View File

@ -62,6 +62,8 @@ protected:
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);
@ -176,6 +178,7 @@ protected:
int _cell_id;
nsapi_connection_status_t _connect_status;
bool _new_context_set;
bool _is_context_active;
RegistrationStatus _reg_status;
RadioAccessTechnology _current_act;
mbed::Callback<void()> _urc_funcs[C_MAX];

View File

@ -19,18 +19,19 @@
#define CELLULAR_COMMON_
#include <stdint.h>
#include "nsapi_types.h"
/**
* Cellular specific event changes.
* Connect and disconnect are handled via NSAPI_EVENT_CONNECTION_STATUS_CHANGE
*/
typedef enum cellular_event_status {
CellularDeviceReady = 0, /*!< Modem is powered and ready to receive commands */
CellularSIMStatusChanged = 1, /*!< SIM state changed, call SIM state */
CellularRegistrationStatusChanged = 2, /*!< Registering status changed, e.g. roaming, registered, smsonly... */
CellularRegistrationTypeChanged = 3, /*!< Registration type changed, e.g. C_EREG, C_GREG, C_REG */
CellularCellIDChanged = 4, /*!< Network Cell ID have changed */
CellularRadioAccessTechnologyChanged = 5, /*!< Network roaming status have changed */
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 */
} cellular_connection_status_t;
#endif // CELLULAR_COMMON_

View File

@ -80,7 +80,8 @@ enum nsapi_error {
*/
typedef enum nsapi_event {
NSAPI_EVENT_CONNECTION_STATUS_CHANGE = 0, /*!< network connection status has changed, the parameter = new status (nsapi_connection_status_t) */
NSAPI_EVENT_CELLULAR_STATUS_CHANGE = 1 /*!< cellular modem status has changed, the parameter = new status (cellular_connection_status_t) */
NSAPI_EVENT_CELLULAR_STATUS_BASE = 0x1000, /*!< Cellular modem status has changed, See the enum values from enum cellular_connection_status_t in /features/cellular/framework/common/CellularCommon.h */
NSAPI_EVENT_CELLULAR_STATUS_END = 0x1FFF /*!< cellular modem status has changed, See the enum values from enum cellular_connection_status_t in /features/cellular/framework/common/CellularCommon.h */
} nsapi_event_t;