Updated cellular

pull/6082/head
Ari Parkkila 2018-02-10 12:17:22 +02:00
parent 863ec3c3cc
commit 5b70492c64
6 changed files with 85 additions and 61 deletions

View File

@ -114,7 +114,7 @@ bool CellularConnectionUtil::open_sim()
#endif #endif
} }
bool CellularConnectionUtil::run_self_tests() void CellularConnectionUtil::device_ready()
{ {
CellularInformation *info = _cellularDevice->open_information(_serial); CellularInformation *info = _cellularDevice->open_information(_serial);
@ -128,7 +128,6 @@ bool CellularConnectionUtil::run_self_tests()
if (info->get_revision(buf, sizeof(buf)) == NSAPI_ERROR_OK) { if (info->get_revision(buf, sizeof(buf)) == NSAPI_ERROR_OK) {
log_info("Cellular device revision: %s", buf); log_info("Cellular device revision: %s", buf);
} }
return true;
} }
bool CellularConnectionUtil::open_network() bool CellularConnectionUtil::open_network()
@ -152,7 +151,11 @@ bool CellularConnectionUtil::get_network_registration(CellularNetwork::Registrat
{ {
is_registered = false; is_registered = false;
bool is_roaming = false; bool is_roaming = false;
if (_network->get_registration_status(type, status) != NSAPI_ERROR_OK) { nsapi_error_t err = _network->get_registration_status(type, status);
if (err != NSAPI_ERROR_OK) {
if (err != NSAPI_ERROR_UNSUPPORTED) {
log_warn("Get network registration failed (type %d)!", type);
}
return false; return false;
} }
switch (status) { switch (status) {
@ -177,6 +180,9 @@ bool CellularConnectionUtil::get_network_registration(CellularNetwork::Registrat
is_registered = true; is_registered = true;
break; break;
case CellularNetwork::AttachedEmergencyOnly: case CellularNetwork::AttachedEmergencyOnly:
log_warn("Emergency only network registration!");
is_registered = true;
break;
case CellularNetwork::RegistrationDenied: case CellularNetwork::RegistrationDenied:
case CellularNetwork::NotRegistered: case CellularNetwork::NotRegistered:
case CellularNetwork::Unknown: case CellularNetwork::Unknown:
@ -238,10 +244,10 @@ void CellularConnectionUtil::event()
cellularDevice.set_timeout(TIMEOUT_POWER_ON); cellularDevice.set_timeout(TIMEOUT_POWER_ON);
log_info("Cellular power ON (timeout %d ms)", TIMEOUT_POWER_ON); log_info("Cellular power ON (timeout %d ms)", TIMEOUT_POWER_ON);
if (open_power(_serial)) { if (open_power(_serial)) {
_next_state = STATE_SELF_TEST; _next_state = STATE_DEVICE_READY;
} else { } else {
static int retry_count; static int retry_count;
if (++retry_count < 10) { if (++retry_count <= 10) {
log_warn("Power ON retry %d", retry_count); log_warn("Power ON retry %d", retry_count);
event_timeout = 1000; event_timeout = 1000;
} else { } else {
@ -250,16 +256,16 @@ void CellularConnectionUtil::event()
} }
} }
break; break;
case STATE_SELF_TEST: case STATE_DEVICE_READY:
cellularDevice.set_timeout(TIMEOUT_POWER_ON); cellularDevice.set_timeout(TIMEOUT_POWER_ON);
log_info("Cellular self-test (timeout %d ms)", TIMEOUT_POWER_ON);
if (_power->set_at_mode() == NSAPI_ERROR_OK) { if (_power->set_at_mode() == NSAPI_ERROR_OK) {
log_info("Cellular device ready");
_next_state = STATE_START_CELLULAR; _next_state = STATE_START_CELLULAR;
run_self_tests(); device_ready();
} else { } else {
static int retry_count = 0; static int retry_count = 0;
if (++retry_count < 10) { log_info("Waiting for cellular device (retry %d/10, timeout %d ms)", retry_count, TIMEOUT_POWER_ON);
log_warn("Waiting for cellular %d", retry_count); if (++retry_count <= 10) {
event_timeout = 1000; event_timeout = 1000;
} else { } else {
report_failure("Power"); report_failure("Power");
@ -281,7 +287,7 @@ void CellularConnectionUtil::event()
log_info("Check for network registration"); log_info("Check for network registration");
} else { } else {
static int retry_count; static int retry_count;
if (++retry_count < 10) { if (++retry_count <= 10) {
log_warn("Waiting for SIM %d", retry_count); log_warn("Waiting for SIM %d", retry_count);
event_timeout = 1000; event_timeout = 1000;
} else { } else {
@ -294,47 +300,40 @@ void CellularConnectionUtil::event()
cellularDevice.set_timeout(TIMEOUT_NETWORK); cellularDevice.set_timeout(TIMEOUT_NETWORK);
CellularNetwork::RegistrationStatus status; CellularNetwork::RegistrationStatus status;
bool is_registered; bool is_registered;
_next_state = STATE_REGISTER_NETWORK;
for (int type = 0; type < CellularNetwork::C_MAX; type++) { for (int type = 0; type < CellularNetwork::C_MAX; type++) {
if (get_network_registration((CellularNetwork::RegistrationType)type, status, is_registered)) { if (get_network_registration((CellularNetwork::RegistrationType)type, status, is_registered)) {
log_debug("get_network_registration: type=%d, status=%d", type, status);
if (is_registered) { if (is_registered) {
log_info("Registered to cellular network (status %d)", status); log_info("Registered to cellular network (type %d, status %d)", type, status);
_next_state = STATE_ATTACH_NETWORK; _next_state = STATE_ATTACH_NETWORK;
log_info("Check cellular network attach state"); log_info("Check cellular network attach state");
event_timeout = 0;
break; break;
} else { } else {
if (status == CellularNetwork::RegistrationDenied) { if (status == CellularNetwork::RegistrationDenied) {
static int backoff_timeout = 1; static int backoff_timeout = 1;
log_warn("Network registration denied! Retry after %d seconds.", backoff_timeout); log_warn("Network registration denied (type %d)! Retry after %d seconds.", type, backoff_timeout);
event_timeout = backoff_timeout * 1000; event_timeout = backoff_timeout * 1000;
backoff_timeout *= 2; backoff_timeout *= 2;
_next_state = STATE_REGISTERING_NETWORK;
break; break;
} else if (status == CellularNetwork::NotRegistered) { } else if (status == CellularNetwork::SearchingNetwork || status == CellularNetwork::Unknown) {
log_info("(STATE_REGISTERING_NETWORK), not registered");
if (event_timeout == -1) {
_next_state = STATE_REGISTER_NETWORK;
event_timeout = 0;
}
} else {
static int retry_count; static int retry_count;
if (++retry_count < 18) { if (++retry_count <= 180) {
log_info("Waiting for registration"); log_info("Waiting for registration %d/180 (type %d, status %d)", retry_count, type, status);
event_timeout = 1*1000; event_timeout = 1*1000;
_next_state = STATE_REGISTERING_NETWORK; _next_state = STATE_REGISTERING_NETWORK;
} else { } else {
if (event_timeout == -1) {
log_info("Start cellular registration"); log_info("Start cellular registration");
_next_state = STATE_REGISTER_NETWORK; _next_state = STATE_REGISTER_NETWORK;
retry_count = 0;
break;
}
} else {
// modem is not yet searching network for this technology
} }
} }
} }
} }
}
}
if (_state == _next_state && event_timeout == -1) {
event_timeout = 0;
}
break; break;
case STATE_REGISTER_NETWORK: case STATE_REGISTER_NETWORK:
cellularDevice.set_timeout(TIMEOUT_REGISTRATION); cellularDevice.set_timeout(TIMEOUT_REGISTRATION);
@ -343,7 +342,7 @@ void CellularConnectionUtil::event()
_next_state = STATE_REGISTERING_NETWORK; _next_state = STATE_REGISTERING_NETWORK;
} else { } else {
static int retry_count; static int retry_count;
if (++retry_count < 3) { if (++retry_count <= 3) {
event_timeout = 1000; event_timeout = 1000;
} else { } else {
report_failure("Registration"); report_failure("Registration");
@ -410,7 +409,7 @@ void CellularConnectionUtil::event()
} else { } else {
if (event_timeout == 0) { if (event_timeout == 0) {
static int retry_count = 0; static int retry_count = 0;
if (++retry_count < 3) { if (++retry_count <= 3) {
log_info("Cellular event retry %d", retry_count); log_info("Cellular event retry %d", retry_count);
} else { } else {
report_failure("Cellular connection failed!"); report_failure("Cellular connection failed!");

View File

@ -36,7 +36,7 @@ class CellularConnectionUtil
public: public:
enum CellularState { enum CellularState {
STATE_POWER_ON = 0, STATE_POWER_ON = 0,
STATE_SELF_TEST = 1, STATE_DEVICE_READY = 1,
STATE_START_CELLULAR = 2, STATE_START_CELLULAR = 2,
STATE_SIM_PIN = 3, STATE_SIM_PIN = 3,
STATE_REGISTER_NETWORK = 4, STATE_REGISTER_NETWORK = 4,
@ -69,7 +69,7 @@ protected:
bool set_attach_network(); bool set_attach_network();
private: private:
bool run_self_tests(); void device_ready();
void report_failure(const char* msg); void report_failure(const char* msg);
void event(); void event();

View File

@ -45,17 +45,6 @@ EasyCellularConnection::EasyCellularConnection()
#endif #endif
cellularConnection.set_serial(&cellularSerial); cellularConnection.set_serial(&cellularSerial);
cellularConnection.set_callback(callback(cellular_status)); cellularConnection.set_callback(callback(cellular_status));
}
EasyCellularConnection::~EasyCellularConnection()
{
cellularConnection.stop();
}
void EasyCellularConnection::set_credentials(const char *apn, const char *uname, const char *pwd)
{
}
/* if (cellularConnection.start()) { /* if (cellularConnection.start()) {
int ret_wait = cellularSemaphore.wait(180*1000); int ret_wait = cellularSemaphore.wait(180*1000);
if (ret_wait == 1) { if (ret_wait == 1) {
@ -68,19 +57,34 @@ void EasyCellularConnection::set_credentials(const char *apn, const char *uname,
} }
} }
}*/ }*/
}
EasyCellularConnection::~EasyCellularConnection()
{
cellularConnection.stop();
}
void EasyCellularConnection::set_credentials(const char *apn, const char *uname, const char *pwd)
{
}
void EasyCellularConnection::set_sim_pin(const char *sim_pin) void EasyCellularConnection::set_sim_pin(const char *sim_pin)
{ {
//go_to_state();
} }
nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd) nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
{ {
/*if (!connected) {
wait();
}
cellularConnection.connect(sim_pin, apn, uname, pwd);*/
return 0; return 0;
} }
nsapi_error_t EasyCellularConnection::connect() nsapi_error_t EasyCellularConnection::connect()
{ {
/*attach();
cellularConnection.connect();*/
return 0; return 0;
} }

View File

@ -21,6 +21,9 @@
#include "Timer.h" #include "Timer.h"
#include "mbed_wait_api.h" #include "mbed_wait_api.h"
#include "mbed_debug.h" #include "mbed_debug.h"
#ifdef MBED_CONF_RTOS_PRESENT
#include "rtos/Thread.h"
#endif
using namespace mbed; using namespace mbed;
using namespace events; using namespace events;
@ -223,7 +226,7 @@ void ATHandler::restore_at_timeout()
void ATHandler::process_oob() void ATHandler::process_oob()
{ {
lock(); lock();
log_info("process_oob %d", (_fileHandle->readable() || (_recv_pos < _recv_len))); log_debug("process_oob %d", (_fileHandle->readable() || (_recv_pos < _recv_len)));
if (_fileHandle->readable() || (_recv_pos < _recv_len)) { if (_fileHandle->readable() || (_recv_pos < _recv_len)) {
_current_scope = NotSet; _current_scope = NotSet;
Timer timer; Timer timer;
@ -242,7 +245,9 @@ void ATHandler::process_oob()
if (_fileHandle->readable()) { if (_fileHandle->readable()) {
fill_buffer(); fill_buffer();
} else { } else {
wait_us(100); // wait for more incoming data #ifdef MBED_CONF_RTOS_PRESENT
rtos::Thread::yield();
#endif
} }
} }
@ -314,9 +319,8 @@ void ATHandler::fill_buffer()
at_debug("\n----------readable----------\n"); at_debug("\n----------readable----------\n");
return; return;
} }
#ifdef MBED_CONF_RTOS_PRESENT #ifdef MBED_CONF_RTOS_PRESENT
wait_us(1000); // let other threads run for 1 milisecond rtos::Thread::yield();
#endif #endif
} while (timer.read_ms() < _at_timeout); } while (timer.read_ms() < _at_timeout);

View File

@ -130,12 +130,29 @@ nsapi_error_t AT_CellularNetwork::open_data_channel()
if (!_stack) { if (!_stack) {
return err; 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;
}
}
_at.resp_stop();
if (!is_context_active) {
log_info("Activate PDP context"); log_info("Activate PDP context");
_at.cmd_start("AT+CGACT=1,"); _at.cmd_start("AT+CGACT=1,");
_at.write_int(_cid); _at.write_int(_cid);
_at.cmd_stop(); _at.cmd_stop();
_at.resp_start(); _at.resp_start();
_at.resp_stop(); _at.resp_stop();
}
err = (_at.get_last_error() == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION; err = (_at.get_last_error() == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION;
#endif #endif
return err; return err;
@ -266,19 +283,19 @@ bool AT_CellularNetwork::get_context(nsapi_ip_stack_t requested_stack)
if (get_modem_stack_type(pdp_stack)) { if (get_modem_stack_type(pdp_stack)) {
if (requested_stack == IPV4_STACK) { if (requested_stack == IPV4_STACK) {
if (pdp_stack == IPV4_STACK || pdp_stack == IPV4V6_STACK) { if (pdp_stack == IPV4_STACK || pdp_stack == IPV4V6_STACK) {
_ip_stack_type = pdp_stack; _ip_stack_type = requested_stack;
_cid = cid; _cid = cid;
break; break;
} }
} else if (requested_stack == IPV6_STACK) { } else if (requested_stack == IPV6_STACK) {
if (pdp_stack == IPV6_STACK || pdp_stack == IPV4V6_STACK) { if (pdp_stack == IPV6_STACK || pdp_stack == IPV4V6_STACK) {
_ip_stack_type = pdp_stack; _ip_stack_type = requested_stack;
_cid = cid; _cid = cid;
break; break;
} }
} else { // accept any but prefer to IPv6 } else { // accept any but prefer to IPv6
if (pdp_stack == IPV6_STACK || pdp_stack == IPV4V6_STACK) { if (pdp_stack == IPV6_STACK || pdp_stack == IPV4V6_STACK) {
_ip_stack_type = pdp_stack; _ip_stack_type = requested_stack;
_cid = cid; _cid = cid;
break; break;
} }
@ -353,7 +370,7 @@ nsapi_error_t AT_CellularNetwork::set_registration(char *plmn)
nsapi_error_t ret = set_registration_urc(false); nsapi_error_t ret = set_registration_urc(false);
if (ret) { if (ret) {
log_error("Setting registration URC failed!"); log_error("Setting registration URC failed!");
return ret; _at.clear_error(); // allow temporary failures here
} }
if (!plmn) { if (!plmn) {

View File

@ -258,7 +258,7 @@ nsapi_size_or_error_t AT_CellularStack::socket_recvfrom(nsapi_socket_t handle, S
/* Check parameters */ /* Check parameters */
if (size < max_packet_size) { if (size < max_packet_size) {
log_warn("Socket receive buffer smaller than max packet size! size:%d max_packet_size:%d", size, max_packet_size); //log_warn("Socket receive buffer smaller than max packet size! size:%d max_packet_size:%d", size, max_packet_size);
} }
_at.lock(); _at.lock();