mirror of https://github.com/ARMmbed/mbed-os.git
working example?
parent
fbfbdc9718
commit
1dcc6684bf
|
@ -39,8 +39,11 @@
|
|||
static EventQueue at_queue(8 * EVENTS_EVENT_SIZE);
|
||||
static CELLULAR_DEVICE cellularDevice(at_queue);
|
||||
|
||||
CellularConnectionUtil::CellularConnectionUtil() : _serial(0), _state(STATE_POWER_ON), _next_state(_state), _status_callback(0), _network(0), _power(0), _queue(8 * EVENTS_EVENT_SIZE), _queue_thread(0), _cellularDevice(&cellularDevice)
|
||||
CellularConnectionUtil::CellularConnectionUtil() : _serial(0), _state(STATE_POWER_ON), _next_state(_state),
|
||||
_status_callback(0), _network(0), _power(0), _queue(8 * EVENTS_EVENT_SIZE),
|
||||
_queue_thread(0), _cellularDevice(&cellularDevice)
|
||||
{
|
||||
memset(_sim_pin, sizeof(_sim_pin), 0);
|
||||
}
|
||||
|
||||
CellularConnectionUtil::~CellularConnectionUtil()
|
||||
|
@ -48,6 +51,25 @@ CellularConnectionUtil::~CellularConnectionUtil()
|
|||
stop();
|
||||
}
|
||||
|
||||
nsapi_error_t CellularConnectionUtil::init()
|
||||
{
|
||||
_power = _cellularDevice->open_power(_serial);
|
||||
if (!_power) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
_network = _cellularDevice->open_network(_serial);
|
||||
if (!_network) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
at_queue.chain(&_queue);
|
||||
|
||||
log_info("init done...");
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
bool CellularConnectionUtil::open_power(FileHandle *fh)
|
||||
{
|
||||
if (!_power) {
|
||||
|
@ -69,45 +91,50 @@ bool CellularConnectionUtil::open_power(FileHandle *fh)
|
|||
return true;
|
||||
}
|
||||
|
||||
void CellularConnectionUtil::set_sim_pin(const char * sim_pin)
|
||||
{
|
||||
strncpy(_sim_pin, sim_pin, PIN_SIZE);
|
||||
}
|
||||
|
||||
bool CellularConnectionUtil::open_sim()
|
||||
{
|
||||
#ifdef MBED_CONF_APP_CELLULAR_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) {
|
||||
log_debug("Waiting for SIM (state %d)...", state);
|
||||
return false;
|
||||
}
|
||||
if (state == CellularSIM::SimStatePinNeeded) {
|
||||
log_info("SIM pin required, entering pin: %s", MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
err = sim->set_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
if (err) {
|
||||
log_error("SIM pin set failed with: %d, bailing out...", err);
|
||||
if (strlen(_sim_pin)) {
|
||||
nsapi_error_t err;
|
||||
static CellularSIM *sim;
|
||||
if (!sim) {
|
||||
sim = _cellularDevice->open_sim(_serial);
|
||||
}
|
||||
if (!sim) {
|
||||
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) {
|
||||
break;
|
||||
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) {
|
||||
log_debug("Waiting for SIM (state %d)...", state);
|
||||
return false;
|
||||
}
|
||||
if (state == CellularSIM::SimStatePinNeeded) {
|
||||
log_info("SIM pin required, entering pin: %s", _sim_pin);
|
||||
err = sim->set_pin(_sim_pin);
|
||||
if (err) {
|
||||
log_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) {
|
||||
break;
|
||||
}
|
||||
log_debug("SIM state: %d", state);
|
||||
return false;
|
||||
}
|
||||
log_debug("SIM state: %d", state);
|
||||
return false;
|
||||
}
|
||||
return state == CellularSIM::SimStateReady;
|
||||
} else {
|
||||
log_info("Continue without SIM.");
|
||||
return true;
|
||||
}
|
||||
return state == CellularSIM::SimStateReady;
|
||||
#else
|
||||
log_info("Continue without SIM.");
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CellularConnectionUtil::device_ready()
|
||||
|
@ -143,7 +170,8 @@ bool CellularConnectionUtil::set_network_registration(char *plmn)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CellularConnectionUtil::get_network_registration(CellularNetwork::RegistrationType type, CellularNetwork::RegistrationStatus &status, bool &is_registered)
|
||||
bool CellularConnectionUtil::get_network_registration(CellularNetwork::RegistrationType type,
|
||||
CellularNetwork::RegistrationStatus &status, bool &is_registered)
|
||||
{
|
||||
is_registered = false;
|
||||
bool is_roaming = false;
|
||||
|
@ -220,9 +248,11 @@ void CellularConnectionUtil::report_failure(const char* msg)
|
|||
}
|
||||
}
|
||||
|
||||
bool CellularConnectionUtil::continue_with_state(CellularState state)
|
||||
nsapi_error_t CellularConnectionUtil::continue_to_state(CellularState state)
|
||||
{
|
||||
_state = state;
|
||||
if (state < _state) {
|
||||
_state = state;
|
||||
}
|
||||
if (!_queue.call_in(0, callback(this, &CellularConnectionUtil::event))) {
|
||||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
|
@ -235,6 +265,7 @@ void CellularConnectionUtil::event()
|
|||
{
|
||||
nsapi_error_t err;
|
||||
int event_timeout = -1;
|
||||
|
||||
switch (_state) {
|
||||
case STATE_POWER_ON:
|
||||
cellularDevice.set_timeout(TIMEOUT_POWER_ON);
|
||||
|
@ -376,18 +407,15 @@ void CellularConnectionUtil::event()
|
|||
//network->set_credentials("internet");
|
||||
err = _network->connect();
|
||||
if (!err) {
|
||||
_next_state = STATE_READY;
|
||||
_next_state = STATE_CONNECTED;
|
||||
} else {
|
||||
report_failure("Network connect");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case STATE_READY:
|
||||
case STATE_CONNECTED:
|
||||
cellularDevice.set_timeout(TIMEOUT_NETWORK);
|
||||
log_debug("Cellular ready! (timeout %d ms)", TIMEOUT_NETWORK);
|
||||
if (_status_callback) {
|
||||
_status_callback(_state, _next_state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MBED_ASSERT(0);
|
||||
|
@ -426,40 +454,36 @@ void CellularConnectionUtil::event()
|
|||
}
|
||||
}
|
||||
|
||||
bool CellularConnectionUtil::start(bool start_dispatch)
|
||||
nsapi_error_t CellularConnectionUtil::start_dispatch()
|
||||
{
|
||||
log_info("CellularConnectionUtil::start");
|
||||
_power = _cellularDevice->open_power(_serial);
|
||||
if (!_power) {
|
||||
log_info("Create cellular thread");
|
||||
|
||||
MBED_ASSERT(!_queue_thread);
|
||||
|
||||
_queue_thread = new Thread();
|
||||
if (!_queue_thread) {
|
||||
stop();
|
||||
return false;
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
_network = _cellularDevice->open_network(_serial);
|
||||
if (!_network) {
|
||||
if (_queue_thread->start(callback(&_queue, &EventQueue::dispatch_forever)) != osOK) {
|
||||
stop();
|
||||
return false;
|
||||
}
|
||||
if (!_queue.call_in(0, callback(this, &CellularConnectionUtil::event))) {
|
||||
stop();
|
||||
return false;
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
at_queue.chain(&_queue);
|
||||
|
||||
if (start_dispatch) {
|
||||
log_info("Create cellular thread");
|
||||
_queue_thread = new Thread();
|
||||
if (!_queue_thread) {
|
||||
stop();
|
||||
return false;
|
||||
}
|
||||
if (_queue_thread->start(callback(&_queue, &EventQueue::dispatch_forever)) != osOK) {
|
||||
stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
log_info("CellularConnectionUtil::started");
|
||||
return true;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularConnectionUtil::disconnect()
|
||||
{
|
||||
log_info("CellularConnectionUtil::disconnect");
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
if (_network) {
|
||||
err = _network->disconnect();
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void CellularConnectionUtil::stop()
|
||||
|
@ -478,7 +502,7 @@ void CellularConnectionUtil::set_serial(UARTSerial *serial)
|
|||
_serial = serial;
|
||||
}
|
||||
|
||||
void CellularConnectionUtil::set_callback(mbed::Callback<int(int, int)> status_callback)
|
||||
void CellularConnectionUtil::set_callback(mbed::Callback<bool(int, int)> status_callback)
|
||||
{
|
||||
_status_callback = status_callback;
|
||||
}
|
||||
|
@ -490,7 +514,7 @@ EventQueue *CellularConnectionUtil::get_queue()
|
|||
|
||||
CellularNetwork* CellularConnectionUtil::get_network()
|
||||
{
|
||||
if (_state != STATE_READY) {
|
||||
if (_state != STATE_CONNECTED) {
|
||||
return NULL;
|
||||
}
|
||||
return _network;
|
||||
|
@ -498,11 +522,9 @@ CellularNetwork* CellularConnectionUtil::get_network()
|
|||
|
||||
CellularDevice* CellularConnectionUtil::get_device()
|
||||
{
|
||||
|
||||
if (_cellularDevice) {
|
||||
return _cellularDevice;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "CellularTargets.h"
|
||||
#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h)
|
||||
|
||||
const int PIN_SIZE = 8;
|
||||
|
||||
class CellularConnectionUtil
|
||||
{
|
||||
public:
|
||||
|
@ -44,20 +46,26 @@ public:
|
|||
STATE_ATTACH_NETWORK = 7,
|
||||
STATE_ATTACHING_NETWORK = 8,
|
||||
STATE_CONNECT_NETWORK = 9,
|
||||
STATE_READY = 10,
|
||||
STATE_CONNECTED = 10,
|
||||
};
|
||||
|
||||
public:
|
||||
CellularConnectionUtil();
|
||||
virtual ~CellularConnectionUtil();
|
||||
void set_serial(UARTSerial *serial);
|
||||
void set_callback(mbed::Callback<int(int, int)> status_callback);
|
||||
void set_callback(mbed::Callback<bool(int, int)> status_callback);
|
||||
EventQueue* get_queue();
|
||||
bool start(bool start_dispatch = true);
|
||||
nsapi_error_t start_dispatch();
|
||||
nsapi_error_t init();
|
||||
|
||||
|
||||
nsapi_error_t disconnect();
|
||||
void stop();
|
||||
CellularNetwork* get_network();
|
||||
CellularDevice* get_device();
|
||||
bool continue_with_state(CellularState state);
|
||||
nsapi_error_t continue_to_state(CellularState state);
|
||||
|
||||
void set_sim_pin(const char * sim_pin);
|
||||
|
||||
protected:
|
||||
bool open_power(FileHandle *fh);
|
||||
|
@ -77,13 +85,14 @@ private:
|
|||
CellularState _state;
|
||||
CellularState _next_state;
|
||||
|
||||
mbed::Callback<int(int, int)> _status_callback;
|
||||
mbed::Callback<bool(int, int)> _status_callback;
|
||||
|
||||
CellularNetwork *_network;
|
||||
CellularPower *_power;
|
||||
EventQueue _queue;
|
||||
Thread *_queue_thread;
|
||||
CellularDevice *_cellularDevice;
|
||||
char _sim_pin[PIN_SIZE+1];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "CellularConnectionUtil.h"
|
||||
#include "CellularTargets.h"
|
||||
#include "CellularUtil.h"
|
||||
#include "CellularConnectionUtil.h"
|
||||
|
||||
#include "EasyCellularConnection.h"
|
||||
|
||||
|
@ -28,18 +27,29 @@
|
|||
static CellularConnectionUtil cellularConnection;
|
||||
static Semaphore cellularSemaphore(0);
|
||||
static UARTSerial cellularSerial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
static int cellular_status(int state, int next_state)
|
||||
|
||||
|
||||
bool EasyCellularConnection::cellular_status(int state, int next_state)
|
||||
{
|
||||
printf("cellular_status %d=>%d", state, next_state);
|
||||
if (state == CellularConnectionUtil::STATE_READY) {
|
||||
log_info("cellular_status %d=>%d", state, next_state);
|
||||
if (_target_state == state) {
|
||||
if (state == CellularConnectionUtil::STATE_CONNECTED) {
|
||||
_is_connected = true;
|
||||
} else {
|
||||
_is_connected = false;
|
||||
}
|
||||
MBED_ASSERT(cellularSemaphore.release() == osOK);
|
||||
return false;
|
||||
}
|
||||
return 1;
|
||||
else {
|
||||
_is_connected = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
EasyCellularConnection::EasyCellularConnection()
|
||||
EasyCellularConnection::EasyCellularConnection() : _is_connected(false), _target_state(CellularConnectionUtil::STATE_POWER_ON)
|
||||
{
|
||||
log_info("EasyCellularConnection start");
|
||||
log_info("EasyCellularConnection()");
|
||||
}
|
||||
|
||||
EasyCellularConnection::~EasyCellularConnection()
|
||||
|
@ -47,49 +57,81 @@ EasyCellularConnection::~EasyCellularConnection()
|
|||
cellularConnection.stop();
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::init()
|
||||
{
|
||||
log_init(STDIO_UART_TX, STDIO_UART_RX, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
|
||||
#if defined (MDMRTS) && defined (MDMCTS)
|
||||
cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
#endif
|
||||
cellularConnection.set_serial(&cellularSerial);
|
||||
cellularConnection.set_callback(callback(this, &EasyCellularConnection::cellular_status));
|
||||
|
||||
nsapi_error_t err = cellularConnection.init();
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
err = cellularConnection.start_dispatch();
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void EasyCellularConnection::set_credentials(const char *apn, const char *uname, const char *pwd)
|
||||
{
|
||||
CellularNetwork * network = cellularConnection.get_network();
|
||||
if (network) {
|
||||
network->set_credentials(apn, uname, pwd);
|
||||
} else {
|
||||
log_error("NO Network...");
|
||||
}
|
||||
}
|
||||
|
||||
void EasyCellularConnection::set_sim_pin(const char *sim_pin)
|
||||
{
|
||||
cellularConnection.set_sim_pin(sim_pin);
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd)
|
||||
{
|
||||
cellularConnection.set_sim_pin(sim_pin);
|
||||
cellularConnection.get_network()->set_credentials(apn, uname, pwd);
|
||||
return connect();
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::connect()
|
||||
{
|
||||
#if defined (MDMRTS) && defined (MDMCTS)
|
||||
cellularSerial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
#endif
|
||||
cellularConnection.set_serial(&cellularSerial);
|
||||
cellularConnection.set_callback(callback(cellular_status));
|
||||
if (cellularConnection.start()) {
|
||||
_target_state = CellularConnectionUtil::STATE_CONNECTED;
|
||||
nsapi_error_t err = cellularConnection.continue_to_state(_target_state);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
int ret_wait = cellularSemaphore.wait(10*60*1000); // cellular network searching may take several minutes
|
||||
if (ret_wait != 1) {
|
||||
log_error("No cellular connection");
|
||||
log_info("No cellular connection");
|
||||
err = NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
}
|
||||
|
||||
return cellularConnection.get_network()?NSAPI_ERROR_OK:NSAPI_ERROR_NO_CONNECTION;
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::disconnect()
|
||||
{
|
||||
return 0;
|
||||
_is_connected = false;
|
||||
return cellularConnection.disconnect();
|
||||
}
|
||||
|
||||
bool EasyCellularConnection::is_connected()
|
||||
{
|
||||
return 0;
|
||||
return _is_connected;
|
||||
}
|
||||
|
||||
const char *EasyCellularConnection::get_ip_address()
|
||||
{
|
||||
return cellularConnection.get_network()->get_ip_address();
|
||||
CellularNetwork * network = cellularConnection.get_network();
|
||||
if (network) {
|
||||
return cellularConnection.get_network()->get_ip_address();
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
const char *EasyCellularConnection::get_netmask()
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define EASY_CELLULAR_CONNECTION_H
|
||||
|
||||
#include "netsocket/CellularBase.h"
|
||||
#include "CellularConnectionUtil.h"
|
||||
|
||||
/** ExampleCellularBase class
|
||||
*
|
||||
|
@ -30,6 +31,11 @@ public:
|
|||
|
||||
public:
|
||||
|
||||
/**
|
||||
* MUST CALL, create power and start dispatcher
|
||||
*/
|
||||
nsapi_error_t init();
|
||||
|
||||
/** Set the Cellular network credentials
|
||||
*
|
||||
* Please check documentation of connect() for default behaviour of APN settings.
|
||||
|
@ -112,6 +118,17 @@ protected:
|
|||
* @return The underlying NetworkStack object
|
||||
*/
|
||||
virtual NetworkStack *get_stack();
|
||||
|
||||
private:
|
||||
/** Callback for cellular status changes
|
||||
*
|
||||
* @return true to continue state machine
|
||||
*/
|
||||
bool cellular_status(int state, int next_state);
|
||||
|
||||
|
||||
CellularConnectionUtil::CellularState _target_state;
|
||||
bool _is_connected;
|
||||
};
|
||||
|
||||
#endif // EASY_CELLULAR_CONNECTION_H
|
||||
|
|
Loading…
Reference in New Issue