From 83ea9be5f581746f179a3ccde7c4bfd9a08b7775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Teppo=20J=C3=A4rvelin?= Date: Thu, 8 Mar 2018 12:20:40 +0200 Subject: [PATCH] temp commit while changing work... --- .../easy_cellular/CellularConnectionFSM.cpp | 142 ++++++++---- .../easy_cellular/CellularConnectionFSM.h | 6 +- .../easy_cellular/EasyCellularConnection.cpp | 10 +- .../easy_cellular/EasyCellularConnection.h | 1 + .../cellular/framework/API/CellularNetwork.h | 39 +++- .../framework/AT/AT_CellularNetwork.cpp | 206 ++++++++++++------ .../framework/AT/AT_CellularNetwork.h | 25 ++- .../framework/common/CellularCommon.h | 12 +- .../BC95/QUECTEL_BC95_CellularNetwork.cpp | 8 +- .../BC95/QUECTEL_BC95_CellularNetwork.h | 2 +- .../BG96/QUECTEL_BG96_CellularNetwork.cpp | 16 +- .../BG96/QUECTEL_BG96_CellularNetwork.h | 2 +- .../HE910/TELIT_HE910_CellularNetwork.cpp | 4 +- .../TELIT/HE910/TELIT_HE910_CellularNetwork.h | 2 +- .../UBLOX/PPP/UBLOX_PPP_CellularNetwork.cpp | 4 +- .../UBLOX/PPP/UBLOX_PPP_CellularNetwork.h | 2 +- features/netsocket/nsapi_types.h | 2 +- 17 files changed, 329 insertions(+), 154 deletions(-) diff --git a/features/cellular/easy_cellular/CellularConnectionFSM.cpp b/features/cellular/easy_cellular/CellularConnectionFSM.cpp index bf18a96361..aee17cd0d7 100644 --- a/features/cellular/easy_cellular/CellularConnectionFSM.cpp +++ b/features/cellular/easy_cellular/CellularConnectionFSM.cpp @@ -24,6 +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) @@ -39,7 +40,8 @@ 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), _retry_count(0), _state_retry_count(0), _event_timeout(-1), _at_queue(8 * EVENTS_EVENT_SIZE) + _queue(8 * EVENTS_EVENT_SIZE), _queue_thread(0), _cellularDevice(0), _retry_count(0), _state_retry_count(0), _event_timeout(-1), + _at_queue(8 * EVENTS_EVENT_SIZE), _eventID(0) { memset(_sim_pin, 0, sizeof(_sim_pin)); #if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0 @@ -61,8 +63,6 @@ CellularConnectionFSM::CellularConnectionFSM() : _retry_timeout_array[8] = 600; _retry_timeout_array[9] = TIMEOUT_NETWORK_MAX; _retry_array_length = MAX_RETRY_ARRAY_SIZE; - - _cellularDevice = new CELLULAR_DEVICE(_at_queue); } CellularConnectionFSM::~CellularConnectionFSM() @@ -72,6 +72,13 @@ CellularConnectionFSM::~CellularConnectionFSM() nsapi_error_t CellularConnectionFSM::init() { + tr_info("CELLULAR_DEVICE: %s", CELLULAR_STRINGIFY(CELLULAR_DEVICE)); + _cellularDevice = new CELLULAR_DEVICE(_at_queue); + if (!_cellularDevice) { + stop(); + return NSAPI_ERROR_NO_MEMORY; + } + _power = _cellularDevice->open_power(_serial); if (!_power) { stop(); @@ -82,6 +89,8 @@ nsapi_error_t CellularConnectionFSM::init() stop(); return NSAPI_ERROR_NO_MEMORY; } + // use asynchronous mode + _network->set_blocking(false); _sim = _cellularDevice->open_sim(_serial); if (!_sim) { @@ -91,7 +100,12 @@ nsapi_error_t CellularConnectionFSM::init() _at_queue.chain(&_queue); + _retry_count = 0; + _state_retry_count = 0; + _state = STATE_INIT; + _next_state = STATE_INIT; tr_info("init done..."); + return NSAPI_ERROR_OK; } @@ -131,11 +145,10 @@ bool CellularConnectionFSM::open_sim() } tr_info("Initial SIM state: %d", state); - if (strlen(_sim_pin)) { - nsapi_error_t err; - if (state == CellularSIM::SimStatePinNeeded) { + if (state == CellularSIM::SimStatePinNeeded) { + if (strlen(_sim_pin)) { tr_info("SIM pin required, entering pin: %s", _sim_pin); - err = _sim->set_pin(_sim_pin); + nsapi_error_t err = _sim->set_pin(_sim_pin); if (err) { if (_event_status_cb) { _event_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularSIMStatusChanged); @@ -152,9 +165,13 @@ bool CellularConnectionFSM::open_sim() wait(1); } } + } else { + tr_warn("PIN required but No SIM pin provided."); } - } else { - tr_info("No SIM pin provided."); + } + + if (state == CellularSIM::SimStateReady) { + tr_info("SIM Ready"); } if (_event_status_cb) { @@ -188,6 +205,23 @@ bool CellularConnectionFSM::set_network_registration(char *plmn) return true; } +bool CellularConnectionFSM::is_registered() +{ + CellularNetwork::RegistrationStatus status; + bool is_registered = false; + + for (int type = 0; type < CellularNetwork::C_MAX; type++) { + if (get_network_registration((CellularNetwork::RegistrationType) type, status, is_registered)) { + tr_debug("get_network_registration: type=%d, status=%d", type, status); + if (is_registered) { + break; + } + } + } + + return is_registered; +} + bool CellularConnectionFSM::get_network_registration(CellularNetwork::RegistrationType type, CellularNetwork::RegistrationStatus &status, bool &is_registered) { @@ -300,12 +334,40 @@ char* CellularConnectionFSM::get_state_string(CellularState state) MBED_ASSERT(0); break; } + + return _st_string; +} + +bool CellularConnectionFSM::is_automatic_registering() +{ + CellularNetwork::NWRegisteringMode mode; + nsapi_error_t err = _network->get_network_registering_mode(mode); + tr_info("automatic registering err: %d, mode: %d", err, mode); + if (err == NSAPI_ERROR_OK && mode == CellularNetwork::NWModeAutomatic) { + return true; + } + return false; +} + + +nsapi_error_t CellularConnectionFSM::continue_from_state(CellularState state) +{ + _state = state; + 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) { 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(); @@ -382,33 +444,18 @@ void CellularConnectionFSM::state_sim_pin() void CellularConnectionFSM::state_registering() { _cellularDevice->set_timeout(TIMEOUT_NETWORK); - CellularNetwork::RegistrationStatus status; - bool is_registered; _next_state = STATE_REGISTER_NETWORK; - for (int type = 0; type < CellularNetwork::C_MAX; type++) { - if (get_network_registration((CellularNetwork::RegistrationType) type, status, is_registered)) { - tr_debug("get_network_registration: type=%d, status=%d", type, status); - if (is_registered) { - tr_info("Registered to cellular network (type %d, status %d)", type, status); - enter_to_state(STATE_ATTACHING_NETWORK); - _state_retry_count = 0; - _event_timeout = 0; - tr_info("Check cellular network attach state"); - break; - } else { - if (_retry_count < 180) { - _event_timeout = 1000; - _next_state = STATE_REGISTERING_NETWORK; - tr_info("Waiting for registration %d/180 (type %d, status %d)", _retry_count, type, status); - } else { - tr_info("Start cellular registration"); - enter_to_state(STATE_REGISTER_NETWORK); - break; - } - } - } + if (is_automatic_registering()) { + _network->set_registration_urc(true); + // Automatic registering is on, we now wait for async response with max time 180s + _next_state = STATE_REGISTERING_NETWORK; + _event_timeout = 180*1000; + tr_info("STATE_REGISTERING_NETWORK, event timeout 180s"); } + if (_retry_count > 3) { + _event_timeout = -1; + } if (_next_state == STATE_REGISTERING_NETWORK) { _retry_count++; } @@ -543,20 +590,21 @@ 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); + //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 milliseconds", _event_timeout); } _state = _next_state; if (_event_timeout == -1) { _event_timeout = 0; } - if (!_queue.call_in(_event_timeout, callback(this, &CellularConnectionFSM::event))) { + _eventID = _queue.call_in(_event_timeout, callback(this, &CellularConnectionFSM::event)); + if (!_eventID) { report_failure("Cellular event failure!"); return; } @@ -608,7 +656,27 @@ void CellularConnectionFSM::set_callback(mbed::Callback status_c void CellularConnectionFSM::attach(mbed::Callback status_cb) { _event_status_cb = status_cb; - _network->attach(status_cb); + _network->attach(callback(this, &CellularConnectionFSM::network_callback)); +} + +void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr) +{ + + tr_info("network_callback called with ev: %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()) { + tr_info("Registered, cancel state and continue to attach..."); + _queue.cancel(_eventID); + continue_from_state(STATE_ATTACH_NETWORK); + } + } + } + + if (_event_status_cb) { + _event_status_cb(ev, ptr); + } } events::EventQueue *CellularConnectionFSM::get_queue() diff --git a/features/cellular/easy_cellular/CellularConnectionFSM.h b/features/cellular/easy_cellular/CellularConnectionFSM.h index eb161992cd..0d83e19574 100644 --- a/features/cellular/easy_cellular/CellularConnectionFSM.h +++ b/features/cellular/easy_cellular/CellularConnectionFSM.h @@ -141,6 +141,7 @@ public: */ void set_retry_timeout_array(uint16_t timeout[], int array_len); + bool is_automatic_registering(); char* get_state_string(CellularState state); private: bool power_on(); @@ -149,6 +150,7 @@ private: bool set_network_registration(char *plmn = 0); bool get_attach_network(CellularNetwork::AttachStatus &status); bool set_attach_network(); + bool is_registered(); // state functions to keep state machine simple void state_init(); @@ -163,7 +165,8 @@ private: 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); private: friend class EasyCellularConnection; @@ -197,6 +200,7 @@ private: int _retry_array_length; events::EventQueue _at_queue; char _st_string[20]; + int _eventID; }; } // namespace diff --git a/features/cellular/easy_cellular/EasyCellularConnection.cpp b/features/cellular/easy_cellular/EasyCellularConnection.cpp index 7b3e89f05a..ba5e009710 100644 --- a/features/cellular/easy_cellular/EasyCellularConnection.cpp +++ b/features/cellular/easy_cellular/EasyCellularConnection.cpp @@ -37,7 +37,9 @@ namespace mbed { bool EasyCellularConnection::cellular_status(int state, int next_state) { - tr_info("cellular_status %s => %s", _cellularConnectionFSM.get_state_string(state), _cellularConnectionFSM.get_state_string(next_state)); + tr_info("cellular_status state: %s", _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)state)); + tr_info("cellular_status next_state: %s", _cellularConnectionFSM.get_state_string((CellularConnectionFSM::CellularState)next_state)); + if (_target_state == state) { if (state == CellularConnectionFSM::STATE_CONNECTED) { _is_connected = true; @@ -53,6 +55,11 @@ bool EasyCellularConnection::cellular_status(int state, int next_state) return true; } +void EasyCellularConnection::network_callback(nsapi_event_t ev, intptr_t ptr) +{ + +} + EasyCellularConnection::EasyCellularConnection(bool debug) : _is_connected(false), _is_initialized(false), _target_state(CellularConnectionFSM::STATE_POWER_ON), _cellularSerial( MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE), _cellularSemaphore(0), _cellularConnectionFSM(), _credentials_err( @@ -84,6 +91,7 @@ nsapi_error_t EasyCellularConnection::init() if (err == NSAPI_ERROR_OK) { err = _cellularConnectionFSM.start_dispatch(); + _cellularConnectionFSM.attach(callback(this, &EasyCellularConnection::network_callback)); } _is_initialized = true; } diff --git a/features/cellular/easy_cellular/EasyCellularConnection.h b/features/cellular/easy_cellular/EasyCellularConnection.h index 144c89e2b3..909499600f 100644 --- a/features/cellular/easy_cellular/EasyCellularConnection.h +++ b/features/cellular/easy_cellular/EasyCellularConnection.h @@ -146,6 +146,7 @@ private: * @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(); diff --git a/features/cellular/framework/API/CellularNetwork.h b/features/cellular/framework/API/CellularNetwork.h index 46934770c5..8a6a71d792 100644 --- a/features/cellular/framework/API/CellularNetwork.h +++ b/features/cellular/framework/API/CellularNetwork.h @@ -116,16 +116,7 @@ public: CHAP }; - // 3GPP TS 27.007 - 7.3 PLMN selection +COPS - struct operator_t { - enum Status { - Unknown, - Available, - Current, - Forbiden - }; - - enum RadioAccessTechnology { + enum RadioAccessTechnology { RAT_GSM, RAT_GSM_COMPACT, RAT_UTRAN, @@ -139,6 +130,14 @@ public: RAT_UNKNOWN }; + // 3GPP TS 27.007 - 7.3 PLMN selection +COPS + struct operator_t { + enum Status { + Unknown, + Available, + Current, + Forbiden + }; Status op_status; char op_long[MAX_OPERATOR_NAME_LONG+1]; @@ -200,6 +199,15 @@ public: }; typedef CellularList pdpContextList_t; + /* Network registering mode */ + enum NWRegisteringMode { + NWModeAutomatic = 0, // automatic registering + NWModeManual, // manual registering with plmn + NWModeDeRegister, // deregister from network + NWModeSetOnly, // set only (for read command +COPS?), do not attempt registration/deregistration + NWModeManualAutomatic // if manual fails, fallback to automatic + }; + /** Request registering to network. * * @param plmn format is in numeric format or 0 for automatic network registration @@ -207,6 +215,15 @@ public: */ virtual nsapi_error_t set_registration(const char *plmn = 0) = 0; + /** Get the current network registering mode + * + * @param on successful return contains the current network registering mode + * @return zero on success + */ + virtual nsapi_error_t get_network_registering_mode(NWRegisteringMode& mode) = 0; + + virtual nsapi_error_t set_registration_urc(bool on) = 0; + /** Gets the network registration status. * * @param type see RegistrationType values @@ -273,7 +290,7 @@ public: * @param op_rat Radio access technology * @return zero on success */ - virtual nsapi_error_t set_access_technology(operator_t::RadioAccessTechnology op_rat) = 0; + virtual nsapi_error_t set_access_technology(RadioAccessTechnology op_rat) = 0; /** Scans for operators module can reach. * diff --git a/features/cellular/framework/AT/AT_CellularNetwork.cpp b/features/cellular/framework/AT/AT_CellularNetwork.cpp index f9306fe206..31812bf98b 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.cpp +++ b/features/cellular/framework/AT/AT_CellularNetwork.cpp @@ -20,6 +20,7 @@ #include "nsapi_ppp.h" #include "CellularUtil.h" #include "CellularLog.h" +#include "CellularCommon.h" using namespace std; using namespace mbed_cellular_util; @@ -31,18 +32,22 @@ struct at_reg_t { }; static const at_reg_t at_reg[] = { - { CellularNetwork::C_EREG, "AT+CEREG" }, - { CellularNetwork::C_GREG, "AT+CGREG" }, - { CellularNetwork::C_REG, "AT+CREG" }, + { CellularNetwork::C_EREG, "AT+CEREG"}, + { CellularNetwork::C_GREG, "AT+CGREG"}, + { CellularNetwork::C_REG, "AT+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(operator_t::RAT_UNKNOWN), _authentication_type(CHAP), _last_reg_type(C_REG), - _connect_status(NSAPI_STATUS_DISCONNECTED), _new_context_set(false) + _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) { _at.set_urc_handler("NO CARRIER", callback(this, &AT_CellularNetwork::urc_no_carrier)); + + _at.set_urc_handler("+CEREG:", callback(this, &AT_CellularNetwork::urc_cereg)); + _at.set_urc_handler("+CGREG:", callback(this, &AT_CellularNetwork::urc_cgreg)); + _at.set_urc_handler("+CREG:", callback(this, &AT_CellularNetwork::urc_creg)); } AT_CellularNetwork::~AT_CellularNetwork() @@ -73,6 +78,47 @@ void AT_CellularNetwork::urc_no_carrier() } } +void AT_CellularNetwork::read_reg_params_and_compare(int index) +{ + RegistrationStatus reg_status = NotRegistered; + int lac = -1, cell_id = -1, act = -1; + + read_reg_params(index, 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); + if (reg_status != _reg_status && _connection_status_cb) { + _connection_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularRegistrationStatusChanged); + } + + if (cell_id != -1 && cell_id != _cell_id && _connection_status_cb) { + _connection_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularCellIDChanged); + } + + if (act != -1 && (RadioAccessTechnology)act != _current_act && _connection_status_cb) { + _connection_status_cb(NSAPI_EVENT_CELLULAR_STATUS_CHANGE, CellularRadioAccessTechnologyChanged); + } + } +} + +void AT_CellularNetwork::urc_creg() +{ + tr_info("urc_creg"); + read_reg_params_and_compare(C_REG); +} + +void AT_CellularNetwork::urc_cereg() +{ + tr_info("urc_cereg"); + read_reg_params_and_compare(C_EREG); +} + +void AT_CellularNetwork::urc_cgreg() +{ + tr_info("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) { @@ -297,14 +343,14 @@ 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 - return NSAPI_ERROR_UNSUPPORTED; + return NSAPI_ERROR_OK; #endif } - #if NSAPI_PPP_AVAILABLE void AT_CellularNetwork::ppp_status_cb(nsapi_event_t event, intptr_t parameter) { @@ -316,8 +362,6 @@ void AT_CellularNetwork::ppp_status_cb(nsapi_event_t event, intptr_t parameter) } #endif - - nsapi_error_t AT_CellularNetwork::set_context_to_be_activated() { // try to find or create context with suitable stack @@ -528,6 +572,7 @@ nsapi_error_t AT_CellularNetwork::set_registration_urc(bool urc_on) if (has_registration(at_reg[i].type)) { _last_reg_type = at_reg[i].type; if (urc_on) { + tr_info("setting reg urc for i: %d", i); _at.cmd_start(at_reg[i].cmd); _at.write_string("=2", false); _at.cmd_stop(); @@ -544,13 +589,26 @@ nsapi_error_t AT_CellularNetwork::set_registration_urc(bool urc_on) return _at.get_last_error(); } +nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode& mode) +{ + _at.lock(); + _at.cmd_start("AT+COPS?"); + _at.cmd_stop(); + _at.resp_start("+COPS:"); + int tmpmode = (NWRegisteringMode)_at.read_int(); + tr_info("get_network_registering_mode, tmpmode: %d", tmpmode); + _at.resp_stop(); + + mode = (NWRegisteringMode)tmpmode; + return _at.unlock_return_error(); +} + nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn) { _at.lock(); - nsapi_error_t ret = set_registration_urc(false); + nsapi_error_t ret = set_registration_urc(_async); if (ret) { - tr_error("Setting registration URC failed!"); _at.clear_error(); // allow temporary failures here } @@ -580,40 +638,13 @@ nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn) return _at.unlock_return_error(); } -nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type, RegistrationStatus &status) +void AT_CellularNetwork::read_reg_params(int type_index, RegistrationStatus ®_status, int &lac, int &cell_id, int &act) { - int i = (int)type; - MBED_ASSERT(i >= 0 && i < C_MAX); - - const char *rsp[] = { "+CEREG:", "+CGREG:", "+CREG:"}; - const int LAC_LENGTH = 5, CELL_ID_LENGTH = 9; char lac_string[LAC_LENGTH] = {0}, cell_id_string[CELL_ID_LENGTH] = {0}; bool lac_read = false, cell_id_read = false; - _cell_id = -1; - _lac = -1; - - _at.lock(); - - if (!has_registration(at_reg[i].type)) { - _at.unlock(); - return NSAPI_ERROR_UNSUPPORTED; - } - - _at.cmd_start(at_reg[i].cmd); - _at.write_string("=2", false); - _at.cmd_stop(); - _at.resp_start(); - _at.resp_stop(); - - _at.cmd_start(at_reg[i].cmd); - _at.write_string("?", false); - _at.cmd_stop(); - - _at.resp_start(rsp[i]); - _at.read_int(); // ignore urc mode subparam - status = (RegistrationStatus)_at.read_int(); + reg_status = (RegistrationStatus)_at.read_int(); int len = _at.read_string(lac_string, LAC_LENGTH); if (memcmp(lac_string, "ffff", LAC_LENGTH-1) && len >= 0) { @@ -625,35 +656,75 @@ nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type, cell_id_read = true; } - _at.resp_stop(); - - _at.cmd_start(at_reg[i].cmd); - _at.write_string("=0", false); - _at.cmd_stop(); - _at.resp_start(); - _at.resp_stop(); - nsapi_error_t ret = _at.get_last_error(); - _at.unlock(); + act = _at.read_int(); if (lac_read) { - _lac = hex_str_to_int(lac_string, LAC_LENGTH); - tr_debug("lac %s %d", lac_string, _lac ); + lac = hex_str_to_int(lac_string, LAC_LENGTH); + tr_debug("lac %s %d", lac_string, lac ); } if (cell_id_read) { - _cell_id = hex_str_to_int(cell_id_string, CELL_ID_LENGTH); - tr_debug("cell_id %s %d", cell_id_string, _cell_id ); + cell_id = hex_str_to_int(cell_id_string, CELL_ID_LENGTH); + tr_debug("cell_id %s %d", cell_id_string, cell_id ); + } +} + +nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type, RegistrationStatus &status) +{ + int i = (int)type; + MBED_ASSERT(i >= 0 && i < C_MAX); + + if (!has_registration(at_reg[i].type)) { + return NSAPI_ERROR_UNSUPPORTED; } - return ret; + _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); + _at.write_string("?", false); + _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); + _at.resp_stop(); + + if (cell_id != -1) { + _cell_id = cell_id; + } + if (act != -1) { + _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(); + } + + 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; @@ -705,10 +776,9 @@ nsapi_error_t AT_CellularNetwork::get_attach(AttachStatus &status) nsapi_error_t AT_CellularNetwork::get_apn_backoff_timer(int &backoff_timer) { - _at.lock(); - // If apn is set if (_apn) { + _at.lock(); _at.cmd_start("AT+CABTRDP="); _at.write_string(_apn); _at.cmd_stop(); @@ -718,9 +788,10 @@ nsapi_error_t AT_CellularNetwork::get_apn_backoff_timer(int &backoff_timer) backoff_timer = _at.read_int(); } _at.resp_stop(); + return _at.unlock_return_error(); } - return _at.unlock_return_error(); + return NSAPI_ERROR_PARAMETER; } NetworkStack *AT_CellularNetwork::get_stack() @@ -751,14 +822,12 @@ const char *AT_CellularNetwork::get_ip_address() 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() @@ -775,14 +844,14 @@ bool AT_CellularNetwork::get_modem_stack_type(nsapi_ip_stack_t requested_stack) } } -nsapi_error_t AT_CellularNetwork::set_access_technology_impl(operator_t::RadioAccessTechnology opsAct) +nsapi_error_t AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct) { return NSAPI_ERROR_UNSUPPORTED; } -nsapi_error_t AT_CellularNetwork::set_access_technology(operator_t::RadioAccessTechnology opAct) +nsapi_error_t AT_CellularNetwork::set_access_technology(RadioAccessTechnology opAct) { - if (opAct == operator_t::RAT_UNKNOWN) { + if (opAct == RAT_UNKNOWN) { return NSAPI_ERROR_UNSUPPORTED; } @@ -816,10 +885,10 @@ nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount // Optional - try read an int ret = _at.read_int(); - op->op_rat = (ret == error_code) ? operator_t::RAT_UNKNOWN:(operator_t::RadioAccessTechnology)ret; + op->op_rat = (ret == error_code) ? RAT_UNKNOWN:(RadioAccessTechnology)ret; - if ((_op_act == operator_t::RAT_UNKNOWN) || - ((op->op_rat != operator_t::RAT_UNKNOWN) && (op->op_rat == _op_act))) { + if ((_op_act == RAT_UNKNOWN) || + ((op->op_rat != RAT_UNKNOWN) && (op->op_rat == _op_act))) { idx++; } else { operators.delete_last(); @@ -1053,7 +1122,6 @@ int AT_CellularNetwork::get_3gpp_error() return _at.get_3gpp_error(); } - nsapi_error_t AT_CellularNetwork::get_operator_params(int &format, operator_t &operator_params) { _at.lock(); @@ -1081,7 +1149,7 @@ nsapi_error_t AT_CellularNetwork::get_operator_params(int &format, operator_t &o break; } - operator_params.op_rat = (operator_t::RadioAccessTechnology)_at.read_int(); + operator_params.op_rat = (RadioAccessTechnology)_at.read_int(); } _at.resp_stop(); diff --git a/features/cellular/framework/AT/AT_CellularNetwork.h b/features/cellular/framework/AT/AT_CellularNetwork.h index eaf25c7f8d..aade820b45 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.h +++ b/features/cellular/framework/AT/AT_CellularNetwork.h @@ -62,6 +62,8 @@ protected: public: // CellularNetwork virtual nsapi_error_t set_registration(const char *plmn = 0); + virtual nsapi_error_t get_network_registering_mode(NWRegisteringMode& mode); + virtual nsapi_error_t get_registration_status(RegistrationType type, RegistrationStatus &status); virtual nsapi_error_t set_attach(int timeout = 10*1000); @@ -81,7 +83,7 @@ public: // CellularNetwork virtual const char *get_ip_address(); - virtual nsapi_error_t set_access_technology(operator_t::RadioAccessTechnology op_rat); + virtual nsapi_error_t set_access_technology(RadioAccessTechnology op_rat); virtual nsapi_error_t scan_plmn(operList_t &operators, int &ops_count); @@ -107,6 +109,8 @@ public: // CellularNetwork virtual nsapi_error_t get_operator_params(int &format, operator_t &operator_params); + virtual nsapi_error_t set_registration_urc(bool on); + protected: /** Check if modem supports the given stack type. @@ -128,11 +132,16 @@ protected: * * @return zero on success */ - virtual nsapi_error_t set_access_technology_impl(operator_t::RadioAccessTechnology op_rat); + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat); + private: // "NO CARRIER" urc void urc_no_carrier(); + void urc_creg(); + void urc_cereg(); + void urc_cgreg(); + nsapi_error_t set_context_to_be_activated(); nsapi_ip_stack_t string_to_stack_type(const char* pdp_type); @@ -141,9 +150,12 @@ private: nsapi_error_t open_data_channel(); bool get_context(); bool set_new_context(int cid); - nsapi_error_t set_registration_urc(bool on); + nsapi_error_t delete_current_context(); + void read_reg_params_and_compare(int index); + void read_reg_params(int type_index, RegistrationStatus ®_status, int &lac, int &cell_id, int &act); + #if NSAPI_PPP_AVAILABLE void ppp_status_cb(nsapi_event_t, intptr_t); #endif @@ -157,13 +169,16 @@ protected: nsapi_ip_stack_t _ip_stack_type; int _cid; Callback _connection_status_cb; - operator_t::RadioAccessTechnology _op_act; + RadioAccessTechnology _op_act; AuthenticationType _authentication_type; - int _lac; int _cell_id; RegistrationType _last_reg_type; nsapi_connection_status_t _connect_status; bool _new_context_set; + RegistrationStatus _reg_status; + RadioAccessTechnology _current_act; + bool _async; + }; } // namespace mbed diff --git a/features/cellular/framework/common/CellularCommon.h b/features/cellular/framework/common/CellularCommon.h index ecee57a35a..2f92ec9ae8 100644 --- a/features/cellular/framework/common/CellularCommon.h +++ b/features/cellular/framework/common/CellularCommon.h @@ -20,12 +20,6 @@ #include -typedef enum nsapi_event { - NSAPI_EVENT_CONNECTION_STATUS_CHANGE = 0, /*!< network connection status has changed, the parameter = new status (nsapi_connection_status_t) */ - NSAPI_CELLULAR_EVENT_STATUS_CHANGE = 1 /*!< cellular modem status has changed, the parameter = new status (cellular_connection_status_t) */ -} nsapi_event_t; - - /** * Cellular specific event changes. * Connect and disconnect are handled via NSAPI_EVENT_CONNECTION_STATUS_CHANGE @@ -34,9 +28,9 @@ typedef enum cellular_event_status { CellularDeviceReady = 1, /*!< Modem is powered and ready to receive commands */ CellularSIMStatusChanged = 2, /*!< SIM state changed, call SIM state */ CellularRegistrationStatusChanged = 3, /*!< Registering status changed, e.g. roaming, registered, smsonly... */ - CellularRegistrationTypeChanged = 6, /*!< Registration type changed, e.g. C_EREG, C_GREG, C_REG */ - CellularCellIDChanged = 8, /*!< Network Cell ID have changed */ - CellularRadioAccessTechnologyChanged = 9, /*!< Network roaming status have changed */ + CellularRegistrationTypeChanged = 4, /*!< Registration type changed, e.g. C_EREG, C_GREG, C_REG */ + CellularCellIDChanged = 5, /*!< Network Cell ID have changed */ + CellularRadioAccessTechnologyChanged = 6, /*!< Network roaming status have changed */ } cellular_connection_status_t; diff --git a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.cpp b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.cpp index a3c59dc051..752a42c97e 100644 --- a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.cpp +++ b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.cpp @@ -22,7 +22,7 @@ using namespace mbed; QUECTEL_BC95_CellularNetwork::QUECTEL_BC95_CellularNetwork(ATHandler &atHandler) : AT_CellularNetwork(atHandler) { - _op_act = operator_t::RAT_NB1; + _op_act = RAT_NB1; } QUECTEL_BC95_CellularNetwork::~QUECTEL_BC95_CellularNetwork() @@ -47,11 +47,11 @@ bool QUECTEL_BC95_CellularNetwork::has_registration(RegistrationType reg_tech) return (reg_tech == C_EREG); } -nsapi_error_t QUECTEL_BC95_CellularNetwork::set_access_technology_impl(operator_t::RadioAccessTechnology opRat) +nsapi_error_t QUECTEL_BC95_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat) { - if (opRat != operator_t::RAT_NB1) { + if (opRat != RAT_NB1) { //TODO: Set as unknown or force to NB1? - _op_act = operator_t::RAT_UNKNOWN; + _op_act = RAT_UNKNOWN; return NSAPI_ERROR_UNSUPPORTED; } diff --git a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.h b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.h index e9d47823fa..1c6ff19f1a 100644 --- a/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.h +++ b/features/cellular/framework/targets/QUECTEL/BC95/QUECTEL_BC95_CellularNetwork.h @@ -31,7 +31,7 @@ public: protected: virtual NetworkStack *get_stack(); - virtual nsapi_error_t set_access_technology_impl(operator_t::RadioAccessTechnology opRat); + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat); virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack); diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.cpp b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.cpp index eaa1377cb6..2a2e3f2245 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.cpp +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.cpp @@ -47,12 +47,12 @@ NetworkStack *QUECTEL_BG96_CellularNetwork::get_stack() return _stack; } -nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(operator_t::RadioAccessTechnology opsAct) +nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct) { _at.lock(); switch (opsAct) { - case operator_t::RAT_CATM1: + case RAT_CATM1: _at.cmd_start("AT+QCFG=\"nwscanseq\",020301"); _at.cmd_stop(); _at.resp_start(); @@ -66,7 +66,7 @@ nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(operator_ _at.resp_start(); _at.resp_stop(); break; - case operator_t::RAT_NB1: + case RAT_NB1: _at.cmd_start("AT+QCFG=\"nwscanseq\",030201"); _at.cmd_stop(); _at.resp_start(); @@ -80,10 +80,10 @@ nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(operator_ _at.resp_start(); _at.resp_stop(); break; - case operator_t::RAT_GSM: - case operator_t::RAT_GSM_COMPACT: - case operator_t::RAT_UTRAN: - case operator_t::RAT_EGPRS: + case RAT_GSM: + case RAT_GSM_COMPACT: + case RAT_UTRAN: + case RAT_EGPRS: _at.cmd_start("AT+QCFG=\"nwscanseq\",010203"); _at.cmd_stop(); _at.resp_start(); @@ -107,7 +107,7 @@ nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(operator_ _at.resp_start(); _at.resp_stop(); _at.unlock(); - _op_act = operator_t::RAT_UNKNOWN; + _op_act = RAT_UNKNOWN; return NSAPI_ERROR_UNSUPPORTED; } diff --git a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h index 0bfa3dc4e5..991799aaed 100644 --- a/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h +++ b/features/cellular/framework/targets/QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h @@ -31,7 +31,7 @@ public: protected: virtual NetworkStack *get_stack(); - virtual nsapi_error_t set_access_technology_impl(operator_t::RadioAccessTechnology opRat); + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat); virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack); }; diff --git a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.cpp b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.cpp index cfb5f88190..5a425a52e4 100644 --- a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.cpp +++ b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.cpp @@ -37,8 +37,8 @@ bool TELIT_HE910_CellularNetwork::has_registration(RegistrationType reg_type) return (reg_type == C_REG || reg_type == C_GREG); } -nsapi_error_t TELIT_HE910_CellularNetwork::set_access_technology_impl(operator_t::RadioAccessTechnology opRat) +nsapi_error_t TELIT_HE910_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat) { - _op_act = operator_t::RAT_UNKNOWN; + _op_act = RAT_UNKNOWN; return NSAPI_ERROR_UNSUPPORTED; } diff --git a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.h b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.h index 35d73fd87c..74cb44bf95 100644 --- a/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.h +++ b/features/cellular/framework/targets/TELIT/HE910/TELIT_HE910_CellularNetwork.h @@ -34,7 +34,7 @@ protected: virtual bool has_registration(RegistrationType rat); - virtual nsapi_error_t set_access_technology_impl(operator_t::RadioAccessTechnology opRat); + virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat); }; } // namespace mbed diff --git a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.cpp b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.cpp index 5df5c5f5e9..a43cd291d5 100644 --- a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.cpp +++ b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.cpp @@ -37,8 +37,8 @@ bool UBLOX_PPP_CellularNetwork::has_registration(RegistrationType reg_type) return (reg_type == C_REG || reg_type == C_GREG); } -nsapi_error_t UBLOX_PPP_CellularNetwork::set_access_technology_impl(operator_t::RadioAccessTechnology opRat) +nsapi_error_t UBLOX_LISA_U_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opRat) { - _op_act = operator_t::RAT_UNKNOWN; + _op_act = RAT_UNKNOWN; return NSAPI_ERROR_UNSUPPORTED; } diff --git a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.h b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.h index 1340755089..a1e5db1159 100644 --- a/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.h +++ b/features/cellular/framework/targets/UBLOX/PPP/UBLOX_PPP_CellularNetwork.h @@ -33,7 +33,7 @@ protected: virtual bool has_registration(RegistrationType rat); - virtual nsapi_error_t set_access_technology_impl(operator_t::RadioAccessTechnology opRat); + 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.") diff --git a/features/netsocket/nsapi_types.h b/features/netsocket/nsapi_types.h index 0dd91244c7..d1c4de773d 100644 --- a/features/netsocket/nsapi_types.h +++ b/features/netsocket/nsapi_types.h @@ -80,7 +80,7 @@ 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 + NSAPI_EVENT_CELLULAR_STATUS_CHANGE = 1 /*!< cellular modem status has changed, the parameter = new status (cellular_connection_status_t) */ } nsapi_event_t;