Cellular: review fixes, added missing fixes from master.

pull/8579/head
Teppo Järvelin 2018-11-05 09:31:05 +02:00
parent 467ae09bef
commit 1a047efade
28 changed files with 118 additions and 78 deletions

View File

@ -105,6 +105,11 @@ 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)
{
}

View File

@ -41,6 +41,10 @@ events::EventQueue *CellularDevice::get_queue()
return NULL;
}
void CellularDevice::set_plmn(char const*)
{
}
void CellularDevice::set_sim_pin(char const*)
{
}

View File

@ -28,16 +28,6 @@ public:
// max simultaneous PDP contexts active
static const int PDP_CONTEXT_COUNT = 4;
/** Get the default cellular interface.
*
* This is provided as a weak method so applications can override.
* Default behaviour is to get the target's default interface, if
* any.
*
* @return pointer to interface, if any.
*/
static CellularBase *get_default_instance();
/* authentication type when activating or modifying the pdp context */
enum AuthenticationType {
NOAUTH = 0,
@ -119,15 +109,18 @@ public: // from NetworkInterface
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;
virtual bool is_connected() = 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 CellularBase *get_default_instance();
// Operations, can be sync/async. Also Connect() is this kind of operations, inherited from NetworkInterface above.

View File

@ -242,10 +242,11 @@ public:
protected:
friend class AT_CellularNetwork;
friend class AT_CellularContext;
/** Cellular callback which is called by Network class after this class attaches to it, CellularStateMachine
* and CellularContext when in PPP mode. This method will broadcast to every interested classes:
/** 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);

View File

@ -24,6 +24,9 @@
#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
@ -141,9 +144,9 @@ nsapi_error_t AT_CellularContext::check_operation(nsapi_error_t err, ContextOper
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
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 = 3 * 60 * 1000; // use 3 minutes for device ready and sim
timeout = DEVICE_TIMEOUT; // use 5 minutes for device ready and sim
}
return timeout;
}
@ -204,6 +207,11 @@ nsapi_error_t AT_CellularContext::set_blocking(bool 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);
@ -260,9 +268,7 @@ nsapi_error_t AT_CellularContext::delete_current_context()
_at.clear_error();
_at.cmd_start("AT+CGDCONT=");
_at.write_int(_cid);
_at.cmd_stop();
_at.resp_start();
_at.resp_stop();
_at.cmd_stop_read_resp();
if (_at.get_last_error() == NSAPI_ERROR_OK) {
_cid = -1;
@ -276,14 +282,15 @@ 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();
_at.resp_start();
_at.resp_stop();
_at.cmd_stop_read_resp();
if (_at.get_last_error() != NSAPI_ERROR_OK) {
return NSAPI_ERROR_AUTH_FAILURE;
}
@ -424,9 +431,7 @@ bool AT_CellularContext::set_new_context(int cid)
_at.write_int(cid);
_at.write_string(pdp_type);
_at.write_string(_apn);
_at.cmd_stop();
_at.resp_start();
_at.resp_stop();
_at.cmd_stop_read_resp();
success = (_at.get_last_error() == NSAPI_ERROR_OK);
// Fall back to ipv4
@ -437,9 +442,7 @@ bool AT_CellularContext::set_new_context(int cid)
_at.write_int(cid);
_at.write_string("IP");
_at.write_string(_apn);
_at.cmd_stop();
_at.resp_start();
_at.resp_stop();
_at.cmd_stop_read_resp();
success = (_at.get_last_error() == NSAPI_ERROR_OK);
}
@ -502,9 +505,7 @@ nsapi_error_t AT_CellularContext::do_activate_context()
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();
_at.cmd_stop_read_resp();
if (_at.get_last_error() == NSAPI_ERROR_OK) {
_is_context_activated = true;
}
@ -569,9 +570,11 @@ nsapi_error_t AT_CellularContext::open_data_channel()
_at.write_int(_cid);
} else {
MBED_ASSERT(_cid >= 0 && _cid <= 99);
char cmd_buf[sizeof("ATD*99***xx#")];
std::sprintf(cmd_buf, "ATD*99***%d#", _cid);
_at.cmd_start(cmd_buf);
_at.cmd_start("ATD*99***");
_at.use_delimiter(false);
_at.write_int(_cid);
_at.write_string("#", false);
_at.use_delimiter(true);
}
_at.cmd_stop();
@ -591,6 +594,7 @@ nsapi_error_t AT_CellularContext::open_data_channel()
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 {
@ -607,7 +611,7 @@ void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
nsapi_error_t AT_CellularContext::disconnect()
{
if (!_nw) {
if (!_nw || !_is_connected) {
return NSAPI_ERROR_NO_CONNECTION;
}
#if NSAPI_PPP_AVAILABLE
@ -655,13 +659,12 @@ nsapi_error_t AT_CellularContext::disconnect()
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();
_at.resp_start();
_at.resp_stop();
_at.cmd_stop_read_resp();
}
}
if (!_at.get_last_error()) {
_is_connected = false;
call_network_cb(NSAPI_STATUS_DISCONNECTED);
}
@ -837,6 +840,11 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
}
}
#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
@ -853,7 +861,6 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
_semaphore.release();
} else if (st == CellularAttachNetwork && (_current_op == OP_ATTACH || _current_op == OP_CONNECT) &&
data->status_data == CellularNetwork::Attached) {
_nw = _device->open_network(_fh);
// target reached, release semaphore
_semaphore.release();
}
@ -871,6 +878,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
}
}
} 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) {

View File

@ -39,6 +39,7 @@ public:
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);

View File

@ -56,9 +56,7 @@ AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(a
_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();
_at.resp_start();
_at.resp_stop();
_at.cmd_stop_read_resp();
_at.unlock();
}
@ -66,9 +64,7 @@ AT_CellularNetwork::~AT_CellularNetwork()
{
_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();
_at.resp_start();
_at.resp_stop();
_at.cmd_stop_read_resp();
_at.unlock();
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
@ -254,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();
}

View File

@ -34,6 +34,12 @@ namespace mbed {
MBED_WEAK CellularDevice *CellularDevice::get_default_instance()
{
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;
}

View File

@ -374,15 +374,19 @@ void CellularStateMachine::state_power_on()
}
}
void CellularStateMachine::device_ready()
bool CellularStateMachine::device_ready()
{
tr_info("Cellular device ready");
if (_cellularDevice.init_module() != NSAPI_ERROR_OK) {
return false;
}
if (_event_status_cb) {
_event_status_cb((nsapi_event_t)CellularDeviceReady, (intptr_t )&_cb_data);
}
_power->remove_device_ready_urc_cb(mbed::callback(this, &CellularStateMachine::ready_urc_cb));
_cellularDevice.close_power();
_power = NULL;
return true;
}
void CellularStateMachine::state_device_ready()
@ -390,8 +394,11 @@ void CellularStateMachine::state_device_ready()
_cellularDevice.set_timeout(TIMEOUT_POWER_ON);
_cb_data.error = _power->set_at_mode();
if (_cb_data.error == NSAPI_ERROR_OK) {
device_ready();
enter_to_state(STATE_SIM_PIN);
if (device_ready()) {
enter_to_state(STATE_SIM_PIN);
} else {
retry_state_or_fail();
}
} else {
if (_retry_count == 0) {
_power->set_device_ready_urc_cb(mbed::callback(this, &CellularStateMachine::ready_urc_cb));
@ -605,7 +612,7 @@ void CellularStateMachine::event()
}
if ((_target_state == _state && _cb_data.error == NSAPI_ERROR_OK && !_is_retry) || _event_id == STM_STOPPED) {
tr_info("Target state reached: %s", get_state_string(_target_state));
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;
}
@ -683,8 +690,11 @@ void CellularStateMachine::ready_urc_cb()
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);
device_ready();
continue_from_state(STATE_SIM_PIN);
if (device_ready()) {
continue_from_state(STATE_SIM_PIN);
} else {
continue_from_state(STATE_DEVICE_READY);
}
}
}

View File

@ -138,7 +138,7 @@ private:
bool open_sim();
bool get_network_registration(CellularNetwork::RegistrationType type, CellularNetwork::RegistrationStatus &status, bool &is_registered);
bool is_registered();
void device_ready();
bool device_ready();
// state functions to keep state machine simple
void state_init();

View File

@ -62,7 +62,7 @@ nsapi_error_t GEMALTO_CINTERION::init_module()
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;
}

View File

@ -33,7 +33,7 @@ protected: // AT_CellularDevice
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn);
public:
virtual nsapi_error_t init_module();
virtual uint16_t get_send_delay();
virtual uint16_t get_send_delay() const;
};
} // namespace mbed

View File

@ -41,14 +41,10 @@ NetworkStack *GEMALTO_CINTERION_CellularContext::get_stack()
bool GEMALTO_CINTERION_CellularContext::stack_type_supported(nsapi_ip_stack_t requested_stack)
{
#if NSAPI_PPP_AVAILABLE
return (requested_stack == IPV4_STACK || requested_stack == IPV6_STACK);
#else
if (GEMALTO_CINTERION_Module::get_model() == GEMALTO_CINTERION_Module::ModelBGS2) {
return (requested_stack == IPV4_STACK);
}
return (requested_stack == IPV4_STACK || requested_stack == IPV6_STACK);
#endif
}
} /* namespace mbed */

View File

@ -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();

View File

@ -36,9 +36,9 @@ NetworkStack *QUECTEL_BC95_CellularContext::get_stack()
return _stack;
}
bool QUECTEL_BC95_CellularContext::get_modem_stack_type(nsapi_ip_stack_t requested_stack)
bool QUECTEL_BC95_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
{
return requested_stack == IPV4_STACK ? true : false;
return stack_type == IPV4_STACK ? true : false;
}
} /* namespace mbed */

View File

@ -28,7 +28,7 @@ public:
protected:
virtual NetworkStack *get_stack();
virtual bool get_modem_stack_type(nsapi_ip_stack_t requested_stack);
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
};
} /* namespace mbed */

View File

@ -27,9 +27,9 @@ QUECTEL_UG96_CellularContext::~QUECTEL_UG96_CellularContext()
{
}
bool QUECTEL_UG96_CellularContext::stack_type_supported(nsapi_ip_stack_t requested_stack)
bool QUECTEL_UG96_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
{
return requested_stack == IPV4_STACK ? true : false;
return stack_type == IPV4_STACK ? true : false;
}
nsapi_error_t QUECTEL_UG96_CellularContext::do_user_authentication()

View File

@ -27,7 +27,7 @@ public:
virtual ~QUECTEL_UG96_CellularContext();
protected:
virtual bool stack_type_supported(nsapi_ip_stack_t requested_stack);
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
virtual nsapi_error_t do_user_authentication();
};

View File

@ -27,9 +27,9 @@ TELIT_HE910_CellularContext::~TELIT_HE910_CellularContext()
{
}
bool TELIT_HE910_CellularContext::stack_type_supported(nsapi_ip_stack_t requested_stack)
bool TELIT_HE910_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
{
return requested_stack == IPV4_STACK || requested_stack == IPV6_STACK;
return stack_type == IPV4_STACK ? true : false;
}
} /* namespace mbed */

View File

@ -27,7 +27,7 @@ public:
virtual ~TELIT_HE910_CellularContext();
protected:
virtual bool stack_type_supported(nsapi_ip_stack_t requested_stack);
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
};
} /* namespace mbed */

View File

@ -23,6 +23,13 @@
using namespace mbed;
using namespace events;
#ifdef TARGET_UBLOX_C030_R410M
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::AT_CGSN_WITH_TYPE,
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
};
#endif
UBLOX_AT::UBLOX_AT(FileHandle *fh) : AT_CellularDevice(fh)
{
#ifdef TARGET_UBLOX_C030_R410M

View File

@ -39,9 +39,9 @@ NetworkStack *UBLOX_AT_CellularContext::get_stack()
return _stack;
}
bool UBLOX_AT_CellularContext::stack_type_supported(nsapi_ip_stack_t requested_stack)
bool UBLOX_AT_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
{
return requested_stack == IPV4_STACK ? true : false;
return stack_type == IPV4_STACK ? true : false;
}
void UBLOX_AT_CellularContext::do_connect()

View File

@ -31,7 +31,7 @@ public:
protected:
virtual NetworkStack *get_stack();
virtual bool stack_type_supported(nsapi_ip_stack_t requested_stack);
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
private:

View File

@ -23,6 +23,13 @@
using namespace mbed;
using namespace events;
#ifdef TARGET_UBLOX_C027
static const AT_CellularBase::SupportedFeature unsupported_features[] = {
AT_CellularBase::AT_CGSN_WITH_TYPE,
AT_CellularBase::SUPPORTED_FEATURE_END_MARK
};
#endif
UBLOX_PPP::UBLOX_PPP(FileHandle *fh) : AT_CellularDevice(fh)
{
#ifdef TARGET_UBLOX_C027

View File

@ -27,9 +27,9 @@ UBLOX_PPP_CellularContext::~UBLOX_PPP_CellularContext()
{
}
bool UBLOX_PPP_CellularContext::stack_type_supported(nsapi_ip_stack_t requested_stack)
bool UBLOX_PPP_CellularContext::stack_type_supported(nsapi_ip_stack_t stack_type)
{
return requested_stack == IPV4_STACK ? true : false;
return stack_type == IPV4_STACK ? true : false;
}
} /* namespace mbed */

View File

@ -27,7 +27,7 @@ public:
virtual ~UBLOX_PPP_CellularContext();
protected:
virtual bool stack_type_supported(nsapi_ip_stack_t requested_stack);
virtual bool stack_type_supported(nsapi_ip_stack_t stack_type);
};
} /* namespace mbed */

View File

@ -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.

View File

@ -110,7 +110,7 @@ MBED_WEAK NetworkInterface *NetworkInterface::get_target_default_instance()
#elif MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE == CELLULAR
MBED_WEAK NetworkInterface *NetworkInterface::get_target_default_instance()
{
return CellularContext::get_default_instance();
return CellularBase::get_default_instance();
}
#elif defined(MBED_CONF_TARGET_NETWORK_DEFAULT_INTERFACE_TYPE)