Cellular: fix issue where CGACT not supported in coming firmware in BG96.

pull/9837/head
Teppo Järvelin 2019-02-25 14:38:23 +02:00
parent 5f38878f3a
commit 4077898de1
11 changed files with 121 additions and 62 deletions

View File

@ -191,6 +191,16 @@ nsapi_error_t AT_CellularContext::do_activate_context()
return NSAPI_ERROR_OK; return NSAPI_ERROR_OK;
} }
void AT_CellularContext::activate_context()
{
}
void AT_CellularContext::deactivate_context()
{
}
void AT_CellularContext::do_connect() void AT_CellularContext::do_connect()
{ {
} }

View File

@ -158,7 +158,7 @@ nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_nam
return NSAPI_ERROR_OK; return NSAPI_ERROR_OK;
} }
bool AT_CellularNetwork::is_active_context() bool AT_CellularNetwork::is_active_context(int *number_of_active_contexts, int cid)
{ {
return false; return false;
} }
@ -167,3 +167,7 @@ nsapi_error_t AT_CellularNetwork::set_receive_period(int mode, EDRXAccessTechnol
{ {
return NSAPI_ERROR_OK; return NSAPI_ERROR_OK;
} }
void AT_CellularNetwork::get_context_state_command()
{
}

View File

@ -338,11 +338,14 @@ public:
*/ */
virtual nsapi_error_t get_operator_names(operator_names_list &op_names) = 0; virtual nsapi_error_t get_operator_names(operator_names_list &op_names) = 0;
/** Check if there is any PDP context active /** Check if there is any PDP context active. If cid is given, then check is done only for that cid.
* *
* @return true is any context is active, false otherwise or in case of error * @param number_of_active_contexts If given then in return contains the number of active contexts
* @param cid If given then active contexts are checked only against this cid
*
* @return true if any (or the given cid) context is active, false otherwise or in case of error
*/ */
virtual bool is_active_context() = 0; virtual bool is_active_context(int *number_of_active_contexts = NULL, int cid = -1) = 0;
/** Gets the latest received registration parameters from the network: /** Gets the latest received registration parameters from the network:
* type, status, access technology, cell_id, lac, active_time, periodic_tau. * type, status, access technology, cell_id, lac, active_time, periodic_tau.

View File

@ -467,15 +467,26 @@ nsapi_error_t AT_CellularContext::do_activate_context()
nsapi_error_t AT_CellularContext::activate_ip_context() nsapi_error_t AT_CellularContext::activate_ip_context()
{ {
return activate_context(); return find_and_activate_context();
} }
nsapi_error_t AT_CellularContext::activate_non_ip_context() nsapi_error_t AT_CellularContext::activate_non_ip_context()
{ {
return activate_context(); return find_and_activate_context();
} }
nsapi_error_t AT_CellularContext::activate_context() void AT_CellularContext::activate_context()
{
tr_info("Activate PDP context %d", _cid);
_at.cmd_start("AT+CGACT=1,");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
if (_at.get_last_error() == NSAPI_ERROR_OK) {
_is_context_activated = true;
}
}
nsapi_error_t AT_CellularContext::find_and_activate_context()
{ {
_at.lock(); _at.lock();
@ -511,26 +522,11 @@ nsapi_error_t AT_CellularContext::activate_context()
_is_context_active = false; _is_context_active = false;
_is_context_activated = false; _is_context_activated = false;
_at.cmd_start("AT+CGACT?");
_at.cmd_stop(); _is_context_active = _nw->is_active_context(NULL, _cid);
_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) { if (!_is_context_active) {
tr_info("Activate PDP context %d", _cid); activate_context();
_at.cmd_start("AT+CGACT=1,");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
if (_at.get_last_error() == NSAPI_ERROR_OK) {
_is_context_activated = true;
}
} }
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;
@ -692,34 +688,27 @@ nsapi_error_t AT_CellularContext::disconnect()
void AT_CellularContext::deactivate_ip_context() void AT_CellularContext::deactivate_ip_context()
{ {
deactivate_context(); check_and_deactivate_context();
} }
void AT_CellularContext::deactivate_non_ip_context() void AT_CellularContext::deactivate_non_ip_context()
{ {
deactivate_context(); check_and_deactivate_context();
} }
void AT_CellularContext::deactivate_context() void AT_CellularContext::deactivate_context()
{
_at.cmd_start("AT+CGACT=0,");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
void AT_CellularContext::check_and_deactivate_context()
{ {
// CGACT and CGATT commands might take up to 3 minutes to respond. // CGACT and CGATT commands might take up to 3 minutes to respond.
_at.set_at_timeout(180 * 1000); _at.set_at_timeout(180 * 1000);
_is_context_active = false; int active_contexts_count = 0;
size_t active_contexts_count = 0; _is_context_active = _nw->is_active_context(&active_contexts_count, _cid);
_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_activation_state == 1) {
active_contexts_count++;
if (context_id == _cid) {
_is_context_active = true;
}
}
}
_at.resp_stop();
CellularNetwork::RadioAccessTechnology rat = CellularNetwork::RAT_GSM; CellularNetwork::RadioAccessTechnology rat = CellularNetwork::RAT_GSM;
// always return NSAPI_ERROR_OK // always return NSAPI_ERROR_OK
@ -730,9 +719,7 @@ void AT_CellularContext::deactivate_context()
// For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR // For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR
if (_is_context_active && (rat < CellularNetwork::RAT_E_UTRAN || active_contexts_count > 1)) { if (_is_context_active && (rat < CellularNetwork::RAT_E_UTRAN || active_contexts_count > 1)) {
_at.clear_error(); _at.clear_error();
_at.cmd_start("AT+CGACT=0,"); deactivate_context();
_at.write_int(_cid);
_at.cmd_stop_read_resp();
} }
if (_new_context_set) { if (_new_context_set) {

View File

@ -97,8 +97,9 @@ protected:
virtual nsapi_error_t activate_non_ip_context(); virtual nsapi_error_t activate_non_ip_context();
virtual nsapi_error_t setup_control_plane_opt(); virtual nsapi_error_t setup_control_plane_opt();
virtual void deactivate_non_ip_context(); virtual void deactivate_non_ip_context();
virtual void deactivate_ip_context();
virtual void set_disconnect(); virtual void set_disconnect();
virtual void deactivate_context();
private: private:
#if NSAPI_PPP_AVAILABLE #if NSAPI_PPP_AVAILABLE
nsapi_error_t open_data_channel(); nsapi_error_t open_data_channel();
@ -106,10 +107,10 @@ private:
void ppp_disconnected(); void ppp_disconnected();
#endif // #if NSAPI_PPP_AVAILABLE #endif // #if NSAPI_PPP_AVAILABLE
nsapi_error_t do_activate_context(); nsapi_error_t do_activate_context();
nsapi_error_t activate_context(); virtual void activate_context();
nsapi_error_t find_and_activate_context();
nsapi_error_t activate_ip_context(); nsapi_error_t activate_ip_context();
void deactivate_context(); void check_and_deactivate_context();
void deactivate_ip_context();
bool set_new_context(int cid); bool set_new_context(int cid);
bool get_context(); bool get_context();
nsapi_error_t delete_current_context(); nsapi_error_t delete_current_context();

View File

@ -573,21 +573,40 @@ nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_nam
return _at.unlock_return_error(); return _at.unlock_return_error();
} }
bool AT_CellularNetwork::is_active_context() void AT_CellularNetwork::get_context_state_command()
{ {
_at.lock();
bool active_found = false;
// read active contexts
_at.cmd_start("AT+CGACT?"); _at.cmd_start("AT+CGACT?");
_at.cmd_stop(); _at.cmd_stop();
_at.resp_start("+CGACT:"); _at.resp_start("+CGACT:");
}
bool AT_CellularNetwork::is_active_context(int *number_of_active_contexts, int cid)
{
_at.lock();
if (number_of_active_contexts) {
*number_of_active_contexts = 0;
}
bool active_found = false;
int context_id;
// read active contexts
get_context_state_command();
while (_at.info_resp()) { while (_at.info_resp()) {
(void)_at.read_int(); // discard context id context_id = _at.read_int(); // discard context id
if (_at.read_int() == 1) { // check state if (_at.read_int() == 1) { // check state
tr_debug("Found active context"); tr_debug("Found active context");
active_found = true; if (number_of_active_contexts) {
break; (*number_of_active_contexts)++;
}
if (cid == -1) {
active_found = true;
} else if (context_id == cid) {
active_found = true;
}
if (!number_of_active_contexts && active_found) {
break;
}
} }
} }
_at.resp_stop(); _at.resp_stop();

View File

@ -88,7 +88,7 @@ public: // CellularNetwork
virtual nsapi_error_t get_operator_names(operator_names_list &op_names); virtual nsapi_error_t get_operator_names(operator_names_list &op_names);
virtual bool is_active_context(); virtual bool is_active_context(int *number_of_active_contexts = NULL, int cid = -1);
virtual nsapi_error_t get_registration_params(registration_params_t &reg_params); virtual nsapi_error_t get_registration_params(registration_params_t &reg_params);
@ -106,6 +106,10 @@ protected:
*/ */
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat); virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology op_rat);
/** Sends a command to query the active state of the PDP contexts.
* Can be overridden by the target class.
*/
virtual void get_context_state_command();
private: private:
// "NO CARRIER" urc // "NO CARRIER" urc
void urc_no_carrier(); void urc_no_carrier();

View File

@ -112,6 +112,24 @@ nsapi_error_t QUECTEL_BG96_CellularContext::activate_non_ip_context()
return (ret == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION; return (ret == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_NO_CONNECTION;
} }
void QUECTEL_BG96_CellularContext::activate_context()
{
tr_info("Activate PDP context %d", _cid);
_at.cmd_start("AT+QIACT=");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
if (_at.get_last_error() == NSAPI_ERROR_OK) {
_is_context_activated = true;
}
}
void QUECTEL_BG96_CellularContext::deactivate_context()
{
_at.cmd_start("AT+QIDEACT=");
_at.write_int(_cid);
_at.cmd_stop_read_resp();
}
void QUECTEL_BG96_CellularContext::deactivate_non_ip_context() void QUECTEL_BG96_CellularContext::deactivate_non_ip_context()
{ {
// Close the NIDD connection // Close the NIDD connection
@ -119,7 +137,6 @@ void QUECTEL_BG96_CellularContext::deactivate_non_ip_context()
_at.cmd_stop(); _at.cmd_stop();
_at.resp_start(); _at.resp_start();
_at.resp_stop(); _at.resp_stop();
} }
void QUECTEL_BG96_CellularContext::urc_nidd() void QUECTEL_BG96_CellularContext::urc_nidd()

View File

@ -35,6 +35,8 @@ protected:
virtual nsapi_error_t activate_non_ip_context(); virtual nsapi_error_t activate_non_ip_context();
virtual nsapi_error_t setup_control_plane_opt(); virtual nsapi_error_t setup_control_plane_opt();
virtual void deactivate_non_ip_context(); virtual void deactivate_non_ip_context();
virtual void deactivate_context();
virtual void activate_context();
rtos::Semaphore _semaphore; rtos::Semaphore _semaphore;
private: private:

View File

@ -15,8 +15,9 @@
* limitations under the License. * limitations under the License.
*/ */
#include "QUECTEL/BG96/QUECTEL_BG96_CellularNetwork.h" #include "QUECTEL_BG96_CellularNetwork.h"
#include "QUECTEL/BG96/QUECTEL_BG96_CellularStack.h" #include "QUECTEL_BG96_CellularStack.h"
#include "CellularLog.h"
using namespace mbed; using namespace mbed;
@ -72,3 +73,12 @@ nsapi_error_t QUECTEL_BG96_CellularNetwork::set_access_technology_impl(RadioAcce
return _at.unlock_return_error(); return _at.unlock_return_error();
} }
void QUECTEL_BG96_CellularNetwork::get_context_state_command()
{
// read active contexts
_at.cmd_start("AT+QIACT?");
_at.cmd_stop();
_at.resp_start("+QIACT:");
}

View File

@ -29,6 +29,8 @@ public:
protected: protected:
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat); virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
virtual void get_context_state_command();
}; };
} // namespace mbed } // namespace mbed