diff --git a/features/cellular/easy_cellular/CellularConnectionFSM.cpp b/features/cellular/easy_cellular/CellularConnectionFSM.cpp index 35c1eace32..b7437b2fbb 100644 --- a/features/cellular/easy_cellular/CellularConnectionFSM.cpp +++ b/features/cellular/easy_cellular/CellularConnectionFSM.cpp @@ -43,7 +43,7 @@ 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(8 * EVENTS_EVENT_SIZE), _event_id(0) + _at_queue(8 * EVENTS_EVENT_SIZE), _event_id(0), _plmn(0) { memset(_sim_pin, 0, sizeof(_sim_pin)); #if MBED_CONF_CELLULAR_RANDOM_MAX_START_DELAY == 0 @@ -146,6 +146,11 @@ void CellularConnectionFSM::set_sim_pin(const char * sim_pin) _sim_pin[sizeof(_sim_pin)-1] = '\0'; } +void CellularConnectionFSM::set_plmn(const char* plmn) +{ + _plmn = plmn; +} + bool CellularConnectionFSM::open_sim() { CellularSIM::SimState state = CellularSIM::SimStateUnknown; @@ -175,11 +180,10 @@ bool CellularConnectionFSM::open_sim() return state == CellularSIM::SimStateReady; } -bool CellularConnectionFSM::set_network_registration(char *plmn) +bool CellularConnectionFSM::set_network_registration() { - nsapi_error_t error = _network->set_registration(plmn); - if (error != NSAPI_ERROR_OK) { - tr_error("Set network registration mode failing (%d)", error); + if (_network->set_registration(_plmn) != NSAPI_ERROR_OK) { + tr_error("Failed to set network registration."); return false; } return true; @@ -279,8 +283,12 @@ 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", "Activating PDP Context", "Connecting network", "Connected"}; +#if MBED_CONF_MBED_TRACE_ENABLE + static const char *strings[] = { "Init", "Power", "Device ready", "SIM pin", "Registering network", "Attaching network", "Connecting network", "Connected"}; return strings[state]; +#else + return NULL; +#endif // #if MBED_CONF_MBED_TRACE_ENABLE } nsapi_error_t CellularConnectionFSM::is_automatic_registering(bool& auto_reg) @@ -416,15 +424,26 @@ void CellularConnectionFSM::state_registering() { _cellularDevice->set_timeout(TIMEOUT_NETWORK); if (is_registered()) { - // we are already registered, go to attach - enter_to_state(STATE_ATTACHING_NETWORK); - } else { - bool auto_reg = false; - nsapi_error_t err = is_automatic_registering(auto_reg); - if (err == NSAPI_ERROR_OK && !auto_reg) { // when we support plmn add this : || plmn - // automatic registering is not on, set registration and retry + if (_plmn && _retry_count == 0) { + // we don't know which network we are registered, try to register to specific network _cellularDevice->set_timeout(TIMEOUT_REGISTRATION); set_network_registration(); + retry_state_or_fail(); + } else { + // we are already registered, go to attach + enter_to_state(STATE_ATTACHING_NETWORK); + } + } else { + if (_plmn) { + set_network_registration(); + } else { + bool auto_reg = false; + nsapi_error_t err = is_automatic_registering(auto_reg); + if (err == NSAPI_ERROR_OK && !auto_reg) { + // automatic registering is not on, set registration and retry + _cellularDevice->set_timeout(TIMEOUT_REGISTRATION); + set_network_registration(); + } } retry_state_or_fail(); } diff --git a/features/cellular/easy_cellular/CellularConnectionFSM.h b/features/cellular/easy_cellular/CellularConnectionFSM.h index 37bbe98f3b..af992f97cd 100644 --- a/features/cellular/easy_cellular/CellularConnectionFSM.h +++ b/features/cellular/easy_cellular/CellularConnectionFSM.h @@ -139,12 +139,24 @@ public: */ void set_retry_timeout_array(uint16_t timeout[], int array_len); + /** 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); + + /** returns readable format of the given state. Used for printing states while debugging. + * + * @param state state which is returned in string format + * @return string format of the given state + */ const char* get_state_string(CellularState state); private: bool power_on(); bool open_sim(); bool get_network_registration(CellularNetwork::RegistrationType type, CellularNetwork::RegistrationStatus &status, bool &is_registered); - bool set_network_registration(char *plmn = 0); + bool set_network_registration(); bool get_attach_network(CellularNetwork::AttachStatus &status); bool set_attach_network(); bool is_registered(); @@ -198,6 +210,7 @@ private: events::EventQueue _at_queue; char _st_string[20]; int _event_id; + const char* _plmn; }; } // namespace diff --git a/features/cellular/easy_cellular/EasyCellularConnection.cpp b/features/cellular/easy_cellular/EasyCellularConnection.cpp index 253cb99479..1b6a3468e1 100644 --- a/features/cellular/easy_cellular/EasyCellularConnection.cpp +++ b/features/cellular/easy_cellular/EasyCellularConnection.cpp @@ -280,6 +280,11 @@ void EasyCellularConnection::modem_debug_on(bool on) } } +void EasyCellularConnection::set_plmn(const char* plmn) +{ + _cellularConnectionFSM.set_plmn(plmn); +} + NetworkStack *EasyCellularConnection::get_stack() { return _cellularConnectionFSM.get_stack(); diff --git a/features/cellular/easy_cellular/EasyCellularConnection.h b/features/cellular/easy_cellular/EasyCellularConnection.h index 7c160f30e4..defd1dd752 100644 --- a/features/cellular/easy_cellular/EasyCellularConnection.h +++ b/features/cellular/easy_cellular/EasyCellularConnection.h @@ -131,6 +131,12 @@ public: */ 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); protected: /** Provide access to the NetworkStack object diff --git a/features/cellular/framework/AT/AT_CellularNetwork.cpp b/features/cellular/framework/AT/AT_CellularNetwork.cpp index 1f466f194b..5bba897ae0 100644 --- a/features/cellular/framework/AT/AT_CellularNetwork.cpp +++ b/features/cellular/framework/AT/AT_CellularNetwork.cpp @@ -656,7 +656,7 @@ nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn) tr_debug("Automatic network registration"); _at.cmd_start("AT+COPS?"); _at.cmd_stop(); - _at.resp_start("AT+COPS:"); + _at.resp_start("+COPS:"); int mode = _at.read_int(); _at.resp_stop(); if (mode != 0) {