From f9a90d82b0640ad8deb3d31aa4b39a995721f798 Mon Sep 17 00:00:00 2001 From: Teemu Kultala Date: Tue, 17 Jul 2018 15:48:02 +0300 Subject: [PATCH 1/3] sms gt tests --- .../cellular/TESTS/api/cellular_sms/main.cpp | 270 ++++++++++++++++++ .../cellular/framework/AT/AT_CellularSMS.cpp | 43 ++- 2 files changed, 301 insertions(+), 12 deletions(-) create mode 100644 features/cellular/TESTS/api/cellular_sms/main.cpp diff --git a/features/cellular/TESTS/api/cellular_sms/main.cpp b/features/cellular/TESTS/api/cellular_sms/main.cpp new file mode 100644 index 0000000000..7d6744b272 --- /dev/null +++ b/features/cellular/TESTS/api/cellular_sms/main.cpp @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#if !defined(MBED_CONF_NSAPI_PRESENT) +#error [NOT_SUPPORTED] A json configuration file is needed. Skipping this build. +#endif + +#include "CellularUtil.h" // for CELLULAR_ helper macros +#include "CellularTargets.h" + +#ifndef CELLULAR_DEVICE +#error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined +#endif + +#ifndef MBED_CONF_APP_SIM_PIN_CODE +#error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build. +#endif + + + +#include "greentea-client/test_env.h" +#include "unity.h" +#include "utest.h" + +#include "mbed.h" + +#include "AT_CellularSMS.h" +#include "CellularConnectionFSM.h" +#include "CellularDevice.h" +#include "../../cellular_tests_common.h" +#include CELLULAR_STRINGIFY(CELLULAR_DEVICE.h) + +#define NETWORK_TIMEOUT (600*1000) + +static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE); +static EventQueue queue(8 * EVENTS_EVENT_SIZE); +static rtos::Semaphore network_semaphore(0); +static CellularConnectionFSM cellularConnectionFSM; +static CellularConnectionFSM::CellularState cellular_target_state; +static CELLULAR_DEVICE *device; +static CellularSMS* sms; +static char service_center_address[SMS_MAX_PHONE_NUMBER_SIZE]; +static int service_address_type; + +static bool cellular_status(int state, int next_state) +{ + if (cellular_target_state == state) { + (void)network_semaphore.release(); + return false; // return false -> state machine is halted + } + return true; +} + +static void init() +{ + //the service center address is checked before any modification tests on it + ATHandler *at_init = new ATHandler(&cellular_serial, queue, 30000, "\r"); + at_init->cmd_start("AT+CSCA?"); + at_init->cmd_stop(); + + TEST_ASSERT(at_init->get_last_error() == NSAPI_ERROR_OK); + + at_init->resp_start("+CSCA:"); + at_init->read_string(service_center_address, sizeof(service_center_address)); + service_address_type = at_init->read_int(); + at_init->resp_stop(); + + TEST_ASSERT(at_init->get_last_error() == NSAPI_ERROR_OK); + + delete at_init; + +#if defined (MDMRTS) && defined (MDMCTS) + cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS); +#endif + cellularConnectionFSM.set_serial(&cellular_serial); + cellularConnectionFSM.set_callback(&cellular_status); + + TEST_ASSERT(cellularConnectionFSM.init() == NSAPI_ERROR_OK); + TEST_ASSERT(cellularConnectionFSM.start_dispatch() == NSAPI_ERROR_OK); + + device = new CELLULAR_DEVICE(queue); + TEST_ASSERT(device != NULL); + device->set_timeout(30000); + + sms = device->open_sms(&cellular_serial); + TEST_ASSERT(sms != NULL); + + wait(3); + +} + +static void activate_context() +{ + CellularNetwork *network = cellularConnectionFSM.get_network(); + + TEST_ASSERT(network != NULL); + TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN, NULL, NULL) == NSAPI_ERROR_OK); + + cellularConnectionFSM.set_sim_pin(MBED_CONF_APP_SIM_PIN_CODE); + + cellular_target_state = CellularConnectionFSM::STATE_REGISTERING_NETWORK; + TEST_ASSERT(cellularConnectionFSM.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK); + TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1); // cellular network searching may take several minutes +} + +static void test_sms_initialize_text_mode() +{ + TEST_ASSERT(sms->initialize(CellularSMS::CellularSMSMmodeText) == NSAPI_ERROR_OK); +} + +static void test_sms_initialize_pdu_mode() +{ + TEST_ASSERT(sms->initialize(CellularSMS::CellularSMSMmodePDU) == NSAPI_ERROR_OK); +} + +static void test_set_cscs() +{ + TEST_ASSERT(sms->set_cscs("IRA") == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_cscs("8859-1") == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_cscs("PCCP437") == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_cscs("UCS2") == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_cscs("GSM") == NSAPI_ERROR_OK); +} + +static void test_set_csca() +{ + TEST_ASSERT(sms->set_csca("55555", 129) == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_csca("+35855555", 145) == NSAPI_ERROR_OK); + TEST_ASSERT(sms->set_csca(service_center_address, service_address_type) == NSAPI_ERROR_OK); +} + +static void test_set_cpms_me() +{ + TEST_ASSERT(sms->set_cpms("ME", "ME", "ME") == NSAPI_ERROR_OK); +} + +#ifdef MBED_CONF_APP_CELLULAR_PHONE_NUMBER +static const char TEST_MESSAGE[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static int callbacks_received = 0; + +static void sms_callback() +{ + callbacks_received++; +} + +static void test_set_sms_callback() +{ + sms->set_sms_callback(sms_callback); +} + + +static void test_set_cpms_sm() +{ + TEST_ASSERT(sms->set_cpms("SM", "SM", "SM") == NSAPI_ERROR_OK); +} + +static void test_sms_send() +{ + const int msg_len = sizeof(TEST_MESSAGE); + TEST_ASSERT(sms->send_sms(MBED_CONF_APP_CELLULAR_PHONE_NUMBER, TEST_MESSAGE, msg_len) == msg_len); +} + +static void test_get_sms() +{ + uint16_t buf_len = sizeof(TEST_MESSAGE); + char buf[buf_len]; + + const uint16_t phone_len = sizeof(MBED_CONF_APP_CELLULAR_PHONE_NUMBER); + char phone_num[phone_len]; + + const uint16_t time_len = sizeof("yy/MM/dd,hh:mm:ss-zz"); + char time_stamp[time_len]; + + int buf_size = 0; + + wait(7); + TEST_ASSERT(sms->get_sms(buf, buf_len, phone_num, phone_len, time_stamp, time_len, &buf_size) == buf_len-1); + TEST_ASSERT(strcmp(phone_num, MBED_CONF_APP_CELLULAR_PHONE_NUMBER) == 0); + TEST_ASSERT(strcmp(buf, TEST_MESSAGE) == 0); + TEST_ASSERT(buf_size == 0); + + TEST_ASSERT(callbacks_received > 0); + callbacks_received = 0; + +} + +static void test_delete_all_messages() +{ + //send a message so that there is something to delete + test_sms_send(); + TEST_ASSERT(sms->delete_all_messages() == NSAPI_ERROR_OK); + callbacks_received = 0; +} + +static void test_set_extra_sim_wait_time_1000() +{ + sms->set_extra_sim_wait_time(1000); +} + +#endif + + +using namespace utest::v1; + +static utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) +{ + greentea_case_failure_abort_handler(source, reason); + return STATUS_ABORT; +} + +static Case cases[] = { + Case("CellularSMS init", init, greentea_failure_handler), + Case("CellularSMS activate context", activate_context, greentea_failure_handler), + Case("CellularSMS test ME for storage", test_set_cpms_me, greentea_failure_handler), + Case("CellularSMS test initialize to PDU mode", test_sms_initialize_pdu_mode, greentea_failure_handler), + Case("CellularSMS test character sets", test_set_cscs, greentea_failure_handler), + Case("CellularSMS test service center address", test_set_csca, greentea_failure_handler) +#ifdef MBED_CONF_APP_CELLULAR_PHONE_NUMBER + , + Case("CellularSMS test delete all messages", test_delete_all_messages, greentea_failure_handler), + Case("CellularSMS test sms callback", test_set_sms_callback, greentea_failure_handler), + Case("CellularSMS test sms send", test_sms_send, greentea_failure_handler), + Case("CellularSMS test get sms", test_get_sms, greentea_failure_handler), + Case("CellularSMS test set sim wait time 1s", test_set_extra_sim_wait_time_1000, greentea_failure_handler), + Case("CellularSMS test SM for storage", test_set_cpms_sm, greentea_failure_handler), + Case("CellularSMS test initialize to text mode", test_sms_initialize_text_mode, greentea_failure_handler), + Case("CellularSMS test delete all messages", test_delete_all_messages, greentea_failure_handler), + Case("CellularSMS test sms send", test_sms_send, greentea_failure_handler), + Case("CellularSMS test get sms", test_get_sms, greentea_failure_handler), + Case("CellularSMS test delete all messages", test_delete_all_messages, greentea_failure_handler) +#endif +}; + + + + +static utest::v1::status_t test_setup(const size_t number_of_cases) +{ + GREENTEA_SETUP(10*60, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +static Specification specification(test_setup, cases); + +int main() +{ +#if MBED_CONF_MBED_TRACE_ENABLE + trace_open(); +#endif + int ret = Harness::run(specification); +#if MBED_CONF_MBED_TRACE_ENABLE + trace_close(); +#endif + return ret; +} diff --git a/features/cellular/framework/AT/AT_CellularSMS.cpp b/features/cellular/framework/AT/AT_CellularSMS.cpp index 624ba93b5b..642b214bd5 100644 --- a/features/cellular/framework/AT/AT_CellularSMS.cpp +++ b/features/cellular/framework/AT/AT_CellularSMS.cpp @@ -640,7 +640,11 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char *b } _at.skip_param(); // if (time_stamp) { - _at.read_string(time_stamp, SMS_MAX_TIME_STAMP_SIZE); + int len = _at.read_string(time_stamp, SMS_MAX_TIME_STAMP_SIZE); + if (len < SMS_MAX_TIME_STAMP_SIZE-2) { + time_stamp[len++] = ','; + _at.read_string(&time_stamp[len], SMS_MAX_TIME_STAMP_SIZE-len); + } } (void)_at.consume_to_stop_tag(); // consume until if (buf) { @@ -735,7 +739,7 @@ nsapi_size_or_error_t AT_CellularSMS::get_sms(char *buf, uint16_t len, char *pho sms_info_t *info = get_oldest_sms_index(); if (info) { - if (info->msg_size + 1 > len) { // +1 for '\0' + if (info->msg_size > len) { tr_warn("Given buf too small, len is: %d but is must be: %d", len, info->msg_size); if (buf_size) { *buf_size = info->msg_size; @@ -800,23 +804,36 @@ nsapi_size_or_error_t AT_CellularSMS::get_data_from_pdu(const char *pdu, sms_inf index += 2; // we just read the high bits of first octet so move +2 // originating address length - oaLength = hex_str_to_int(pdu + index, 2); - index += 2; // add index over address length - index += 2; // skip number type + oaLength = hex_str_to_int(pdu+index, 2); + index +=2; // add index over address length + int type = hex_str_to_int(pdu+index, 1); + index +=2; // add index over type if (phone_number) { // phone number as reverse nibble encoded - int a = 0; - for (; a < oaLength; a += 2) { - if (a + 1 == oaLength) { - phone_number[a] = pdu[index + a + 1]; + int a = 0, field_length = oaLength; + + if (type == 9) { + //add the plus sign in case of international number (23.040 chapter address fields) + phone_number[a++] = '+'; + field_length++; + } + + for (; a < field_length; a +=2) { + if (a+1 == field_length) { + phone_number[a] = pdu[index+1]; + index++; } else { - phone_number[a] = pdu[index + a + 1]; - phone_number[a + 1] = pdu[index + a]; + phone_number[a] = pdu[index+1]; + phone_number[a+1] = pdu[index]; + index += 2; } } - phone_number[oaLength] = '\0'; + phone_number[field_length] = '\0'; + } else { + index += oaLength; } + index += oaLength; if (oaLength & 0x01) { // if phone number length is odd then it has padded F so skip that index++; @@ -1281,5 +1298,7 @@ uint16_t AT_CellularSMS::unpack_7_bit_gsm_to_str(const char *str, int len, char decodedCount++; } + buf[--decodedCount] = '\0'; + return decodedCount; } From 2b82746ae29dcb6b6ec466c46c57a8fb0c314352 Mon Sep 17 00:00:00 2001 From: Teemu Kultala Date: Tue, 7 Aug 2018 13:35:44 +0300 Subject: [PATCH 2/3] sms gt tests: changes after review --- .../cellular/TESTS/api/cellular_sms/main.cpp | 25 ++++++++++--------- .../cellular/framework/AT/AT_CellularSMS.cpp | 2 -- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/features/cellular/TESTS/api/cellular_sms/main.cpp b/features/cellular/TESTS/api/cellular_sms/main.cpp index 7d6744b272..f5a9f542af 100644 --- a/features/cellular/TESTS/api/cellular_sms/main.cpp +++ b/features/cellular/TESTS/api/cellular_sms/main.cpp @@ -27,7 +27,7 @@ #error [NOT_SUPPORTED] CELLULAR_DEVICE must be defined #endif -#ifndef MBED_CONF_APP_SIM_PIN_CODE +#ifndef MBED_CONF_APP_CELLULAR_SIM_PIN #error [NOT_SUPPORTED] SIM pin code is needed. Skipping this build. #endif @@ -52,7 +52,6 @@ static EventQueue queue(8 * EVENTS_EVENT_SIZE); static rtos::Semaphore network_semaphore(0); static CellularConnectionFSM cellularConnectionFSM; static CellularConnectionFSM::CellularState cellular_target_state; -static CELLULAR_DEVICE *device; static CellularSMS* sms; static char service_center_address[SMS_MAX_PHONE_NUMBER_SIZE]; static int service_address_type; @@ -93,7 +92,9 @@ static void init() TEST_ASSERT(cellularConnectionFSM.init() == NSAPI_ERROR_OK); TEST_ASSERT(cellularConnectionFSM.start_dispatch() == NSAPI_ERROR_OK); - device = new CELLULAR_DEVICE(queue); + + CellularDevice *device = cellularConnectionFSM.get_device(); + TEST_ASSERT(device != NULL); device->set_timeout(30000); @@ -111,7 +112,7 @@ static void activate_context() TEST_ASSERT(network != NULL); TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN, NULL, NULL) == NSAPI_ERROR_OK); - cellularConnectionFSM.set_sim_pin(MBED_CONF_APP_SIM_PIN_CODE); + cellularConnectionFSM.set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN); cellular_target_state = CellularConnectionFSM::STATE_REGISTERING_NETWORK; TEST_ASSERT(cellularConnectionFSM.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK); @@ -171,7 +172,7 @@ static void test_set_cpms_sm() static void test_sms_send() { - const int msg_len = sizeof(TEST_MESSAGE); + const int msg_len = strlen(TEST_MESSAGE); TEST_ASSERT(sms->send_sms(MBED_CONF_APP_CELLULAR_PHONE_NUMBER, TEST_MESSAGE, msg_len) == msg_len); } @@ -180,20 +181,18 @@ static void test_get_sms() uint16_t buf_len = sizeof(TEST_MESSAGE); char buf[buf_len]; - const uint16_t phone_len = sizeof(MBED_CONF_APP_CELLULAR_PHONE_NUMBER); - char phone_num[phone_len]; + char phone_num[SMS_MAX_PHONE_NUMBER_SIZE]; - const uint16_t time_len = sizeof("yy/MM/dd,hh:mm:ss-zz"); - char time_stamp[time_len]; + char time_stamp[SMS_MAX_TIME_STAMP_SIZE]; int buf_size = 0; wait(7); - TEST_ASSERT(sms->get_sms(buf, buf_len, phone_num, phone_len, time_stamp, time_len, &buf_size) == buf_len-1); + + TEST_ASSERT(sms->get_sms(buf, buf_len, phone_num, SMS_MAX_PHONE_NUMBER_SIZE, time_stamp, SMS_MAX_TIME_STAMP_SIZE, &buf_size) == buf_len-1); TEST_ASSERT(strcmp(phone_num, MBED_CONF_APP_CELLULAR_PHONE_NUMBER) == 0); TEST_ASSERT(strcmp(buf, TEST_MESSAGE) == 0); TEST_ASSERT(buf_size == 0); - TEST_ASSERT(callbacks_received > 0); callbacks_received = 0; @@ -203,6 +202,7 @@ static void test_delete_all_messages() { //send a message so that there is something to delete test_sms_send(); + wait(7); TEST_ASSERT(sms->delete_all_messages() == NSAPI_ERROR_OK); callbacks_received = 0; } @@ -223,6 +223,7 @@ static utest::v1::status_t greentea_failure_handler(const Case *const source, co return STATUS_ABORT; } + static Case cases[] = { Case("CellularSMS init", init, greentea_failure_handler), Case("CellularSMS activate context", activate_context, greentea_failure_handler), @@ -251,7 +252,7 @@ static Case cases[] = { static utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(10*60, "default_auto"); + GREENTEA_SETUP(600, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/features/cellular/framework/AT/AT_CellularSMS.cpp b/features/cellular/framework/AT/AT_CellularSMS.cpp index 642b214bd5..71a094c867 100644 --- a/features/cellular/framework/AT/AT_CellularSMS.cpp +++ b/features/cellular/framework/AT/AT_CellularSMS.cpp @@ -1298,7 +1298,5 @@ uint16_t AT_CellularSMS::unpack_7_bit_gsm_to_str(const char *str, int len, char decodedCount++; } - buf[--decodedCount] = '\0'; - return decodedCount; } From df8252539b8986785600bd2ade964538ba7ae218 Mon Sep 17 00:00:00 2001 From: Teemu Kultala Date: Tue, 7 Aug 2018 16:34:46 +0300 Subject: [PATCH 3/3] sms gt tests: rebase and astyle fix --- .../cellular/framework/AT/AT_CellularSMS.cpp | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/features/cellular/framework/AT/AT_CellularSMS.cpp b/features/cellular/framework/AT/AT_CellularSMS.cpp index 71a094c867..7605566cbb 100644 --- a/features/cellular/framework/AT/AT_CellularSMS.cpp +++ b/features/cellular/framework/AT/AT_CellularSMS.cpp @@ -641,10 +641,10 @@ nsapi_size_or_error_t AT_CellularSMS::read_sms_from_index(int msg_index, char *b _at.skip_param(); // if (time_stamp) { int len = _at.read_string(time_stamp, SMS_MAX_TIME_STAMP_SIZE); - if (len < SMS_MAX_TIME_STAMP_SIZE-2) { + if (len < (SMS_MAX_TIME_STAMP_SIZE - 2)) { time_stamp[len++] = ','; _at.read_string(&time_stamp[len], SMS_MAX_TIME_STAMP_SIZE-len); - } + } } (void)_at.consume_to_stop_tag(); // consume until if (buf) { @@ -804,10 +804,10 @@ nsapi_size_or_error_t AT_CellularSMS::get_data_from_pdu(const char *pdu, sms_inf index += 2; // we just read the high bits of first octet so move +2 // originating address length - oaLength = hex_str_to_int(pdu+index, 2); - index +=2; // add index over address length - int type = hex_str_to_int(pdu+index, 1); - index +=2; // add index over type + oaLength = hex_str_to_int(pdu + index, 2); + index += 2; // add index over address length + int type = hex_str_to_int(pdu + index, 1); + index += 2; // add index over type if (phone_number) { // phone number as reverse nibble encoded int a = 0, field_length = oaLength; @@ -818,13 +818,13 @@ nsapi_size_or_error_t AT_CellularSMS::get_data_from_pdu(const char *pdu, sms_inf field_length++; } - for (; a < field_length; a +=2) { - if (a+1 == field_length) { - phone_number[a] = pdu[index+1]; + for (; a < field_length; a += 2) { + if ((a + 1) == field_length) { + phone_number[a] = pdu[index + 1]; index++; } else { - phone_number[a] = pdu[index+1]; - phone_number[a+1] = pdu[index]; + phone_number[a] = pdu[index + 1]; + phone_number[a + 1] = pdu[index]; index += 2; } } @@ -834,7 +834,6 @@ nsapi_size_or_error_t AT_CellularSMS::get_data_from_pdu(const char *pdu, sms_inf } - index += oaLength; if (oaLength & 0x01) { // if phone number length is odd then it has padded F so skip that index++; }