Working version of async registration.

pull/6496/head
Teppo Järvelin 2018-03-14 15:24:29 +02:00
parent 2b14a9ee5f
commit d1f2e91e93
11 changed files with 90 additions and 90 deletions

View File

@ -24,7 +24,7 @@
#endif
#include "CellularLog.h"
#include "CellularCommon.h"
#include "mbed_wait_api.h"
// timeout to wait for AT responses
#define TIMEOUT_POWER_ON (1*1000)
#define TIMEOUT_SIM_PIN (1*1000)
@ -110,16 +110,11 @@ nsapi_error_t CellularConnectionFSM::init()
_at_queue.chain(&_queue);
_network->set_registration_urc(CellularNetwork::C_EREG, true);
_network->set_registration_urc(CellularNetwork::C_GREG, true);
_network->set_registration_urc(CellularNetwork::C_REG, true);
_retry_count = 0;
_state = STATE_INIT;
_next_state = STATE_INIT;
tr_info("init done...");
return NSAPI_ERROR_OK;
return _network->init();
}
bool CellularConnectionFSM::power_on()
@ -305,7 +300,7 @@ void CellularConnectionFSM::report_failure(const char* msg)
const char* CellularConnectionFSM::get_state_string(CellularState state)
{
static const char *strings[] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Attaching network", "Connect network", "Connected"};
static const char *strings[] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Attaching network", "Connecting network", "Connected"};
return strings[state];
}
@ -393,6 +388,19 @@ void CellularConnectionFSM::state_device_ready()
if (_event_status_cb) {
_event_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularDeviceReady);
}
bool success = false;
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
if (!_network->set_registration_urc((CellularNetwork::RegistrationType)type, true)) {
success = true;
}
}
if (!success) {
tr_error("Failed to set any URC's for registration");
report_failure(get_state_string(_state));
return;
}
print_device_info();
enter_to_state(STATE_SIM_PIN);
} else {
@ -433,7 +441,7 @@ void CellularConnectionFSM::state_attaching()
CellularNetwork::AttachStatus attach_status;
if (get_attach_network(attach_status)) {
if (attach_status == CellularNetwork::Attached) {
enter_to_state(STATE_CONNECT_NETWORK);
enter_to_state(STATE_CONNECTING_NETWORK);
} else {
set_attach_network();
retry_state_or_fail();
@ -487,7 +495,7 @@ void CellularConnectionFSM::event()
case STATE_ATTACHING_NETWORK:
state_attaching();
break;
case STATE_CONNECT_NETWORK:
case STATE_CONNECTING_NETWORK:
state_connect_to_network();
break;
case STATE_CONNECTED:
@ -500,20 +508,19 @@ void CellularConnectionFSM::event()
if (_next_state != _state || _event_timeout >= 0) {
if (_next_state != _state) { // state exit condition
//tr_info("Cellular state from %d to %d", _state, _next_state);
if (_status_callback) {
if (!_status_callback(_state, _next_state)) {
return;
}
}
} else {
tr_info("Cellular event in %d milliseconds", _event_timeout);
tr_info("Cellular event in %d seconds", _event_timeout);
}
_state = _next_state;
if (_event_timeout == -1) {
_event_timeout = 0;
}
_eventID = _queue.call_in(_event_timeout, callback(this, &CellularConnectionFSM::event));
_eventID = _queue.call_in(_event_timeout*1000, callback(this, &CellularConnectionFSM::event));
if (!_eventID) {
report_failure("Cellular event failure!");
return;
@ -569,7 +576,7 @@ void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr)
} /*else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
if (ptr == NSAPI_STATUS_GLOBAL_UP) {
// we are connected
if (_state == STATE_CONNECT_NETWORK) {
if (_state == STATE_CONNECTING_NETWORK) {
_queue.cancel(_eventID);
continue_from_state(STATE_CONNECTED);
}

View File

@ -60,8 +60,8 @@ public:
STATE_SIM_PIN,
STATE_REGISTERING_NETWORK,
STATE_ATTACHING_NETWORK,
STATE_CONNECT_NETWORK,
STATE_CONNECTED,
STATE_CONNECTING_NETWORK,
STATE_CONNECTED
};
public:

View File

@ -130,11 +130,6 @@ void EasyCellularConnection::set_sim_pin(const char *sim_pin)
}
}
void EasyCellularConnection::set_is_blocking(bool blocking)
{
}
nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
{
if (_is_connected) {

View File

@ -132,7 +132,6 @@ public:
*/
void modem_debug_on(bool on);
void set_is_blocking(bool blocking);
protected:
/** Provide access to the NetworkStack object

View File

@ -209,6 +209,12 @@ public:
};
/** Does all the needed initializations that can fail
*
* @return zero on success
*/
virtual nsapi_error_t init() = 0;
/** Request registering to network.
*
* @param plmn format is in numeric format or 0 for automatic network registration

View File

@ -153,17 +153,17 @@ void ATHandler::set_file_handle(FileHandle *fh)
_fileHandle = fh;
}
void ATHandler::set_urc_handler(const char *prefix, mbed::Callback<void()> callback)
nsapi_error_t ATHandler::set_urc_handler(const char *prefix, mbed::Callback<void()> callback)
{
if (check_urc_existance(prefix, callback)) {
tr_warn("URC already added with prefix: %s", prefix);
return;
return NSAPI_ERROR_OK;
}
// TODO: what to do if this allocation fails? Should this return boolean false? Quite a few urc urc's are
// called from constructors which is another problem...
struct oob_t *oob = new struct oob_t;
if (oob) {
if (!oob) {
return NSAPI_ERROR_NO_MEMORY;
} else {
size_t prefix_len = strlen(prefix);
if (prefix_len > _oob_string_max_length) {
_oob_string_max_length = prefix_len;
@ -177,6 +177,8 @@ void ATHandler::set_urc_handler(const char *prefix, mbed::Callback<void()> callb
oob->next = _oobs;
_oobs = oob;
}
return NSAPI_ERROR_OK;
}
bool ATHandler::check_urc_existance(const char *prefix, mbed::Callback<void()> callback)

View File

@ -106,11 +106,13 @@ public:
nsapi_error_t unlock_return_error();
/** Set the urc callback for urc. If urc is found when parsing AT responses, then call if called.
* If urc is already set then it's not set twice.
*
* @param prefix Register urc prefix for callback. Urc could be for example "+CMTI: "
* @param callback Callback, which is called if urc is found in AT response
* @return NSAPI_ERROR_OK or NSAPI_ERROR_NO_MEMORY if no memory
*/
void set_urc_handler(const char *prefix, mbed::Callback<void()> callback);
nsapi_error_t set_urc_handler(const char *prefix, mbed::Callback<void()> callback);
ATHandler *_nextATHandler; // linked list

View File

@ -29,24 +29,23 @@ using namespace mbed;
struct at_reg_t {
const CellularNetwork::RegistrationType type;
const char *const cmd;
const char *const urc;
void (*urc_handler)();
const char *const urc_prefix;
};
static const at_reg_t at_reg[] = {
{ CellularNetwork::C_EREG, "AT+CEREG", "+CEREG:", AT_CellularNetwork::urc_creg},
{ CellularNetwork::C_GREG, "AT+CGREG", "+CGREG:", AT_CellularNetwork::urc_cgreg},
{ CellularNetwork::C_REG, "AT+CREG", "+CREG:", AT_CellularNetwork::urc_creg}
{ CellularNetwork::C_EREG, "AT+CEREG", "+CEREG:"},
{ CellularNetwork::C_GREG, "AT+CGREG", "+CGREG:"},
{ CellularNetwork::C_REG, "AT+CREG", "+CREG:"}
};
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), _last_reg_type(C_REG),
_connect_status(NSAPI_STATUS_DISCONNECTED), _new_context_set(false), _reg_status(NotRegistered), _async(false)
_connect_status(NSAPI_STATUS_DISCONNECTED), _new_context_set(false), _reg_status(NotRegistered)
{
_at.set_urc_handler("NO CARRIER", callback(this, &AT_CellularNetwork::urc_no_carrier));
_at.set_urc_handler("NO CARRIER", callback(this, &AT_CellularNetwork::urc_no_carrier));
_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);
}
AT_CellularNetwork::~AT_CellularNetwork()
@ -54,6 +53,19 @@ AT_CellularNetwork::~AT_CellularNetwork()
free_credentials();
}
nsapi_error_t AT_CellularNetwork::init()
{
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
if (has_registration((RegistrationType)type)) {
if (_at.set_urc_handler(at_reg[type].urc_prefix, _urc_funcs[type])) {
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) {
@ -77,15 +89,15 @@ void AT_CellularNetwork::urc_no_carrier()
}
}
void AT_CellularNetwork::read_reg_params_and_compare(int index)
void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
{
RegistrationStatus reg_status = NotRegistered;
int lac = -1, cell_id = -1, act = -1;
read_reg_params(index, reg_status, lac, cell_id, act);
read_reg_params(type, reg_status, lac, cell_id, act);
if (_at.get_last_error() == NSAPI_ERROR_OK) {
tr_info("stat: %d, lac: %d, cellID: %d, act: %d", reg_status, lac, cell_id, act);
tr_debug("stat: %d, lac: %d, cellID: %d, act: %d", reg_status, lac, cell_id, act);
if (reg_status != _reg_status && _connection_status_cb) {
_connection_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularRegistrationStatusChanged);
}
@ -102,19 +114,19 @@ void AT_CellularNetwork::read_reg_params_and_compare(int index)
void AT_CellularNetwork::urc_creg()
{
tr_info("urc_creg");
tr_debug("urc_creg");
read_reg_params_and_compare(C_REG);
}
void AT_CellularNetwork::urc_cereg()
{
tr_info("urc_cereg");
tr_debug("urc_cereg");
read_reg_params_and_compare(C_EREG);
}
void AT_CellularNetwork::urc_cgreg()
{
tr_info("urc_cgreg");
tr_debug("urc_cgreg");
read_reg_params_and_compare(C_GREG);
}
@ -342,7 +354,6 @@ nsapi_connection_status_t AT_CellularNetwork::get_connection_status() const
nsapi_error_t AT_CellularNetwork::set_blocking(bool blocking)
{
_async = !blocking;
#if NSAPI_PPP_AVAILABLE
return nsapi_ppp_set_blocking(blocking);
#else
@ -567,14 +578,13 @@ nsapi_ip_stack_t AT_CellularNetwork::string_to_stack_type(const char* pdp_type)
nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bool urc_on)
{
_at.lock();
MBED_ASSERT(type >= 0 && type < C_MAX);
int index = (int)type;
MBED_ASSERT(index >= 0 && index < C_MAX);
if (has_registration(type)) {
_at.lock();
_last_reg_type = type;
if (urc_on) {
_at.set_urc_handler(at_reg[type].urc, at_reg[type].urc_handler);
_at.cmd_start(at_reg[type].cmd);
_at.write_string("=2", false);
_at.cmd_stop();
@ -586,9 +596,10 @@ nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bo
_at.resp_start();
_at.resp_stop();
return _at.unlock_return_error();
} else {
return NSAPI_ERROR_UNSUPPORTED;
}
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode& mode)
@ -634,7 +645,7 @@ nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn)
return _at.unlock_return_error();
}
void AT_CellularNetwork::read_reg_params(int type_index, RegistrationStatus &reg_status, int &lac, int &cell_id, int &act)
void AT_CellularNetwork::read_reg_params(RegistrationType type, RegistrationStatus &reg_status, int &lac, int &cell_id, int &act)
{
const int LAC_LENGTH = 5, CELL_ID_LENGTH = 9;
char lac_string[LAC_LENGTH] = {0}, cell_id_string[CELL_ID_LENGTH] = {0};
@ -663,6 +674,10 @@ void AT_CellularNetwork::read_reg_params(int type_index, RegistrationStatus &reg
cell_id = hex_str_to_int(cell_id_string, CELL_ID_LENGTH);
tr_debug("cell_id %s %d", cell_id_string, cell_id );
}
if (_at.get_last_error() == NSAPI_ERROR_OK) {
_last_reg_type = type;
}
}
nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type, RegistrationStatus &status)
@ -675,13 +690,6 @@ nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type,
}
_at.lock();
if (!_async) {
_at.cmd_start(at_reg[i].cmd);
_at.write_string("=2", false);
_at.cmd_stop();
_at.resp_start();
_at.resp_stop();
}
const char *rsp[] = { "+CEREG:", "+CGREG:", "+CREG:"};
_at.cmd_start(at_reg[i].cmd);
@ -689,10 +697,9 @@ nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type,
_at.cmd_stop();
_at.resp_start(rsp[i]);
_at.read_int(); // ignore urc mode subparam
int lac = -1, cell_id = -1, act = -1;
read_reg_params(i, status, lac, cell_id, act);
read_reg_params(type, status, lac, cell_id, act);
_at.resp_stop();
if (cell_id != -1) {
@ -702,32 +709,12 @@ nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type,
_current_act = (RadioAccessTechnology)act;
}
if (!_async) {
_at.cmd_start(at_reg[i].cmd);
_at.write_string("=0", false);
_at.cmd_stop();
_at.resp_start();
_at.resp_stop();
}
if (_at.get_last_error() == NSAPI_ERROR_OK) {
_last_reg_type = type;
}
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularNetwork::get_cell_id(int &cell_id)
{
if (_async) {
return _cell_id;
}
RegistrationStatus tmp;
nsapi_error_t error = get_registration_status(_last_reg_type, tmp);
cell_id = _cell_id;
return error;
return _cell_id;
}
bool AT_CellularNetwork::has_registration(RegistrationType reg_type)

View File

@ -60,6 +60,8 @@ protected:
virtual NetworkStack *get_stack();
public: // CellularNetwork
virtual nsapi_error_t init();
virtual nsapi_error_t set_registration(const char *plmn = 0);
virtual nsapi_error_t get_network_registering_mode(NWRegisteringMode& mode);
@ -135,7 +137,6 @@ protected:
*/
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat);
private:
// "NO CARRIER" urc
void urc_no_carrier();
@ -154,8 +155,8 @@ private:
nsapi_error_t delete_current_context();
void read_reg_params_and_compare(int index);
void read_reg_params(int type_index, RegistrationStatus &reg_status, int &lac, int &cell_id, int &act);
void read_reg_params_and_compare(RegistrationType type);
void read_reg_params(RegistrationType type, RegistrationStatus &reg_status, int &lac, int &cell_id, int &act);
#if NSAPI_PPP_AVAILABLE
void ppp_status_cb(nsapi_event_t, intptr_t);
@ -178,8 +179,7 @@ protected:
bool _new_context_set;
RegistrationStatus _reg_status;
RadioAccessTechnology _current_act;
bool _async;
mbed::Callback<void()> _urc_funcs[C_MAX];
};
} // namespace mbed

View File

@ -176,9 +176,6 @@ const int GSM_TO_ASCII_TABLE_SIZE = sizeof(gsm_to_ascii)/sizeof(gsm_to_ascii[0])
AT_CellularSMS::AT_CellularSMS(ATHandler &at) : AT_CellularBase(at), _cb(0), _mode(CellularSMSMmodeText),
_use_8bit_encoding(false), _sim_wait_time(0), _sms_message_ref_number(1), _sms_info(NULL)
{
/* URCs, handled out of band */
_at.set_urc_handler("+CMTI:", callback(this, &AT_CellularSMS::cmti_urc));
_at.set_urc_handler("+CMT:", callback(this, &AT_CellularSMS::cmt_urc));
}
AT_CellularSMS::~AT_CellularSMS()
@ -258,6 +255,11 @@ nsapi_error_t AT_CellularSMS::set_csdh(int show_header)
nsapi_error_t AT_CellularSMS::initialize(CellularSMSMmode mode)
{
if (_at.set_urc_handler("+CMTI:", callback(this, &AT_CellularSMS::cmti_urc)) ||
_at.set_urc_handler("+CMT:", callback(this, &AT_CellularSMS::cmt_urc))) {
return NSAPI_ERROR_NO_MEMORY;
}
_at.lock();
set_cnmi(); //set new SMS indication
set_cmgf(mode); //set message format/PDU

View File

@ -31,6 +31,6 @@ typedef enum cellular_event_status {
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 */
} cellular_connection_status_t
} cellular_connection_status_t;
#endif // CELLULAR_COMMON_