mirror of https://github.com/ARMmbed/mbed-os.git
Cellular: send disconnect to correct ctx
Disconnect was sent to all CellularContext classes even it concerned one specific context. Some disconnect events are still sent to all context classes. These event are coming from network and ment for all context classes or event did not specify cid.pull/10402/head
parent
beed42e666
commit
9d67a8b61c
|
|
@ -156,6 +156,11 @@ void ATHandler::set_file_handle(FileHandle *fh)
|
|||
|
||||
void ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()> cb)
|
||||
{
|
||||
if (!cb) {
|
||||
remove_urc_handler(urc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ATHandler_stub::urc_amount < kATHandler_urc_table_max_size) {
|
||||
ATHandler_stub::callback[ATHandler_stub::urc_amount] = cb;
|
||||
if (urc) {
|
||||
|
|
@ -176,6 +181,20 @@ void ATHandler::set_urc_handler(const char *urc, mbed::Callback<void()> cb)
|
|||
|
||||
void ATHandler::remove_urc_handler(const char *prefix)
|
||||
{
|
||||
bool found_urc = false;
|
||||
for (int i = 0; i < ATHandler_stub::urc_amount; i++) {
|
||||
if (found_urc && i < 0) {
|
||||
ATHandler_stub::urc_string_table[i - 1] = ATHandler_stub::urc_string_table[i];
|
||||
ATHandler_stub::urc_string_table[i] = 0;
|
||||
} else if (ATHandler_stub::urc_string_table[i] && strcmp(prefix, ATHandler_stub::urc_string_table[i]) == 0) {
|
||||
delete [] ATHandler_stub::urc_string_table[i];
|
||||
ATHandler_stub::urc_string_table[i] = 0;
|
||||
found_urc = true;
|
||||
}
|
||||
}
|
||||
if (found_urc) {
|
||||
ATHandler_stub::urc_amount--;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t ATHandler::get_last_error() const
|
||||
|
|
|
|||
|
|
@ -95,11 +95,6 @@ nsapi_error_t AT_CellularNetwork::detach()
|
|||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::urc_no_carrier()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct)
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ CellularDevice *CellularContext::get_device() const
|
|||
return _device;
|
||||
}
|
||||
|
||||
int CellularContext::get_cid() const
|
||||
{
|
||||
return _cid;
|
||||
}
|
||||
|
||||
void CellularContext::do_connect_with_retry()
|
||||
{
|
||||
do_connect();
|
||||
|
|
|
|||
|
|
@ -282,6 +282,12 @@ public: // from NetworkInterface
|
|||
*/
|
||||
virtual ControlPlane_netif *get_cp_netif() = 0;
|
||||
|
||||
/** Get the pdp context id associated with this context.
|
||||
*
|
||||
* @return cid
|
||||
*/
|
||||
int get_cid() const;
|
||||
|
||||
protected: // Device specific implementations might need these so protected
|
||||
enum ContextOperation {
|
||||
OP_INVALID = -1,
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ public:
|
|||
|
||||
/** Set callback function for URC
|
||||
*
|
||||
* @param prefix URC text to look for, e.g. "+CMTI:"
|
||||
* @param prefix URC text to look for, e.g. "+CMTI:". Maximum length is BUFF_SIZE.
|
||||
* @param callback function to call on prefix, or 0 to remove callback
|
||||
*/
|
||||
void set_urc_handler(const char *prefix, Callback<void()> callback);
|
||||
|
|
|
|||
|
|
@ -67,18 +67,18 @@ public:
|
|||
*/
|
||||
static void set_cellular_properties(const intptr_t *property_array);
|
||||
|
||||
protected:
|
||||
|
||||
static const intptr_t *_property_array;
|
||||
|
||||
ATHandler &_at;
|
||||
|
||||
/** Get value for the given key.
|
||||
*
|
||||
* @param key key for value to be fetched
|
||||
* @return property value for the given key. Value type is defined in enum CellularProperty
|
||||
*/
|
||||
static intptr_t get_property(CellularProperty key);
|
||||
|
||||
protected:
|
||||
|
||||
static const intptr_t *_property_array;
|
||||
|
||||
ATHandler &_at;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
// Timeout to wait for URC indicating ciot optimization support from network
|
||||
#define CP_OPT_NW_REPLY_TIMEOUT 3000 // 3 seconds
|
||||
|
||||
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
#define AT_SYNC_TIMEOUT 1000 // 1 second timeout
|
||||
#include "nsapi_ppp.h"
|
||||
|
|
@ -591,8 +590,6 @@ void AT_CellularContext::do_connect()
|
|||
_at.unlock();
|
||||
if (_cb_data.error != NSAPI_ERROR_OK) {
|
||||
_is_connected = false;
|
||||
} else {
|
||||
_is_context_activated = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
|
@ -646,21 +643,20 @@ nsapi_error_t AT_CellularContext::open_data_channel()
|
|||
void AT_CellularContext::ppp_status_cb(nsapi_event_t ev, intptr_t ptr)
|
||||
{
|
||||
tr_debug("ppp_status_cb: event %d, ptr %d", ev, ptr);
|
||||
|
||||
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_GLOBAL_UP) {
|
||||
_is_connected = true;
|
||||
} else {
|
||||
_is_connected = false;
|
||||
}
|
||||
|
||||
_connect_status = (nsapi_connection_status_t)ptr;
|
||||
|
||||
// catch all NSAPI_STATUS_DISCONNECTED events but send to device only when we did not ask for disconnect.
|
||||
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
|
||||
if (_is_connected) {
|
||||
ppp_disconnected();
|
||||
_device->cellular_callback(ev, ptr, this);
|
||||
// catch all NSAPI_STATUS_DISCONNECTED events but send to device only when we did not ask for disconnect.
|
||||
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
|
||||
if (_is_connected) { // set to false in disconnect() before calling nsapi_ppp_disconnect()
|
||||
_is_connected = false;
|
||||
ppp_disconnected();
|
||||
_device->cellular_callback(ev, ptr, this);
|
||||
}
|
||||
return; // return here so if we were not in connected state we don't send NSAPI_STATUS_DISCONNECTED event
|
||||
}
|
||||
return;
|
||||
_is_connected = false;
|
||||
}
|
||||
|
||||
// call device's callback, it will broadcast this to here (cellular_callback)
|
||||
|
|
@ -714,11 +710,14 @@ nsapi_error_t AT_CellularContext::disconnect()
|
|||
deactivate_ip_context();
|
||||
}
|
||||
}
|
||||
|
||||
// don't call multiple times disconnect if we already got that event from network urc or ppp
|
||||
if (_connect_status != NSAPI_STATUS_DISCONNECTED) {
|
||||
_device->cellular_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED, this);
|
||||
}
|
||||
_is_context_active = false;
|
||||
_connect_status = NSAPI_STATUS_DISCONNECTED;
|
||||
|
||||
// call device's callback, it will broadcast this to here (cellular_callback)
|
||||
_device->cellular_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED, this);
|
||||
|
||||
if (_new_context_set) {
|
||||
delete_current_context();
|
||||
|
|
@ -770,6 +769,8 @@ void AT_CellularContext::check_and_deactivate_context()
|
|||
_at.write_int(_cid);
|
||||
_at.cmd_stop_read_resp();
|
||||
}
|
||||
|
||||
_at.restore_at_timeout();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularContext::get_apn_backoff_timer(int &backoff_timer)
|
||||
|
|
@ -993,7 +994,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
|
|||
if (st == CellularAttachNetwork && _current_op == OP_CONNECT && _cb_data.error == NSAPI_ERROR_OK &&
|
||||
data->status_data == CellularNetwork::Attached) {
|
||||
_current_op = OP_INVALID;
|
||||
// forward to application
|
||||
// forward all Cellular specific events to application
|
||||
if (_status_cb) {
|
||||
_status_cb(ev, ptr);
|
||||
}
|
||||
|
|
@ -1002,6 +1003,11 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// forward all Cellular specific events to application
|
||||
if (_status_cb) {
|
||||
_status_cb(ev, ptr);
|
||||
}
|
||||
} else {
|
||||
#if NSAPI_PPP_AVAILABLE
|
||||
if (_is_blocking) {
|
||||
|
|
@ -1009,7 +1015,7 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
|
|||
tr_info("CellularContext IP %s", get_ip_address());
|
||||
_cb_data.error = NSAPI_ERROR_OK;
|
||||
} else if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE && ptr == NSAPI_STATUS_DISCONNECTED) {
|
||||
tr_info("PPP disconnected");
|
||||
tr_info("cellular_callback: PPP mode and NSAPI_STATUS_DISCONNECTED");
|
||||
_cb_data.error = NSAPI_ERROR_NO_CONNECTION;
|
||||
}
|
||||
}
|
||||
|
|
@ -1020,11 +1026,8 @@ void AT_CellularContext::cellular_callback(nsapi_event_t ev, intptr_t ptr)
|
|||
}
|
||||
#endif // MBED_CONF_MBED_TRACE_ENABLE
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
}
|
||||
|
||||
// forward to application
|
||||
if (_status_cb) {
|
||||
_status_cb(ev, ptr);
|
||||
// forward status change events to application, call_network_cb will make sure that only changed event are forwarded
|
||||
call_network_cb((nsapi_connection_status_t)ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,6 @@ protected:
|
|||
bool _cp_req;
|
||||
// flag indicating if Non-IP context was requested to be setup
|
||||
bool _nonip_req;
|
||||
|
||||
// tells if CCIOTOPTI received green from network for CP optimization use
|
||||
bool _cp_in_use;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "UARTSerial.h"
|
||||
#endif // #if DEVICE_SERIAL
|
||||
#include "FileHandle.h"
|
||||
#include <ctype.h>
|
||||
|
||||
using namespace mbed_cellular_util;
|
||||
using namespace events;
|
||||
|
|
@ -43,10 +44,24 @@ AT_CellularDevice::AT_CellularDevice(FileHandle *fh) : CellularDevice(fh), _netw
|
|||
MBED_ASSERT(fh);
|
||||
_at = get_at_handler(fh);
|
||||
MBED_ASSERT(_at);
|
||||
|
||||
if (AT_CellularBase::get_property(AT_CellularBase::PROPERTY_AT_CGEREP)) {
|
||||
_at->set_urc_handler("+CGEV: NW DEACT", callback(this, &AT_CellularDevice::urc_nw_deact));
|
||||
_at->set_urc_handler("+CGEV: ME DEACT", callback(this, &AT_CellularDevice::urc_nw_deact));
|
||||
_at->set_urc_handler("+CGEV: NW PDN D", callback(this, &AT_CellularDevice::urc_pdn_deact));
|
||||
_at->set_urc_handler("+CGEV: ME PDN D", callback(this, &AT_CellularDevice::urc_pdn_deact));
|
||||
}
|
||||
}
|
||||
|
||||
AT_CellularDevice::~AT_CellularDevice()
|
||||
{
|
||||
if (AT_CellularBase::get_property(AT_CellularBase::PROPERTY_AT_CGEREP)) {
|
||||
_at->set_urc_handler("+CGEV: NW DEACT", 0);
|
||||
_at->set_urc_handler("+CGEV: ME DEACT", 0);
|
||||
_at->set_urc_handler("+CGEV: NW PDN D", 0);
|
||||
_at->set_urc_handler("+CGEV: ME PDN D", 0);
|
||||
}
|
||||
|
||||
// make sure that all is deleted even if somewhere close was not called and reference counting is messed up.
|
||||
_network_ref_count = 1;
|
||||
_sms_ref_count = 1;
|
||||
|
|
@ -69,6 +84,56 @@ AT_CellularDevice::~AT_CellularDevice()
|
|||
release_at_handler(_at);
|
||||
}
|
||||
|
||||
void AT_CellularDevice::urc_nw_deact()
|
||||
{
|
||||
// The network has forced a context deactivation
|
||||
char buf[10];
|
||||
_at->read_string(buf, 10);
|
||||
int cid;
|
||||
if (isalpha(buf[0])) {
|
||||
// this is +CGEV: NW DEACT <PDP_type>, <PDP_addr>, [<cid>]
|
||||
// or +CGEV: ME DEACT <PDP_type>, <PDP_addr>, [<cid>]
|
||||
_at->skip_param(); // skip <PDP_addr>
|
||||
cid = _at->read_int();
|
||||
} else {
|
||||
// this is +CGEV: NW DEACT <p_cid>, <cid>, <event_type>[,<WLAN_Offload>]
|
||||
// or +CGEV: ME DEACT <p_cid>, <cid>, <event_type
|
||||
cid = _at->read_int();
|
||||
}
|
||||
send_disconnect_to_context(cid);
|
||||
}
|
||||
|
||||
void AT_CellularDevice::urc_pdn_deact()
|
||||
{
|
||||
// The network has deactivated a context
|
||||
// The mobile termination has deactivated a context.
|
||||
// +CGEV: NW PDN DEACT <cid>[,<WLAN_Offload>]
|
||||
// +CGEV: ME PDN DEACT <cid>
|
||||
_at->set_delimiter(' ');
|
||||
_at->skip_param();
|
||||
_at->set_delimiter(',');
|
||||
|
||||
int cid = _at->read_int();
|
||||
send_disconnect_to_context(cid);
|
||||
}
|
||||
|
||||
void AT_CellularDevice::send_disconnect_to_context(int cid)
|
||||
{
|
||||
tr_debug("send_disconnect_to_context, cid: %d", cid);
|
||||
AT_CellularContext *curr = _context_list;
|
||||
while (curr) {
|
||||
if (cid >= 0) {
|
||||
if (curr->get_cid() == cid) {
|
||||
CellularDevice::cellular_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED, curr);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
CellularDevice::cellular_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED);
|
||||
}
|
||||
curr = (AT_CellularContext *)curr->_next;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularDevice::hard_power_on()
|
||||
{
|
||||
return NSAPI_ERROR_OK;
|
||||
|
|
|
|||
|
|
@ -140,6 +140,11 @@ public:
|
|||
int _default_timeout;
|
||||
bool _modem_debug_on;
|
||||
ATHandler *_at;
|
||||
|
||||
private:
|
||||
void urc_nw_deact();
|
||||
void urc_pdn_deact();
|
||||
void send_disconnect_to_context(int cid);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
|||
|
|
@ -85,9 +85,13 @@ AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(a
|
|||
}
|
||||
}
|
||||
|
||||
_at.set_urc_handler("NO CARRIER", callback(this, &AT_CellularNetwork::urc_no_carrier));
|
||||
// additional urc to get better disconnect info for application. Not critical.
|
||||
_at.set_urc_handler("+CGEV:", callback(this, &AT_CellularNetwork::urc_cgev));
|
||||
if (get_property(AT_CellularBase::PROPERTY_AT_CGEREP)) {
|
||||
// additional urc to get better disconnect info for application. Not critical.
|
||||
_at.set_urc_handler("+CGEV: NW DET", callback(this, &AT_CellularNetwork::urc_cgev));
|
||||
_at.set_urc_handler("+CGEV: ME DET", callback(this, &AT_CellularNetwork::urc_cgev));
|
||||
}
|
||||
|
||||
|
||||
_at.set_urc_handler("+CCIOTOPTI:", callback(this, &AT_CellularNetwork::urc_cciotopti));
|
||||
}
|
||||
|
||||
|
|
@ -100,44 +104,16 @@ AT_CellularNetwork::~AT_CellularNetwork()
|
|||
}
|
||||
}
|
||||
|
||||
_at.set_urc_handler("NO CARRIER", 0);
|
||||
_at.set_urc_handler("+CGEV:", 0);
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::urc_no_carrier()
|
||||
{
|
||||
tr_info("NO CARRIER");
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
if (get_property(AT_CellularBase::PROPERTY_AT_CGEREP)) {
|
||||
_at.set_urc_handler("+CGEV: ME DET", 0);
|
||||
_at.set_urc_handler("+CGEV: NW DET", 0);
|
||||
}
|
||||
_at.set_urc_handler("+CCIOTOPTI:", 0);
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::urc_cgev()
|
||||
{
|
||||
char buf[13];
|
||||
if (_at.read_string(buf, 13) < 8) { // smallest string length we wan't to compare is 8
|
||||
return;
|
||||
}
|
||||
tr_debug("CGEV: %s", buf);
|
||||
|
||||
bool call_cb = false;
|
||||
// NOTE! If in future there will be 2 or more active contexts we might wan't to read context id also but not for now.
|
||||
|
||||
if (memcmp(buf, "NW DETACH", 9) == 0) { // The network has forced a PS detach
|
||||
call_cb = true;
|
||||
} else if (memcmp(buf, "ME DETACH", 9) == 0) {// The mobile termination has forced a PS detach.
|
||||
call_cb = true;
|
||||
} else if (memcmp(buf, "NW DEACT", 8) == 0) {// The network has forced a context deactivation
|
||||
call_cb = true;
|
||||
} else if (memcmp(buf, "ME DEACT", 8) == 0) {// The mobile termination has forced a context deactivation
|
||||
call_cb = true;
|
||||
} else if (memcmp(buf, "NW PDN DEACT", 12) == 0) {// The network has deactivated a context
|
||||
call_cb = true;
|
||||
} else if (memcmp(buf, "ME PDN DEACT", 12) == 0) {// The mobile termination has deactivated a context.
|
||||
call_cb = true;
|
||||
}
|
||||
|
||||
if (call_cb) {
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
}
|
||||
call_network_cb(NSAPI_STATUS_DISCONNECTED);
|
||||
}
|
||||
|
||||
void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
|
||||
|
|
@ -159,8 +135,7 @@ void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
|
|||
_reg_params._status = reg_params._status;
|
||||
data.status_data = reg_params._status;
|
||||
_connection_status_cb((nsapi_event_t)CellularRegistrationStatusChanged, (intptr_t)&data);
|
||||
if (!(reg_params._status == RegisteredHomeNetwork ||
|
||||
reg_params._status == RegisteredRoaming)) {
|
||||
if (reg_params._status == NotRegistered) { // Other states means that we are trying to connect or connected
|
||||
if (previous_registration_status == RegisteredHomeNetwork ||
|
||||
previous_registration_status == RegisteredRoaming) {
|
||||
if (type != C_REG) {// we are interested only if we drop from packet network
|
||||
|
|
@ -713,8 +688,8 @@ nsapi_error_t AT_CellularNetwork::set_packet_domain_event_reporting(bool on)
|
|||
}
|
||||
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CGEREP=");// 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.write_int(on ? 1 : 0);
|
||||
_at.cmd_start("AT+CGEREP=");
|
||||
_at.write_int(on ? 1 : 0); // 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_read_resp();
|
||||
|
||||
return _at.unlock_return_error();
|
||||
|
|
|
|||
|
|
@ -111,8 +111,6 @@ protected:
|
|||
*/
|
||||
virtual void get_context_state_command();
|
||||
private:
|
||||
// "NO CARRIER" urc
|
||||
void urc_no_carrier();
|
||||
void urc_creg();
|
||||
void urc_cereg();
|
||||
void urc_cgreg();
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@ CellularDevice *CellularContext::get_device() const
|
|||
return _device;
|
||||
}
|
||||
|
||||
int CellularContext::get_cid() const
|
||||
{
|
||||
return _cid;
|
||||
}
|
||||
|
||||
void CellularContext::do_connect_with_retry()
|
||||
{
|
||||
if (_cb_data.final_try) {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
|
|||
0, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
1, // PROPERTY_AT_CGEREP
|
||||
0, // PROPERTY_AT_CGEREP
|
||||
};
|
||||
|
||||
QUECTEL_BC95::QUECTEL_BC95(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
|
|
|
|||
Loading…
Reference in New Issue