APN lookup from database support.

pull/6082/head
Teppo Järvelin 2018-02-24 15:12:53 +02:00 committed by Ari Parkkila
parent 6670ebbc5f
commit 1fd9ba6caa
7 changed files with 121 additions and 46 deletions

View File

@ -36,7 +36,7 @@ static CELLULAR_DEVICE cellularDevice(at_queue);
static char device_info_buf[2048];
CellularConnectionUtil::CellularConnectionUtil() : _serial(0), _state(STATE_POWER_ON), _next_state(_state),
_status_callback(0), _network(0), _power(0), _queue(8 * EVENTS_EVENT_SIZE),
_status_callback(0), _network(0), _power(0), _sim(0), _queue(8 * EVENTS_EVENT_SIZE),
_queue_thread(0), _cellularDevice(&cellularDevice)
{
memset(_sim_pin, 0, sizeof(_sim_pin));
@ -60,6 +60,12 @@ nsapi_error_t CellularConnectionUtil::init()
return NSAPI_ERROR_NO_MEMORY;
}
_sim = _cellularDevice->open_sim(_serial);
if (!_sim) {
stop();
return NSAPI_ERROR_NO_MEMORY;
}
at_queue.chain(&_queue);
tr_info("init done...");
@ -94,43 +100,38 @@ void CellularConnectionUtil::set_sim_pin(const char * sim_pin)
bool CellularConnectionUtil::open_sim()
{
CellularSIM::SimState state = CellularSIM::SimStateUnknown;
// wait until SIM is readable
// here you could add wait(secs) if you know start delay of your SIM
while (_sim->get_sim_state(state) != NSAPI_ERROR_OK || state == CellularSIM::SimStateUnknown) {
tr_info("Waiting for SIM (state %d)...", state);
return false;
}
tr_info("Initial SIM state: %d", state);
if (strlen(_sim_pin)) {
nsapi_error_t err;
static CellularSIM *sim;
if (!sim) {
sim = _cellularDevice->open_sim(_serial);
}
if (!sim) {
return false;
}
CellularSIM::SimState state = CellularSIM::SimStateUnknown;
// wait until SIM is readable
// here you could add wait(secs) if you know start delay of your SIM
while (sim->get_sim_state(state) != NSAPI_ERROR_OK || state == CellularSIM::SimStateUnknown) {
tr_debug("Waiting for SIM (state %d)...", state);
return false;
}
if (state == CellularSIM::SimStatePinNeeded) {
tr_info("SIM pin required, entering pin: %s", _sim_pin);
err = sim->set_pin(_sim_pin);
err = _sim->set_pin(_sim_pin);
if (err) {
tr_error("SIM pin set failed with: %d, bailing out...", err);
return false;
}
// here you could add wait(secs) if you know delay of changing PIN on your SIM
for (int i = 0; i < MAX_SIM_READY_WAITING_TIME; i++) {
if (sim->get_sim_state(state) == NSAPI_ERROR_OK && state == CellularSIM::SimStateReady) {
if (_sim->get_sim_state(state) == NSAPI_ERROR_OK && state == CellularSIM::SimStateReady) {
break;
}
tr_debug("SIM state: %d", state);
return false;
}
}
return state == CellularSIM::SimStateReady;
} else {
tr_info("Continue without SIM.");
return true;
tr_info("No SIM pin provided.");
}
return state == CellularSIM::SimStateReady;
}
void CellularConnectionUtil::device_ready()
@ -506,6 +507,11 @@ CellularDevice* CellularConnectionUtil::get_device()
return _cellularDevice;
}
CellularSIM* CellularConnectionUtil::get_sim()
{
return _sim;
}
NetworkStack *CellularConnectionUtil::get_stack()
{
return _cellularDevice->get_stack();

View File

@ -28,6 +28,7 @@
#include "CellularNetwork.h"
#include "CellularPower.h"
#include "CellularSIM.h"
// modem type is defined as CELLULAR_DEVICE macro
#define _CELLULAR_STRINGIFY(a) #a
@ -105,6 +106,11 @@ public:
*/
CellularDevice* get_device();
/** Get cellular sim interface
* @return sim interface, NULL on failure
*/
CellularSIM* get_sim();
/** Change cellular connection to the target state
* @param state to continue
* @return see nsapi_error_t, 0 on success
@ -142,6 +148,7 @@ private:
CellularNetwork *_network;
CellularPower *_power;
CellularSIM *_sim;
events::EventQueue _queue;
rtos::Thread *_queue_thread;
CellularDevice *_cellularDevice;

View File

@ -26,9 +26,12 @@
#include "CellularUtil.h"
#include "EasyCellularConnection.h"
#include "CellularLog.h"
#if MBED_CONF_APP_CELLULAR_USE_APN_LOOKUP
#include "APN_db.h"
#endif //MBED_CONF_APP_CELLULAR_USE_APN_LOOKUP
namespace mbed {
bool EasyCellularConnection::cellular_status(int state, int next_state)
@ -50,7 +53,7 @@ bool EasyCellularConnection::cellular_status(int state, int next_state)
}
EasyCellularConnection::EasyCellularConnection() : _is_connected(false), _is_initialized(false),
_target_state(CellularConnectionUtil::STATE_POWER_ON),
_credentials_set(false), _target_state(CellularConnectionUtil::STATE_POWER_ON),
_cellularSerial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE),
_cellularSemaphore(0), _cellularConnectionUtil(), _credentials_err(NSAPI_ERROR_OK)
{
@ -67,7 +70,7 @@ nsapi_error_t EasyCellularConnection::init()
nsapi_error_t err = NSAPI_ERROR_OK;
if (!_is_initialized) {
#if defined (MDMRTS) && defined (MDMCTS)
_cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
_cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
#endif
_cellularConnectionUtil.set_serial(&_cellularSerial);
_cellularConnectionUtil.set_callback(callback(this, &EasyCellularConnection::cellular_status));
@ -85,16 +88,21 @@ nsapi_error_t EasyCellularConnection::init()
void EasyCellularConnection::set_credentials(const char *apn, const char *uname, const char *pwd)
{
_credentials_err = init();
if (apn && strlen(apn) > 0) {
_credentials_err = init();
if (_credentials_err) {
return;
}
CellularNetwork * network = _cellularConnectionUtil.get_network();
if (network) {
_credentials_err = network->set_credentials(apn, uname, pwd);
} else {
tr_error("NO Network...");
if (_credentials_err) {
return;
}
CellularNetwork * network = _cellularConnectionUtil.get_network();
if (network) {
_credentials_err = network->set_credentials(apn, uname, pwd);
if (_credentials_err == NSAPI_ERROR_OK) {
_credentials_set = true;
}
} else {
tr_error("NO Network...");
}
}
}
@ -107,20 +115,19 @@ void EasyCellularConnection::set_sim_pin(const char *sim_pin)
nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
{
nsapi_error_t err = check_connect();
if (err) {
return err;
if (_is_connected) {
return NSAPI_ERROR_IS_CONNECTED;
}
set_credentials(apn, uname, pwd);
if (_credentials_err) {
return _credentials_err;
}
if (sim_pin) {
_cellularConnectionUtil.set_sim_pin(sim_pin);
}
err = _cellularConnectionUtil.get_network()->set_credentials(apn, uname, pwd);
if (err) {
return err;
}
return connect();
}
@ -129,6 +136,12 @@ nsapi_error_t EasyCellularConnection::check_connect()
if (_is_connected) {
return NSAPI_ERROR_IS_CONNECTED;
}
// there was an error while setting credentials but it's a void function so check error here...
if (_credentials_err) {
return _credentials_err;
}
nsapi_error_t err = init();
if (err) {
return err;
@ -139,15 +152,39 @@ nsapi_error_t EasyCellularConnection::check_connect()
nsapi_error_t EasyCellularConnection::connect()
{
// there was an error while setting credentials but it's a void function so check error here...
if (_credentials_err) {
return _credentials_err;
}
nsapi_error_t err = check_connect();
if (err) {
return err;
}
#if MBED_CONF_APP_CELLULAR_USE_APN_LOOKUP
if (!_credentials_set) {
_target_state = CellularConnectionUtil::STATE_SIM_PIN;
err = _cellularConnectionUtil.continue_to_state(_target_state);
if (err == NSAPI_ERROR_OK) {
int sim_wait = _cellularSemaphore.wait(6*1000); // reserve 6 seconds to access to SIM
if (sim_wait != 1) {
tr_error("NO SIM ACCESS");
err = NSAPI_ERROR_NO_CONNECTION;
} else {
char imsi[MAX_IMSI_LENGTH+1];
err = _cellularConnectionUtil.get_sim()->get_imsi(imsi);
if (err == NSAPI_ERROR_OK) {
const char *apn_config = apnconfig(imsi);
if (apn_config) {
const char* apn = _APN_GET(apn_config);
const char* uname = _APN_GET(apn_config);
const char* pwd = _APN_GET(apn_config);
tr_info("Looked up APN %s", apn);
err = _cellularConnectionUtil.get_network()->set_credentials(apn, uname, pwd);
}
}
}
}
if (err) {
return err;
}
}
#endif // MBED_CONF_APP_CELLULAR_USE_APN_LOOKUP
_target_state = CellularConnectionUtil::STATE_CONNECTED;
err = _cellularConnectionUtil.continue_to_state(_target_state);
@ -166,6 +203,7 @@ nsapi_error_t EasyCellularConnection::disconnect()
{
_credentials_err = NSAPI_ERROR_OK;
_is_connected = false;
_credentials_set = false;
if (!_cellularConnectionUtil.get_network()) {
return NSAPI_ERROR_NO_CONNECTION;
}

View File

@ -136,6 +136,7 @@ private:
bool _is_connected;
bool _is_initialized;
bool _credentials_set;
CellularConnectionUtil::CellularState _target_state;
UARTSerial _cellularSerial;

View File

@ -23,7 +23,7 @@
namespace mbed {
const int MAX_SIM_READY_WAITING_TIME = 30;
const int MAX_IMSI_LENGTH = 15;
/**
* Class CellularSIM
*
@ -78,6 +78,13 @@ public:
* @return zero on success
*/
virtual nsapi_error_t get_sim_state(SimState &state) = 0;
/** Get IMSI from the sim card
*
* @param imsi preallocated char* which after successful request contains imsi
* @return zero on success
*/
virtual nsapi_error_t get_imsi(char* imsi) = 0;
};
} // namespace mbed

View File

@ -114,3 +114,17 @@ nsapi_error_t AT_CellularSIM::set_pin_query(const char *sim_pin, bool query_pin)
}
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularSIM::get_imsi(char* imsi)
{
_at.lock();
_at.cmd_start("AT+CIMI");
_at.cmd_stop();
_at.resp_start();
int len = _at.read_string(imsi, MAX_IMSI_LENGTH);
if (len > 0) {
imsi[len] = '\0';
}
_at.resp_stop();
return _at.unlock_return_error();
}

View File

@ -43,6 +43,8 @@ public:
virtual nsapi_error_t set_pin_query(const char *sim_pin, bool query_pin);
virtual nsapi_error_t get_sim_state(SimState &state);
virtual nsapi_error_t get_imsi(char* imsi);
};
} // namespace mbed