Merge pull request #8114 from mirelachirica/registration_params_2

Registration parameters as struct
pull/8364/merge
Cruz Monrreal 2018-10-10 08:42:06 -05:00 committed by GitHub
commit 70252f8271
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 370 additions and 205 deletions

View File

@ -434,7 +434,7 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_registration)
EXPECT_TRUE(NSAPI_ERROR_OK == cn.set_registration("12345"));
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_registration_status)
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_registration_params)
{
EventQueue que;
FileHandle_stub fh1;
@ -443,33 +443,86 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_registration_status)
AT_CellularNetwork cn(at);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
ATHandler_stub::int_value = 3;
CellularNetwork::RegistrationStatus stat = CellularNetwork::NotRegistered;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_status(CellularNetwork::C_EREG, stat));
EXPECT_TRUE(stat == CellularNetwork::RegistrationDenied);
stat = CellularNetwork::NotRegistered;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_status(CellularNetwork::C_GREG, stat));
EXPECT_TRUE(stat == CellularNetwork::RegistrationDenied);
CellularNetwork::registration_params_t reg_params;
CellularNetwork::registration_params_t reg_params_check;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_params(CellularNetwork::C_EREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::RegistrationDenied);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_EGPRS);
EXPECT_TRUE(reg_params._cell_id == -1);
ATHandler_stub::read_string_index = 4;
ATHandler_stub::read_string_table[3] = "00C3";
ATHandler_stub::read_string_table[2] = "1234FFC1";//== cellid and in dec: 305463233
ATHandler_stub::read_string_table[1] = "00100100";
ATHandler_stub::read_string_table[0] = "01000111";
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_params(CellularNetwork::C_EREG, reg_params));
EXPECT_TRUE(reg_params._cell_id == 305463233);
EXPECT_TRUE(reg_params._active_time == 240);
EXPECT_TRUE(reg_params._periodic_tau == 70 * 60 *60);
ATHandler_stub::read_string_index = kRead_string_table_size;
ATHandler_stub::read_string_value = NULL;
ATHandler_stub::ssize_value = 0;
// Check get_registration_params without specifying the registration type
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_params(reg_params_check));
EXPECT_TRUE(reg_params_check._status == CellularNetwork::RegistrationDenied);
EXPECT_TRUE(reg_params_check._act == CellularNetwork::RAT_EGPRS);
EXPECT_TRUE(reg_params_check._cell_id == 305463233);
EXPECT_TRUE(reg_params_check._active_time == 240);
EXPECT_TRUE(reg_params_check._periodic_tau == 70 * 60 *60);
reg_params._status = CellularNetwork::NotRegistered;
reg_params._act = CellularNetwork::RAT_GSM;
reg_params._cell_id = 1;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_params(CellularNetwork::C_GREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::RegistrationDenied);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_EGPRS);
EXPECT_TRUE(reg_params._cell_id == -1);
my_AT_CN nw(at);
stat = CellularNetwork::NotRegistered;
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == nw.get_registration_status(CellularNetwork::C_GREG, stat));
EXPECT_TRUE(stat == CellularNetwork::NotRegistered);
EXPECT_TRUE(NSAPI_ERROR_OK == nw.get_registration_status(CellularNetwork::C_EREG, stat));
EXPECT_TRUE(stat == CellularNetwork::RegistrationDenied);
reg_params._status = CellularNetwork::NotRegistered;
reg_params._act = CellularNetwork::RAT_GSM;
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == nw.get_registration_params(CellularNetwork::C_GREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::NotRegistered);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_GSM);
EXPECT_TRUE(NSAPI_ERROR_OK == nw.get_registration_params(CellularNetwork::C_EREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::RegistrationDenied);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_EGPRS);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
stat = CellularNetwork::NotRegistered;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_status(CellularNetwork::C_EREG, stat));
EXPECT_TRUE(stat == -1);
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_status(CellularNetwork::C_GREG, stat));
EXPECT_TRUE(stat == -1);
reg_params._status = CellularNetwork::NotRegistered;
reg_params._act = CellularNetwork::RAT_GSM;
reg_params._cell_id = 1;
reg_params._active_time = 2;
reg_params._periodic_tau = 3;
stat = CellularNetwork::NotRegistered;
EXPECT_TRUE(NSAPI_ERROR_UNSUPPORTED == nw.get_registration_status(CellularNetwork::C_GREG, stat));
EXPECT_TRUE(stat == CellularNetwork::NotRegistered);
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == nw.get_registration_status(CellularNetwork::C_EREG, stat));
EXPECT_TRUE(stat == -1);
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_params(CellularNetwork::C_EREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::StatusNotAvailable);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params._cell_id == -1 && reg_params._active_time == -1 && reg_params._periodic_tau == -1);
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == cn.get_registration_params(CellularNetwork::C_GREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::StatusNotAvailable);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params._cell_id == -1);
reg_params._status = CellularNetwork::SearchingNetwork;
reg_params._act = CellularNetwork::RAT_GSM;
reg_params._cell_id = 1;
reg_params._active_time = 2;
reg_params._periodic_tau = 3;
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == nw.get_registration_params(CellularNetwork::C_EREG, reg_params));
EXPECT_TRUE(reg_params._status == CellularNetwork::StatusNotAvailable);
EXPECT_TRUE(reg_params._act == CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params._cell_id == -1 && reg_params._active_time == -1 && reg_params._periodic_tau == -1);
// Check get_registration_params without specifying the registration type
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_params(reg_params_check));
EXPECT_TRUE(reg_params_check._status == CellularNetwork::StatusNotAvailable);
EXPECT_TRUE(reg_params_check._act == CellularNetwork::RAT_UNKNOWN);
EXPECT_TRUE(reg_params_check._cell_id == -1 && reg_params_check._active_time == -1 && reg_params_check._periodic_tau == -1);
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_network_registering_mode)
@ -762,19 +815,6 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_set_access_technology)
EXPECT_TRUE(NSAPI_ERROR_OK == my_cn.set_access_technology(CellularNetwork::RAT_GSM_COMPACT));
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_access_technology)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularNetwork cn(at);
CellularNetwork::RadioAccessTechnology rat;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_access_technology(rat));
EXPECT_TRUE(CellularNetwork::RAT_UNKNOWN == rat);
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_scan_plmn)
{
EventQueue que;
@ -989,34 +1029,6 @@ TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_signal_quality)
EXPECT_TRUE(rs == 1 && ber == 1);
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_cell_id)
{
EventQueue que;
FileHandle_stub fh1;
ATHandler at(&fh1, que, 0, ",");
AT_CellularNetwork cn(at);
int id = 0;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_cell_id(id));
EXPECT_TRUE(id == -1);
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_DEVICE_ERROR;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_cell_id(id));
EXPECT_TRUE(id == -1);
ATHandler_stub::read_string_index = 2;
ATHandler_stub::read_string_table[1] = (char *)"00C3";
ATHandler_stub::read_string_table[0] = (char *)"1234FFC1"; //== cellid and in dec: 305463233
ATHandler_stub::int_value = 1;
// Get registration status to modify cell_id
CellularNetwork::RegistrationType type;
CellularNetwork::RegistrationStatus status;
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_registration_status(CellularNetwork::C_EREG, status));
EXPECT_TRUE(NSAPI_ERROR_OK == cn.get_cell_id(id));
EXPECT_TRUE(id == 305463233);
}
TEST_F(TestAT_CellularNetwork, test_AT_CellularNetwork_get_3gpp_error)
{
EventQueue que;

View File

@ -579,7 +579,7 @@ TEST_F(TestATHandler, test_ATHandler_read_string)
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == at.get_last_error());
at.clear_error();
// Device error because empty buffer and attempt to fill_buffer by consume_char('\"')
EXPECT_TRUE(-1 == at.read_string(buf1, 1));
EXPECT_TRUE(0 == at.read_string(buf1, 1));
// *** 1 BYTE ***
at.clear_error();
@ -599,7 +599,7 @@ TEST_F(TestATHandler, test_ATHandler_read_string)
// *** CRLF ***
at.clear_error();
char table3[] = "\r\ns\r\n\0";
char table3[] = "\r\n,s\r\n\0";
at.flush();
filehandle_stub_table = table3;
filehandle_stub_table_pos = 0;
@ -670,13 +670,9 @@ TEST_F(TestATHandler, test_ATHandler_read_string)
at.resp_start();
// TO read 1 byte from: "s"OK\r\n -> read "
at.read_bytes(buf5, 1);
// TO read max 1 byte from: s"OK\r\n -> read s
// TO read max 1 byte from: s"OK\r\n -> read s + read to stop_tag(OKCRLF)
EXPECT_TRUE(1 == at.read_string(buf4, 1 + 1/*for NULL*/));
// *** Consume " and run into OKCRLF ***
// TO read max 1 byte from: "OK\r\n -> consume " and find stop tag OKCRLF
EXPECT_TRUE(0 == at.read_string(buf4, 1 + 1/*for NULL*/));
// *** Try to read after stop tag was found ***
// stop tag found do not read further
EXPECT_TRUE(-1 == at.read_string(buf4, 1 + 1/*for NULL*/));
@ -706,7 +702,7 @@ TEST_F(TestATHandler, test_ATHandler_read_string)
mbed_poll_stub::revents_value = POLLIN;
mbed_poll_stub::int_value = 1;
at.resp_start("s");
// TO read from buffer having only " -> consume " -> trying to read when nothing in buffer
// TO read from buffer having only " -> trying to find delimiter or stop_tag(OKCRLF)
EXPECT_TRUE(-1 == at.read_string(buf4, 5));
EXPECT_TRUE(NSAPI_ERROR_DEVICE_ERROR == at.get_last_error());
@ -739,6 +735,21 @@ TEST_F(TestATHandler, test_ATHandler_read_string)
// TO read from
EXPECT_TRUE(6 == at.read_string(buf9, 6 + 1/*for NULL*/));
at.clear_error();
char table11[] = "\"1016\",\"39AB\",9\r\n\0";
mbed_poll_stub::int_value = 0;
at.flush();
filehandle_stub_table = table11;
filehandle_stub_table_pos = 0;
mbed_poll_stub::revents_value = POLLIN;
mbed_poll_stub::int_value = 1;
at.resp_start();
EXPECT_TRUE(4 == at.read_string(buf4, 4 + 1/*for NULL*/));
EXPECT_TRUE(!strncmp(buf4, "1016", 4));
EXPECT_TRUE(4 == at.read_string(buf4, 4 + 1/*for NULL*/));
EXPECT_TRUE(!strncmp(buf4, "39AB", 4));
EXPECT_TRUE(9 == at.read_int());
// *** CRLF part of the string ***
at.clear_error();
char table10[] = "\"s\"\r\nOK\r\n\0";

View File

@ -35,6 +35,23 @@ protected:
};
// *INDENT-ON*
TEST_F(Testutil, test_util_binary_str_to_uint)
{
char binary_str[]="011001011101101000";
uint32_t value = binary_str_to_uint(binary_str, strlen(binary_str) + 1);
EXPECT_TRUE(value == 104296);
value = binary_str_to_uint(binary_str, strlen(binary_str));
EXPECT_TRUE(value == 104296);
value = binary_str_to_uint(binary_str, strlen(binary_str) - 1);
EXPECT_TRUE(value == 52148);
value = binary_str_to_uint(binary_str, strlen(binary_str) - 3);
EXPECT_TRUE(value == 13037);
value = binary_str_to_uint(binary_str + 5, strlen(binary_str) - 5);
EXPECT_TRUE(value == 5992);
EXPECT_TRUE(0 == binary_str_to_uint(NULL, 5));
EXPECT_TRUE(0 == binary_str_to_uint(binary_str, 0));
}
TEST_F(Testutil, test_util_uint_to_binary_string)
{
char str[33];

View File

@ -111,12 +111,12 @@ nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn)
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type, RegistrationStatus &status)
nsapi_error_t AT_CellularNetwork::get_registration_params(RegistrationType type, registration_params_t &reg_params)
{
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::get_cell_id(int &cell_id)
nsapi_error_t AT_CellularNetwork::get_registration_params(registration_params_t &reg_params)
{
return NSAPI_ERROR_OK;
}
@ -186,12 +186,6 @@ nsapi_error_t AT_CellularNetwork::set_access_technology(RadioAccessTechnology op
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::get_access_technology(RadioAccessTechnology &rat)
{
rat = RAT_CATM1;
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount)
{
return NSAPI_ERROR_OK;

View File

@ -102,9 +102,11 @@ static bool get_network_registration(CellularNetwork::RegistrationType type,
CellularNetwork::RegistrationStatus &status, bool &is_registered)
{
is_registered = false;
nsapi_error_t err = nw->get_registration_status(type, status);
CellularNetwork::registration_params_t reg_params;
nsapi_error_t err = nw->get_registration_params(type, reg_params);
TEST_ASSERT(err == NSAPI_ERROR_OK || err == NSAPI_ERROR_UNSUPPORTED);
status = reg_params._status;
switch (status) {
case CellularNetwork::RegisteredRoaming:
case CellularNetwork::RegisteredHomeNetwork:
@ -312,9 +314,10 @@ static void test_other()
TEST_ASSERT(ber >= 0);
}
int cell_id = -5;
TEST_ASSERT(nw->get_cell_id(cell_id) == NSAPI_ERROR_OK);
TEST_ASSERT(cell_id != -5);
CellularNetwork::registration_params_t reg_params;
reg_params._cell_id = -5;
TEST_ASSERT(nw->get_registration_params(reg_params) == NSAPI_ERROR_OK);
TEST_ASSERT(reg_params._cell_id != -5);
int format = -1;
CellularNetwork::operator_t operator_params;

View File

@ -223,13 +223,15 @@ bool CellularConnectionFSM::get_network_registration(CellularNetwork::Registrati
{
is_registered = false;
bool is_roaming = false;
nsapi_error_t err = _network->get_registration_status(type, status);
CellularNetwork::registration_params_t reg_params;
nsapi_error_t err = _network->get_registration_params(type, reg_params);
if (err != NSAPI_ERROR_OK) {
if (err != NSAPI_ERROR_UNSUPPORTED) {
tr_warn("Get network registration failed (type %d)!", type);
}
return false;
}
status = reg_params._status;
switch (status) {
case CellularNetwork::RegisteredRoaming:
is_roaming = true;

View File

@ -66,6 +66,7 @@ public:
/* Network registration status */
enum RegistrationStatus {
StatusNotAvailable = -1,
NotRegistered = 0,
RegisteredHomeNetwork,
SearchingNetwork,
@ -225,6 +226,27 @@ public:
NWModeManualAutomatic // if manual fails, fallback to automatic
};
/* Network registration information */
struct registration_params_t {
RegistrationType _type;
RegistrationStatus _status;
RadioAccessTechnology _act;
int _cell_id;
int _lac;
int _active_time;
int _periodic_tau;
registration_params_t()
{
_type = C_MAX;
_status = StatusNotAvailable;
_act = RAT_UNKNOWN;
_cell_id = -1;
_lac = -1;
_active_time = -1;
_periodic_tau = -1;
}
};
/** Does all the needed initializations that can fail
*
@ -263,15 +285,6 @@ public:
*/
virtual nsapi_error_t set_registration_urc(RegistrationType type, bool on) = 0;
/** Gets the network registration status.
*
* @param type see RegistrationType values
* @param status see RegistrationStatus values
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_UNSUPPORTED if the modem does not support RegistrationType
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_registration_status(RegistrationType type, RegistrationStatus &status) = 0;
/** Set the cellular network APN and credentials
*
@ -352,13 +365,6 @@ public:
*/
virtual nsapi_error_t set_access_technology(RadioAccessTechnology rat) = 0;
/** Get current radio access technology.
*
* @param rat Radio access technology
* @return NSAPI_ERROR_OK
*/
virtual nsapi_error_t get_access_technology(RadioAccessTechnology &rat) = 0;
/** Scans for operators module can reach.
*
* @param operators Container of reachable operators and their access technologies
@ -475,13 +481,6 @@ public:
*/
virtual nsapi_error_t get_signal_quality(int &rssi, int &ber) = 0;
/** Get cell id.
*
* @param cell_id cell ID
* @return NSAPI_ERROR_OK
*/
virtual nsapi_error_t get_cell_id(int &cell_id) = 0;
/** Get the last 3GPP error code
* @return see 3GPP TS 27.007 error codes
*/
@ -528,6 +527,26 @@ public:
* NSAPI_ERROR_DEVICE_ERROR on other failures
*/
virtual nsapi_error_t get_operator_names(operator_names_list &op_names) = 0;
/** Gets current network registration parameters:
* type, status, access technology, cell_id, lac, active_time, periodic_tau.
*
* @param reg_params see registration_params_t
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_registration_params(registration_params_t &reg_params) = 0;
/** Gets the network registration parameters based on required registration type:
* status, access technology, cell_id, lac, active_time, periodic_tau.
*
* @param type see RegistrationType values
* @param reg_params see registration_params_t
* @return NSAPI_ERROR_OK on success
* NSAPI_ERROR_UNSUPPORTED if the modem does not support RegistrationType
* NSAPI_ERROR_DEVICE_ERROR on failure
*/
virtual nsapi_error_t get_registration_params(RegistrationType type, registration_params_t &reg_params) = 0;
};
} // namespace mbed

View File

@ -460,14 +460,9 @@ ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag)
return -1;
}
consume_char('\"');
if (_last_err) {
return -1;
}
size_t len = 0;
int len = 0;
size_t match_pos = 0;
bool delimiter_found = false;
for (; len < (size - 1 + match_pos); len++) {
int c = get_char();
@ -476,6 +471,7 @@ ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag)
return -1;
} else if (c == _delimiter) {
buf[len] = '\0';
delimiter_found = true;
break;
} else if (c == '\"') {
match_pos = 0;
@ -501,6 +497,26 @@ ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag)
buf[len] = '\0';
}
// Consume to delimiter or stop_tag
if (!delimiter_found && !_stop_tag->found) {
match_pos = 0;
while(1) {
int c = get_char();
if (c == -1) {
set_error(NSAPI_ERROR_DEVICE_ERROR);
break;
} else if (c == _delimiter) {
break;
} else if (_stop_tag->len && c == _stop_tag->tag[match_pos]) {
match_pos++;
if (match_pos == _stop_tag->len) {
_stop_tag->found = true;
break;
}
}
}
}
return len;
}
@ -830,6 +846,7 @@ void ATHandler::resp_start(const char *prefix, bool stop)
return;
}
set_scope(NotSet);
// Try get as much data as possible
rewind_buffer();
(void)fill_buffer(false);

View File

@ -41,8 +41,8 @@ static const at_reg_t at_reg[] = {
AT_CellularNetwork::AT_CellularNetwork(ATHandler &atHandler) : AT_CellularBase(atHandler),
_stack(NULL), _apn(NULL), _uname(NULL), _pwd(NULL), _ip_stack_type_requested(DEFAULT_STACK),
_ip_stack_type(DEFAULT_STACK), _cid(-1), _connection_status_cb(NULL), _op_act(RAT_UNKNOWN),
_authentication_type(CHAP), _cell_id(-1), _connect_status(NSAPI_STATUS_DISCONNECTED), _new_context_set(false),
_is_context_active(false), _reg_status(NotRegistered), _current_act(RAT_UNKNOWN)
_authentication_type(CHAP), _connect_status(NSAPI_STATUS_DISCONNECTED), _new_context_set(false),
_is_context_active(false)
{
}
@ -138,13 +138,11 @@ void AT_CellularNetwork::urc_cgev()
void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
{
RegistrationStatus reg_status = NotRegistered;
int lac = -1, cell_id = -1, act = -1;
read_reg_params(type, reg_status, lac, cell_id, act);
registration_params_t reg_params;
read_reg_params(reg_params);
#if MBED_CONF_MBED_TRACE_ENABLE
switch (reg_status) {
switch (reg_params._status) {
case NotRegistered:
tr_warn("not registered");
break;
@ -160,18 +158,19 @@ void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
#endif
if (_at.get_last_error() == NSAPI_ERROR_OK && _connection_status_cb) {
tr_debug("stat: %d, lac: %d, cellID: %d, act: %d", reg_status, lac, cell_id, act);
if (act != -1 && (RadioAccessTechnology)act != _current_act) {
_current_act = (RadioAccessTechnology)act;
_connection_status_cb((nsapi_event_t)CellularRadioAccessTechnologyChanged, _current_act);
tr_debug("type: %d, status: %d, lac: %d, cellID: %d, act: %d", type, reg_params._status, reg_params._lac, reg_params._cell_id, reg_params._act);
_reg_params._type = type;
if (reg_params._act != _reg_params._act) {
_reg_params._act = reg_params._act;
_connection_status_cb((nsapi_event_t)CellularRadioAccessTechnologyChanged, _reg_params._act);
}
if (reg_status != _reg_status) {
_reg_status = reg_status;
_connection_status_cb((nsapi_event_t)CellularRegistrationStatusChanged, _reg_status);
if (reg_params._status != _reg_params._status) {
_reg_params._status = reg_params._status;
_connection_status_cb((nsapi_event_t)CellularRegistrationStatusChanged, _reg_params._status);
}
if (cell_id != -1 && cell_id != _cell_id) {
_cell_id = cell_id;
_connection_status_cb((nsapi_event_t)CellularCellIDChanged, _cell_id);
if (reg_params._cell_id != -1 && reg_params._cell_id != _reg_params._cell_id) {
_reg_params._cell_id = reg_params._cell_id;
_connection_status_cb((nsapi_event_t)CellularCellIDChanged, _reg_params._cell_id);
}
}
}
@ -455,7 +454,7 @@ nsapi_error_t AT_CellularNetwork::disconnect()
// 3GPP TS 27.007:
// For EPS, if an attempt is made to disconnect the last PDN connection, then the MT responds with ERROR
if (_is_context_active && (_current_act < RAT_E_UTRAN || active_contexts_count > 1)) {
if (_is_context_active && (_reg_params._act < RAT_E_UTRAN || active_contexts_count > 1)) {
_at.cmd_start("AT+CGACT=0,");
_at.write_int(_cid);
_at.cmd_stop();
@ -785,76 +784,49 @@ nsapi_error_t AT_CellularNetwork::set_registration(const char *plmn)
return _at.unlock_return_error();
}
void AT_CellularNetwork::read_reg_params(RegistrationType type, RegistrationStatus &reg_status, int &lac, int &cell_id, int &act)
void AT_CellularNetwork::read_reg_params(registration_params_t &reg_params)
{
const int LAC_LENGTH = 5, CELL_ID_LENGTH = 9;
char lac_string[LAC_LENGTH] = {0}, cell_id_string[CELL_ID_LENGTH] = {0};
bool lac_read = false, cell_id_read = false;
const int MAX_STRING_LENGTH = 9;
char string_param[MAX_STRING_LENGTH] = {0};
reg_status = (RegistrationStatus)_at.read_int();
int int_param = _at.read_int();
reg_params._status = (RegistrationStatus)int_param;
int len = _at.read_string(lac_string, LAC_LENGTH);
if (memcmp(lac_string, "ffff", LAC_LENGTH - 1) && len >= 0) {
lac_read = true;
int len = _at.read_string(string_param, TWO_BYTES_HEX + 1);
if (len > 0) {
reg_params._lac = hex_str_to_int(string_param, TWO_BYTES_HEX);
tr_debug("lac %s %d", string_param, reg_params._lac);
} else {
reg_params._lac = -1;
}
len = _at.read_string(cell_id_string, CELL_ID_LENGTH);
if (memcmp(cell_id_string, "ffffffff", CELL_ID_LENGTH - 1) && len >= 0) {
cell_id_read = true;
len = _at.read_string(string_param, FOUR_BYTES_HEX + 1);
if (len > 0) {
reg_params._cell_id = hex_str_to_int(string_param, FOUR_BYTES_HEX);
tr_debug("cell_id %s %d", string_param, reg_params._cell_id);
} else {
reg_params._cell_id = -1;
}
act = _at.read_int();
int_param = _at.read_int();
reg_params._act = (int_param == -1) ? RAT_UNKNOWN : (RadioAccessTechnology)int_param;
if (lac_read) {
lac = hex_str_to_int(lac_string, LAC_LENGTH);
tr_debug("lac %s %d", lac_string, lac);
// Skip [<cause_type>],[<reject_cause>]
_at.skip_param(2);
len = _at.read_string(string_param, ONE_BYTE_BINARY + 1);
reg_params._active_time = calculate_active_time(string_param, len);
if (reg_params._active_time != -1) {
tr_debug("active_time %s %d", string_param, reg_params._active_time);
}
if (cell_id_read) {
cell_id = hex_str_to_int(cell_id_string, CELL_ID_LENGTH);
tr_debug("cell_id %s %d", cell_id_string, cell_id);
len = _at.read_string(string_param, ONE_BYTE_BINARY + 1);
reg_params._periodic_tau = calculate_periodic_tau(string_param, len);
if (reg_params._periodic_tau == -1) {
tr_debug("periodic_tau %s %d", string_param, reg_params._periodic_tau);
}
}
nsapi_error_t AT_CellularNetwork::get_registration_status(RegistrationType type, RegistrationStatus &status)
{
int i = (int)type;
MBED_ASSERT(i >= 0 && i < C_MAX);
if (has_registration(at_reg[i].type) == RegistrationModeDisable) {
return NSAPI_ERROR_UNSUPPORTED;
}
_at.lock();
const char *rsp[] = { "+CEREG:", "+CGREG:", "+CREG:"};
_at.cmd_start(at_reg[i].cmd);
_at.write_string("?", false);
_at.cmd_stop();
_at.resp_start(rsp[i]);
(void)_at.read_int(); // ignore urc mode subparam
int lac = -1, cell_id = -1, act = -1;
read_reg_params(type, status, lac, cell_id, act);
_at.resp_stop();
_reg_status = status;
if (cell_id != -1) {
_cell_id = cell_id;
}
if (act != -1) {
_current_act = (RadioAccessTechnology)act;
}
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularNetwork::get_cell_id(int &cell_id)
{
cell_id = _cell_id;
return NSAPI_ERROR_OK;
}
AT_CellularNetwork::RegistrationMode AT_CellularNetwork::has_registration(RegistrationType reg_type)
{
(void)reg_type;
@ -988,12 +960,6 @@ nsapi_error_t AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnolo
return NSAPI_ERROR_UNSUPPORTED;
}
nsapi_error_t AT_CellularNetwork::get_access_technology(RadioAccessTechnology &rat)
{
rat = _current_act;
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::set_access_technology(RadioAccessTechnology opAct)
{
if (opAct == RAT_UNKNOWN) {
@ -1329,3 +1295,88 @@ nsapi_error_t AT_CellularNetwork::get_operator_names(operator_names_list &op_nam
_at.resp_stop();
return _at.unlock_return_error();
}
nsapi_error_t AT_CellularNetwork::get_registration_params(registration_params_t &reg_params)
{
reg_params = _reg_params;
return NSAPI_ERROR_OK;
}
nsapi_error_t AT_CellularNetwork::get_registration_params(RegistrationType type, registration_params_t &reg_params)
{
int i = (int)type;
MBED_ASSERT(i >= 0 && i < C_MAX);
if (!has_registration(at_reg[i].type)) {
return NSAPI_ERROR_UNSUPPORTED;
}
_at.lock();
const char *rsp[] = { "+CEREG:", "+CGREG:", "+CREG:"};
_at.cmd_start(at_reg[i].cmd);
_at.write_string("?", false);
_at.cmd_stop();
_at.resp_start(rsp[i]);
(void)_at.read_int(); // ignore urc mode subparam
_reg_params._type = type;
read_reg_params(reg_params);
_at.resp_stop();
_reg_params = reg_params;
return _at.unlock_return_error();
}
int AT_CellularNetwork::calculate_active_time(const char *active_time_string, int active_time_length)
{
if (active_time_length != ONE_BYTE_BINARY) {
return -1;
}
uint32_t ie_unit = binary_str_to_uint(active_time_string, TIMER_UNIT_LENGTH);
uint32_t ie_value = binary_str_to_uint(active_time_string + TIMER_UNIT_LENGTH, active_time_length - TIMER_UNIT_LENGTH);
switch (ie_unit) {
case 0: // multiples of 2 seconds
return 2 * ie_value;
case 1: // multiples of 1 minute
return 60 * ie_value;
case 2: // multiples of decihours
return 6 * 60 * ie_value;
case 7: // timer is deactivated
return 0;
default: // other values shall be interpreted as multiples of 1 minute
return 60 * ie_value;
}
}
int AT_CellularNetwork::calculate_periodic_tau(const char *periodic_tau_string, int periodic_tau_length)
{
if (periodic_tau_length != ONE_BYTE_BINARY) {
return -1;
}
uint32_t ie_unit = binary_str_to_uint(periodic_tau_string, TIMER_UNIT_LENGTH);
uint32_t ie_value = binary_str_to_uint(periodic_tau_string + TIMER_UNIT_LENGTH, periodic_tau_length - TIMER_UNIT_LENGTH);
switch (ie_unit) {
case 0: // multiples of 10 minutes
return 60 * 10 * ie_value;
case 1: // multiples of 1 hour
return 60 * 60 * ie_value;
case 2: // multiples of 10 hours
return 10 * 60 * 60 * ie_value;
case 3: // multiples of 2 seconds
return 2 * ie_value;
case 4: // multiples of 30 seconds
return 30 * ie_value;
case 5: // multiples of 1 minute
return 60 * ie_value;
case 6: // multiples of 320 hours
return 320 * 60 * 60 * ie_value;
default: // timer is deactivated
return 0;
}
}

View File

@ -25,6 +25,10 @@
namespace mbed {
#define AT_NETWORK_TRIALS 5
#define TIMER_UNIT_LENGTH 3
#define TWO_BYTES_HEX 4
#define FOUR_BYTES_HEX 8
#define ONE_BYTE_BINARY 8
/**
* Class AT_CellularNetwork
@ -67,8 +71,6 @@ public: // CellularNetwork
virtual nsapi_error_t get_network_registering_mode(NWRegisteringMode &mode);
virtual nsapi_error_t get_registration_status(RegistrationType type, RegistrationStatus &status);
virtual nsapi_error_t set_attach(int timeout = 10 * 1000);
virtual nsapi_error_t get_attach(AttachStatus &status);
@ -89,7 +91,6 @@ public: // CellularNetwork
virtual const char *get_ip_address();
virtual nsapi_error_t set_access_technology(RadioAccessTechnology rat);
virtual nsapi_error_t get_access_technology(RadioAccessTechnology &rat);
virtual nsapi_error_t scan_plmn(operList_t &operators, int &ops_count);
@ -109,8 +110,6 @@ public: // CellularNetwork
virtual nsapi_error_t get_signal_quality(int &rssi, int &ber);
virtual nsapi_error_t get_cell_id(int &cell_id);
virtual int get_3gpp_error();
virtual nsapi_error_t get_operator_params(int &format, operator_t &operator_params);
@ -118,6 +117,10 @@ public: // CellularNetwork
virtual nsapi_error_t set_registration_urc(RegistrationType type, bool on);
virtual nsapi_error_t get_operator_names(operator_names_list &op_names);
virtual nsapi_error_t get_registration_params(registration_params_t &reg_params);
virtual nsapi_error_t get_registration_params(RegistrationType type, registration_params_t &reg_params);
protected:
/** Check if modem supports the given stack type.
@ -171,10 +174,17 @@ private:
nsapi_error_t delete_current_context();
void read_reg_params_and_compare(RegistrationType type);
void read_reg_params(RegistrationType type, RegistrationStatus &reg_status, int &lac, int &cell_id, int &act);
// calls network callback only if status was changed, updates local connection status
void call_network_cb(nsapi_connection_status_t status);
void read_reg_params_and_compare(RegistrationType type);
void read_reg_params(registration_params_t &reg_params);
// Returns active time(Table 10.5.163/3GPP TS 24.008: GPRS Timer 2 information element) in seconds
int calculate_active_time(const char *active_time_string, int active_time_length);
// Returns periodic tau(Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element) in seconds
int calculate_periodic_tau(const char *periodic_tau_string, int periodic_tau_length);
#if NSAPI_PPP_AVAILABLE
void ppp_status_cb(nsapi_event_t, intptr_t);
#endif
@ -190,12 +200,12 @@ protected:
Callback<void(nsapi_event_t, intptr_t)> _connection_status_cb;
RadioAccessTechnology _op_act;
AuthenticationType _authentication_type;
int _cell_id;
nsapi_connection_status_t _connect_status;
bool _new_context_set;
bool _is_context_active;
RegistrationStatus _reg_status;
RadioAccessTechnology _current_act;
registration_params_t _reg_params;
mbed::Callback<void()> _urc_funcs[C_MAX];
};

View File

@ -300,6 +300,26 @@ void uint_to_binary_str(uint32_t num, char *str, int str_size, int bit_cnt)
}
}
uint32_t binary_str_to_uint(const char *binary_string, int binary_string_length)
{
if (!binary_string || !binary_string_length) {
return 0;
}
int integer_output = 0, base_exp = 1;
for (int i = binary_string_length - 1; i >= 0; i--) {
if (binary_string[i] == '1') {
integer_output += base_exp;
}
if (binary_string[i] != '\0') {
base_exp <<= 1;
}
}
return integer_output;
}
int char_str_to_hex_str(const char *str, uint16_t len, char *buf, bool omit_leading_zero)
{
if (!str || !buf) {

View File

@ -105,6 +105,15 @@ int hex_str_to_char_str(const char *str, uint16_t len, char *buf);
*/
void uint_to_binary_str(uint32_t num, char *str, int str_size, int bit_cnt);
/** Converts the given binary string to uint.
* For example binary_str_to_uint("0000001001", 10) would return 9
*
* @param binary_string binary string from where chars are converted to uint
* @param binary_string_length length of the param binary_string
* @return uint represented by the binary string
*/
uint32_t binary_str_to_uint(const char *binary_string, int binary_string_length);
/** Get dynamic port for socket
*
* @return next port number above 49152