mirror of https://github.com/ARMmbed/mbed-os.git
Cellular: Added dynamic alloc and destruction to easycellular.
Now application can call connect and disconnect multiple times and resources are freed and constructed properly. Also whole easycellular can be deleted and constructed again.pull/6792/head
parent
d08c819830
commit
b22a16fe4a
|
@ -70,18 +70,28 @@ CellularConnectionFSM::CellularConnectionFSM() :
|
|||
CellularConnectionFSM::~CellularConnectionFSM()
|
||||
{
|
||||
stop();
|
||||
delete _cellularDevice;
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::stop()
|
||||
{
|
||||
tr_info("CellularConnectionUtil::stop");
|
||||
_queue.cancel(_event_id);
|
||||
_queue.break_dispatch();
|
||||
|
||||
if (_queue_thread) {
|
||||
_queue_thread->terminate();
|
||||
delete _queue_thread;
|
||||
_queue_thread = NULL;
|
||||
}
|
||||
|
||||
delete _cellularDevice;
|
||||
_cellularDevice = NULL;
|
||||
// _cellularDevice closes all interfaces in destructor
|
||||
_power = NULL;
|
||||
_network = NULL;
|
||||
_sim = NULL;
|
||||
|
||||
_state = STATE_INIT;
|
||||
_next_state = _state;
|
||||
}
|
||||
|
||||
nsapi_error_t CellularConnectionFSM::init()
|
||||
|
@ -98,6 +108,7 @@ nsapi_error_t CellularConnectionFSM::init()
|
|||
stop();
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
_network = _cellularDevice->open_network(_serial);
|
||||
if (!_network) {
|
||||
stop();
|
||||
|
@ -360,6 +371,7 @@ nsapi_error_t CellularConnectionFSM::continue_from_state(CellularState state)
|
|||
|
||||
nsapi_error_t CellularConnectionFSM::continue_to_state(CellularState state)
|
||||
{
|
||||
MBED_ASSERT(_cellularDevice);
|
||||
_retry_count = 0;
|
||||
if (state < _state) {
|
||||
_state = state;
|
||||
|
@ -647,8 +659,13 @@ void CellularConnectionFSM::set_callback(mbed::Callback<bool(int, int)> status_c
|
|||
|
||||
void CellularConnectionFSM::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||
{
|
||||
MBED_ASSERT(_network);
|
||||
_event_status_cb = status_cb;
|
||||
_network->attach(callback(this, &CellularConnectionFSM::network_callback));
|
||||
if (status_cb) {
|
||||
_network->attach(callback(this, &CellularConnectionFSM::network_callback));
|
||||
} else {
|
||||
_network->attach(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void CellularConnectionFSM::network_callback(nsapi_event_t ev, intptr_t ptr)
|
||||
|
|
|
@ -102,7 +102,8 @@ public:
|
|||
*/
|
||||
nsapi_error_t start_dispatch();
|
||||
|
||||
/** Stop event queue dispatching and close cellular interfaces
|
||||
/** Stop event queue dispatching and close cellular interfaces. After calling stop(), init() must be called
|
||||
* before any other methods.
|
||||
*/
|
||||
void stop();
|
||||
|
||||
|
@ -153,6 +154,7 @@ public:
|
|||
* @return string format of the given state
|
||||
*/
|
||||
const char* get_state_string(CellularState state);
|
||||
|
||||
private:
|
||||
bool power_on();
|
||||
bool open_sim();
|
||||
|
|
|
@ -76,7 +76,8 @@ EasyCellularConnection::EasyCellularConnection(bool debug) :
|
|||
|
||||
EasyCellularConnection::~EasyCellularConnection()
|
||||
{
|
||||
_cellularConnectionFSM.stop();
|
||||
_cellularConnectionFSM.set_callback(NULL);
|
||||
_cellularConnectionFSM.attach(NULL);
|
||||
}
|
||||
|
||||
nsapi_error_t EasyCellularConnection::init()
|
||||
|
@ -118,7 +119,7 @@ void EasyCellularConnection::set_credentials(const char *apn, const char *uname,
|
|||
}
|
||||
#endif // #if USE_APN_LOOKUP
|
||||
} else {
|
||||
//if get_network() returns NULL it means there was not enough memory for
|
||||
//if get_network() returns NULL it means there was not enough memory for
|
||||
//an AT_CellularNetwork element during CellularConnectionFSM initialization
|
||||
tr_error("There was not enough memory during CellularConnectionFSM initialization");
|
||||
}
|
||||
|
@ -224,13 +225,19 @@ nsapi_error_t EasyCellularConnection::disconnect()
|
|||
{
|
||||
_credentials_err = NSAPI_ERROR_OK;
|
||||
_is_connected = false;
|
||||
_is_initialized = false;
|
||||
#if USE_APN_LOOKUP
|
||||
_credentials_set = false;
|
||||
#endif // #if USE_APN_LOOKUP
|
||||
if (!_cellularConnectionFSM.get_network()) {
|
||||
return NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
nsapi_error_t err = NSAPI_ERROR_OK;
|
||||
if (_cellularConnectionFSM.get_network()) {
|
||||
err = _cellularConnectionFSM.get_network()->disconnect();
|
||||
}
|
||||
return _cellularConnectionFSM.get_network()->disconnect();
|
||||
|
||||
_cellularConnectionFSM.stop();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
bool EasyCellularConnection::is_connected()
|
||||
|
|
|
@ -63,7 +63,6 @@ static const uint8_t map_3gpp_errors[][2] = {
|
|||
|
||||
ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char *output_delimiter, uint16_t send_delay) :
|
||||
_nextATHandler(0),
|
||||
_fileHandle(fh),
|
||||
_queue(queue),
|
||||
_last_err(NSAPI_ERROR_OK),
|
||||
_last_3gpp_error(0),
|
||||
|
@ -109,9 +108,7 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char
|
|||
set_tag(&_info_stop, CRLF);
|
||||
set_tag(&_elem_stop, ")");
|
||||
|
||||
_fileHandle->set_blocking(false);
|
||||
|
||||
set_filehandle_sigio();
|
||||
set_file_handle(fh);
|
||||
}
|
||||
|
||||
void ATHandler::enable_debug(bool enable)
|
||||
|
@ -153,7 +150,20 @@ FileHandle *ATHandler::get_file_handle()
|
|||
|
||||
void ATHandler::set_file_handle(FileHandle *fh)
|
||||
{
|
||||
_fh_sigio_set = false;
|
||||
_fileHandle = fh;
|
||||
_fileHandle->set_blocking(false);
|
||||
set_filehandle_sigio();
|
||||
}
|
||||
|
||||
void ATHandler::set_filehandle_sigio()
|
||||
{
|
||||
if (_fh_sigio_set) {
|
||||
return;
|
||||
}
|
||||
|
||||
_fileHandle->sigio(mbed::Callback<void()>(this, &ATHandler::event));
|
||||
_fh_sigio_set = true;
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::set_urc_handler(const char *prefix, mbed::Callback<void()> callback)
|
||||
|
@ -310,15 +320,6 @@ void ATHandler::process_oob()
|
|||
unlock();
|
||||
}
|
||||
|
||||
void ATHandler::set_filehandle_sigio()
|
||||
{
|
||||
if (_fh_sigio_set) {
|
||||
return;
|
||||
}
|
||||
_fileHandle->sigio(mbed::Callback<void()>(this, &ATHandler::event));
|
||||
_fh_sigio_set = true;
|
||||
}
|
||||
|
||||
void ATHandler::reset_buffer()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
|
@ -1023,8 +1024,8 @@ void ATHandler::cmd_start(const char* cmd)
|
|||
if (time_difference < (uint64_t)_at_send_delay) {
|
||||
wait_ms((uint64_t)_at_send_delay - time_difference);
|
||||
tr_debug("AT wait %llu %llu", current_time, _last_response_stop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
at_debug("AT cmd %s (err %d)\n", cmd, _last_err);
|
||||
|
||||
|
@ -1088,7 +1089,7 @@ void ATHandler::cmd_stop()
|
|||
size_t ATHandler::write_bytes(const uint8_t *data, size_t len)
|
||||
{
|
||||
at_debug("AT write bytes %d (err %d)\n", len, _last_err);
|
||||
|
||||
|
||||
if (_last_err != NSAPI_ERROR_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -86,12 +86,6 @@ public:
|
|||
*/
|
||||
FileHandle *get_file_handle();
|
||||
|
||||
/** Set file handle, which is used for reading AT responses and writing AT commands
|
||||
*
|
||||
* @param fh file handle used for reading AT responses and writing AT commands
|
||||
*/
|
||||
void set_file_handle(FileHandle *fh);
|
||||
|
||||
/** Locks the mutex for file handle if AT_HANDLER_MUTEX is defined.
|
||||
*/
|
||||
void lock();
|
||||
|
@ -165,6 +159,11 @@ public:
|
|||
*/
|
||||
void clear_error();
|
||||
|
||||
/**
|
||||
* Flushes the underlying stream
|
||||
*/
|
||||
void flush();
|
||||
|
||||
/** Tries to find oob's from the AT response. Call the urc callback if one is found.
|
||||
*/
|
||||
void process_oob();
|
||||
|
@ -173,10 +172,11 @@ public:
|
|||
*/
|
||||
void set_filehandle_sigio();
|
||||
|
||||
/**
|
||||
* Flushes the underlying stream
|
||||
/** Set file handle, which is used for reading AT responses and writing AT commands
|
||||
*
|
||||
* @param fh file handle used for reading AT responses and writing AT commands
|
||||
*/
|
||||
void flush();
|
||||
void set_file_handle(FileHandle *fh);
|
||||
|
||||
protected:
|
||||
void event();
|
||||
|
|
|
@ -48,6 +48,19 @@ AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(a
|
|||
|
||||
AT_CellularNetwork::~AT_CellularNetwork()
|
||||
{
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
(void)disconnect();
|
||||
#else
|
||||
delete _stack;
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
|
||||
for (int type = 0; type < CellularNetwork::C_MAX; type++) {
|
||||
if (has_registration((RegistrationType)type)) {
|
||||
_at.remove_urc_handler(at_reg[type].urc_prefix, _urc_funcs[type]);
|
||||
}
|
||||
}
|
||||
|
||||
_at.remove_urc_handler("NO CARRIER", callback(this, &AT_CellularNetwork::urc_no_carrier));
|
||||
free_credentials();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue