mirror of https://github.com/ARMmbed/mbed-os.git
commit
614d058bb2
|
|
@ -3,16 +3,22 @@ cmsis
|
|||
features/cryptocell
|
||||
features/mbedtls
|
||||
features/lwipstack/lwip
|
||||
features/lwipstack/lwip-sys
|
||||
rtos/TARGET_CORTEX/rtx4
|
||||
features/filesystem/littlefs/littlefs
|
||||
features/filesystem/fat/ChaN
|
||||
features/storage/filesystem/littlefs/littlefs/
|
||||
features/storage/filesystem/fat/ChaN
|
||||
features/storage/FEATURE_STORAGE
|
||||
features/frameworks
|
||||
features/FEATURE_BLE/targets
|
||||
features/FEATURE_BLE
|
||||
features/unsupported/
|
||||
features/FEATURE_COMMON_PAL/
|
||||
features/netsocket/emac-drivers
|
||||
hal/storage_abstraction
|
||||
FEATURE_NANOSTACK/coap-service
|
||||
FEATURE_NANOSTACK/sal-stack-nanostack
|
||||
TESTS/mbed_hal/trng/pithy
|
||||
features/nanostack/coap-service
|
||||
features/nanostack/sal-stack-nanostack
|
||||
rtos/TARGET_CORTEX/rtx5
|
||||
TESTS/mbed_hal/trng/pithy
|
||||
targets
|
||||
components/802.15.4_RF
|
||||
components/wifi
|
||||
tools
|
||||
|
|
|
|||
|
|
@ -1,5 +1,22 @@
|
|||
<!--
|
||||
|
||||
************************************** WARNING **************************************
|
||||
|
||||
The ciarcom bot parses this header automatically. Any deviation from the
|
||||
template may cause the bot to automatically correct this header or may result in a
|
||||
warning message, requesting updates.
|
||||
|
||||
Please ensure that nothing follows the Issue request type section, all
|
||||
issue details are within the Description section and no changes are made to the
|
||||
template format (as detailed below).
|
||||
|
||||
*************************************************************************************
|
||||
|
||||
-->
|
||||
|
||||
### Description
|
||||
<!--
|
||||
|
||||
<!--
|
||||
Required
|
||||
Add detailed description of what you are reporting.
|
||||
Good example: https://os.mbed.com/docs/latest/reference/workflow.html
|
||||
|
|
@ -13,19 +30,15 @@
|
|||
|
||||
|
||||
### Issue request type
|
||||
<!--
|
||||
|
||||
<!--
|
||||
Required
|
||||
Please add only one X to one of the following types. Do not fill multiple types. (Split the issue otherwise.)
|
||||
Please note this is not a GitHub task list; indenting the boxes or changing the format to add a '.' or '*' in front
|
||||
of them changes the meaning incorrectly. The only changes to make are to add a description under the
|
||||
description heading and to add an 'x' to the correct box.
|
||||
|
||||
[X] Question
|
||||
[ ] Enhancement
|
||||
[ ] Bug
|
||||
Please add only one X to one of the following types. Do not fill multiple types (split the issue otherwise.)
|
||||
Please note this is not a GitHub task list, indenting the boxes or changing the format to add a '.' or '*' in front
|
||||
of them would change the meaning incorrectly. The only changes to be made are to add a description text under the
|
||||
description heading and to add a 'x' to the correct box.
|
||||
-->
|
||||
|
||||
[ ] Question
|
||||
[ ] Enhancement
|
||||
[ ] Bug
|
||||
[ ] Question
|
||||
[ ] Enhancement
|
||||
[ ] Bug
|
||||
|
||||
|
|
|
|||
|
|
@ -20,5 +20,7 @@
|
|||
[ ] Refactor
|
||||
[ ] Target update
|
||||
[ ] Functionality change
|
||||
[ ] Docs update
|
||||
[ ] Test update
|
||||
[ ] Breaking change
|
||||
|
||||
|
|
|
|||
21
.travis.yml
21
.travis.yml
|
|
@ -51,15 +51,25 @@ matrix:
|
|||
# Print versions we use
|
||||
- doxygen --version
|
||||
before_script:
|
||||
# Build doxygen
|
||||
- >
|
||||
(git clone --depth=1 --single-branch --branch Release_1_8_14 https://github.com/doxygen/doxygen;
|
||||
cd doxygen;
|
||||
mkdir build;
|
||||
cd build;
|
||||
cmake -G "Unix Makefiles" ..;
|
||||
make;
|
||||
sudo make install)
|
||||
# Create BUILD directory for tests
|
||||
- mkdir BUILD
|
||||
script:
|
||||
# Assert that the Doxygen build produced no warnings.
|
||||
# The strange command below asserts that the Doxygen command had an
|
||||
# output of zero length
|
||||
- >
|
||||
doxygen doxyfile_options 2>&1 |
|
||||
tee BUILD/doxygen.out && [ ! -s BUILD/doxygen.out ]
|
||||
- doxygen doxyfile_options 2>&1
|
||||
# Once Mbed OS has been fixed, enable the full test by replacing the top line with this:
|
||||
# - ( ! doxygen doxyfile_options 2>&1 | grep . )
|
||||
|
||||
# Assert that all binary libraries are named correctly
|
||||
# The strange command below asserts that there are exactly 0 libraries
|
||||
# that do not start with lib
|
||||
|
|
@ -86,6 +96,7 @@ matrix:
|
|||
|
||||
- arm-none-eabi-gcc --version
|
||||
- python --version
|
||||
- pip list --verbose
|
||||
script:
|
||||
# Run local testing on tools
|
||||
- PYTHONPATH=. coverage run -a -m pytest tools/test
|
||||
|
|
@ -132,10 +143,10 @@ matrix:
|
|||
# update status if we succeeded, compare with master if possible
|
||||
- |
|
||||
CURR=$(cat astyle-branch.out | grep Formatted | wc -l)
|
||||
PREV=$(curl https://api.github.com/repos/$TRAVIS_REPO_SLUG/status/master \
|
||||
PREV=$(curl -u "$MBED_BOT" https://api.github.com/repos/$TRAVIS_REPO_SLUG/status/master \
|
||||
| jq -re "select(.sha != \"$TRAVIS_COMMIT\")
|
||||
| .statuses[] | select(.context == \"travis-ci/$NAME\").description
|
||||
| capture(\", (?<files>[0-9]+) files\").warnings" \
|
||||
| capture(\", (?<files>[0-9]+) files\").files" \
|
||||
|| echo 0)
|
||||
|
||||
STATUSM="Passed, ${CURR} files"
|
||||
|
|
|
|||
|
|
@ -1,45 +1,5 @@
|
|||
# Description
|
||||
This document is cheat sheet for everyone who wants to contribute to [ARMmbed/mbed-os](https://github.com/ARMmbed/mbed-os) GitHub repository at GitHub.
|
||||
All changes in code base should originate from GitHub Issues and take advantage of existing GitHub flows. Goal is to attract contributors and allow them contribute to code and documentation at the same time.
|
||||
# Contributing to Mbed OS
|
||||
|
||||
Guidelines from this document are created to help new and existing contributors understand process workflow and align to project rules before pull request is submitted. It explains how a participant should do things like format code, test fixes, and submit patches.
|
||||
Mbed OS is an open-source, device software platform for the Internet of Things. Contributions are an important part of the platform, and our goal is to make it as simple as possible to become a contributor.
|
||||
|
||||
## Where to get more information?
|
||||
You can read more on our [documentation page](https://docs.mbed.com/docs/mbed-os-handbook/en/latest/cont/contributing/).
|
||||
|
||||
# How to contribute
|
||||
We really appreciate your contributions! We are Open Source project and we need your help. We want to keep it as easy as possible to contribute changes that get things working in your environment. There are a few guidelines that we need contributors to follow so that we can have a chance of keeping on top of things.
|
||||
|
||||
Before a pull request will be merged, the [mbed Contributor Agreement](http://developer.mbed.org/contributor_agreement/) must be signed.
|
||||
|
||||
You can pick up existing [mbed-os GitHub Issue](https://github.com/ARMmbed/mbed-os/issues) and solve it or implement new feature you find important, attractive or just necessary. We will review your proposal via pull request mechanism, give you comments and merge your changes if we decide your contribution satisfy criteria such as quality.
|
||||
|
||||
# Enhancements vs Bugs
|
||||
Enhancements are:
|
||||
* New features implementation.
|
||||
* Code refactoring.
|
||||
* Coding rules, coding styles improvements.
|
||||
* Code comments improvement.
|
||||
* Documentation work.
|
||||
|
||||
Bugs are:
|
||||
* Issues rose internally or externally by [ARMmbed/mbed-os](https://github.com/ARMmbed/mbed-os) users.
|
||||
* Internally (within mbed team) created issues from Continuous Integration pipeline and build servers.
|
||||
* Issues detected using automation tools such as compilers, sanitizers, static code analysis tools etc.
|
||||
|
||||
# Gate Keeper role
|
||||
Gate Keeper is a person responsible for GitHub process workflow execution and is responsible for repository / project code base. Gate Keeper is also responsible for code (pull request) quality stamp and approves or rejects code changes in project’s code base.
|
||||
|
||||
Gate Keepers will review your pull request code, give you comments in pull request comment section and in the end if everything goes well merge your pull request to one of our branches (most probably default ```master``` branch).
|
||||
|
||||
Please be patient, digest Gate Keeper's feedback and respond promptly :)
|
||||
|
||||
# mbed SDK porting
|
||||
* For more information regarding mbed SDK porting please refer to [mbed SDK porting](http://developer.mbed.org/handbook/mbed-SDK-porting) handbook.
|
||||
* Before starting the mbed SDK porting, you might want to familiarize with the [mbed SDK library internals](http://developer.mbed.org/handbook/mbed-library-internals) first.
|
||||
|
||||
# Glossary
|
||||
* Gate Keeper – persons responsible for overall code-base quality of [ARMmbed/mbed-os](https://github.com/ARMmbed/mbed-os) project.
|
||||
* Enhancement – New feature deployment, code refactoring actions or existing code improvements.
|
||||
* Bugfix – Issues originated from GitHub Issues pool, raised internally within mbed classic team or issues from automated code validators like linters, static code analysis tools etc.
|
||||
* Mbed classic – mbed SDK 2.0 located in GitHub at [ARMmbed/mbed-os](https://github.com/ARMmbed/mbed-os).
|
||||
To encourage productive collaboration, as well as robust, consistent and maintainable code, we have a set of guidelines for [contributing to Mbed OS](https://os.mbed.com/docs/latest/reference/contributing.html).
|
||||
|
|
|
|||
18
README.md
18
README.md
|
|
@ -19,13 +19,20 @@
|
|||
Arm Mbed OS is an open source embedded operating system designed specifically for the "things" in the Internet of Things. It includes all the features you need to develop a connected product based on an Arm Cortex-M microcontroller, including security, connectivity, an RTOS and drivers for sensors and I/O devices.
|
||||
|
||||
Mbed OS provides a platform that includes:
|
||||
* Security foundations.
|
||||
* Cloud management services.
|
||||
* Drivers for sensors, I/O devices and connectivity.
|
||||
|
||||
- Security foundations.
|
||||
- Cloud management services.
|
||||
- Drivers for sensors, I/O devices and connectivity.
|
||||
|
||||
## Release notes
|
||||
The [release notes](https://os.mbed.com/releases) detail the current release. You can also find information about previous versions.
|
||||
|
||||
## License and contributions
|
||||
|
||||
The software is provided under [Apache-2.0 license](LICENSE). Contributions to this project are accepted under the same license. Please see [contributing.md](CONTRIBUTING.md) for more info.
|
||||
|
||||
This project contains code from other projects. The original license text is included in those source files. They must comply with our [license guide](https://os.mbed.com/docs/latest/reference/license.html)
|
||||
|
||||
## Getting started for developers
|
||||
|
||||
We have a [developer website](https://os.mbed.com) for asking questions, engaging with others, finding information on boards and components, using an online IDE and compiler, reading the documentation and learning about what's new and what's coming next in Mbed OS.
|
||||
|
|
@ -36,6 +43,7 @@ We also have a [contributing and publishing guide](https://os.mbed.com/contribut
|
|||
|
||||
## Documentation
|
||||
|
||||
For more information about Mbed OS, please see [our published documentation](https://os.mbed.com/docs/latest). It includes published Doxygen for our APIs, step-by-step tutorials, porting information and background reference materials about our architecture and tools.
|
||||
For more information about Mbed OS, please see [our published documentation](https://os.mbed.com/docs/latest). It includes Doxygen for our APIs, step-by-step tutorials, porting information and background reference materials about our architecture and tools.
|
||||
|
||||
To contribute to this documentation, please see the [mbed-os-5-docs repository](https://github.com/ARMmbed/mbed-os-5-docs).
|
||||
|
||||
To contribute to this documentation, please see the [mbed-os-5-docs repo](https://github.com/ARMmbed/mbed-os-5-docs).
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class RtcResetTest(BaseHostTest):
|
|||
"""
|
||||
|
||||
"""Start of the RTC"""
|
||||
START_TIME = 50000
|
||||
START_TIME = 1537789823 # GMT: Monday, 24 September 2018 11:50:23
|
||||
START_TIME_TOLERANCE = 10
|
||||
"""Time to delay after sending reset"""
|
||||
DELAY_TIME = 5.0
|
||||
|
|
|
|||
|
|
@ -36,9 +36,6 @@ class SystemResetTest(BaseHostTest):
|
|||
def __init__(self):
|
||||
super(SystemResetTest, self).__init__()
|
||||
self.reset = False
|
||||
cycle_s = self.get_config_item('program_cycle_s')
|
||||
self.program_cycle_s = cycle_s if cycle_s is not None else DEFAULT_CYCLE_PERIOD
|
||||
|
||||
self.test_steps_sequence = self.test_steps()
|
||||
# Advance the coroutine to it's first yield statement.
|
||||
self.test_steps_sequence.send(None)
|
||||
|
|
@ -61,16 +58,18 @@ class SystemResetTest(BaseHostTest):
|
|||
"""Reset the device and check the status
|
||||
"""
|
||||
system_reset = yield
|
||||
|
||||
self.reset = False
|
||||
|
||||
wait_after_reset = self.get_config_item('forced_reset_timeout')
|
||||
wait_after_reset = wait_after_reset if wait_after_reset is not None else DEFAULT_CYCLE_PERIOD
|
||||
|
||||
self.send_kv(MSG_KEY_DEVICE_RESET, MSG_VALUE_DUMMY)
|
||||
time.sleep(self.program_cycle_s)
|
||||
time.sleep(wait_after_reset)
|
||||
self.send_kv(MSG_KEY_SYNC, MSG_VALUE_DUMMY)
|
||||
|
||||
system_reset = yield
|
||||
|
||||
if self.reset == False:
|
||||
raise RuntimeError('Platform did not reset as expected.')
|
||||
|
||||
# The sequence is correct -- test passed.
|
||||
yield True
|
||||
yield True
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
|
||||
using namespace utest::v1;
|
||||
using namespace mbed;
|
||||
|
||||
static LoRaRadio *radio = NULL;
|
||||
rtos::Semaphore event_sem(0);
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ void test_thread(void)
|
|||
char test[] = "123456789";
|
||||
uint32_t crc;
|
||||
MbedCRC<POLY_32BIT_ANSI, 32> ct;
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char*)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0, ct.compute((void *)test, strlen((const char *)test), &crc));
|
||||
TEST_ASSERT_EQUAL(0xCBF43926, crc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,9 +55,6 @@ void flashiap_program_test()
|
|||
TEST_ASSERT_TRUE(sector_size % page_size == 0);
|
||||
uint32_t prog_size = std::max(page_size, (uint32_t)8);
|
||||
uint8_t *data = new uint8_t[prog_size + 2];
|
||||
for (uint32_t i = 0; i < prog_size + 2; i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
|
||||
// the one before the last sector in the system
|
||||
uint32_t address = (flash_device.get_flash_start() + flash_device.get_flash_size()) - (sector_size);
|
||||
|
|
@ -68,6 +65,20 @@ void flashiap_program_test()
|
|||
ret = flash_device.erase(address, sector_size);
|
||||
TEST_ASSERT_EQUAL_INT32(0, ret);
|
||||
|
||||
uint8_t erase_val = flash_device.get_erase_value();
|
||||
memset(data, erase_val, prog_size);
|
||||
|
||||
uint8_t *data_flashed = new uint8_t[prog_size];
|
||||
for (uint32_t i = 0; i < sector_size / prog_size; i++) {
|
||||
uint32_t page_addr = address + i * prog_size;
|
||||
ret = flash_device.read(data_flashed, page_addr, prog_size);
|
||||
TEST_ASSERT_EQUAL_INT32(0, ret);
|
||||
TEST_ASSERT_EQUAL_UINT8_ARRAY(data, data_flashed, prog_size);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < prog_size + 2; i++) {
|
||||
data[i] = i;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < sector_size / prog_size; i++) {
|
||||
uint32_t prog_addr = address + i * prog_size;
|
||||
|
|
@ -75,7 +86,6 @@ void flashiap_program_test()
|
|||
TEST_ASSERT_EQUAL_INT32(0, ret);
|
||||
}
|
||||
|
||||
uint8_t *data_flashed = new uint8_t[prog_size];
|
||||
for (uint32_t i = 0; i < sector_size / prog_size; i++) {
|
||||
uint32_t page_addr = address + i * prog_size;
|
||||
ret = flash_device.read(data_flashed, page_addr, prog_size);
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ void test_multi_ticker(void)
|
|||
ticker[i].attach_us(callback(increment_multi_counter), MULTI_TICKER_TIME_MS * 1000);
|
||||
}
|
||||
|
||||
Thread::wait(MULTI_TICKER_TIME_MS + extra_wait);
|
||||
ThisThread::sleep_for(MULTI_TICKER_TIME_MS + extra_wait);
|
||||
TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
|
||||
|
||||
for (int i = 0; i < TICKER_COUNT; i++) {
|
||||
|
|
@ -95,7 +95,7 @@ void test_multi_ticker(void)
|
|||
ticker[i].attach_us(callback(increment_multi_counter), (MULTI_TICKER_TIME_MS + i) * 1000);
|
||||
}
|
||||
|
||||
Thread::wait(MULTI_TICKER_TIME_MS + TICKER_COUNT + extra_wait);
|
||||
ThisThread::sleep_for(MULTI_TICKER_TIME_MS + TICKER_COUNT + extra_wait);
|
||||
TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
|
||||
|
||||
for (int i = 0; i < TICKER_COUNT; i++) {
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !MBED_MEM_TRACING_ENABLED
|
||||
#error [NOT_SUPPORTED] test not supported
|
||||
#ifndef MBED_MEM_TRACING_ENABLED
|
||||
#error [NOT_SUPPORTED] test not supported
|
||||
#endif
|
||||
|
||||
using utest::v1::Case;
|
||||
|
|
@ -391,7 +391,7 @@ static void test_case_multithread_malloc_free()
|
|||
threads[i].start(callback(malloc_free, &threads_continue));
|
||||
}
|
||||
|
||||
Thread::wait(wait_time_us);
|
||||
ThisThread::sleep_for(wait_time_us);
|
||||
threads_continue = false;
|
||||
|
||||
for (int i = 0; i < NUM_TEST_THREADS; i++) {
|
||||
|
|
|
|||
|
|
@ -39,13 +39,13 @@ class TestClass {
|
|||
public:
|
||||
TestClass()
|
||||
{
|
||||
Thread::wait(500);
|
||||
ThisThread::sleep_for(500);
|
||||
instance_count++;
|
||||
}
|
||||
|
||||
void do_something()
|
||||
{
|
||||
Thread::wait(100);
|
||||
ThisThread::sleep_for(100);
|
||||
}
|
||||
|
||||
~TestClass()
|
||||
|
|
@ -83,7 +83,7 @@ void test_case_func_race()
|
|||
// Start start first thread
|
||||
t1.start(cb);
|
||||
// Start second thread while the first is inside the constructor
|
||||
Thread::wait(250);
|
||||
ThisThread::sleep_for(250);
|
||||
t2.start(cb);
|
||||
|
||||
// Wait for the threads to finish
|
||||
|
|
@ -105,7 +105,7 @@ void test_case_class_race()
|
|||
// Start start first thread
|
||||
t1.start(cb);
|
||||
// Start second thread while the first is inside the constructor
|
||||
Thread::wait(250);
|
||||
ThisThread::sleep_for(250);
|
||||
t2.start(cb);
|
||||
|
||||
// Wait for the threads to finish
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ void test_multi_ticker(void)
|
|||
ticker[i].attach_us(callback(increment_multi_counter), MULTI_TICKER_TIME_MS * 1000);
|
||||
}
|
||||
|
||||
Thread::wait(MULTI_TICKER_TIME_MS + extra_wait);
|
||||
ThisThread::sleep_for(MULTI_TICKER_TIME_MS + extra_wait);
|
||||
TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
|
||||
|
||||
for (int i = 0; i < TICKER_COUNT; i++) {
|
||||
|
|
@ -211,7 +211,7 @@ void test_multi_ticker(void)
|
|||
ticker[i].attach_us(callback(increment_multi_counter), (MULTI_TICKER_TIME_MS + i) * 1000);
|
||||
}
|
||||
|
||||
Thread::wait(MULTI_TICKER_TIME_MS + TICKER_COUNT + extra_wait);
|
||||
ThisThread::sleep_for(MULTI_TICKER_TIME_MS + TICKER_COUNT + extra_wait);
|
||||
TEST_ASSERT_EQUAL(TICKER_COUNT, multi_counter);
|
||||
|
||||
for (int i = 0; i < TICKER_COUNT; i++) {
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ void test_multiple(void)
|
|||
for (size_t i = 0; i < NUM_TIMEOUTS; i++) {
|
||||
timeouts[i].attach_callback(mbed::callback(cnt_callback, &callback_count), TEST_DELAY_US);
|
||||
}
|
||||
Thread::wait(TEST_DELAY_MS + 2);
|
||||
ThisThread::sleep_for(TEST_DELAY_MS + 2);
|
||||
TEST_ASSERT_EQUAL(NUM_TIMEOUTS, callback_count);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** \addtogroup hal_critical_tests
|
||||
/** \addtogroup hal_critical
|
||||
* @{
|
||||
* \defgroup hal_critical_test Tests
|
||||
* Tests definitions of the HAL Critical module.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef MBED_CRITICAL_SECTION_TEST_H
|
||||
|
|
@ -45,7 +48,7 @@
|
|||
template <int N>
|
||||
void test_critical_section();
|
||||
|
||||
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
#endif // MBED_CRITICAL_SECTION_TEST_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "utest/utest.h"
|
||||
#include "unity/unity.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
|
||||
#include "mbed.h"
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
/**
|
||||
* This test is intended to gate devices that do not have enough RAM to run
|
||||
* Mbed os. Devices passing this test should have enough RAM to run all
|
||||
* other Mbed OS tests.
|
||||
*
|
||||
* If your device does not pass this test, then you should determine the
|
||||
* cause of high memory usage and fix it. If you cannot free enough memory,
|
||||
* then you should turn off Mbed OS support for this device.
|
||||
*/
|
||||
|
||||
#define MIN_HEAP_SIZE 2048
|
||||
#define MIN_DATA_SIZE 2048
|
||||
|
||||
volatile uint8_t test_buffer[MIN_DATA_SIZE];
|
||||
|
||||
static void minimum_heap_test()
|
||||
{
|
||||
void *mem = malloc(MIN_HEAP_SIZE);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, mem);
|
||||
free(mem);
|
||||
}
|
||||
|
||||
static void minimum_data_test()
|
||||
{
|
||||
// Use test buffer so it is not optimized away
|
||||
for (int i = 0; i < MIN_DATA_SIZE; i++) {
|
||||
test_buffer[i] = i & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(30, "default_auto");
|
||||
return greentea_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("Minimum heap test", minimum_heap_test),
|
||||
Case("Minimum data test", minimum_data_test),
|
||||
};
|
||||
|
||||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
|
||||
|
||||
int main()
|
||||
{
|
||||
Harness::run(specification);
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018-2018 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MBED_QSPI_FLASH_CONFIG_H
|
||||
#define MBED_QSPI_FLASH_CONFIG_H
|
||||
|
||||
#include "../../MX25RXX35F_config.h"
|
||||
|
||||
/* Fast mode not supported in MX25U3235F */
|
||||
#undef FAST_MODE_ENABLE
|
||||
#undef FAST_MODE_DISABLE
|
||||
|
||||
#ifdef QSPI_SECTOR_COUNT
|
||||
#undef QSPI_SECTOR_COUNT
|
||||
#define QSPI_SECTOR_COUNT 1024 // for MX25U3235F
|
||||
#endif
|
||||
|
||||
/* The values for MX25U3235F are different, specify this here */
|
||||
#undef QSPI_COMMON_MAX_FREQUENCY
|
||||
#undef QSPI_WRSR_MAX_TIME
|
||||
#undef QSPI_PAGE_PROG_MAX_TIME
|
||||
#undef QSPI_ERASE_SECTOR_MAX_TIME
|
||||
#undef QSPI_ERASE_BLOCK_32_MAX_TIME
|
||||
#undef QSPI_ERASE_BLOCK_64_MAX_TIME
|
||||
|
||||
/* Implementation of these macros are slightly different for MX25U3235F */
|
||||
#undef EXTENDED_SPI_ENABLE
|
||||
#undef EXTENDED_SPI_DISABLE
|
||||
|
||||
/* Max frequency for basic rw operation in MX25U3235F */
|
||||
#define QSPI_COMMON_MAX_FREQUENCY 54000000
|
||||
|
||||
/* WRSR operations max time [us] (datasheet max time + 15%) */
|
||||
#define QSPI_WRSR_MAX_TIME 46000 // 40ms
|
||||
|
||||
/* Write operations max time [us] (datasheet max time + 15%) */
|
||||
#define QSPI_PAGE_PROG_MAX_TIME 3450 // 3ms
|
||||
|
||||
/* erase operations max time [us] (datasheet max time + 15%) */
|
||||
#define QSPI_ERASE_SECTOR_MAX_TIME 230000 // 200 ms
|
||||
#define QSPI_ERASE_BLOCK_32_MAX_TIME 1150000 // 1s
|
||||
#define QSPI_ERASE_BLOCK_64_MAX_TIME 2300000 // 2s
|
||||
|
||||
#define EXTENDED_SPI_ENABLE() \
|
||||
\
|
||||
const int32_t reg_size = QSPI_STATUS_REG_SIZE; \
|
||||
uint8_t reg_data[reg_size] = { 0 }; \
|
||||
\
|
||||
if (read_register(STATUS_REG, reg_data, \
|
||||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
if (write_enable(qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
reg_data[0] = STATUS_BIT_QE; \
|
||||
if (write_register(QSPI_CMD_WRSR, reg_data, \
|
||||
reg_size, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
WAIT_FOR(WRSR_MAX_TIME, qspi); \
|
||||
\
|
||||
memset(reg_data, 0, QSPI_STATUS_REG_SIZE); \
|
||||
if (read_register(STATUS_REG, reg_data, \
|
||||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
return ((reg_data[0] & STATUS_BIT_QE) != 0 ? \
|
||||
QSPI_STATUS_OK : QSPI_STATUS_ERROR)
|
||||
|
||||
|
||||
|
||||
#define EXTENDED_SPI_DISABLE() \
|
||||
\
|
||||
const int32_t reg_size = QSPI_STATUS_REG_SIZE; \
|
||||
uint8_t reg_data[reg_size] = { 0 }; \
|
||||
\
|
||||
if (read_register(STATUS_REG, reg_data, \
|
||||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
if (write_enable(qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
reg_data[0] &= ~(STATUS_BIT_QE); \
|
||||
\
|
||||
if (write_register(QSPI_CMD_WRSR, reg_data, \
|
||||
reg_size, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
WAIT_FOR(WRSR_MAX_TIME, qspi); \
|
||||
\
|
||||
reg_data[0] = 0; \
|
||||
if (read_register(STATUS_REG, reg_data, \
|
||||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
return ((reg_data[0] & STATUS_BIT_QE) == 0 ? \
|
||||
QSPI_STATUS_OK : QSPI_STATUS_ERROR)
|
||||
|
||||
#endif // MBED_QSPI_FLASH_CONFIG_H
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018-2018 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef MBED_QSPI_FLASH_CONFIG_H
|
||||
#define MBED_QSPI_FLASH_CONFIG_H
|
||||
|
||||
#include "../../MX25RXX35F_config.h"
|
||||
|
||||
/* Fast mode not supported in MX25L12845G */
|
||||
#undef FAST_MODE_ENABLE
|
||||
#undef FAST_MODE_DISABLE
|
||||
|
||||
#ifdef QSPI_SECTOR_COUNT
|
||||
#undef QSPI_SECTOR_COUNT
|
||||
#define QSPI_SECTOR_COUNT 4096 // for MX25L12845G
|
||||
#endif
|
||||
|
||||
/* The values for MX25U3235F are different, specify this here */
|
||||
#undef QSPI_COMMON_MAX_FREQUENCY
|
||||
#undef QSPI_WRSR_MAX_TIME
|
||||
#undef QSPI_PAGE_PROG_MAX_TIME
|
||||
#undef QSPI_ERASE_SECTOR_MAX_TIME
|
||||
#undef QSPI_ERASE_BLOCK_32_MAX_TIME
|
||||
#undef QSPI_ERASE_BLOCK_64_MAX_TIME
|
||||
|
||||
/* Implementation of these macros are slightly different for MX25L12845G */
|
||||
#undef EXTENDED_SPI_ENABLE
|
||||
#undef EXTENDED_SPI_DISABLE
|
||||
|
||||
/* Max frequency for basic rw operation based on max bus frequency of 24MHz */
|
||||
#define QSPI_COMMON_MAX_FREQUENCY 23000000
|
||||
|
||||
/* WRSR operations max time [us] (datasheet max time + 15%) */
|
||||
#define QSPI_WRSR_MAX_TIME 46000 // 40ms
|
||||
|
||||
/* Write operations max time [us] (datasheet max time + 15%) */
|
||||
#define QSPI_PAGE_PROG_MAX_TIME 1000 // 0.75ms
|
||||
|
||||
/* erase operations max time [us] (datasheet max time + 15%) */
|
||||
#define QSPI_ERASE_SECTOR_MAX_TIME 460000 // 400 ms
|
||||
#define QSPI_ERASE_BLOCK_32_MAX_TIME 1150000 // 1s
|
||||
#define QSPI_ERASE_BLOCK_64_MAX_TIME 2300000 // 2s
|
||||
|
||||
#define EXTENDED_SPI_ENABLE() \
|
||||
\
|
||||
const int32_t reg_size = QSPI_STATUS_REG_SIZE; \
|
||||
uint8_t reg_data[reg_size] = { 0 }; \
|
||||
\
|
||||
if (read_register(STATUS_REG, reg_data, \
|
||||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
if (write_enable(qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
reg_data[0] = STATUS_BIT_QE; \
|
||||
if (write_register(QSPI_CMD_WRSR, reg_data, \
|
||||
reg_size, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
WAIT_FOR(WRSR_MAX_TIME, qspi); \
|
||||
\
|
||||
memset(reg_data, 0, QSPI_STATUS_REG_SIZE); \
|
||||
if (read_register(STATUS_REG, reg_data, \
|
||||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
return ((reg_data[0] & STATUS_BIT_QE) != 0 ? \
|
||||
QSPI_STATUS_OK : QSPI_STATUS_ERROR)
|
||||
|
||||
|
||||
|
||||
#define EXTENDED_SPI_DISABLE() \
|
||||
\
|
||||
const int32_t reg_size = QSPI_STATUS_REG_SIZE; \
|
||||
uint8_t reg_data[reg_size] = { 0 }; \
|
||||
\
|
||||
if (read_register(STATUS_REG, reg_data, \
|
||||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
if (write_enable(qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
reg_data[0] &= ~(STATUS_BIT_QE); \
|
||||
\
|
||||
if (write_register(QSPI_CMD_WRSR, reg_data, \
|
||||
reg_size, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
WAIT_FOR(WRSR_MAX_TIME, qspi); \
|
||||
\
|
||||
reg_data[0] = 0; \
|
||||
if (read_register(STATUS_REG, reg_data, \
|
||||
QSPI_STATUS_REG_SIZE, qspi) != QSPI_STATUS_OK) { \
|
||||
return QSPI_STATUS_ERROR; \
|
||||
} \
|
||||
\
|
||||
return ((reg_data[0] & STATUS_BIT_QE) == 0 ? \
|
||||
QSPI_STATUS_OK : QSPI_STATUS_ERROR)
|
||||
|
||||
#endif // MBED_QSPI_FLASH_CONFIG_H
|
||||
|
|
@ -25,6 +25,10 @@
|
|||
#include "STM/DISCO_F413ZH/flash_config.h"
|
||||
#elif defined(TARGET_EFM32GG11_STK3701)
|
||||
#include "SiliconLabs/EFM32GG11_STK3701/flash_config.h"
|
||||
#elif defined(TARGET_K82F)
|
||||
#include "Freescale/K82F/flash_config.h"
|
||||
#elif defined(TARGET_KL82Z)
|
||||
#include "Freescale/KL82Z/flash_config.h"
|
||||
#endif
|
||||
|
||||
#endif // MBED_FLASH_CONFIGS_H
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
|
|||
TEST_ASSERT_EQUAL(QSPI_STATUS_OK, ret);
|
||||
TEST_ASSERT_EQUAL(write_size, buf_len);
|
||||
|
||||
if(is_extended_mode(write_inst_width, write_addr_width, write_data_width)) {
|
||||
if (is_extended_mode(write_inst_width, write_addr_width, write_data_width)) {
|
||||
// on some flash chips in extended-SPI mode, control commands works only in 1-1-1 mode
|
||||
// so switching back to 1-1-1 mode
|
||||
qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
|
||||
|
|
@ -195,7 +195,7 @@ static void _qspi_write_read_test(Qspi &qspi, qspi_bus_width_t write_inst_width,
|
|||
}
|
||||
qspi.cmd.set_dummy_cycles(0);
|
||||
|
||||
if(is_extended_mode(read_inst_width, read_addr_width, read_data_width)) {
|
||||
if (is_extended_mode(read_inst_width, read_addr_width, read_data_width)) {
|
||||
// on some flash chips in extended-SPI mode, control commands works only in 1-1-1 mode
|
||||
// so switching back to 1-1-1 mode
|
||||
qspi.cmd.configure(MODE_1_1_1, ADDR_SIZE_24, ALT_SIZE_8);
|
||||
|
|
|
|||
|
|
@ -14,8 +14,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** \addtogroup hal_qspi_tests
|
||||
/** \addtogroup hal_qspi
|
||||
* @{
|
||||
* \defgroup hal_qspi_tests Tests
|
||||
* QSPI tests of the HAL.
|
||||
* @{
|
||||
*/
|
||||
#ifndef MBED_QSPI_TEST_H
|
||||
#define MBED_QSPI_TEST_H
|
||||
|
|
@ -96,3 +99,4 @@ void qspi_write_read_test(void);
|
|||
#endif
|
||||
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
|
|
|||
|
|
@ -201,11 +201,11 @@ qspi_status_t erase(uint32_t erase_cmd, uint32_t flash_addr, Qspi &qspi)
|
|||
|
||||
qspi_status_t mode_enable(Qspi &qspi, qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width)
|
||||
{
|
||||
if(is_extended_mode(inst_width, addr_width, data_width)) {
|
||||
if (is_extended_mode(inst_width, addr_width, data_width)) {
|
||||
return extended_enable(qspi);
|
||||
} else if(is_dual_mode(inst_width, addr_width, data_width)) {
|
||||
} else if (is_dual_mode(inst_width, addr_width, data_width)) {
|
||||
return dual_enable(qspi);
|
||||
} else if(is_quad_mode(inst_width, addr_width, data_width)) {
|
||||
} else if (is_quad_mode(inst_width, addr_width, data_width)) {
|
||||
return quad_enable(qspi);
|
||||
} else {
|
||||
return QSPI_STATUS_OK;
|
||||
|
|
@ -214,11 +214,11 @@ qspi_status_t mode_enable(Qspi &qspi, qspi_bus_width_t inst_width, qspi_bus_widt
|
|||
|
||||
qspi_status_t mode_disable(Qspi &qspi, qspi_bus_width_t inst_width, qspi_bus_width_t addr_width, qspi_bus_width_t data_width)
|
||||
{
|
||||
if(is_extended_mode(inst_width, addr_width, data_width)) {
|
||||
if (is_extended_mode(inst_width, addr_width, data_width)) {
|
||||
return extended_disable(qspi);
|
||||
} else if(is_dual_mode(inst_width, addr_width, data_width)) {
|
||||
} else if (is_dual_mode(inst_width, addr_width, data_width)) {
|
||||
return dual_disable(qspi);
|
||||
} else if(is_quad_mode(inst_width, addr_width, data_width)) {
|
||||
} else if (is_quad_mode(inst_width, addr_width, data_width)) {
|
||||
return quad_disable(qspi);
|
||||
} else {
|
||||
return QSPI_STATUS_OK;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
using namespace utest::v1;
|
||||
|
||||
static rtc_leap_year_support_t rtc_leap_year_support;
|
||||
|
||||
/* Regular is_leap_year, see platform/mbed_mktime.c for the optimised version. */
|
||||
bool is_leap_year(int year)
|
||||
{
|
||||
|
|
@ -53,6 +51,7 @@ bool is_leap_year(int year)
|
|||
* When _rtc_is_leap_year() function is called.
|
||||
* Then _rtc_is_leap_year() returns true if given year is a leap year; false otherwise.
|
||||
*/
|
||||
template <rtc_leap_year_support_t rtc_leap_year_support>
|
||||
void test_is_leap_year()
|
||||
{
|
||||
for (int i = 70; i <= LAST_VALID_YEAR; ++i) {
|
||||
|
|
@ -79,31 +78,6 @@ typedef struct {
|
|||
bool result;
|
||||
} test_mk_time_struct;
|
||||
|
||||
/* Array which contains data to test boundary values for the RTC devices which handles correctly leap years in
|
||||
* whole range (1970 - 2106).
|
||||
* Expected range: the 1st of January 1970 at 00:00:00 (seconds: 0) to the 7th of February 2106 at 06:28:15 (seconds: UINT_MAX).
|
||||
*/
|
||||
test_mk_time_struct test_mk_time_arr_full[] = {
|
||||
{{ 0, 0, 0, 1, 0, 70, 0, 0, 0 }, (time_t) 0, true}, // valid lower bound - the 1st of January 1970 at 00:00:00
|
||||
{{ 59, 59, 23, 31, 11, 59, 0, 0, 0 }, (time_t) 0, false }, // invalid lower bound - the 31st of December 1969 at 23:59:59
|
||||
|
||||
{{ 15, 28, 6, 7, 1, 206, 0, 0, 0 }, (time_t)(UINT_MAX), true }, // valid upper bound - the 7th of February 2106 at 06:28:15
|
||||
{{ 16, 28, 6, 7, 1, 206, 0, 0, 0 }, (time_t) 0, false }, // invalid upper bound - the 7th of February 2106 at 06:28:16
|
||||
};
|
||||
|
||||
/* Array which contains data to test boundary values for the RTC devices which does not handle correctly leap years in
|
||||
* whole range (1970 - 2106). On this platforms we will be one day off after 28.02.2100 since 2100 year will be
|
||||
* incorrectly treated as a leap year.
|
||||
* Expected range: the 1st of January 1970 at 00:00:00 (seconds: 0) to the 6th of February 2106 at 06:28:15 (seconds: UINT_MAX).
|
||||
*/
|
||||
test_mk_time_struct test_mk_time_arr_partial[] = {
|
||||
{{ 0, 0, 0, 1, 0, 70, 0, 0, 0 }, (time_t) 0, true}, // valid lower bound - the 1st of January 1970 at 00:00:00
|
||||
{{ 59, 59, 23, 31, 11, 59, 0, 0, 0 }, (time_t) 0, false }, // invalid lower bound - the 31st of December 1969 at 23:59:59
|
||||
|
||||
{{ 15, 28, 6, 6, 1, 206, 0, 0, 0 }, (time_t)(UINT_MAX), true }, // valid upper bound - the 6th of February 2106 at 06:28:15
|
||||
{{ 16, 28, 6, 6, 1, 206, 0, 0, 0 }, (time_t) 0, false }, // invalid upper bound - the 6th of February 2106 at 06:28:16
|
||||
};
|
||||
|
||||
/* Test boundary values for _rtc_maketime().
|
||||
*
|
||||
* Note: This test case is designed for both types of RTC devices:
|
||||
|
|
@ -116,10 +90,36 @@ test_mk_time_struct test_mk_time_arr_partial[] = {
|
|||
* When _rtc_maketime() function is called to convert the calendar time into timestamp.
|
||||
* Then if given calendar time is valid function returns true and conversion result, otherwise returns false.
|
||||
*/
|
||||
template <rtc_leap_year_support_t rtc_leap_year_support>
|
||||
void test_mk_time_boundary()
|
||||
{
|
||||
test_mk_time_struct *pTestCases;
|
||||
|
||||
/* Array which contains data to test boundary values for the RTC devices which handles correctly leap years in
|
||||
* whole range (1970 - 2106).
|
||||
* Expected range: the 1st of January 1970 at 00:00:00 (seconds: 0) to the 7th of February 2106 at 06:28:15 (seconds: UINT_MAX).
|
||||
*/
|
||||
test_mk_time_struct test_mk_time_arr_full[] = {
|
||||
{{ 0, 0, 0, 1, 0, 70, 0, 0, 0 }, (time_t) 0, true}, // valid lower bound - the 1st of January 1970 at 00:00:00
|
||||
{{ 59, 59, 23, 31, 11, 59, 0, 0, 0 }, (time_t) 0, false }, // invalid lower bound - the 31st of December 1969 at 23:59:59
|
||||
|
||||
{{ 15, 28, 6, 7, 1, 206, 0, 0, 0 }, (time_t)(UINT_MAX), true }, // valid upper bound - the 7th of February 2106 at 06:28:15
|
||||
{{ 16, 28, 6, 7, 1, 206, 0, 0, 0 }, (time_t) 0, false }, // invalid upper bound - the 7th of February 2106 at 06:28:16
|
||||
};
|
||||
|
||||
/* Array which contains data to test boundary values for the RTC devices which does not handle correctly leap years in
|
||||
* whole range (1970 - 2106). On this platforms we will be one day off after 28.02.2100 since 2100 year will be
|
||||
* incorrectly treated as a leap year.
|
||||
* Expected range: the 1st of January 1970 at 00:00:00 (seconds: 0) to the 6th of February 2106 at 06:28:15 (seconds: UINT_MAX).
|
||||
*/
|
||||
test_mk_time_struct test_mk_time_arr_partial[] = {
|
||||
{{ 0, 0, 0, 1, 0, 70, 0, 0, 0 }, (time_t) 0, true}, // valid lower bound - the 1st of January 1970 at 00:00:00
|
||||
{{ 59, 59, 23, 31, 11, 59, 0, 0, 0 }, (time_t) 0, false }, // invalid lower bound - the 31st of December 1969 at 23:59:59
|
||||
|
||||
{{ 15, 28, 6, 6, 1, 206, 0, 0, 0 }, (time_t)(UINT_MAX), true }, // valid upper bound - the 6th of February 2106 at 06:28:15
|
||||
{{ 16, 28, 6, 6, 1, 206, 0, 0, 0 }, (time_t) 0, false }, // invalid upper bound - the 6th of February 2106 at 06:28:16
|
||||
};
|
||||
|
||||
/* Select array with test cases. */
|
||||
if (rtc_leap_year_support == RTC_FULL_LEAP_YEAR_SUPPORT) {
|
||||
pTestCases = test_mk_time_arr_full;
|
||||
|
|
@ -169,33 +169,41 @@ void test_local_time_invalid_param()
|
|||
TEST_ASSERT_EQUAL(false, _rtc_localtime(1, NULL, RTC_4_YEAR_LEAP_YEAR_SUPPORT));
|
||||
}
|
||||
|
||||
utest::v1::status_t teardown_handler_t(const Case *const source, const size_t passed, const size_t failed,
|
||||
const failure_t reason)
|
||||
/* Test set_time() function called a few seconds apart.
|
||||
*
|
||||
* Given is set_time() function.
|
||||
* When set_time() is used to set the system time two times.
|
||||
* Then if the value returned from time() is always correct return true, otherwise return false.
|
||||
*/
|
||||
#define NEW_TIME 15
|
||||
void test_set_time_twice()
|
||||
{
|
||||
return greentea_case_teardown_handler(source, passed, failed, reason);
|
||||
}
|
||||
time_t current_time;
|
||||
|
||||
utest::v1::status_t full_leap_year_case_setup_handler_t(const Case *const source, const size_t index_of_case)
|
||||
{
|
||||
rtc_leap_year_support = RTC_FULL_LEAP_YEAR_SUPPORT;
|
||||
/* Set the time to NEW_TIME and check it */
|
||||
set_time(NEW_TIME);
|
||||
current_time = time(NULL);
|
||||
TEST_ASSERT_EQUAL (true, (current_time == NEW_TIME));
|
||||
|
||||
return greentea_case_setup_handler(source, index_of_case);
|
||||
}
|
||||
/* Wait 2 seconds */
|
||||
wait_ms(2000);
|
||||
|
||||
utest::v1::status_t partial_leap_year_case_setup_handler_t(const Case *const source, const size_t index_of_case)
|
||||
{
|
||||
rtc_leap_year_support = RTC_4_YEAR_LEAP_YEAR_SUPPORT;
|
||||
|
||||
return greentea_case_setup_handler(source, index_of_case);
|
||||
/* set the time to NEW_TIME again and check it */
|
||||
set_time(NEW_TIME);
|
||||
current_time = time(NULL);
|
||||
TEST_ASSERT_EQUAL (true, (current_time == NEW_TIME));
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("test is leap year - RTC leap years full support", full_leap_year_case_setup_handler_t, test_is_leap_year, teardown_handler_t),
|
||||
Case("test is leap year - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_is_leap_year, teardown_handler_t),
|
||||
Case("test make time boundary values - RTC leap years full support", full_leap_year_case_setup_handler_t, test_mk_time_boundary, teardown_handler_t),
|
||||
Case("test make time boundary values - RTC leap years partial support", partial_leap_year_case_setup_handler_t, test_mk_time_boundary, teardown_handler_t),
|
||||
Case("test make time - invalid param", test_mk_time_invalid_param, teardown_handler_t),
|
||||
Case("test local time - invalid param", test_local_time_invalid_param, teardown_handler_t),
|
||||
Case("test is leap year - RTC leap years full support", test_is_leap_year<RTC_FULL_LEAP_YEAR_SUPPORT>),
|
||||
Case("test is leap year - RTC leap years partial support", test_is_leap_year<RTC_4_YEAR_LEAP_YEAR_SUPPORT>),
|
||||
Case("test make time boundary values - RTC leap years full support", test_mk_time_boundary<RTC_FULL_LEAP_YEAR_SUPPORT>),
|
||||
Case("test make time boundary values - RTC leap years partial support", test_mk_time_boundary<RTC_4_YEAR_LEAP_YEAR_SUPPORT>),
|
||||
Case("test make time - invalid param", test_mk_time_invalid_param),
|
||||
Case("test local time - invalid param", test_local_time_invalid_param),
|
||||
#if DEVICE_RTC || DEVICE_LPTICKER
|
||||
Case("test set_time twice", test_set_time_twice),
|
||||
#endif
|
||||
};
|
||||
|
||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
||||
|
|
|
|||
|
|
@ -25,28 +25,13 @@
|
|||
#include "greentea-client/test_env.h"
|
||||
#include "mbed_lp_ticker_wrapper.h"
|
||||
|
||||
#include "sleep_test_utils.h"
|
||||
#include "sleep_api_tests.h"
|
||||
|
||||
#define US_PER_S 1000000
|
||||
|
||||
/* Flush serial buffer before deep sleep
|
||||
*
|
||||
* Since deepsleep() may shut down the UART peripheral, we wait for some time
|
||||
* to allow for hardware serial buffers to completely flush.
|
||||
*
|
||||
* Take NUMAKER_PFM_NUC472 as an example:
|
||||
* Its UART peripheral has 16-byte Tx FIFO. With baud rate set to 9600, flush
|
||||
* Tx FIFO would take: 16 * 8 * 1000 / 9600 = 13.3 (ms). So set wait time to
|
||||
* 20ms here for safe.
|
||||
*
|
||||
* This should be replaced with a better function that checks if the
|
||||
* hardware buffers are empty. However, such an API does not exist now,
|
||||
* so we'll use the busy_wait_ms() function for now.
|
||||
*/
|
||||
#define SERIAL_FLUSH_TIME_MS 20
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
static char info[512] = {0};
|
||||
|
||||
/* The following ticker frequencies are possible:
|
||||
* high frequency ticker: 250 KHz (1 tick per 4 us) - 8 Mhz (1 tick per 1/8 us)
|
||||
* low power ticker: 8 KHz (1 tick per 125 us) - 64 KHz (1 tick per ~15.6 us)
|
||||
|
|
@ -65,71 +50,6 @@ static const uint32_t sleep_mode_delta_us = (10 + 4 + 5);
|
|||
* delta = default 10 ms + worst ticker resolution + extra time for code execution */
|
||||
static const uint32_t deepsleep_mode_delta_us = (10000 + 125 + 5);
|
||||
|
||||
unsigned int ticks_to_us(unsigned int ticks, unsigned int freq)
|
||||
{
|
||||
return (unsigned int)((unsigned long long) ticks * US_PER_S / freq);
|
||||
}
|
||||
|
||||
unsigned int us_to_ticks(unsigned int us, unsigned int freq)
|
||||
{
|
||||
return (unsigned int)((unsigned long long) us * freq / US_PER_S);
|
||||
}
|
||||
|
||||
unsigned int overflow_protect(unsigned int timestamp, unsigned int ticker_width)
|
||||
{
|
||||
unsigned int counter_mask = ((1 << ticker_width) - 1);
|
||||
|
||||
return (timestamp & counter_mask);
|
||||
}
|
||||
|
||||
bool compare_timestamps(unsigned int delta_ticks, unsigned int ticker_width, unsigned int expected, unsigned int actual)
|
||||
{
|
||||
const unsigned int counter_mask = ((1 << ticker_width) - 1);
|
||||
|
||||
const unsigned int lower_bound = ((expected - delta_ticks) & counter_mask);
|
||||
const unsigned int upper_bound = ((expected + delta_ticks) & counter_mask);
|
||||
|
||||
if (lower_bound < upper_bound) {
|
||||
if (actual >= lower_bound && actual <= upper_bound) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ((actual >= lower_bound && actual <= counter_mask) || (actual >= 0 && actual <= upper_bound)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void busy_wait_ms(int ms)
|
||||
{
|
||||
const ticker_info_t *info = us_ticker_get_info();
|
||||
uint32_t mask = (1 << info->bits) - 1;
|
||||
int delay = (int)((uint64_t)ms * info->frequency / 1000);
|
||||
|
||||
uint32_t prev = us_ticker_read();
|
||||
while (delay > 0) {
|
||||
uint32_t next = us_ticker_read();
|
||||
delay -= (next - prev) & mask;
|
||||
prev = next;
|
||||
}
|
||||
}
|
||||
|
||||
void us_ticker_isr(const ticker_data_t *const ticker_data)
|
||||
{
|
||||
us_ticker_clear_interrupt();
|
||||
}
|
||||
|
||||
#ifdef DEVICE_LPTICKER
|
||||
void lp_ticker_isr(const ticker_data_t *const ticker_data)
|
||||
{
|
||||
lp_ticker_clear_interrupt();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Test that wake-up time from sleep should be less than 10 us and
|
||||
* high frequency ticker interrupt can wake-up target from sleep. */
|
||||
void sleep_usticker_test()
|
||||
|
|
@ -140,6 +60,11 @@ void sleep_usticker_test()
|
|||
|
||||
const ticker_irq_handler_type us_ticker_irq_handler_org = set_us_ticker_irq_handler(us_ticker_isr);
|
||||
|
||||
/* Give some time Green Tea to finish UART transmission before entering
|
||||
* sleep mode.
|
||||
*/
|
||||
busy_wait_ms(SERIAL_FLUSH_TIME_MS);
|
||||
|
||||
/* Test only sleep functionality. */
|
||||
sleep_manager_lock_deep_sleep();
|
||||
TEST_ASSERT_FALSE_MESSAGE(sleep_manager_can_deep_sleep(), "deep sleep should be locked");
|
||||
|
|
@ -147,7 +72,8 @@ void sleep_usticker_test()
|
|||
/* Testing wake-up time 10 us. */
|
||||
for (timestamp_t i = 100; i < 1000; i += 100) {
|
||||
/* note: us_ticker_read() operates on ticks. */
|
||||
const timestamp_t next_match_timestamp = overflow_protect(us_ticker_read() + us_to_ticks(i, ticker_freq),
|
||||
const timestamp_t start_timestamp = us_ticker_read();
|
||||
const timestamp_t next_match_timestamp = overflow_protect(start_timestamp + us_to_ticks(i, ticker_freq),
|
||||
ticker_width);
|
||||
|
||||
us_ticker_set_interrupt(next_match_timestamp);
|
||||
|
|
@ -156,9 +82,11 @@ void sleep_usticker_test()
|
|||
|
||||
const unsigned int wakeup_timestamp = us_ticker_read();
|
||||
|
||||
TEST_ASSERT(
|
||||
compare_timestamps(us_to_ticks(sleep_mode_delta_us, ticker_freq), ticker_width, next_match_timestamp,
|
||||
wakeup_timestamp));
|
||||
sprintf(info, "Delta ticks: %u, Ticker width: %u, Expected wake up tick: %d, Actual wake up tick: %d, delay ticks: %d, wake up after ticks: %d",
|
||||
us_to_ticks(sleep_mode_delta_us, ticker_freq), ticker_width, next_match_timestamp, wakeup_timestamp, us_to_ticks(i, ticker_freq), wakeup_timestamp - start_timestamp);
|
||||
|
||||
TEST_ASSERT_MESSAGE(compare_timestamps(us_to_ticks(sleep_mode_delta_us, ticker_freq),
|
||||
ticker_width, next_match_timestamp, wakeup_timestamp), info);
|
||||
}
|
||||
|
||||
set_us_ticker_irq_handler(us_ticker_irq_handler_org);
|
||||
|
|
@ -189,7 +117,8 @@ void deepsleep_lpticker_test()
|
|||
/* Testing wake-up time 10 ms. */
|
||||
for (timestamp_t i = 20000; i < 200000; i += 20000) {
|
||||
/* note: lp_ticker_read() operates on ticks. */
|
||||
const timestamp_t next_match_timestamp = overflow_protect(lp_ticker_read() + us_to_ticks(i, ticker_freq), ticker_width);
|
||||
const timestamp_t start_timestamp = lp_ticker_read();
|
||||
const timestamp_t next_match_timestamp = overflow_protect(start_timestamp + us_to_ticks(i, ticker_freq), ticker_width);
|
||||
|
||||
lp_ticker_set_interrupt(next_match_timestamp);
|
||||
|
||||
|
|
@ -197,7 +126,11 @@ void deepsleep_lpticker_test()
|
|||
|
||||
const timestamp_t wakeup_timestamp = lp_ticker_read();
|
||||
|
||||
TEST_ASSERT(compare_timestamps(us_to_ticks(deepsleep_mode_delta_us, ticker_freq), ticker_width, next_match_timestamp, wakeup_timestamp));
|
||||
sprintf(info, "Delta ticks: %u, Ticker width: %u, Expected wake up tick: %d, Actual wake up tick: %d, delay ticks: %d, wake up after ticks: %d",
|
||||
us_to_ticks(deepsleep_mode_delta_us, ticker_freq), ticker_width, next_match_timestamp, wakeup_timestamp, us_to_ticks(i, ticker_freq), wakeup_timestamp - start_timestamp);
|
||||
|
||||
TEST_ASSERT_MESSAGE(compare_timestamps(us_to_ticks(deepsleep_mode_delta_us, ticker_freq), ticker_width,
|
||||
next_match_timestamp, wakeup_timestamp), info);
|
||||
}
|
||||
|
||||
set_lp_ticker_irq_handler(lp_ticker_irq_handler_org);
|
||||
|
|
@ -240,8 +173,12 @@ void deepsleep_high_speed_clocks_turned_off_test()
|
|||
|
||||
TEST_ASSERT_UINT32_WITHIN(1000, 0, ticks_to_us(us_ticks_diff, us_ticker_freq));
|
||||
|
||||
sprintf(info, "Delta ticks: %u, Ticker width: %u, Expected wake up tick: %d, Actual wake up tick: %d",
|
||||
us_to_ticks(deepsleep_mode_delta_us, lp_ticker_freq), lp_ticker_width, wakeup_time, lp_ticks_after_sleep);
|
||||
|
||||
/* Check if we have woken-up after expected time. */
|
||||
TEST_ASSERT(compare_timestamps(us_to_ticks(deepsleep_mode_delta_us, lp_ticker_freq), lp_ticker_width, wakeup_time, lp_ticks_after_sleep));
|
||||
TEST_ASSERT_MESSAGE(compare_timestamps(us_to_ticks(deepsleep_mode_delta_us, lp_ticker_freq), lp_ticker_width,
|
||||
wakeup_time, lp_ticks_after_sleep), info);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup hal_sleep
|
||||
* @{
|
||||
* @defgroup hal_sleep_test_util Tests
|
||||
* Tests of the sleep HAL.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef MBED_SLEEP_TEST_UTILS_H
|
||||
#define MBED_SLEEP_TEST_UTILS_H
|
||||
|
||||
#include "hal/ticker_api.h"
|
||||
#include "hal/us_ticker_api.h"
|
||||
#include "hal/lp_ticker_api.h"
|
||||
|
||||
/* Flush serial buffer before deep sleep
|
||||
*
|
||||
* Since deepsleep() may shut down the UART peripheral, we wait for some time
|
||||
* to allow for hardware serial buffers to completely flush.
|
||||
*
|
||||
* Take NUMAKER_PFM_NUC472 as an example:
|
||||
* Its UART peripheral has 16-byte Tx FIFO. With baud rate set to 9600, flush
|
||||
* Tx FIFO would take: 16 * 8 * 1000 / 9600 = 13.3 (ms). So set wait time to
|
||||
* 20ms here for safe.
|
||||
*
|
||||
* This should be replaced with a better function that checks if the
|
||||
* hardware buffers are empty. However, such an API does not exist now,
|
||||
* so we'll use the busy_wait_ms() function for now.
|
||||
*/
|
||||
#define SERIAL_FLUSH_TIME_MS 20
|
||||
|
||||
#define US_PER_S 1000000
|
||||
|
||||
unsigned int ticks_to_us(unsigned int ticks, unsigned int freq)
|
||||
{
|
||||
return (unsigned int)((unsigned long long) ticks * US_PER_S / freq);
|
||||
}
|
||||
|
||||
unsigned int us_to_ticks(unsigned int us, unsigned int freq)
|
||||
{
|
||||
return (unsigned int)((unsigned long long) us * freq / US_PER_S);
|
||||
}
|
||||
|
||||
unsigned int overflow_protect(unsigned int timestamp, unsigned int ticker_width)
|
||||
{
|
||||
unsigned int counter_mask = ((1 << ticker_width) - 1);
|
||||
|
||||
return (timestamp & counter_mask);
|
||||
}
|
||||
|
||||
bool compare_timestamps(unsigned int delta_ticks, unsigned int ticker_width, unsigned int expected, unsigned int actual)
|
||||
{
|
||||
const unsigned int counter_mask = ((1 << ticker_width) - 1);
|
||||
|
||||
const unsigned int lower_bound = ((expected - delta_ticks) & counter_mask);
|
||||
const unsigned int upper_bound = ((expected + delta_ticks) & counter_mask);
|
||||
|
||||
if (lower_bound < upper_bound) {
|
||||
if (actual >= lower_bound && actual <= upper_bound) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ((actual >= lower_bound && actual <= counter_mask) || (actual >= 0 && actual <= upper_bound)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void busy_wait_ms(int ms)
|
||||
{
|
||||
const ticker_info_t *info = us_ticker_get_info();
|
||||
uint32_t mask = (1 << info->bits) - 1;
|
||||
int delay = (int)((uint64_t) ms * info->frequency / 1000);
|
||||
|
||||
uint32_t prev = us_ticker_read();
|
||||
while (delay > 0) {
|
||||
uint32_t next = us_ticker_read();
|
||||
delay -= (next - prev) & mask;
|
||||
prev = next;
|
||||
}
|
||||
}
|
||||
|
||||
void us_ticker_isr(const ticker_data_t *const ticker_data)
|
||||
{
|
||||
us_ticker_clear_interrupt();
|
||||
}
|
||||
|
||||
#ifdef DEVICE_LPTICKER
|
||||
void lp_ticker_isr(const ticker_data_t *const ticker_data)
|
||||
{
|
||||
lp_ticker_clear_interrupt();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
|
@ -16,46 +16,238 @@
|
|||
#include "utest/utest.h"
|
||||
#include "unity/unity.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include <limits.h>
|
||||
#include "mbed.h"
|
||||
#include "mbed_lp_ticker_wrapper.h"
|
||||
#include "../sleep/sleep_test_utils.h"
|
||||
#include "sleep_manager_api_tests.h"
|
||||
|
||||
#if !DEVICE_SLEEP
|
||||
#error [NOT_SUPPORTED] test not supported
|
||||
#endif
|
||||
|
||||
using namespace utest::v1;
|
||||
#define SLEEP_DURATION_US 20000ULL
|
||||
#define DEEP_SLEEP_TEST_CHECK_WAIT_US 2000
|
||||
#define DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US 500
|
||||
|
||||
void sleep_manager_deepsleep_counter_test()
|
||||
using utest::v1::Case;
|
||||
using utest::v1::Specification;
|
||||
using utest::v1::Harness;
|
||||
|
||||
void test_lock_unlock()
|
||||
{
|
||||
bool deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_TRUE(deep_sleep_allowed);
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep());
|
||||
|
||||
sleep_manager_lock_deep_sleep();
|
||||
deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_FALSE(deep_sleep_allowed);
|
||||
TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep());
|
||||
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
deep_sleep_allowed = sleep_manager_can_deep_sleep_test_check();
|
||||
TEST_ASSERT_TRUE(deep_sleep_allowed);
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep());
|
||||
}
|
||||
|
||||
utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
|
||||
void test_lock_eq_ushrt_max()
|
||||
{
|
||||
greentea_case_failure_abort_handler(source, reason);
|
||||
return STATUS_CONTINUE;
|
||||
uint32_t lock_count = 0;
|
||||
while (lock_count < USHRT_MAX) {
|
||||
sleep_manager_lock_deep_sleep();
|
||||
lock_count++;
|
||||
TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep());
|
||||
}
|
||||
while (lock_count > 1) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
lock_count--;
|
||||
TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep());
|
||||
}
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep());
|
||||
}
|
||||
|
||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
||||
#if DEVICE_LPTICKER
|
||||
#if DEVICE_USTICKER
|
||||
utest::v1::status_t testcase_setup(const Case *const source, const size_t index_of_case)
|
||||
{
|
||||
GREENTEA_SETUP(20, "default_auto");
|
||||
return greentea_test_setup_handler(number_of_cases);
|
||||
// Suspend the RTOS kernel scheduler to prevent interference with duration of sleep.
|
||||
osKernelSuspend();
|
||||
#if DEVICE_LPTICKER
|
||||
ticker_suspend(get_lp_ticker_data());
|
||||
#if (LPTICKER_DELAY_TICKS > 0)
|
||||
// Suspend the low power ticker wrapper to prevent interference with deep sleep lock.
|
||||
lp_ticker_wrapper_suspend();
|
||||
#endif
|
||||
#endif
|
||||
ticker_suspend(get_us_ticker_data());
|
||||
// Make sure HAL tickers are initialized.
|
||||
us_ticker_init();
|
||||
#if DEVICE_LPTICKER
|
||||
lp_ticker_init();
|
||||
#endif
|
||||
return utest::v1::greentea_case_setup_handler(source, index_of_case);
|
||||
}
|
||||
|
||||
utest::v1::status_t testcase_teardown(const Case *const source, const size_t passed, const size_t failed,
|
||||
const utest::v1::failure_t failure)
|
||||
{
|
||||
ticker_resume(get_us_ticker_data());
|
||||
#if DEVICE_LPTICKER
|
||||
#if (LPTICKER_DELAY_TICKS > 0)
|
||||
lp_ticker_wrapper_resume();
|
||||
#endif
|
||||
ticker_resume(get_lp_ticker_data());
|
||||
#endif
|
||||
osKernelResume(0);
|
||||
return utest::v1::greentea_case_teardown_handler(source, passed, failed, failure);
|
||||
}
|
||||
|
||||
/* This test is based on the fact that the high-speed clocks are turned off
|
||||
* in deep sleep mode but remain on in the ordinary sleep mode. Low-speed
|
||||
* clocks stay on for both sleep and deep sleep modes.
|
||||
*
|
||||
* The type of sleep that was actually used by sleep_manager_sleep_auto()
|
||||
* can be detected by comparing times measured by us and lp tickers.
|
||||
*/
|
||||
void test_sleep_auto()
|
||||
{
|
||||
const ticker_info_t *us_ticker_info = get_us_ticker_data()->interface->get_info();
|
||||
const unsigned us_ticker_mask = ((1 << us_ticker_info->bits) - 1);
|
||||
const ticker_irq_handler_type us_ticker_irq_handler_org = set_us_ticker_irq_handler(us_ticker_isr);
|
||||
const ticker_info_t *lp_ticker_info = get_lp_ticker_data()->interface->get_info();
|
||||
const unsigned lp_ticker_mask = ((1 << lp_ticker_info->bits) - 1);
|
||||
const ticker_irq_handler_type lp_ticker_irq_handler_org = set_lp_ticker_irq_handler(lp_ticker_isr);
|
||||
us_timestamp_t us_ts1, us_ts2, lp_ts1, lp_ts2, us_diff1, us_diff2, lp_diff1, lp_diff2;
|
||||
|
||||
sleep_manager_lock_deep_sleep();
|
||||
uint32_t lp_wakeup_ts_raw = lp_ticker_read() + us_to_ticks(SLEEP_DURATION_US, lp_ticker_info->frequency);
|
||||
timestamp_t lp_wakeup_ts = overflow_protect(lp_wakeup_ts_raw, lp_ticker_info->bits);
|
||||
lp_ticker_set_interrupt(lp_wakeup_ts);
|
||||
us_ts1 = ticks_to_us(us_ticker_read(), us_ticker_info->frequency);
|
||||
lp_ts1 = ticks_to_us(lp_ticker_read(), lp_ticker_info->frequency);
|
||||
|
||||
sleep_manager_sleep_auto();
|
||||
us_ts2 = ticks_to_us(us_ticker_read(), us_ticker_info->frequency);
|
||||
us_diff1 = (us_ts1 <= us_ts2) ? (us_ts2 - us_ts1) : (us_ticker_mask - us_ts1 + us_ts2 + 1);
|
||||
lp_ts2 = ticks_to_us(lp_ticker_read(), lp_ticker_info->frequency);
|
||||
lp_diff1 = (lp_ts1 <= lp_ts2) ? (lp_ts2 - lp_ts1) : (lp_ticker_mask - lp_ts1 + lp_ts2 + 1);
|
||||
|
||||
// Deep sleep locked -- ordinary sleep mode used:
|
||||
// * us_ticker powered ON,
|
||||
// * lp_ticker powered ON,
|
||||
// so both should increment equally.
|
||||
|
||||
// Verify us and lp tickers incremented equally, with 10% tolerance.
|
||||
TEST_ASSERT_UINT64_WITHIN_MESSAGE(
|
||||
SLEEP_DURATION_US / 10ULL, lp_diff1, us_diff1,
|
||||
"Deep sleep mode locked, but still used");
|
||||
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep());
|
||||
|
||||
// Wait for hardware serial buffers to flush.
|
||||
busy_wait_ms(SERIAL_FLUSH_TIME_MS);
|
||||
|
||||
lp_wakeup_ts_raw = lp_ticker_read() + us_to_ticks(SLEEP_DURATION_US, lp_ticker_info->frequency);
|
||||
lp_wakeup_ts = overflow_protect(lp_wakeup_ts_raw, lp_ticker_info->bits);
|
||||
lp_ticker_set_interrupt(lp_wakeup_ts);
|
||||
us_ts1 = ticks_to_us(us_ticker_read(), us_ticker_info->frequency);
|
||||
lp_ts1 = ticks_to_us(lp_ticker_read(), lp_ticker_info->frequency);
|
||||
|
||||
sleep_manager_sleep_auto();
|
||||
us_ts2 = ticks_to_us(us_ticker_read(), us_ticker_info->frequency);
|
||||
us_diff2 = (us_ts1 <= us_ts2) ? (us_ts2 - us_ts1) : (us_ticker_mask - us_ts1 + us_ts2 + 1);
|
||||
lp_ts2 = ticks_to_us(lp_ticker_read(), lp_ticker_info->frequency);
|
||||
lp_diff2 = (lp_ts1 <= lp_ts2) ? (lp_ts2 - lp_ts1) : (lp_ticker_mask - lp_ts1 + lp_ts2 + 1);
|
||||
|
||||
// Deep sleep unlocked -- deep sleep mode used:
|
||||
// * us_ticker powered OFF,
|
||||
// * lp_ticker powered ON.
|
||||
// The us_ticker increment represents only the code execution time
|
||||
// and should be much shorter than both:
|
||||
// 1. current lp_ticker increment,
|
||||
// 2. previous us_ticker increment (locked sleep test above)
|
||||
|
||||
// Verify that the current us_ticker increment:
|
||||
// 1. is at most 10% of lp_ticker increment
|
||||
// 2. is at most 10% of previous us_ticker increment.
|
||||
TEST_ASSERT_MESSAGE(us_diff2 < lp_diff2 / 10ULL, "Deep sleep mode unlocked, but not used");
|
||||
TEST_ASSERT_MESSAGE(us_diff2 < us_diff1 / 10ULL, "Deep sleep mode unlocked, but not used");
|
||||
|
||||
set_us_ticker_irq_handler(us_ticker_irq_handler_org);
|
||||
set_lp_ticker_irq_handler(lp_ticker_irq_handler_org);
|
||||
}
|
||||
#endif
|
||||
|
||||
void test_lock_unlock_test_check()
|
||||
{
|
||||
// Make sure HAL tickers are initialized.
|
||||
ticker_read(get_us_ticker_data());
|
||||
ticker_read(get_lp_ticker_data());
|
||||
|
||||
// Use LowPowerTimer instead of Timer to prevent deep sleep lock.
|
||||
LowPowerTimer lp_timer;
|
||||
us_timestamp_t exec_time_unlocked, exec_time_locked;
|
||||
LowPowerTimeout lp_timeout;
|
||||
|
||||
// Deep sleep unlocked:
|
||||
// * sleep_manager_can_deep_sleep() returns true,
|
||||
// * sleep_manager_can_deep_sleep_test_check() returns true instantly.
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep());
|
||||
lp_timer.start();
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check());
|
||||
lp_timer.stop();
|
||||
exec_time_unlocked = lp_timer.read_high_resolution_us();
|
||||
|
||||
// Deep sleep locked:
|
||||
// * sleep_manager_can_deep_sleep() returns false,
|
||||
// * sleep_manager_can_deep_sleep_test_check() returns false with 2 ms delay.
|
||||
sleep_manager_lock_deep_sleep();
|
||||
TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep());
|
||||
lp_timer.reset();
|
||||
lp_timer.start();
|
||||
TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep_test_check());
|
||||
lp_timer.stop();
|
||||
exec_time_locked = lp_timer.read_high_resolution_us();
|
||||
TEST_ASSERT_UINT64_WITHIN(DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US, DEEP_SLEEP_TEST_CHECK_WAIT_US,
|
||||
exec_time_locked - exec_time_unlocked);
|
||||
|
||||
// Deep sleep unlocked with a 1 ms delay:
|
||||
// * sleep_manager_can_deep_sleep() returns false,
|
||||
// * sleep_manager_can_deep_sleep_test_check() returns true with a 1 ms delay,
|
||||
// * sleep_manager_can_deep_sleep() returns true when checked again.
|
||||
lp_timer.reset();
|
||||
lp_timeout.attach_us(mbed::callback(sleep_manager_unlock_deep_sleep_internal),
|
||||
DEEP_SLEEP_TEST_CHECK_WAIT_US / 2);
|
||||
lp_timer.start();
|
||||
TEST_ASSERT_FALSE(sleep_manager_can_deep_sleep());
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep_test_check());
|
||||
lp_timer.stop();
|
||||
TEST_ASSERT_UINT64_WITHIN(DEEP_SLEEP_TEST_CHECK_WAIT_DELTA_US, DEEP_SLEEP_TEST_CHECK_WAIT_US / 2,
|
||||
lp_timer.read_high_resolution_us());
|
||||
TEST_ASSERT_TRUE(sleep_manager_can_deep_sleep());
|
||||
}
|
||||
#endif
|
||||
|
||||
utest::v1::status_t testsuite_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(10, "default_auto");
|
||||
return utest::v1::greentea_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("sleep manager - deep sleep counter", sleep_manager_deepsleep_counter_test, greentea_failure_handler),
|
||||
Case("deep sleep lock/unlock", test_lock_unlock),
|
||||
Case("deep sleep locked USHRT_MAX times", test_lock_eq_ushrt_max),
|
||||
#if DEVICE_LPTICKER
|
||||
#if DEVICE_USTICKER
|
||||
Case("sleep_auto calls sleep/deep sleep based on lock",
|
||||
(utest::v1::case_setup_handler_t) testcase_setup,
|
||||
test_sleep_auto,
|
||||
(utest::v1::case_teardown_handler_t) testcase_teardown),
|
||||
#endif
|
||||
Case("deep sleep lock/unlock test_check", test_lock_unlock_test_check),
|
||||
#endif
|
||||
};
|
||||
|
||||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
|
||||
Specification specification(testsuite_setup, cases);
|
||||
|
||||
int main()
|
||||
{
|
||||
Harness::run(specification);
|
||||
return !Harness::run(specification);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup hal_sleep_manager_tests
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef MBED_HAL_SLEEP_MANAGER_API_TESTS_H
|
||||
#define MBED_HAL_SLEEP_MANAGER_API_TESTS_H
|
||||
|
||||
#if DEVICE_SLEEP
|
||||
|
||||
/** Test lock/unlock
|
||||
*
|
||||
* Given no prior calls to lock/unlock
|
||||
* When the deep sleep status is checked
|
||||
* Then the deep sleep is allowed
|
||||
*
|
||||
* When the lock function is called
|
||||
* Then the deep sleep is not allowed
|
||||
*
|
||||
* When the unlock function is called
|
||||
* Then the deep sleep is allowed again
|
||||
*/
|
||||
void test_lock_unlock();
|
||||
|
||||
/** Test lock USHRT_MAX times
|
||||
*
|
||||
* Given a device with sleep mode support
|
||||
* When deep sleep mode is locked USHRT_MAX times
|
||||
* Then the deep sleep mode is locked
|
||||
*
|
||||
* When unlock is called repeatedly
|
||||
* Then deep sleep mode stays locked until the number
|
||||
* of unlock calls is equal to number of lock calls
|
||||
*/
|
||||
void test_lock_eq_ushrt_max();
|
||||
|
||||
/** Test sleep_auto calls sleep and deep sleep based on lock
|
||||
*
|
||||
* Given a device with sleep mode support
|
||||
* When the deep sleep mode is locked
|
||||
* Then sleep_auto uses sleep mode
|
||||
*
|
||||
* When the deep sleep mode is unlocked
|
||||
* Then sleep_auto uses deep sleep mode
|
||||
*/
|
||||
void test_sleep_auto();
|
||||
|
||||
/** Test lock/unlock test_check fun
|
||||
*
|
||||
* Given the deep sleep has not been locked
|
||||
* When the deep sleep status is checked
|
||||
* Then sleep_manager_can_deep_sleep() returns true
|
||||
* and sleep_manager_can_deep_sleep_test_check() returns true instantly.
|
||||
*
|
||||
* When the deep sleep mode is locked
|
||||
* Then sleep_manager_can_deep_sleep() returns false
|
||||
* and sleep_manager_can_deep_sleep_test_check() returns false with 2 ms delay.
|
||||
*
|
||||
* When the deep sleep mode is unlocked with a 1 ms delay
|
||||
* Then sleep_manager_can_deep_sleep() returns false
|
||||
* and sleep_manager_can_deep_sleep_test_check() returns true with 1 ms delay
|
||||
* and sleep_manager_can_deep_sleep() returns true when checked again.
|
||||
*/
|
||||
void test_lock_unlock_test_check();
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
|
|
@ -13,10 +13,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "utest/utest.h"
|
||||
#include "unity/unity.h"
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "mbed.h"
|
||||
#include "sleep_manager_api_racecondition_tests.h"
|
||||
|
||||
#if !DEVICE_SLEEP
|
||||
#error [NOT_SUPPORTED] test not supported
|
||||
|
|
@ -34,7 +35,7 @@ void sleep_manager_locking_thread_test()
|
|||
{
|
||||
for (uint32_t i = 0; i < 100; i++) {
|
||||
sleep_manager_lock_deep_sleep();
|
||||
Thread::wait(25);
|
||||
ThisThread::sleep_for(25);
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
}
|
||||
|
|
@ -47,7 +48,7 @@ void sleep_manager_multithread_test()
|
|||
Thread t2(osPriorityNormal, TEST_STACK_SIZE);
|
||||
|
||||
t1.start(callback(cb));
|
||||
Thread::wait(25);
|
||||
ThisThread::sleep_for(25);
|
||||
t2.start(callback(cb));
|
||||
|
||||
// Wait for the threads to finish
|
||||
|
|
@ -94,8 +95,8 @@ utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
|||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("sleep manager HAL - locking multithreaded", sleep_manager_multithread_test),
|
||||
Case("sleep manager HAL - locking IRQ", sleep_manager_irq_test),
|
||||
Case("deep sleep lock/unlock is thread safe", sleep_manager_multithread_test),
|
||||
Case("deep sleep lock/unlock is IRQ safe", sleep_manager_irq_test),
|
||||
};
|
||||
|
||||
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup hal_sleep_manager_tests
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef MBED_HAL_SLEEP_MANAGER_API_RACECONDITION_TESTS_H
|
||||
#define MBED_HAL_SLEEP_MANAGER_API_RACECONDITION_TESTS_H
|
||||
|
||||
/** Test lock/unlock is thread safe
|
||||
*
|
||||
* Given a device with sleep mode support
|
||||
* When multiple threads are using the sleep manager API
|
||||
* Then lock/unlock calls are thread safe
|
||||
*/
|
||||
void sleep_manager_multithread_test();
|
||||
|
||||
/** Test lock/unlock is IRQ safe
|
||||
*
|
||||
* Given a device with sleep mode support
|
||||
* When the sleep manager API is used from IRQ and the main thread concurrently
|
||||
* Then lock/unlock calls are IRQ safe
|
||||
*/
|
||||
void sleep_manager_irq_test();
|
||||
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
|
|
@ -72,10 +72,10 @@ base64_result_e trng_DecodeNBase64(const char *string,
|
|||
}
|
||||
|
||||
*writePtr = 0;
|
||||
while (( currPos < stringMaxSize ) &&
|
||||
( string[currPos] != 0 ) &&
|
||||
( writePtr < bufferEnd ) &&
|
||||
( !isEndOfString )) {
|
||||
while ((currPos < stringMaxSize) &&
|
||||
(string[currPos] != 0) &&
|
||||
(writePtr < bufferEnd) &&
|
||||
(!isEndOfString)) {
|
||||
uint8_t val;
|
||||
|
||||
if (string[currPos] == 0) {
|
||||
|
|
@ -125,11 +125,11 @@ base64_result_e trng_DecodeNBase64(const char *string,
|
|||
}
|
||||
|
||||
// Check if additional bytes should have been processed but buffer isn't sufficient.
|
||||
if (( result == BASE64_SUCCESS ) &&
|
||||
( !isEndOfString ) &&
|
||||
( currPos < stringMaxSize ) &&
|
||||
( string[currPos] != 0 ) &&
|
||||
( string[currPos] != '=' ) ) {
|
||||
if ((result == BASE64_SUCCESS) &&
|
||||
(!isEndOfString) &&
|
||||
(currPos < stringMaxSize) &&
|
||||
(string[currPos] != 0) &&
|
||||
(string[currPos] != '=')) {
|
||||
return BASE64_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ static int fill_buffer_trng(uint8_t *buffer, trng_t *trng_obj, size_t trng_len)
|
|||
|
||||
void print_array(uint8_t *buffer, size_t size)
|
||||
{
|
||||
for (size_t i=0; i < size; i++) {
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
utest_printf("%02x", buffer[i]);
|
||||
}
|
||||
utest_printf("\n");
|
||||
|
|
@ -120,7 +120,7 @@ static void compress_and_compare(char *key, char *value)
|
|||
uint32_t lengthWritten = 0;
|
||||
uint32_t charsProcessed = 0;
|
||||
result = trng_DecodeNBase64((const char *)value,
|
||||
MSG_VALUE_LEN,
|
||||
MSG_VALUE_LEN,
|
||||
buffer,
|
||||
BUFFER_LEN,
|
||||
&lengthWritten,
|
||||
|
|
@ -143,11 +143,11 @@ static void compress_and_compare(char *key, char *value)
|
|||
(char *)out_comp_buf,
|
||||
OUT_COMP_BUF_SIZE,
|
||||
9);
|
||||
if (comp_sz <= BUFFER_LEN){
|
||||
print_array(buffer, BUFFER_LEN);
|
||||
if (comp_sz <= BUFFER_LEN) {
|
||||
print_array(buffer, BUFFER_LEN);
|
||||
}
|
||||
TEST_ASSERT_MESSAGE(comp_sz > BUFFER_LEN,
|
||||
"TRNG_TEST_STEP1: trng_get_bytes was able to compress thus not random");
|
||||
"TRNG_TEST_STEP1: trng_get_bytes was able to compress thus not random");
|
||||
|
||||
/*pithy_Compress will try to compress the random data with a different buffer size*/
|
||||
result = fill_buffer_trng(temp_buf, &trng_obj, TEMP_BUF_SIZE);
|
||||
|
|
@ -158,11 +158,11 @@ static void compress_and_compare(char *key, char *value)
|
|||
(char *)out_comp_buf,
|
||||
OUT_COMP_BUF_SIZE,
|
||||
9);
|
||||
if (comp_sz <= TEMP_BUF_SIZE){
|
||||
print_array(temp_buf, TEMP_BUF_SIZE);
|
||||
if (comp_sz <= TEMP_BUF_SIZE) {
|
||||
print_array(temp_buf, TEMP_BUF_SIZE);
|
||||
}
|
||||
TEST_ASSERT_MESSAGE(comp_sz > TEMP_BUF_SIZE,
|
||||
"TRNG_TEST_STEP2: trng_get_bytes was able to compress thus not random");
|
||||
"TRNG_TEST_STEP2: trng_get_bytes was able to compress thus not random");
|
||||
|
||||
memcpy(input_buf + BUFFER_LEN, temp_buf, TEMP_BUF_SIZE);
|
||||
/*pithy_Compress will try to compress the random data from before reset concatenated with new random data*/
|
||||
|
|
@ -171,11 +171,11 @@ static void compress_and_compare(char *key, char *value)
|
|||
(char *)out_comp_buf,
|
||||
OUT_COMP_BUF_SIZE,
|
||||
9);
|
||||
if (comp_sz <= TEMP_BUF_SIZE + BUFFER_LEN){
|
||||
print_array(input_buf, TEMP_BUF_SIZE + BUFFER_LEN);
|
||||
if (comp_sz <= TEMP_BUF_SIZE + BUFFER_LEN) {
|
||||
print_array(input_buf, TEMP_BUF_SIZE + BUFFER_LEN);
|
||||
}
|
||||
TEST_ASSERT_MESSAGE(comp_sz > TEMP_BUF_SIZE + BUFFER_LEN,
|
||||
"TRNG_TEST_STEP3: concatenated buffer after reset was able to compress thus not random");
|
||||
"TRNG_TEST_STEP3: concatenated buffer after reset was able to compress thus not random");
|
||||
|
||||
greentea_send_kv(MSG_TRNG_TEST_SUITE_ENDED, MSG_VALUE_DUMMY);
|
||||
}
|
||||
|
|
@ -184,9 +184,9 @@ static void compress_and_compare(char *key, char *value)
|
|||
if (strcmp(key, MSG_TRNG_TEST_STEP1) == 0) {
|
||||
int result = 0;
|
||||
/*Using base64 to encode data sending from host*/
|
||||
result = trng_EncodeBase64(buffer,
|
||||
BUFFER_LEN,
|
||||
(char *)out_comp_buf,
|
||||
result = trng_EncodeBase64(buffer,
|
||||
BUFFER_LEN,
|
||||
(char *)out_comp_buf,
|
||||
OUT_COMP_BUF_SIZE);
|
||||
TEST_ASSERT_EQUAL(RESULT_SUCCESS, result);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,14 +18,13 @@
|
|||
|
||||
#include "platform/FileHandle.h"
|
||||
|
||||
|
||||
#define POS_IS_VALID(pos) (pos >= 0 && pos < _end)
|
||||
#define NEW_POS_IS_VALID(pos) (pos >= 0 && pos < (int32_t)FILE_SIZE)
|
||||
#define SEEK_POS_IS_VALID(pos) (pos >= 0 && pos <= _end)
|
||||
#define INVALID_POS (-1)
|
||||
|
||||
template<uint32_t FILE_SIZE>
|
||||
class TestFile : public FileHandle {
|
||||
class TestFile : public mbed::FileHandle {
|
||||
public:
|
||||
TestFile(): _pos(0), _end(0) {}
|
||||
~TestFile() {}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2018 ARM Limited
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "greentea-client/test_env.h"
|
||||
#include "utest/utest.h"
|
||||
#include "unity/unity.h"
|
||||
#include "mbed.h"
|
||||
|
||||
using utest::v1::Case;
|
||||
|
||||
class Loopback : public Stream {
|
||||
public:
|
||||
Loopback(const char *name = NULL) : Stream(name) {}
|
||||
|
||||
protected:
|
||||
virtual int _getc()
|
||||
{
|
||||
return _c;
|
||||
}
|
||||
virtual int _putc(int c)
|
||||
{
|
||||
_c = c;
|
||||
return c;
|
||||
}
|
||||
private:
|
||||
char _c;
|
||||
};
|
||||
|
||||
Loopback loop("loopback");
|
||||
|
||||
void test_putc_getc()
|
||||
{
|
||||
int ret;
|
||||
char char_buf[2] = {'a', 'b'};
|
||||
|
||||
ret = loop.putc(char_buf[0]);
|
||||
TEST_ASSERT_EQUAL_INT(char_buf[0], ret);
|
||||
ret = loop.getc();
|
||||
TEST_ASSERT_EQUAL_INT(char_buf[0], ret);
|
||||
ret = loop.putc(char_buf[1]);
|
||||
TEST_ASSERT_EQUAL_INT(char_buf[1], ret);
|
||||
ret = loop.getc();
|
||||
TEST_ASSERT_EQUAL_INT(char_buf[1], ret);
|
||||
return;
|
||||
}
|
||||
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(10, "default_auto");
|
||||
return utest::v1::verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("Test putc/getc", test_putc_getc)
|
||||
};
|
||||
|
||||
utest::v1::Specification specification(test_setup, cases);
|
||||
|
||||
int main()
|
||||
{
|
||||
return !utest::v1::Harness::run(specification);
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ void get_cpu_usage()
|
|||
uint8_t usage = 100 - ((diff * 100) / (SAMPLE_TIME * 1000));
|
||||
prev_idle_time = stats.idle_time;
|
||||
TEST_ASSERT_NOT_EQUAL(0, usage);
|
||||
Thread::wait(SAMPLE_TIME);
|
||||
ThisThread::sleep_for(SAMPLE_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ void test_cpu_info(void)
|
|||
mbed_stats_cpu_t stats;
|
||||
// Additional read to make sure timer is initialized
|
||||
mbed_stats_cpu_get(&stats);
|
||||
Thread::wait(3);
|
||||
ThisThread::sleep_for(3);
|
||||
mbed_stats_cpu_get(&stats);
|
||||
TEST_ASSERT_NOT_EQUAL(0, stats.uptime);
|
||||
TEST_ASSERT_NOT_EQUAL(0, stats.idle_time);
|
||||
|
|
@ -83,7 +83,7 @@ void test_cpu_load(void)
|
|||
|
||||
// Steadily increase the system load
|
||||
for (int count = 1; ; count++) {
|
||||
Thread::wait(LOOP_TIME);
|
||||
ThisThread::sleep_for(LOOP_TIME);
|
||||
if (wait_time <= 0) {
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,11 +66,13 @@ void test_case_malloc_free_size()
|
|||
TEST_ASSERT_EQUAL_UINT32(stats_start.total_size + ALLOCATION_SIZE_DEFAULT * (i + 1), stats_current.total_size);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_cnt + 1, stats_current.alloc_cnt);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt, stats_current.alloc_fail_cnt);
|
||||
|
||||
// Library header 0x4-0x8, stats header 0x8 and alignment addition 0x4
|
||||
TEST_ASSERT_INT_WITHIN(0x8, stats_start.overhead_size + 0xC, stats_current.overhead_size);
|
||||
// Free memory and assert back to starting size
|
||||
free(data);
|
||||
mbed_stats_heap_get(&stats_current);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.current_size, stats_current.current_size);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.overhead_size, stats_current.overhead_size);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_cnt, stats_current.alloc_cnt);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt, stats_current.alloc_fail_cnt);
|
||||
}
|
||||
|
|
@ -93,10 +95,14 @@ void test_case_allocate_zero()
|
|||
TEST_ASSERT_EQUAL_UINT32(stats_start.current_size, stats_current.current_size);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.total_size, stats_current.total_size);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt, stats_current.alloc_fail_cnt);
|
||||
|
||||
// Library header 0x4-0x8, stats header 0x8 and alignment addition 0x4
|
||||
if (NULL != data) {
|
||||
TEST_ASSERT_INT_WITHIN(0x8, stats_start.overhead_size + 0xC, stats_current.overhead_size);
|
||||
}
|
||||
// Free memory and assert back to starting size
|
||||
free(data);
|
||||
mbed_stats_heap_get(&stats_current);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.overhead_size, stats_current.overhead_size);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.current_size, stats_current.current_size);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_cnt, stats_current.alloc_cnt);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt, stats_current.alloc_fail_cnt);
|
||||
|
|
@ -121,6 +127,7 @@ void test_case_allocate_fail()
|
|||
TEST_ASSERT_EQUAL_UINT32(stats_start.total_size, stats_current.total_size);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_cnt, stats_current.alloc_cnt);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.alloc_fail_cnt + i + 1, stats_current.alloc_fail_cnt);
|
||||
TEST_ASSERT_EQUAL_UINT32(stats_start.overhead_size, stats_current.overhead_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ void increment_with_delay()
|
|||
{
|
||||
while (1) {
|
||||
counter++;
|
||||
Thread::wait(500);
|
||||
ThisThread::sleep_for(500);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ void test_case_multi_threads_blocked()
|
|||
uint32_t ret = ef.set(FLAG_SIGNAL_DEC);
|
||||
TEST_ASSERT_FALSE(ret & osFlagsError);
|
||||
|
||||
Thread::wait(100);
|
||||
ThisThread::sleep_for(100);
|
||||
|
||||
count = mbed_stats_thread_get_each(stats, MAX_THREAD_STATS);
|
||||
TEST_ASSERT_EQUAL(1, (count - old_count));
|
||||
|
|
|
|||
|
|
@ -43,9 +43,9 @@ void test_system_reset()
|
|||
|
||||
int main(void)
|
||||
{
|
||||
GREENTEA_SETUP(2, "system_reset");
|
||||
GREENTEA_SETUP(30, "system_reset");
|
||||
test_system_reset();
|
||||
GREENTEA_TESTSUITE_RESULT(0); // Fail on any error.
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ static const int test_timeout = 40;
|
|||
void update_tick_thread(Mutex *mutex)
|
||||
{
|
||||
while (true) {
|
||||
Thread::wait(1);
|
||||
ThisThread::sleep_for(1);
|
||||
mutex->lock();
|
||||
++elapsed_time_ms;
|
||||
mutex->unlock();
|
||||
|
|
@ -56,7 +56,7 @@ void update_tick_thread(Mutex *mutex)
|
|||
}
|
||||
|
||||
|
||||
/** Tests is to measure the accuracy of Thread::wait() over a period of time
|
||||
/** Tests is to measure the accuracy of ThisThread::sleep_for() over a period of time
|
||||
|
||||
Given
|
||||
a thread updating elapsed_time_ms every milli sec
|
||||
|
|
@ -109,7 +109,7 @@ void test(void)
|
|||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("Test Thread::wait accuracy", test)
|
||||
Case("Test ThisThread::sleep_for accuracy", test)
|
||||
};
|
||||
|
||||
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
|
||||
|
|
|
|||
|
|
@ -48,26 +48,6 @@ using utest::v1::Case;
|
|||
|
||||
Semaphore sync_sem(0, 1);
|
||||
|
||||
/* In order to successfully run this test suite when compiled with --profile=debug
|
||||
* error() has to be redefined as noop.
|
||||
*
|
||||
* EventFlags calls RTX API which uses Event Recorder functionality. When compiled
|
||||
* with MBED_TRAP_ERRORS_ENABLED=1 (set in debug profile) EvrRtxEventFlagsError() calls error()
|
||||
* which aborts test program.
|
||||
*/
|
||||
#if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
|
||||
void error(const char *format, ...)
|
||||
{
|
||||
(void) format;
|
||||
}
|
||||
|
||||
//Override the set_error function to trap the errors
|
||||
mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
|
||||
{
|
||||
return MBED_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
template<uint32_t flags, uint32_t wait_ms>
|
||||
void send_thread(EventFlags *ef)
|
||||
{
|
||||
|
|
@ -75,7 +55,7 @@ void send_thread(EventFlags *ef)
|
|||
const uint32_t flag = flags & (1 << i);
|
||||
if (flag) {
|
||||
ef->set(flag);
|
||||
Thread::wait(wait_ms);
|
||||
ThisThread::sleep_for(wait_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +68,7 @@ void send_thread_sync(EventFlags *ef)
|
|||
if (flag) {
|
||||
sync_sem.wait();
|
||||
ef->set(flag);
|
||||
Thread::wait(wait_ms);
|
||||
ThisThread::sleep_for(wait_ms);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -167,14 +147,18 @@ void test_prohibited(void)
|
|||
|
||||
ev.set(FLAG01 | FLAG02 | FLAG03);
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
flags = ev.clear(PROHIBITED_FLAG);
|
||||
TEST_ASSERT_EQUAL(osFlagsErrorParameter, flags);
|
||||
#endif
|
||||
|
||||
flags = ev.get();
|
||||
TEST_ASSERT_EQUAL(FLAG01 | FLAG02 | FLAG03, flags);
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
flags = ev.set(PROHIBITED_FLAG);
|
||||
TEST_ASSERT_EQUAL(osFlagsErrorParameter, flags);
|
||||
#endif
|
||||
|
||||
flags = ev.get();
|
||||
TEST_ASSERT_EQUAL(FLAG01 | FLAG02 | FLAG03, flags);
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@ void test_heap_allocation_free(void)
|
|||
check_and_free_heap(head, max_allocation_size);
|
||||
|
||||
// Force a task switch so a stack check is performed
|
||||
Thread::wait(10);
|
||||
ThisThread::sleep_for(10);
|
||||
|
||||
printf("Total size dynamically allocated: %luB\n", max_allocation_size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ void send_thread(Mail<mail_t, QUEUE_SIZE> *m)
|
|||
mail->thread_id = thread_id;
|
||||
mail->data = data++;
|
||||
m->put(mail);
|
||||
Thread::wait(wait_ms);
|
||||
ThisThread::sleep_for(wait_ms);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ void receive_thread(Mail<mail_t, queue_size> *m)
|
|||
int result_counter = 0;
|
||||
uint32_t data = thread_id * DATA_BASE;
|
||||
|
||||
Thread::wait(wait_ms);
|
||||
ThisThread::sleep_for(wait_ms);
|
||||
for (uint32_t i = 0; i < queue_size; i++) {
|
||||
osEvent evt = m->get();
|
||||
if (evt.status == osEventMail) {
|
||||
|
|
@ -108,7 +108,7 @@ void test_single_thread_order(void)
|
|||
thread.start(callback(send_thread<THREAD_1_ID, QUEUE_PUT_DELAY_1, QUEUE_SIZE>, &mail_box));
|
||||
|
||||
// wait for some mail to be collected
|
||||
Thread::wait(10);
|
||||
ThisThread::sleep_for(10);
|
||||
|
||||
for (uint32_t i = 0; i < QUEUE_SIZE; i++) {
|
||||
// mail receive (main thread)
|
||||
|
|
@ -150,7 +150,7 @@ void test_multi_thread_order(void)
|
|||
thread3.start(callback(send_thread<THREAD_3_ID, QUEUE_PUT_DELAY_3, 4>, &mail_box));
|
||||
|
||||
// wait for some mail to be collected
|
||||
Thread::wait(10);
|
||||
ThisThread::sleep_for(10);
|
||||
|
||||
for (uint32_t i = 0; i < QUEUE_SIZE; i++) {
|
||||
// mail receive (main thread)
|
||||
|
|
@ -211,7 +211,7 @@ void test_multi_thread_multi_mail_order(void)
|
|||
mail->data = data[id]++;
|
||||
mail_box[id].put(mail);
|
||||
|
||||
Thread::wait(i * 10);
|
||||
ThisThread::sleep_for(i * 10);
|
||||
}
|
||||
|
||||
thread1.join();
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ void test_multithread_allocation(void)
|
|||
|
||||
// Give the test time to run
|
||||
while (test_time--) {
|
||||
Thread::wait(1000);
|
||||
ThisThread::sleep_for(1000);
|
||||
}
|
||||
|
||||
// Join and delete all threads
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ bool manipulate_protected_zone(const int thread_delay)
|
|||
change_counter++;
|
||||
core_util_critical_section_exit();
|
||||
|
||||
Thread::wait(thread_delay);
|
||||
ThisThread::sleep_for(thread_delay);
|
||||
|
||||
core_util_critical_section_enter();
|
||||
changing_counter = false;
|
||||
|
|
@ -100,7 +100,7 @@ void test_multiple_threads(void)
|
|||
|
||||
while (true) {
|
||||
// Thread 1 action
|
||||
Thread::wait(t1_delay);
|
||||
ThisThread::sleep_for(t1_delay);
|
||||
manipulate_protected_zone(t1_delay);
|
||||
|
||||
core_util_critical_section_enter();
|
||||
|
|
@ -199,7 +199,7 @@ void test_dual_thread_lock_lock_thread(Mutex *mutex)
|
|||
|
||||
bool stat = mutex->trylock_for(TEST_DELAY);
|
||||
TEST_ASSERT_EQUAL(false, stat);
|
||||
TEST_ASSERT_UINT32_WITHIN(5000, TEST_DELAY*1000, timer.read_us());
|
||||
TEST_ASSERT_UINT32_WITHIN(5000, TEST_DELAY * 1000, timer.read_us());
|
||||
}
|
||||
|
||||
/** Test dual thread lock
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ using namespace utest::v1;
|
|||
template <uint32_t ms>
|
||||
void thread_put_uint_msg(Queue<uint32_t, 1> *q)
|
||||
{
|
||||
Thread::wait(ms);
|
||||
ThisThread::sleep_for(ms);
|
||||
osStatus stat = q->put((uint32_t *) TEST_UINT_MSG);
|
||||
TEST_ASSERT_EQUAL(osOK, stat);
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ void thread_put_uint_msg(Queue<uint32_t, 1> *q)
|
|||
template <uint32_t ms, uint32_t val>
|
||||
void thread_get_uint_msg(Queue<uint32_t, 1> *q)
|
||||
{
|
||||
Thread::wait(ms);
|
||||
ThisThread::sleep_for(ms);
|
||||
osEvent evt = q->get();
|
||||
TEST_ASSERT_EQUAL(osEventMessage, evt.status);
|
||||
TEST_ASSERT_EQUAL(val, evt.value.v);
|
||||
|
|
|
|||
|
|
@ -77,25 +77,6 @@ void sem_callback(Semaphore *sem)
|
|||
sem->release();
|
||||
}
|
||||
|
||||
/* In order to successfully run this test suite when compiled with --profile=debug
|
||||
* error() has to be redefined as noop.
|
||||
*
|
||||
* RtosTimer calls RTX API which uses Event Recorder functionality. When compiled
|
||||
* with MBED_TRAP_ERRORS_ENABLED=1 (set in debug profile) EvrRtxTimerError() calls error()
|
||||
* which aborts test program.
|
||||
*/
|
||||
#if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
|
||||
void error(const char *format, ...)
|
||||
{
|
||||
(void) format;
|
||||
}
|
||||
|
||||
mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
|
||||
{
|
||||
return MBED_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Test one-shot not restarted when elapsed
|
||||
*
|
||||
* Given a one-shot RtosTimer
|
||||
|
|
@ -121,8 +102,11 @@ void test_oneshot_not_restarted()
|
|||
|
||||
slots = stopwatch.wait_until_stopped(DELAY_MS + DELTA_MS);
|
||||
TEST_ASSERT_EQUAL(0, slots);
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
status = rtostimer.stop();
|
||||
TEST_ASSERT_EQUAL(osErrorResource, status);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Test periodic repeats continuously
|
||||
|
|
@ -160,8 +144,11 @@ void test_periodic_repeats()
|
|||
|
||||
slots = stopwatch.wait_until_stopped(DELAY_MS + DELTA_MS);
|
||||
TEST_ASSERT_EQUAL(0, slots);
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
status = rtostimer.stop();
|
||||
TEST_ASSERT_EQUAL(osErrorResource, status);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Test timer can be started again
|
||||
|
|
@ -185,8 +172,10 @@ void test_start_again()
|
|||
int32_t slots = sem.wait(DELAY_MS + DELTA_MS);
|
||||
TEST_ASSERT_EQUAL(1, slots);
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
status = rtostimer.stop();
|
||||
TEST_ASSERT_EQUAL(osErrorResource, status);
|
||||
#endif
|
||||
|
||||
status = rtostimer.start(DELAY_MS);
|
||||
TEST_ASSERT_EQUAL(osOK, status);
|
||||
|
|
@ -194,8 +183,10 @@ void test_start_again()
|
|||
slots = sem.wait(DELAY_MS + DELTA_MS);
|
||||
TEST_ASSERT_EQUAL(1, slots);
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
status = rtostimer.stop();
|
||||
TEST_ASSERT_EQUAL(osErrorResource, status);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Test timer restart updates delay
|
||||
|
|
@ -228,8 +219,10 @@ void test_restart_updates_delay()
|
|||
TEST_ASSERT_EQUAL(1, slots);
|
||||
TEST_ASSERT_INT_WITHIN(DELTA_MS, DELAY2_MS, stopwatch.read_ms());
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
status = rtostimer.stop();
|
||||
TEST_ASSERT_EQUAL(osErrorResource, status);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Test timer is created in stopped state
|
||||
|
|
@ -241,8 +234,10 @@ void test_restart_updates_delay()
|
|||
void test_created_stopped()
|
||||
{
|
||||
RtosTimer rtostimer(mbed::callback(sem_callback, (Semaphore *) NULL), osTimerOnce);
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
osStatus status = rtostimer.stop();
|
||||
TEST_ASSERT_EQUAL(osErrorResource, status);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Test one-shot can be stopped
|
||||
|
|
@ -269,8 +264,10 @@ void test_stop()
|
|||
slots = sem.wait(DELAY_MS + DELTA_MS);
|
||||
TEST_ASSERT_EQUAL(0, slots);
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
status = rtostimer.stop();
|
||||
TEST_ASSERT_EQUAL(osErrorResource, status);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Test timer started with infinite delay
|
||||
|
|
@ -290,6 +287,7 @@ void test_wait_forever()
|
|||
TEST_ASSERT_EQUAL(osOK, status);
|
||||
}
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
/** Test timer started with zero delay
|
||||
*
|
||||
* Given a one-shot RtosTimer
|
||||
|
|
@ -331,6 +329,7 @@ void test_isr_calls_fail()
|
|||
|
||||
wait_ms(DELAY_MS + DELTA_MS);
|
||||
}
|
||||
#endif // !MBED_TRAP_ERRORS_ENABLED
|
||||
|
||||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
|
|
@ -346,8 +345,10 @@ Case cases[] = {
|
|||
Case("Timer can be stopped", test_stop),
|
||||
Case("Timer is created in stopped state", test_created_stopped),
|
||||
Case("Timer started with infinite delay", test_wait_forever),
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
Case("Timer started with zero delay", test_no_wait),
|
||||
Case("Calls from ISR fail", test_isr_calls_fail)
|
||||
#endif
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ void test_thread(int const *delay)
|
|||
if (sem_lock_failed) {
|
||||
sem_defect = true;
|
||||
}
|
||||
Thread::wait(thread_delay);
|
||||
ThisThread::sleep_for(thread_delay);
|
||||
sem_counter--;
|
||||
change_counter++;
|
||||
two_slots.release();
|
||||
|
|
@ -123,7 +123,7 @@ void test_single_thread()
|
|||
|
||||
res = t.start(callback(single_thread, &data));
|
||||
TEST_ASSERT_EQUAL(osOK, res);
|
||||
Thread::wait(SHORT_WAIT);
|
||||
ThisThread::sleep_for(SHORT_WAIT);
|
||||
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingSemaphore, t.get_state());
|
||||
TEST_ASSERT_EQUAL(0, data.data);
|
||||
|
|
@ -131,7 +131,7 @@ void test_single_thread()
|
|||
res = sem.release();
|
||||
TEST_ASSERT_EQUAL(osOK, res);
|
||||
|
||||
Thread::wait(SHORT_WAIT);
|
||||
ThisThread::sleep_for(SHORT_WAIT);
|
||||
|
||||
TEST_ASSERT_EQUAL(1, data.data);
|
||||
|
||||
|
|
@ -160,7 +160,7 @@ void test_timeout()
|
|||
timer.start();
|
||||
res = t.start(callback(timeout_thread, &sem));
|
||||
TEST_ASSERT_EQUAL(osOK, res);
|
||||
Thread::wait(SHORT_WAIT);
|
||||
ThisThread::sleep_for(SHORT_WAIT);
|
||||
|
||||
TEST_ASSERT_EQUAL(Thread::WaitingSemaphore, t.get_state());
|
||||
|
||||
|
|
|
|||
|
|
@ -46,27 +46,6 @@ struct Sync {
|
|||
Semaphore &sem_child;
|
||||
};
|
||||
|
||||
|
||||
/* In order to successfully run this test suite when compiled with --profile=debug
|
||||
* error() has to be redefined as noop.
|
||||
*
|
||||
* ThreadFlags calls RTX API which uses Event Recorder functionality. When compiled
|
||||
* with MBED_TRAP_ERRORS_ENABLED=1 (set in debug profile) EvrRtxEventFlagsError() calls error()
|
||||
* which aborts test program.
|
||||
*/
|
||||
#if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED
|
||||
void error(const char *format, ...)
|
||||
{
|
||||
(void) format;
|
||||
}
|
||||
|
||||
mbed_error_status_t mbed_error(mbed_error_status_t error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
|
||||
{
|
||||
return MBED_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
template <int32_t signals, uint32_t timeout, int32_t test_val>
|
||||
void run_signal_wait(void)
|
||||
{
|
||||
|
|
@ -103,7 +82,7 @@ void run_wait_clear(Sync *sync)
|
|||
{
|
||||
sync->sem_parent.release();
|
||||
sync->sem_child.wait();
|
||||
int32_t ret = Thread::signal_clr(signals);
|
||||
int32_t ret = ThisThread::flags_clear(signals);
|
||||
TEST_ASSERT_EQUAL(test_val, ret);
|
||||
}
|
||||
|
||||
|
|
@ -114,10 +93,10 @@ void run_double_wait_clear(Sync *sync)
|
|||
|
||||
sync->sem_parent.release();
|
||||
sync->sem_child.wait();
|
||||
ret = Thread::signal_clr(signals1);
|
||||
ret = ThisThread::flags_clear(signals1);
|
||||
TEST_ASSERT_EQUAL(test_val1, ret);
|
||||
|
||||
ret = Thread::signal_clr(signals2);
|
||||
ret = ThisThread::flags_clear(signals2);
|
||||
TEST_ASSERT_EQUAL(test_val2, ret);
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +107,7 @@ void run_loop_wait_clear(Sync *sync)
|
|||
int32_t signal = 1 << i;
|
||||
signals |= signal;
|
||||
sync->sem_child.wait();
|
||||
int32_t ret = Thread::signal_clr(NO_SIGNALS);
|
||||
int32_t ret = ThisThread::flags_clear(NO_SIGNALS);
|
||||
TEST_ASSERT_EQUAL(signals, ret);
|
||||
sync->sem_parent.release();
|
||||
}
|
||||
|
|
@ -214,8 +193,10 @@ void test_set_prohibited(void)
|
|||
sem_parent.wait();
|
||||
t.signal_set(ALL_SIGNALS);
|
||||
|
||||
#if !MBED_TRAP_ERRORS_ENABLED
|
||||
ret = t.signal_set(PROHIBITED_SIGNAL);
|
||||
TEST_ASSERT_EQUAL(osErrorParameter, ret);
|
||||
#endif
|
||||
|
||||
sem_child.release();
|
||||
t.join();
|
||||
|
|
|
|||
|
|
@ -474,7 +474,7 @@ void test_thread_wait()
|
|||
Timer timer;
|
||||
timer.start();
|
||||
|
||||
Thread::wait(150);
|
||||
ThisThread::sleep_for(150);
|
||||
|
||||
TEST_ASSERT_UINT32_WITHIN(50000, 150000, timer.read_us());
|
||||
}
|
||||
|
|
@ -528,7 +528,7 @@ void test_deleted()
|
|||
|
||||
void test_delay_thread()
|
||||
{
|
||||
Thread::wait(50);
|
||||
ThisThread::sleep_for(50);
|
||||
}
|
||||
|
||||
/** Testing thread states: wait delay
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ void test_case_sha256_multi()
|
|||
for (i = 0; i < 32; i++) {
|
||||
printf("%02X", outsum1[i]);
|
||||
}
|
||||
printf("\nawaited result : 248D6A61D20638B8E5C026930C3E6039A33CE45964FF216F6ECEDD19DB06C1\n"); // for abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
|
||||
printf("\nawaited result : 248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1\n"); // for abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq
|
||||
printf("\nreceived result ctx2 : ");
|
||||
for (i = 0; i < 32; i++) {
|
||||
printf("%02X", outsum2[i]);
|
||||
|
|
|
|||
|
|
@ -715,10 +715,9 @@ Call `UDPSocket::sendto()` with invalid parameters.
|
|||
3. Call `UDPSocket:sendto( "", 0, NULL, 0);`
|
||||
4. Call `UDPSocket:sendto(NULL, 9, "hello", 5);`
|
||||
5. Call `UDPSocket:sendto(NULL, 0, "hello", 5);`
|
||||
6. Call `UDPSocket:sendto("echo.mbedcloudtesting.com", 0, "hello", 5);`
|
||||
7. Call `UDPSocket:sendto("echo.mbedcloudtesting.com", 9,NULL, 0);`
|
||||
8. Call `UDPSocket:sendto("echo.mbedcloudtesting.com", 9, "hello", 5);`
|
||||
9. destroy the socket
|
||||
6. Call `UDPSocket:sendto("echo.mbedcloudtesting.com", 9,NULL, 0);`
|
||||
7. Call `UDPSocket:sendto("echo.mbedcloudtesting.com", 9, "hello", 5);`
|
||||
8. destroy the socket
|
||||
|
||||
**Expected result:**
|
||||
|
||||
|
|
@ -990,9 +989,8 @@ Call `TCPSocket::connect()` with invalid parameters.
|
|||
1. Call `TCPSocket:connect( NULL, 9);`
|
||||
2. Call `TCPSocket:connect( "", 9);`
|
||||
3. Call `TCPSocket:connect( "", 0);`
|
||||
4. Call `TCPSocket:connect( "echo.mbedcloudtesting.com", 0);`
|
||||
5. Call `TCPSocket:connect( "echo.mbedcloudtesting.com", 9);`
|
||||
6. destroy the socket
|
||||
4. Call `TCPSocket:connect( "echo.mbedcloudtesting.com", 9);`
|
||||
5. destroy the socket
|
||||
|
||||
**Expected result:**
|
||||
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ Case cases[] = {
|
|||
Case("SYNCHRONOUS_DNS_INVALID", SYNCHRONOUS_DNS_INVALID),
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
Specification specification(test_setup, cases, greentea_continue_handlers);
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ Case cases[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
Specification specification(greentea_setup, cases, greentea_teardown);
|
||||
Specification specification(greentea_setup, cases, greentea_teardown, greentea_continue_handlers);
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ void TCPSOCKET_CONNECT_INVALID()
|
|||
TEST_ASSERT(sock.connect(NULL, 9) < 0);
|
||||
TEST_ASSERT(sock.connect("", 9) < 0);
|
||||
TEST_ASSERT(sock.connect("", 0) < 0);
|
||||
TEST_ASSERT(sock.connect(MBED_CONF_APP_ECHO_SERVER_ADDR, 0) < 0);
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.connect(MBED_CONF_APP_ECHO_SERVER_ADDR, 9));
|
||||
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.close());
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ void TCPSOCKET_ECHOTEST_NONBLOCK()
|
|||
|
||||
tcpsocket_connect_to_echo_srv(sock);
|
||||
sock.set_blocking(false);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
int bytes2send;
|
||||
int sent;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ void TCPSOCKET_ECHOTEST_BURST()
|
|||
{
|
||||
TCPSocket sock;
|
||||
tcpsocket_connect_to_echo_srv(sock);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
// TX buffer to be preserved for comparison
|
||||
fill_tx_buffer_ascii(tcp_global::tx_buffer, BURST_SIZE);
|
||||
|
|
@ -94,7 +94,7 @@ void TCPSOCKET_ECHOTEST_BURST_NONBLOCK()
|
|||
TCPSocket sock;
|
||||
tcpsocket_connect_to_echo_srv(sock);
|
||||
sock.set_blocking(false);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
// TX buffer to be preserved for comparison
|
||||
fill_tx_buffer_ascii(tcp_global::tx_buffer, BURST_SIZE);
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void TCPSOCKET_ENDPOINT_CLOSE()
|
|||
TEST_FAIL();
|
||||
return;
|
||||
}
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
int recvd = 0;
|
||||
int recvd_total = 0;
|
||||
|
|
|
|||
|
|
@ -58,15 +58,19 @@ static nsapi_error_t _tcpsocket_connect_to_chargen_srv(TCPSocket &sock)
|
|||
* \param offset Start pattern from offset
|
||||
* \param len Length of pattern to generate.
|
||||
*/
|
||||
static void generate_RFC_864_pattern(size_t offset, uint8_t *buf, size_t len)
|
||||
static void generate_RFC_864_pattern(size_t offset, uint8_t *buf, size_t len, bool is_xinetd)
|
||||
{
|
||||
const int row_size = 74; // Number of chars in single row
|
||||
const int row_count = 95; // Number of rows in pattern after which pattern start from beginning
|
||||
const int chars_scope = is_xinetd ? 93 : 95; // Number of chars from ASCII table used in pattern
|
||||
const char first_char = is_xinetd ? '!' : ' '; // First char from ASCII table used in pattern
|
||||
while (len--) {
|
||||
if (offset % 74 == 72) {
|
||||
if (offset % row_size == (row_size - 2)) {
|
||||
*buf++ = '\r';
|
||||
} else if (offset % 74 == 73) {
|
||||
} else if (offset % row_size == (row_size - 1)) {
|
||||
*buf++ = '\n';
|
||||
} else {
|
||||
*buf++ = ' ' + (offset % 74 + offset / 74) % 95 ;
|
||||
*buf++ = first_char + (offset % row_size + ((offset / row_size) % row_count)) % chars_scope;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
|
|
@ -74,10 +78,14 @@ static void generate_RFC_864_pattern(size_t offset, uint8_t *buf, size_t len)
|
|||
|
||||
static void check_RFC_864_pattern(void *rx_buff, const size_t len, const size_t offset)
|
||||
{
|
||||
static bool is_xinetd = false;
|
||||
void *ref_buff = malloc(len);
|
||||
TEST_ASSERT_NOT_NULL(ref_buff);
|
||||
|
||||
generate_RFC_864_pattern(offset, (uint8_t *)ref_buff, len);
|
||||
if (offset == 0) {
|
||||
is_xinetd = ((uint8_t *)rx_buff)[0] == '!';
|
||||
}
|
||||
generate_RFC_864_pattern(offset, (uint8_t *)ref_buff, len, is_xinetd);
|
||||
bool match = memcmp(ref_buff, rx_buff, len) == 0;
|
||||
|
||||
free(ref_buff);
|
||||
|
|
@ -170,7 +178,7 @@ void TCPSOCKET_RECV_100K_NONBLOCK()
|
|||
}
|
||||
|
||||
sock.set_blocking(false);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
rcv_n_chk_against_rfc864_pattern_nonblock(sock);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ void TCPSOCKET_RECV_TIMEOUT()
|
|||
TCPSocket sock;
|
||||
tcpsocket_connect_to_echo_srv(sock);
|
||||
sock.set_timeout(100);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
int recvd = 0;
|
||||
int pkt_unrecvd;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ static void check_const_len_rand_sequence()
|
|||
{
|
||||
TCPSocket sock;
|
||||
tcpsocket_connect_to_echo_srv(sock);
|
||||
sock.sigio(callback(_sigio_handler1, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler1, ThisThread::get_id()));
|
||||
|
||||
static const int BUFF_SIZE = 10;
|
||||
static char rx_buff[BUFF_SIZE] = {0};
|
||||
|
|
@ -104,7 +104,7 @@ static void check_var_len_rand_sequence()
|
|||
{
|
||||
TCPSocket sock;
|
||||
tcpsocket_connect_to_echo_srv(sock);
|
||||
sock.sigio(callback(_sigio_handler2, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler2, ThisThread::get_id()));
|
||||
|
||||
static const int BUFF_SIZE = 1001;
|
||||
static char rx_buff[BUFF_SIZE];
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ Case cases[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
Specification specification(greentea_setup, cases, greentea_teardown);
|
||||
Specification specification(greentea_setup, cases, greentea_teardown, greentea_continue_handlers);
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ void UDPSOCKET_ECHOTEST_NONBLOCK()
|
|||
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
|
||||
sock.set_blocking(false);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
int sent;
|
||||
int s_idx = 0;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void UDPSOCKET_ECHOTEST_BURST()
|
|||
const int TIMEOUT = 5000; // [ms]
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
|
||||
sock.set_timeout(TIMEOUT);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
// TX buffers to be preserved for comparison
|
||||
prepare_tx_buffers();
|
||||
|
|
@ -156,7 +156,7 @@ void UDPSOCKET_ECHOTEST_BURST_NONBLOCK()
|
|||
UDPSocket sock;
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
|
||||
sock.set_blocking(false);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
// TX buffers to be preserved for comparison
|
||||
prepare_tx_buffers();
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ void UDPSOCKET_RECV_TIMEOUT()
|
|||
UDPSocket sock;
|
||||
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, sock.open(get_interface()));
|
||||
sock.set_timeout(100);
|
||||
sock.sigio(callback(_sigio_handler, Thread::gettid()));
|
||||
sock.sigio(callback(_sigio_handler, ThisThread::get_id()));
|
||||
|
||||
int recvd;
|
||||
Timer timer;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ void UDPSOCKET_SENDTO_INVALID()
|
|||
TEST_ASSERT(sock.sendto(NULL, 9, NULL, 0) < 0);
|
||||
TEST_ASSERT(sock.sendto("", 9, NULL, 0) < 0);
|
||||
TEST_ASSERT(sock.sendto("", 0, NULL, 0) < 0);
|
||||
TEST_ASSERT_EQUAL(5, sock.sendto(MBED_CONF_APP_ECHO_SERVER_ADDR, 0, "hello", 5));
|
||||
TEST_ASSERT_EQUAL(0, sock.sendto(MBED_CONF_APP_ECHO_SERVER_ADDR, 9, NULL, 0));
|
||||
TEST_ASSERT_EQUAL(5, sock.sendto(MBED_CONF_APP_ECHO_SERVER_ADDR, 9, "hello", 5));
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ using namespace utest::v1;
|
|||
utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
#if !MBED_CONF_APP_ECHO_SERVER
|
||||
GREENTEA_SETUP(1200, "default_auto");
|
||||
GREENTEA_SETUP(1400, "default_auto");
|
||||
#endif
|
||||
return verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,10 +38,10 @@ utest::v1::status_t test_setup(const size_t number_of_cases)
|
|||
}
|
||||
|
||||
Case cases[] = {
|
||||
Case("NETWORKINTERFACE_STATUS", NETWORKINTERFACE_STATUS),
|
||||
Case("NETWORKINTERFACE_STATUS_NONBLOCK", NETWORKINTERFACE_STATUS_NONBLOCK),
|
||||
Case("NETWORKINTERFACE_STATUS_GET", NETWORKINTERFACE_STATUS_GET),
|
||||
Case("NETWORKINTERFACE_CONN_DISC_REPEAT", NETWORKINTERFACE_CONN_DISC_REPEAT),
|
||||
Case("NETWORKINTERFACE_STATUS", NETWORKINTERFACE_STATUS),
|
||||
Case("NETWORKINTERFACE_STATUS_NONBLOCK", NETWORKINTERFACE_STATUS_NONBLOCK),
|
||||
Case("NETWORKINTERFACE_STATUS_GET", NETWORKINTERFACE_STATUS_GET),
|
||||
Case("NETWORKINTERFACE_CONN_DISC_REPEAT", NETWORKINTERFACE_CONN_DISC_REPEAT),
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
|
|
|
|||
|
|
@ -23,10 +23,9 @@
|
|||
|
||||
using namespace utest::v1;
|
||||
|
||||
namespace
|
||||
{
|
||||
NetworkInterface* net;
|
||||
const int repeats = 5;
|
||||
namespace {
|
||||
NetworkInterface *net;
|
||||
const int repeats = 5;
|
||||
}
|
||||
|
||||
void NETWORKINTERFACE_CONN_DISC_REPEAT()
|
||||
|
|
|
|||
|
|
@ -23,16 +23,15 @@
|
|||
|
||||
using namespace utest::v1;
|
||||
|
||||
namespace
|
||||
{
|
||||
NetworkInterface* net;
|
||||
rtos::Semaphore status_semaphore;
|
||||
int status_write_counter = 0;
|
||||
int status_read_counter = 0;
|
||||
const int repeats = 5;
|
||||
const int status_buffer_size = 100;
|
||||
nsapi_connection_status_t current_status = NSAPI_STATUS_ERROR_UNSUPPORTED;
|
||||
nsapi_connection_status_t statuses[status_buffer_size];
|
||||
namespace {
|
||||
NetworkInterface *net;
|
||||
rtos::Semaphore status_semaphore;
|
||||
int status_write_counter = 0;
|
||||
int status_read_counter = 0;
|
||||
const int repeats = 5;
|
||||
const int status_buffer_size = 100;
|
||||
nsapi_connection_status_t current_status = NSAPI_STATUS_ERROR_UNSUPPORTED;
|
||||
nsapi_connection_status_t statuses[status_buffer_size];
|
||||
}
|
||||
|
||||
void status_cb(nsapi_event_t event, intptr_t value)
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ Case cases[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
Specification specification(test_setup, cases);
|
||||
Specification specification(test_setup, cases, greentea_continue_handlers);
|
||||
|
||||
// Entry point into the tests
|
||||
int main()
|
||||
|
|
|
|||
|
|
@ -25,13 +25,27 @@ using namespace utest::v1;
|
|||
|
||||
#if defined(MBED_CONF_APP_WIFI_UNSECURE_SSID)
|
||||
|
||||
#define SSID_MAX_LEN 32
|
||||
|
||||
void wifi_connect(void)
|
||||
{
|
||||
WiFiInterface *wifi = get_interface();
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->set_credentials(MBED_CONF_APP_WIFI_UNSECURE_SSID, NULL));
|
||||
char ssid[SSID_MAX_LEN + 1] = MBED_CONF_APP_WIFI_UNSECURE_SSID;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->set_credentials(ssid, NULL));
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->connect());
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->disconnect());
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->set_credentials(ssid, ""));
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->connect());
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->disconnect());
|
||||
|
||||
// Driver is expected to cache the credentials
|
||||
memset(ssid, 0, SSID_MAX_LEN + 1);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->connect());
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_ERROR_OK, wifi->disconnect());
|
||||
}
|
||||
|
||||
#endif // defined(MBED_CONF_APP_WIFI_UNSECURE_SSID)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ void wifi_connect_params_channel_fail(void)
|
|||
return;
|
||||
}
|
||||
|
||||
nsapi_error_t error = wifi->connect(MBED_CONF_APP_WIFI_SECURE_SSID, MBED_CONF_APP_WIFI_PASSWORD, get_security(), MBED_CONF_APP_WIFI_CH_UNSECURE);
|
||||
uint8_t wrong_channel = 1 + (MBED_CONF_APP_WIFI_CH_SECURE % 10);
|
||||
nsapi_error_t error = wifi->connect(MBED_CONF_APP_WIFI_SECURE_SSID, MBED_CONF_APP_WIFI_PASSWORD, get_security(), wrong_channel);
|
||||
TEST_ASSERT(error == NSAPI_ERROR_CONNECTION_TIMEOUT || error == NSAPI_ERROR_NO_CONNECTION);
|
||||
|
||||
wifi->set_channel(0);
|
||||
|
|
|
|||
|
|
@ -48,25 +48,18 @@ void wifi_scan(void)
|
|||
const char *ssid = ap[i].get_ssid();
|
||||
nsapi_security_t security = ap[i].get_security();
|
||||
int8_t rssi = ap[i].get_rssi();
|
||||
uint8_t ch = ap[i].get_channel();
|
||||
TEST_ASSERT_INT8_WITHIN(-10, -100, rssi);
|
||||
if (strcmp(MBED_CONF_APP_WIFI_SECURE_SSID, ssid) == 0) {
|
||||
secure_found = true;
|
||||
TEST_ASSERT_EQUAL_INT(get_security(), security);
|
||||
if (MBED_CONF_APP_WIFI_CH_SECURE) {
|
||||
TEST_ASSERT_EQUAL_INT(MBED_CONF_APP_WIFI_CH_SECURE, ch);
|
||||
}
|
||||
}
|
||||
if (strcmp(MBED_CONF_APP_WIFI_UNSECURE_SSID, ssid) == 0) {
|
||||
unsecure_found = true;
|
||||
TEST_ASSERT_EQUAL_INT(NSAPI_SECURITY_NONE, security);
|
||||
if (MBED_CONF_APP_WIFI_CH_UNSECURE) {
|
||||
TEST_ASSERT_EQUAL_INT(MBED_CONF_APP_WIFI_CH_UNSECURE, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
TEST_ASSERT_TRUE(secure_found);
|
||||
TEST_ASSERT_TRUE(unsecure_found);
|
||||
// Finding one SSID is enough
|
||||
TEST_ASSERT_TRUE(secure_found || unsecure_found);
|
||||
}
|
||||
|
||||
#endif // defined(MBED_CONF_APP_WIFI_SECURE_SSID) && defined(MBED_CONF_APP_WIFI_UNSECURE_SSID)
|
||||
|
|
|
|||
|
|
@ -69,5 +69,6 @@ void wifi_set_channel(void)
|
|||
TEST_ASSERT(error == NSAPI_ERROR_PARAMETER);
|
||||
}
|
||||
|
||||
wifi->set_channel(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
# Nanostack MAC test application
|
||||
|
||||
You can use this application to test the Nanostack RF driver implementations that follow the [Nanostack RF driver porting instructions](https://os.mbed.com/docs/v5.6/reference/contributing-connectivity.html#porting-new-rf-driver-for-6lowpan-stack). The application has a command-line interface that is used to send commands to Nanostack's MAC layer, for example starting PANs, scanning or sending data. The provided tests do not test performance or stability and only indirectly test RF functionalities.
|
||||
|
||||
## Table of contents
|
||||
|
||||
* [Prerequisites](#prerequisites)
|
||||
* [Setting up the application](#setting-up-the-application)
|
||||
* [Application usage](#application-usage)
|
||||
* [Interactive mode](#interactive-mode)
|
||||
* [Automated mode](#automated-mode)
|
||||
* [Testcases](#testcases)
|
||||
* [Considerations](#considerations)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* [Mbed CLI](https://github.com/ARMmbed/mbed-cli).
|
||||
* Mbed OS target board with build in radio, OR RF shield with Mbed OS driver
|
||||
|
||||
## Setting up the application
|
||||
|
||||
### Add your RF driver
|
||||
|
||||
When using RF shield, you need to configure it to be a default RF driver and instruct Mbed OS that RF driver is present. For example, configuring Atmel RF driver to provide default driver:
|
||||
|
||||
```
|
||||
"target_overrides": {
|
||||
"*": {
|
||||
"target.device_has_add": ["802_15_4_RF_PHY"],
|
||||
"atmel-rf.provide-default": true
|
||||
```
|
||||
|
||||
### Checking platform support
|
||||
|
||||
Check that your choice of platform is supported by your choice of toolchain:
|
||||
|
||||
```
|
||||
mbed compile --supported
|
||||
```
|
||||
|
||||
<span class="notes">**Note:** Targets are often abbreviated from the full model names. In the case of `FRDM-K64F` the target is `K64F`.</span>
|
||||
|
||||
## Run tests
|
||||
|
||||
You can use this application in interactive or automated mode.
|
||||
|
||||
### Interactive mode
|
||||
|
||||
To set the application to interactive mode:
|
||||
|
||||
1. Build the application.
|
||||
```
|
||||
mbed test --compile --icetea -t TOOLCHAIN -m TARGET_PLATFORM -DICETEA_MAC_TESTER_ENABLED --test-config NANOSTACK_MAC_TESTER -n address_read_and_write,send_data,send_data_indirect,send_large_payloads,create_and_join_PAN,ED_scan
|
||||
```
|
||||
2. Connect your board and copy the compiled application binary from the `BUILD/tests/TARGET_PLATFORM/TOOLCHAIN/TEST_APPS/device/nanostack_mac_tester/` folder to the board.
|
||||
3. Wait for the device to flash the binary.
|
||||
4. Open a serial connection with a program such as PuTTY, screen or minicom. The default baudrate is 115200.
|
||||
5. Press the reset button on the board. The Arm Mbed logo and trace appears in the terminal window.
|
||||
|
||||
If the driver registration and SW MAC creation was successful, the application is ready to receive commands.
|
||||
|
||||
To start off, type `help` to list all commands available and furthermore `help <command>` to print detailed information about a specific command.
|
||||
|
||||
### Automated mode
|
||||
|
||||
```
|
||||
mbed test --clean --compile --run --icetea -t TOOLCHAIN -m TARGET_PLATFORM -DICETEA_MAC_TESTER_ENABLED --test-config NANOSTACK_MAC_TESTER -n address_read_and_write,send_data,send_data_indirect,send_large_payloads,create_and_join_PAN,ED_scan
|
||||
```
|
||||
|
||||
Many of the provided testcases have a `self.channel` variable in the `setUp()` function for setting the RF channel. The default channel is 11. If you wish to run a test on another channel, you will need to change it manually in TEST_APPS/testcases/nanostack_mac_tester/.
|
||||
|
||||
Some testcases also use a secondary channel for transmitting and will use the next higher channel for that purpose. If the given channel is 26, the secondary channel will default to 25.
|
||||
|
||||
### Test cases
|
||||
|
||||
The automated test set runs the following testcases included in the repository under `TEST_APPS/testcases/nanostack_mac_tester/`.
|
||||
* Create and join PAN
|
||||
* Direct data transmission(Transmission between two devices)
|
||||
* Indirect data transmission(Transmission between two devices with one device acting as intermediary)
|
||||
* ED scan(Energy Density scanning)
|
||||
* Address read and write
|
||||
* Large data transmission
|
||||
|
||||
### Considerations
|
||||
|
||||
* Devices need to be power cycled if they are unresponsive to test framework commands even after resetting.
|
||||
* Devices can be enclosed in an RF isolation box to improve the consistency of test results.
|
||||
* Some boards and radio modules come with a PCB trace antenna, instead of an SMD antenna, and need to be spaced further apart to decrease interference.
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
#include "mbed.h"
|
||||
#include "rtos.h"
|
||||
#include "sw_mac.h"
|
||||
#include "ns_hal_init.h"
|
||||
#define MBED_CMDLINE_MAX_LINE_LENGTH 250
|
||||
#include "ns_cmdline.h"
|
||||
|
||||
#include "mac_commands.h"
|
||||
|
||||
#define HEAP_FOR_MAC_TESTER_SIZE 10000
|
||||
#define RX_BUFFER_SIZE 512
|
||||
|
||||
#define ATMEL 1
|
||||
#define MCR20 2
|
||||
#define OTHER 3
|
||||
|
||||
#define TRACE_GROUP "Main"
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
|
||||
#include "NanostackRfPhy.h"
|
||||
|
||||
#if !DEVICE_802_15_4_PHY
|
||||
#error [NOT_SUPPORTED] No 802.15.4 RF driver found for this target
|
||||
#endif
|
||||
|
||||
#ifndef ICETEA_MAC_TESTER_ENABLED
|
||||
#error [NOT_SUPPORTED] Skipping Nanostack MAC tester application.
|
||||
#endif
|
||||
|
||||
extern mac_api_s *mac_interface;
|
||||
RawSerial pc(USBTX, USBRX);
|
||||
osThreadId_t main_thread;
|
||||
static CircularBuffer<uint8_t, RX_BUFFER_SIZE> rx_buffer;
|
||||
static uint8_t ns_heap[HEAP_FOR_MAC_TESTER_SIZE];
|
||||
|
||||
static void app_heap_error_handler(heap_fail_t event)
|
||||
{
|
||||
tr_error("Heap error (%d), app_heap_error_handler()", event);
|
||||
switch (event) {
|
||||
case NS_DYN_MEM_NULL_FREE:
|
||||
case NS_DYN_MEM_DOUBLE_FREE:
|
||||
case NS_DYN_MEM_ALLOCATE_SIZE_NOT_VALID:
|
||||
case NS_DYN_MEM_POINTER_NOT_VALID:
|
||||
case NS_DYN_MEM_HEAP_SECTOR_CORRUPTED:
|
||||
case NS_DYN_MEM_HEAP_SECTOR_UNITIALIZED:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
while (1);
|
||||
}
|
||||
|
||||
static void rx_interrupt(void)
|
||||
{
|
||||
uint8_t c = pc.getc();
|
||||
rx_buffer.push(c);
|
||||
if (main_thread != NULL) {
|
||||
osThreadFlagsSet(main_thread, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_rx_data(void)
|
||||
{
|
||||
bool exit = false;
|
||||
uint8_t data;
|
||||
|
||||
while (1) {
|
||||
exit = !rx_buffer.pop(data);
|
||||
if (exit) {
|
||||
break;
|
||||
}
|
||||
cmd_char_input(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int mac_prepare(void)
|
||||
{
|
||||
NanostackRfPhy &rf_phy = NanostackRfPhy::get_default_instance();
|
||||
int8_t rf_driver_id = rf_phy.rf_register();
|
||||
uint8_t rf_eui64[8];
|
||||
|
||||
if (rf_driver_id < 0) {
|
||||
tr_error("Failed to register RF driver.");
|
||||
return -1;
|
||||
}
|
||||
rf_phy.get_mac_address(rf_eui64);
|
||||
mac_description_storage_size_t mac_description;
|
||||
mac_description.device_decription_table_size = DEVICE_DESCRIPTOR_TABLE_SIZE; /** MAC Device description list size */
|
||||
mac_description.key_description_table_size = KEY_DESCRIPTOR_TABLE_SIZE; /** MAC Key description list size */
|
||||
mac_description.key_lookup_size = LOOKUP_DESCRIPTOR_TABLE_SIZE; /** Key description key lookup list size */
|
||||
mac_description.key_usage_size = USAGE_DESCRIPTOR_TABLE_SIZE; /** Key description key usage list size */
|
||||
tr_info("Registered RF driver with id: %hhu, EUI64: %s", rf_driver_id, mbed_trace_array(rf_eui64, 8));
|
||||
mac_interface = ns_sw_mac_create(rf_driver_id, &mac_description);
|
||||
if (!mac_interface) {
|
||||
tr_error("Failed to create SW MAC.");
|
||||
return -2;
|
||||
}
|
||||
|
||||
return mac_interface->mac_initialize(mac_interface, mac_data_confirm_handler,
|
||||
mac_data_indication_handler, mac_purge_confirm_handler, mac_mlme_confirm_handler,
|
||||
mac_mlme_indication_handler, rf_driver_id);
|
||||
}
|
||||
|
||||
static void cmd_ready_cb(int retcode)
|
||||
{
|
||||
cmd_next(retcode);
|
||||
}
|
||||
|
||||
static void trace_printer(const char *str)
|
||||
{
|
||||
printf("%s\n", str);
|
||||
cmd_output();
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
main_thread = ThisThread::get_id();
|
||||
pc.baud(MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
|
||||
pc.attach(rx_interrupt);
|
||||
ns_hal_init(ns_heap, HEAP_FOR_MAC_TESTER_SIZE, app_heap_error_handler, NULL);
|
||||
mbed_trace_init();
|
||||
mbed_trace_print_function_set(trace_printer);
|
||||
cmd_init(&default_cmd_response_out);
|
||||
cmd_set_ready_cb(cmd_ready_cb);
|
||||
mac_commands_init();
|
||||
|
||||
if (mac_prepare() != 0) {
|
||||
return -1;
|
||||
}
|
||||
tr_info("Created driver & SW MAC");
|
||||
|
||||
while (true) {
|
||||
ThisThread::flags_wait_any(1);
|
||||
handle_rx_data();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"macros": ["MBED_TRACE_LINE_LENGTH=200", "OS_TASKCNT=4", "OS_IDLESTKSIZE=32"],
|
||||
"target_overrides": {
|
||||
"*": {
|
||||
"nanostack.configuration": "lowpan_host",
|
||||
"platform.stdio-convert-newlines": true,
|
||||
"platform.stdio-baud-rate": 115200,
|
||||
"mbed-mesh-api.heap-size": 6000,
|
||||
"nanostack-hal.event_loop_thread_stack_size": 2000,
|
||||
"mbed-trace.enable": true,
|
||||
"nsapi.default-stack": "LWIP",
|
||||
"target.device_has_add": ["802_15_4_PHY"],
|
||||
"atmel-rf.provide-default": true
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
#ifndef MAC_COMMANDS_H_
|
||||
#define MAC_COMMANDS_H_
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "ns_cmdline.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "mbed_trace.h"
|
||||
#include "mac_api.h"
|
||||
#include "mlme.h"
|
||||
#include "mac_mcps.h"
|
||||
#include "mac_common_defines.h"
|
||||
#include "mac_filter_api.h"
|
||||
#include "util.h"
|
||||
|
||||
#define LOOKUP_DESCRIPTOR_TABLE_SIZE 2
|
||||
#define DEVICE_DESCRIPTOR_TABLE_SIZE 2
|
||||
#define USAGE_DESCRIPTOR_TABLE_SIZE 2
|
||||
#define KEY_DESCRIPTOR_TABLE_SIZE 2
|
||||
|
||||
void mac_commands_init(void);
|
||||
|
||||
void mac_data_confirm_handler(const mac_api_t *api, const mcps_data_conf_t *data);
|
||||
void mac_data_indication_handler(const mac_api_t *api, const mcps_data_ind_t *data);
|
||||
void mac_purge_confirm_handler(const mac_api_t *api, mcps_purge_conf_t *data);
|
||||
void mac_mlme_confirm_handler(const mac_api_t *api, mlme_primitive id, const void *data);
|
||||
void mac_mlme_indication_handler(const mac_api_t *api, mlme_primitive id, const void *data);
|
||||
|
||||
int mac_start_command(int argc, char *argv[]);
|
||||
int mac_scan_command(int argc, char *argv[]);
|
||||
int mac_data_command(int argc, char *argv[]);
|
||||
int mac_poll_command(int argc, char *argv[]);
|
||||
int mac_purge_command(int argc, char *argv[]);
|
||||
int mac_set_command(int argc, char *argv[]);
|
||||
int mac_get_command(int argc, char *argv[]);
|
||||
int mac_reset_command(int argc, char *argv[]);
|
||||
int mac_address_command(int argc, char *argv[]);
|
||||
int mac_key_command(int argc, char *argv[]);
|
||||
int mac_add_neighbour_command(int argc, char *argv[]);
|
||||
int mac_filter_command(int argc, char *argv[]);
|
||||
int mac_config_status_command(int argc, char *argv[]);
|
||||
int mac_find_beacon_command(int argc, char *argv[]);
|
||||
int mac_wait_command(int argc, char *argv[]);
|
||||
int mac_analyze_ed_command(int argc, char *argv[]);
|
||||
int reset_command(int argc, char *argv[]);
|
||||
int silent_mode_command(int argc, char *argv[]);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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.
|
||||
*/
|
||||
#include "util.h"
|
||||
|
||||
int string_to_bytes(const char *str, uint8_t *buf, int bytes)
|
||||
{
|
||||
int len = strlen(str);
|
||||
|
||||
if (len <= (3 * bytes - 1)) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bytes; ++i) {
|
||||
if (i * 3 < len) {
|
||||
buf[i] = (uint8_t)strtoul(str + i * 3, NULL, 16);
|
||||
} else {
|
||||
buf[i] = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *mlme_status_string(uint8_t status)
|
||||
{
|
||||
switch (status) {
|
||||
case MLME_SUCCESS:
|
||||
return "MLME_SUCCESS";
|
||||
case MLME_BUSY_CHAN:
|
||||
return "MLME_BUSY_CHAN";
|
||||
case MLME_BUSY_RX:
|
||||
return "MLME_BUSY_RX";
|
||||
case MLME_BUSY_TX:
|
||||
return "MLME_BUSY_TX";
|
||||
case MLME_FORCE_TRX_OFF:
|
||||
return "MLME_FORCE_TRX_OFF";
|
||||
case MLME_IDLE:
|
||||
return "MLME_IDLE";
|
||||
case MLME_RX_ON:
|
||||
return "MLME_RX_ON";
|
||||
case MLME_TRX_OFF:
|
||||
return "MLME_TRX_OFF";
|
||||
case MLME_TX_ON:
|
||||
return "MLME_TX_ON";
|
||||
case MLME_COUNTER_ERROR:
|
||||
return "MLME_COUNTER_ERROR";
|
||||
case MLME_IMPROPER_KEY_TYPE:
|
||||
return "MLME_IMPROPER_KEY_TYPE";
|
||||
case MLME_IMPROPER_SECURITY_LEVEL:
|
||||
return "MLME_IMPROPER_SECURITY_LEVEL";
|
||||
case MLME_UNSUPPORTED_LEGACY:
|
||||
return "MLME_UNSUPPORTED_LEGACY";
|
||||
case MLME_UNSUPPORTED_SECURITY:
|
||||
return "MLME_UNSUPPORTED_SECURITY";
|
||||
case MLME_SECURITY_FAIL:
|
||||
return "MLME_SECURITY_FAIL";
|
||||
case MLME_FRAME_TOO_LONG:
|
||||
return "MLME_FRAME_TOO_LONG";
|
||||
case MLME_INVALID_HANDLE:
|
||||
return "MLME_INVALID_HANDLE";
|
||||
case MLME_INVALID_PARAMETER:
|
||||
return "MLME_INVALID_PARAMETER";
|
||||
case MLME_TX_NO_ACK:
|
||||
return "MLME_TX_NO_ACK";
|
||||
case MLME_NO_BEACON:
|
||||
return "MLME_NO_BEACON";
|
||||
case MLME_NO_DATA:
|
||||
return "MLME_NO_DATA";
|
||||
case MLME_NO_SHORT_ADDRESS:
|
||||
return "MLME_NO_SHORT_ADDRESS";
|
||||
case MLME_PAN_ID_CONFLICT:
|
||||
return "MLME_PAN_ID_CONFLICT";
|
||||
case MLME_TRANSACTION_EXPIRED:
|
||||
return "MLME_TRANSACTION_EXPIRED";
|
||||
case MLME_TRANSACTION_OVERFLOW:
|
||||
return "MLME_TRANSACTION_OVERFLOW";
|
||||
case MLME_UNAVAILABLE_KEY:
|
||||
return "MLME_UNAVAILABLE_KEY";
|
||||
case MLME_UNSUPPORTED_ATTRIBUTE:
|
||||
return "MLME_UNSUPPORTED_ATTRIBUTE";
|
||||
case MLME_INVALID_ADDRESS:
|
||||
return "MLME_INVALID_ADDRESS";
|
||||
case MLME_INVALID_INDEX:
|
||||
return "MLME_INVALID_INDEX";
|
||||
case MLME_LIMIT_REACHED:
|
||||
return "MLME_LIMIT_REACHED";
|
||||
case MLME_READ_ONLY:
|
||||
return "MLME_READ_ONLY";
|
||||
case MLME_SCAN_IN_PROGRESS:
|
||||
return "MLME_SCAN_IN_PROGRESS";
|
||||
case MLME_DATA_POLL_NOTIFICATION:
|
||||
return "MLME_DATA_POLL_NOTIFICATION";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int channel_from_mask(uint32_t channel_mask, int index)
|
||||
{
|
||||
int expected_index = 0;
|
||||
for (int i = 0; i < 27; ++i) {
|
||||
if ((channel_mask >> i) & 1) {
|
||||
if (expected_index == index) {
|
||||
return i;
|
||||
}
|
||||
++expected_index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -14,23 +14,17 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef UTIL_H_
|
||||
#define UTIL_H_
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "mbed.h"
|
||||
#include "mlme.h"
|
||||
|
||||
int string_to_bytes(const char *str, uint8_t *buf, int bytes);
|
||||
const char *mlme_status_string(uint8_t status);
|
||||
int channel_from_mask(uint32_t channel_mask, int index);
|
||||
|
||||
#ifndef IP6STRING_H
|
||||
#define IP6STRING_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint_fast8_t ip6tos(const void *ip6addr, char *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stoip6(const char *ip6addr, size_t len, void *dest) {}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -18,13 +18,13 @@
|
|||
#include "UDPSocket.h"
|
||||
#include "TCPSocket.h"
|
||||
#include "TCPServer.h"
|
||||
#include "TLSSocket.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "SocketAddress.h"
|
||||
#include "Queue.h"
|
||||
|
||||
#include <vector>
|
||||
#include <cctype>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS
|
||||
|
|
@ -42,23 +42,26 @@
|
|||
|
||||
#define SIGNAL_SIGIO 0x1
|
||||
#define PACKET_SIZE_ARRAY_LEN 5
|
||||
#define CERT_BUFFER_SIZE 1648
|
||||
|
||||
|
||||
#define MAN_SOCKET "\r\nSOCKET API\r\n"\
|
||||
"\r\n"\
|
||||
"socket <operation> [options]\r\n\r\n"\
|
||||
" new <type>\r\n" \
|
||||
" type: UDPSocket|TCPSocket|TCPServer\r\n"\
|
||||
" type: UDPSocket|TCPSocket|TCPServer|TLSSocket [--cert_file <file>|--cert_default]\r\n"\
|
||||
" return socket id\r\n"\
|
||||
" <id> delete\r\n"\
|
||||
" remote the space allocated for Socket\r\n"\
|
||||
" <id> open\r\n"\
|
||||
" <id> open [--if <interface>] \r\n"\
|
||||
" interface (or use default interface) \r\n"\
|
||||
" <id> close\r\n"\
|
||||
" <id> bind [port] <port> [addr <addr>]\r\n"\
|
||||
" <id> set_blocking <bool>\r\n"\
|
||||
" <id> set_timeout <ms>\r\n"\
|
||||
" <id> register_sigio_cb\r\n"\
|
||||
" <id> set_RFC_864_pattern_check <true|false>\r\n"\
|
||||
"\r\nFor UDPSocket\r\n"\
|
||||
" <id> set_root_ca_cert --cert_url <url>|--cert_file <file>|--cert_default\r\n"\
|
||||
" <id> sendto <addr> <port> (\"msg\" | --data_len <len>)\r\n"\
|
||||
" \"msg\" Send packet with defined string content\r\n"\
|
||||
" --data_len Send packet with random content with size <len>\r\n"\
|
||||
|
|
@ -66,7 +69,6 @@
|
|||
" <id> start_udp_receiver_thread --max_data_len <len> [--packets <N>]\r\n"\
|
||||
" --max_data_len Size of input buffer to fill up\r\n"\
|
||||
" --packets Receive N number of packets, default 1\r\n"\
|
||||
"\r\nFor TCPSocket\r\n"\
|
||||
" <id> connect <host> <port>\r\n"\
|
||||
" <id> send (\"msg\" | --data_len <len>)\r\n"\
|
||||
" <id> recv <len>\r\n"\
|
||||
|
|
@ -79,28 +81,60 @@
|
|||
" <id> join_bg_traffic_thread\r\n"\
|
||||
" <id> setsockopt_keepalive <seconds[0-7200]>\r\n"\
|
||||
" <id> getsockopt_keepalive\r\n"\
|
||||
"\r\nFor TCPServer\r\n"\
|
||||
" <id> listen [backlog]\r\n"\
|
||||
" <id> accept\r\n" \
|
||||
" accept new connection and returns new socket ID\r\n" \
|
||||
"\r\nFor TCPServer\r\n"\
|
||||
" <id> accept <new_id>\r\n"\
|
||||
" accept new connection into <new_id> socket. Requires <new_id> to be pre-allocated.\r\n"\
|
||||
"\r\nOther options\r\n"\
|
||||
" print-mode [--string|--hex|--disabled] [--col-width <width>]"
|
||||
|
||||
class SInfo;
|
||||
static Queue<SInfo, 10> event_queue;
|
||||
static int id_count = 0;
|
||||
|
||||
|
||||
const char *cert = \
|
||||
"-----BEGIN CERTIFICATE-----\n" \
|
||||
"MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/\n" \
|
||||
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n" \
|
||||
"DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow\n" \
|
||||
"SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT\n" \
|
||||
"GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC\n" \
|
||||
"AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF\n" \
|
||||
"q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8\n" \
|
||||
"SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0\n" \
|
||||
"Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA\n" \
|
||||
"a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj\n" \
|
||||
"/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T\n" \
|
||||
"AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG\n" \
|
||||
"CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv\n" \
|
||||
"bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k\n" \
|
||||
"c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw\n" \
|
||||
"VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC\n" \
|
||||
"ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz\n" \
|
||||
"MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu\n" \
|
||||
"Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF\n" \
|
||||
"AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo\n" \
|
||||
"uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/\n" \
|
||||
"wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu\n" \
|
||||
"X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG\n" \
|
||||
"PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6\n" \
|
||||
"KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg==\n" \
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
class SInfo {
|
||||
public:
|
||||
enum SocketType {
|
||||
TCP_CLIENT,
|
||||
IP,
|
||||
TCP_SERVER,
|
||||
UDP
|
||||
OTHER,
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
TLS
|
||||
#endif
|
||||
};
|
||||
SInfo(TCPSocket *sock):
|
||||
SInfo(InternetSocket *sock, bool delete_on_exit = true):
|
||||
_id(id_count++),
|
||||
_sock(sock),
|
||||
_type(SInfo::TCP_CLIENT),
|
||||
_type(SInfo::IP),
|
||||
_blocking(true),
|
||||
_dataLen(0),
|
||||
_maxRecvLen(0),
|
||||
|
|
@ -111,11 +145,12 @@ public:
|
|||
_senderThreadId(NULL),
|
||||
_receiverThreadId(NULL),
|
||||
_packetSizes(NULL),
|
||||
_check_pattern(false)
|
||||
_check_pattern(false),
|
||||
_delete_on_exit(delete_on_exit)
|
||||
{
|
||||
assert(sock);
|
||||
MBED_ASSERT(sock);
|
||||
}
|
||||
SInfo(TCPServer *sock):
|
||||
SInfo(TCPServer *sock, bool delete_on_exit = true):
|
||||
_id(id_count++),
|
||||
_sock(sock),
|
||||
_type(SInfo::TCP_SERVER),
|
||||
|
|
@ -129,14 +164,15 @@ public:
|
|||
_senderThreadId(NULL),
|
||||
_receiverThreadId(NULL),
|
||||
_packetSizes(NULL),
|
||||
_check_pattern(false)
|
||||
_check_pattern(false),
|
||||
_delete_on_exit(delete_on_exit)
|
||||
{
|
||||
assert(sock);
|
||||
MBED_ASSERT(sock);
|
||||
}
|
||||
SInfo(UDPSocket *sock):
|
||||
SInfo(Socket *sock, bool delete_on_exit = true):
|
||||
_id(id_count++),
|
||||
_sock(sock),
|
||||
_type(SInfo::UDP),
|
||||
_type(SInfo::OTHER),
|
||||
_blocking(true),
|
||||
_dataLen(0),
|
||||
_maxRecvLen(0),
|
||||
|
|
@ -147,10 +183,32 @@ public:
|
|||
_senderThreadId(NULL),
|
||||
_receiverThreadId(NULL),
|
||||
_packetSizes(NULL),
|
||||
_check_pattern(false)
|
||||
_check_pattern(false),
|
||||
_delete_on_exit(delete_on_exit)
|
||||
{
|
||||
assert(sock);
|
||||
MBED_ASSERT(sock);
|
||||
}
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
SInfo(TLSSocket *sock, bool delete_on_exit = true):
|
||||
_id(id_count++),
|
||||
_sock(sock),
|
||||
_type(SInfo::TLS),
|
||||
_blocking(true),
|
||||
_dataLen(0),
|
||||
_maxRecvLen(0),
|
||||
_repeatBufferFill(1),
|
||||
_receivedTotal(0),
|
||||
_receiverThread(NULL),
|
||||
_receiveBuffer(NULL),
|
||||
_senderThreadId(NULL),
|
||||
_receiverThreadId(NULL),
|
||||
_packetSizes(NULL),
|
||||
_check_pattern(false),
|
||||
_delete_on_exit(delete_on_exit)
|
||||
{
|
||||
MBED_ASSERT(sock);
|
||||
}
|
||||
#endif
|
||||
~SInfo()
|
||||
{
|
||||
this->_sock->sigio(Callback<void()>());
|
||||
|
|
@ -161,7 +219,9 @@ public:
|
|||
if (this->_receiveBuffer) {
|
||||
delete this->_receiveBuffer;
|
||||
}
|
||||
delete this->_sock;
|
||||
if (_delete_on_exit) {
|
||||
delete this->_sock;
|
||||
}
|
||||
}
|
||||
int id() const
|
||||
{
|
||||
|
|
@ -175,18 +235,20 @@ public:
|
|||
{
|
||||
return *(this->_sock);
|
||||
}
|
||||
TCPSocket *tcp_socket()
|
||||
InternetSocket *internetsocket()
|
||||
{
|
||||
return this->_type == SInfo::TCP_CLIENT ? static_cast<TCPSocket *>(this->_sock) : NULL;
|
||||
return this->_type == SInfo::IP ? static_cast<InternetSocket *>(this->_sock) : NULL;
|
||||
}
|
||||
TCPServer *tcp_server()
|
||||
{
|
||||
return this->_type == SInfo::TCP_SERVER ? static_cast<TCPServer *>(this->_sock) : NULL;
|
||||
}
|
||||
UDPSocket *udp_socket()
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
TLSSocket *tls_socket()
|
||||
{
|
||||
return this->_type == SInfo::UDP ? static_cast<UDPSocket *>(this->_sock) : NULL;
|
||||
return this->_type == SInfo::TLS ? static_cast<TLSSocket *>(this->_sock) : NULL;
|
||||
}
|
||||
#endif
|
||||
SInfo::SocketType type() const
|
||||
{
|
||||
return this->_type;
|
||||
|
|
@ -285,17 +347,22 @@ public:
|
|||
{
|
||||
const char *str;
|
||||
switch (this->_type) {
|
||||
case SInfo::TCP_CLIENT:
|
||||
str = "TCPSocket";
|
||||
case SInfo::IP:
|
||||
str = "InternetSocket";
|
||||
break;
|
||||
case SInfo::TCP_SERVER:
|
||||
str = "TCPServer";
|
||||
break;
|
||||
case SInfo::UDP:
|
||||
str = "UDPSocket";
|
||||
case SInfo::OTHER:
|
||||
str = "Socket";
|
||||
break;
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
case SInfo::TLS:
|
||||
str = "TLSSocket";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
MBED_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
return str;
|
||||
|
|
@ -309,39 +376,8 @@ public:
|
|||
socket().set_blocking(blocking);
|
||||
this->_blocking = blocking;
|
||||
}
|
||||
bool can_connect()
|
||||
{
|
||||
return (this->type() == SInfo::TCP_CLIENT);
|
||||
}
|
||||
bool can_bind()
|
||||
{
|
||||
return (this->type() == SInfo::UDP || this->type() == SInfo::TCP_SERVER);
|
||||
}
|
||||
bool can_send()
|
||||
{
|
||||
return (this->type() == SInfo::TCP_CLIENT);
|
||||
}
|
||||
bool can_recv()
|
||||
{
|
||||
return (this->type() == SInfo::TCP_CLIENT);
|
||||
}
|
||||
bool can_sendto()
|
||||
{
|
||||
return (this->type() == SInfo::UDP);
|
||||
}
|
||||
bool can_recvfrom()
|
||||
{
|
||||
return (this->type() == SInfo::UDP);
|
||||
}
|
||||
bool can_listen()
|
||||
{
|
||||
return (this->type() == SInfo::TCP_SERVER);
|
||||
}
|
||||
bool can_accept()
|
||||
{
|
||||
return (this->type() == SInfo::TCP_SERVER);
|
||||
}
|
||||
private:
|
||||
static int id_count;
|
||||
const int _id;
|
||||
Socket *_sock;
|
||||
const SInfo::SocketType _type;
|
||||
|
|
@ -357,9 +393,11 @@ private:
|
|||
int *_packetSizes;
|
||||
bool _available;
|
||||
bool _check_pattern;
|
||||
bool _delete_on_exit;
|
||||
|
||||
SInfo();
|
||||
};
|
||||
int SInfo::id_count = 0;
|
||||
|
||||
static std::vector<SInfo *> m_sockets;
|
||||
|
||||
|
|
@ -389,22 +427,43 @@ static void print_data_as_hex(const uint8_t *buf, int len, int col_width);
|
|||
* \param offset Start pattern from offset
|
||||
* \param len Length of pattern to generate.
|
||||
*/
|
||||
static void generate_RFC_864_pattern(size_t offset, uint8_t *buf, size_t len)
|
||||
static void generate_RFC_864_pattern(size_t offset, uint8_t *buf, size_t len, bool is_xinetd)
|
||||
{
|
||||
const int row_size = 74; // Number of chars in single row
|
||||
const int row_count = 95; // Number of rows in pattern after which pattern start from beginning
|
||||
const int chars_scope = is_xinetd ? 93 : 95; // Number of chars from ASCII table used in pattern
|
||||
const char first_char = is_xinetd ? '!' : ' '; // First char from ASCII table used in pattern
|
||||
while (len--) {
|
||||
if (offset % 74 == 72) {
|
||||
if (offset % row_size == (row_size - 2)) {
|
||||
*buf++ = '\r';
|
||||
} else if (offset % 74 == 73) {
|
||||
} else if (offset % row_size == (row_size - 1)) {
|
||||
*buf++ = '\n';
|
||||
} else {
|
||||
*buf++ = ' ' + (offset % 74 + offset / 74) % 95 ;
|
||||
*buf++ = first_char + (offset % row_size + ((offset / row_size) % row_count)) % chars_scope;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
||||
static int get_cert_from_file(const char *filename, char **cert)
|
||||
{
|
||||
int filedesc = open(filename, O_RDONLY);
|
||||
if (filedesc < 0) {
|
||||
cmd_printf("Cannot open file: %s\r\n", filename);
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
|
||||
if (read(filedesc, *cert, CERT_BUFFER_SIZE) != CERT_BUFFER_SIZE) {
|
||||
cmd_printf("Cannot read from file %s\r\n", filename);
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
|
||||
return CMDLINE_RETCODE_SUCCESS;
|
||||
}
|
||||
|
||||
bool SInfo::check_pattern(void *buffer, size_t len)
|
||||
{
|
||||
static bool is_xinetd = false;
|
||||
if (!_check_pattern) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -412,8 +471,14 @@ bool SInfo::check_pattern(void *buffer, size_t len)
|
|||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t offset = _receivedTotal;
|
||||
generate_RFC_864_pattern(offset, (uint8_t *)buf, len);
|
||||
|
||||
if (offset == 0) {
|
||||
is_xinetd = ((uint8_t *)buffer)[0] == '!';
|
||||
}
|
||||
|
||||
generate_RFC_864_pattern(offset, (uint8_t *)buf, len, is_xinetd);
|
||||
bool match = memcmp(buf, buffer, len) == 0;
|
||||
if (!match) {
|
||||
cmd_printf("Pattern check failed\r\nWAS:%.*s\r\nREF:%.*s\r\n", len, (char *)buffer, len, (char *)buf);
|
||||
|
|
@ -435,6 +500,9 @@ static void sigio_handler(SInfo *info)
|
|||
void cmd_socket_init(void)
|
||||
{
|
||||
cmd_add("socket", cmd_socket, "socket", MAN_SOCKET);
|
||||
cmd_alias_add("socket help", "socket -h");
|
||||
cmd_alias_add("socket --help", "socket -h");
|
||||
cmd_alias_add("ping server start", "socket echo-server new start");
|
||||
}
|
||||
|
||||
int handle_nsapi_error(const char *function, nsapi_error_t ret)
|
||||
|
|
@ -479,13 +547,46 @@ static int del_sinfo(SInfo *info)
|
|||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
static int tls_set_cert(int argc, char *argv[], SInfo *info)
|
||||
{
|
||||
static char read_cert[CERT_BUFFER_SIZE];
|
||||
char *ptr_cert = NULL;
|
||||
char *src = NULL;
|
||||
if (cmd_parameter_val(argc, argv, "--cert_file", &src)) {
|
||||
tr_debug("Root ca certificate read from file: %s", src);
|
||||
ptr_cert = read_cert;
|
||||
if (get_cert_from_file(src, &ptr_cert) == CMDLINE_RETCODE_FAIL) {
|
||||
cmd_printf("Cannot read from url: %s\r\n", src);
|
||||
return CMDLINE_RETCODE_INVALID_PARAMETERS;
|
||||
}
|
||||
} else if (cmd_parameter_index(argc, argv, "--cert_default") != -1) {
|
||||
cmd_printf("Using default certificate\r\n");
|
||||
ptr_cert = (char *)cert;
|
||||
} else {
|
||||
cmd_printf("No cert specified. Use set_root_ca_cert to set it.\r\n");
|
||||
// Do not return error, allow the certificate not to be set.
|
||||
return CMDLINE_RETCODE_SUCCESS;
|
||||
}
|
||||
|
||||
int ret = info->tls_socket()->set_root_ca_cert(ptr_cert);
|
||||
if (ret != NSAPI_ERROR_OK) {
|
||||
cmd_printf("Invalid root certificate\r\n");
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
|
||||
return CMDLINE_RETCODE_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cmd_socket_new(int argc, char *argv[])
|
||||
{
|
||||
const char *s;
|
||||
SInfo *info;
|
||||
nsapi_error_t ret;
|
||||
|
||||
if (cmd_parameter_last(argc, argv)) {
|
||||
s = cmd_parameter_last(argc, argv);
|
||||
if (argc > 2) {
|
||||
s = argv[2];
|
||||
if (strcmp(s, "UDPSocket") == 0) {
|
||||
tr_debug("Creating a new UDPSocket");
|
||||
info = new SInfo(new UDPSocket);
|
||||
|
|
@ -495,6 +596,16 @@ static int cmd_socket_new(int argc, char *argv[])
|
|||
} else if (strcmp(s, "TCPServer") == 0) {
|
||||
tr_debug("Creating a new TCPServer");
|
||||
info = new SInfo(new TCPServer);
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
} else if (strcmp(s, "TLSSocket") == 0) {
|
||||
tr_debug("Creating a new TLSSocket");
|
||||
info = new SInfo(new TLSSocket);
|
||||
ret = tls_set_cert(argc, argv, info);
|
||||
if (ret) {
|
||||
delete info;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
cmd_printf("unsupported protocol: %s\r\n", s);
|
||||
return CMDLINE_RETCODE_INVALID_PARAMETERS;
|
||||
|
|
@ -518,10 +629,10 @@ static void udp_receiver_thread(SInfo *info)
|
|||
int *packetSizes = info->getPacketSizeArray();
|
||||
nsapi_size_or_error_t ret = 0;
|
||||
|
||||
info->setReceiverThreadId(Thread::gettid());
|
||||
info->setReceiverThreadId(ThisThread::get_id());
|
||||
|
||||
while (i < n) {
|
||||
ret = static_cast<UDPSocket &>(info->socket()).recvfrom(&addr, info->getReceiveBuffer() + received, info->getDataCount() - received);
|
||||
ret = info->socket().recvfrom(&addr, info->getReceiveBuffer() + received, info->getDataCount() - received);
|
||||
if (ret > 0) {
|
||||
if (!info->check_pattern(info->getReceiveBuffer() + received, ret)) {
|
||||
return;
|
||||
|
|
@ -531,9 +642,9 @@ static void udp_receiver_thread(SInfo *info)
|
|||
i++;
|
||||
info->setRecvTotal(info->getRecvTotal() + ret);
|
||||
} else if (ret == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
Thread::signal_wait(SIGNAL_SIGIO);
|
||||
ThisThread::flags_wait_any(SIGNAL_SIGIO);
|
||||
} else {
|
||||
handle_nsapi_size_or_error("Thread: UDPSocket::recvfrom()", ret);
|
||||
handle_nsapi_size_or_error("Thread: Socket::recvfrom()", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -612,7 +723,12 @@ static nsapi_size_or_error_t udp_sendto_command_handler(SInfo *info, int argc, c
|
|||
}
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t ret = static_cast<UDPSocket &>(info->socket()).sendto(host, port, data, len);
|
||||
SocketAddress addr(NULL, port);
|
||||
nsapi_size_or_error_t ret = get_interface()->gethostbyname(host, &addr);
|
||||
if (ret) {
|
||||
return handle_nsapi_size_or_error("NetworkInterface::gethostbyname()", ret);
|
||||
}
|
||||
ret = info->socket().sendto(addr, data, len);
|
||||
if (ret > 0) {
|
||||
cmd_printf("sent: %d bytes\r\n", ret);
|
||||
}
|
||||
|
|
@ -620,7 +736,7 @@ static nsapi_size_or_error_t udp_sendto_command_handler(SInfo *info, int argc, c
|
|||
free(data);
|
||||
}
|
||||
|
||||
return handle_nsapi_size_or_error("UDPSocket::sendto()", ret);
|
||||
return handle_nsapi_size_or_error("Socket::sendto()", ret);
|
||||
}
|
||||
|
||||
static nsapi_size_or_error_t udp_recvfrom_command_handler(SInfo *info, int argc, char *argv[])
|
||||
|
|
@ -638,9 +754,9 @@ static nsapi_size_or_error_t udp_recvfrom_command_handler(SInfo *info, int argc,
|
|||
cmd_printf("malloc() failed\r\n");
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
nsapi_size_or_error_t ret = static_cast<UDPSocket &>(info->socket()).recvfrom(&addr, data, len);
|
||||
nsapi_size_or_error_t ret = info->socket().recvfrom(&addr, data, len);
|
||||
if (ret > 0) {
|
||||
cmd_printf("UDPSocket::recvfrom, addr=%s port=%d\r\n", addr.get_ip_address(), addr.get_port());
|
||||
cmd_printf("Socket::recvfrom, addr=%s port=%d\r\n", addr.get_ip_address(), addr.get_port());
|
||||
cmd_printf("received: %d bytes\r\n", ret);
|
||||
print_data((const uint8_t *)data, len);
|
||||
if (!info->check_pattern(data, len)) {
|
||||
|
|
@ -649,7 +765,7 @@ static nsapi_size_or_error_t udp_recvfrom_command_handler(SInfo *info, int argc,
|
|||
info->setRecvTotal(info->getRecvTotal() + ret);
|
||||
}
|
||||
free(data);
|
||||
return handle_nsapi_size_or_error("UDPSocket::recvfrom()", ret);
|
||||
return handle_nsapi_size_or_error("Socket::recvfrom()", ret);
|
||||
}
|
||||
|
||||
static void tcp_receiver_thread(SInfo *info)
|
||||
|
|
@ -660,12 +776,12 @@ static void tcp_receiver_thread(SInfo *info)
|
|||
int bufferSize = info->getDataCount();
|
||||
nsapi_size_or_error_t ret = 0;
|
||||
|
||||
info->setReceiverThreadId(Thread::gettid());
|
||||
info->setReceiverThreadId(ThisThread::get_id());
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
received = 0;
|
||||
while (received < bufferSize) {
|
||||
ret = static_cast<TCPSocket &>(info->socket()).recv(info->getReceiveBuffer() + received, recv_len - received);
|
||||
ret = info->socket().recv(info->getReceiveBuffer() + received, recv_len - received);
|
||||
if (ret > 0) {
|
||||
if (!info->check_pattern(info->getReceiveBuffer() + received, ret)) {
|
||||
return;
|
||||
|
|
@ -673,9 +789,9 @@ static void tcp_receiver_thread(SInfo *info)
|
|||
received += ret;
|
||||
info->setRecvTotal(info->getRecvTotal() + ret);
|
||||
} else if (ret == NSAPI_ERROR_WOULD_BLOCK) {
|
||||
Thread::signal_wait(SIGNAL_SIGIO);
|
||||
ThisThread::flags_wait_all(SIGNAL_SIGIO);
|
||||
} else {
|
||||
handle_nsapi_size_or_error("Thread: TCPSocket::recv()", ret);
|
||||
handle_nsapi_size_or_error("Thread: Socket::recv()", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -729,7 +845,7 @@ static nsapi_size_or_error_t tcp_send_command_handler(SInfo *info, int argc, cha
|
|||
void *data;
|
||||
nsapi_size_or_error_t ret = 0;
|
||||
|
||||
info->setSenderThreadId(Thread::gettid());
|
||||
info->setSenderThreadId(ThisThread::get_id());
|
||||
|
||||
if (cmd_parameter_int(argc, argv, "--data_len", &len)) {
|
||||
data = malloc(len);
|
||||
|
|
@ -742,7 +858,7 @@ static nsapi_size_or_error_t tcp_send_command_handler(SInfo *info, int argc, cha
|
|||
len = strlen(argv[3]);
|
||||
}
|
||||
|
||||
ret = static_cast<TCPSocket &>(info->socket()).send(data, len);
|
||||
ret = info->socket().send(data, len);
|
||||
|
||||
if (ret > 0) {
|
||||
cmd_printf("sent: %d bytes\r\n", ret);
|
||||
|
|
@ -750,7 +866,7 @@ static nsapi_size_or_error_t tcp_send_command_handler(SInfo *info, int argc, cha
|
|||
if (data != argv[3]) {
|
||||
free(data);
|
||||
}
|
||||
return handle_nsapi_size_or_error("TCPSocket::send()", ret);
|
||||
return handle_nsapi_size_or_error("Socket::send()", ret);
|
||||
}
|
||||
|
||||
static nsapi_size_or_error_t tcp_recv_command_handler(SInfo *info, int argc, char *argv[])
|
||||
|
|
@ -768,7 +884,7 @@ static nsapi_size_or_error_t tcp_recv_command_handler(SInfo *info, int argc, cha
|
|||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t ret = static_cast<TCPSocket &>(info->socket()).recv(data, len);
|
||||
nsapi_size_or_error_t ret = info->socket().recv(data, len);
|
||||
if (ret > 0) {
|
||||
cmd_printf("received: %d bytes\r\n", ret);
|
||||
print_data((const uint8_t *)data, ret);
|
||||
|
|
@ -778,7 +894,7 @@ static nsapi_size_or_error_t tcp_recv_command_handler(SInfo *info, int argc, cha
|
|||
info->setRecvTotal(info->getRecvTotal() + ret);
|
||||
}
|
||||
free(data);
|
||||
return handle_nsapi_size_or_error("TCPSocket::recv()", ret);
|
||||
return handle_nsapi_size_or_error("Socket::recv()", ret);
|
||||
}
|
||||
|
||||
static nsapi_size_or_error_t recv_all(char *const rbuffer, const int expt_len, SInfo *const info)
|
||||
|
|
@ -790,7 +906,7 @@ static nsapi_size_or_error_t recv_all(char *const rbuffer, const int expt_len, S
|
|||
rhead = rbuffer;
|
||||
|
||||
while (rtotal < expt_len) {
|
||||
rbytes = info->tcp_socket()->recv(rhead, expt_len);
|
||||
rbytes = info->socket().recv(rhead, expt_len);
|
||||
if (rbytes <= 0) { // Connection closed abruptly
|
||||
rbuffer[rtotal] = '\0';
|
||||
return rbytes;
|
||||
|
|
@ -809,7 +925,7 @@ static void bg_traffic_thread(SInfo *info)
|
|||
char sbuffer[data_len + 1] = "dummydata_";
|
||||
char rbuffer[data_len + 1];
|
||||
int scount, rtotal = 0;
|
||||
info->setSenderThreadId(Thread::gettid());
|
||||
info->setSenderThreadId(ThisThread::get_id());
|
||||
|
||||
for (;;) {
|
||||
if (!info->available()) {
|
||||
|
|
@ -817,7 +933,7 @@ static void bg_traffic_thread(SInfo *info)
|
|||
break;
|
||||
}
|
||||
sbuffer[data_len - 1] = 'A' + (rand() % 26);
|
||||
scount = info->tcp_socket()->send(sbuffer, data_len);
|
||||
scount = info->socket().send(sbuffer, data_len);
|
||||
rtotal = recv_all(rbuffer, data_len, info);
|
||||
|
||||
if (scount != rtotal || (strcmp(sbuffer, rbuffer) != 0)) {
|
||||
|
|
@ -920,14 +1036,18 @@ static int cmd_socket(int argc, char *argv[])
|
|||
}
|
||||
|
||||
switch (info->type()) {
|
||||
case SInfo::TCP_CLIENT:
|
||||
return handle_nsapi_error("Socket::open()", info->tcp_socket()->open(interface));
|
||||
case SInfo::UDP:
|
||||
return handle_nsapi_error("Socket::open()", info->udp_socket()->open(interface));
|
||||
case SInfo::IP:
|
||||
return handle_nsapi_error("Socket::open()", info->internetsocket()->open(interface));
|
||||
case SInfo::TCP_SERVER:
|
||||
return handle_nsapi_error("Socket::open()", info->tcp_server()->open(interface));
|
||||
return handle_nsapi_error("TCPServer::open()", info->tcp_server()->open(interface));
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
case SInfo::TLS:
|
||||
return handle_nsapi_error("Socket::open()", info->tls_socket()->open(interface));
|
||||
#endif
|
||||
default:
|
||||
cmd_printf("Not a IP socket\r\n");
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
|
||||
} else if (COMMAND_IS("close")) {
|
||||
return handle_nsapi_error("Socket::close()", info->socket().close());
|
||||
|
||||
|
|
@ -986,12 +1106,6 @@ static int cmd_socket(int argc, char *argv[])
|
|||
* Commands related to UDPSocket:
|
||||
* sendto, recvfrom
|
||||
*/
|
||||
if ((COMMAND_IS("sendto") || COMMAND_IS("recvfrom") || COMMAND_IS("start_udp_receiver_thread")
|
||||
|| COMMAND_IS("last_data_received")) && info->type() != SInfo::UDP) {
|
||||
cmd_printf("Not UDPSocket\r\n");
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
|
||||
if (COMMAND_IS("sendto")) {
|
||||
return udp_sendto_command_handler(info, argc, argv);
|
||||
} else if (COMMAND_IS("recvfrom")) {
|
||||
|
|
@ -1013,22 +1127,13 @@ static int cmd_socket(int argc, char *argv[])
|
|||
}
|
||||
thread_clean_up(info);
|
||||
|
||||
return handle_nsapi_error("UDPSocket::last_data_received()", NSAPI_ERROR_OK);
|
||||
return handle_nsapi_error("Socket::last_data_received()", NSAPI_ERROR_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Commands related to TCPSocket
|
||||
* Commands related to TCPSocket, TLSSocket
|
||||
* connect, send, recv
|
||||
*/
|
||||
if ((COMMAND_IS("connect") || COMMAND_IS("recv")
|
||||
|| COMMAND_IS("start_tcp_receiver_thread") || COMMAND_IS("join_tcp_receiver_thread")
|
||||
|| COMMAND_IS("start_bg_traffic_thread") || COMMAND_IS("join_bg_traffic_thread")
|
||||
|| COMMAND_IS("setsockopt_keepalive") || COMMAND_IS("getsockopt_keepalive"))
|
||||
&& info->type() != SInfo::TCP_CLIENT) {
|
||||
cmd_printf("Not TCPSocket\r\n");
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
|
||||
if (COMMAND_IS("connect")) {
|
||||
char *host;
|
||||
int32_t port;
|
||||
|
|
@ -1046,7 +1151,18 @@ static int cmd_socket(int argc, char *argv[])
|
|||
}
|
||||
|
||||
cmd_printf("Host name: %s port: %" PRId32 "\r\n", host, port);
|
||||
return handle_nsapi_error("TCPSocket::connect()", static_cast<TCPSocket &>(info->socket()).connect(host, port));
|
||||
if (info->type() == SInfo::IP) {
|
||||
SocketAddress addr(NULL, port);
|
||||
nsapi_error_t ret = get_interface()->gethostbyname(host, &addr);
|
||||
if (ret) {
|
||||
return handle_nsapi_error("NetworkInterface::gethostbyname()", ret);
|
||||
}
|
||||
return handle_nsapi_error("Socket::connect()", info->socket().connect(addr));
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
} else if (info->type() == SInfo::TLS) {
|
||||
return handle_nsapi_error("TLSSocket::connect()", static_cast<TLSSocket &>(info->socket()).connect(host, port));
|
||||
#endif
|
||||
}
|
||||
|
||||
} else if (COMMAND_IS("send")) {
|
||||
return tcp_send_command_handler(info, argc, argv);
|
||||
|
|
@ -1091,7 +1207,7 @@ static int cmd_socket(int argc, char *argv[])
|
|||
|
||||
ret = info->socket().setsockopt(NSAPI_SOCKET, NSAPI_KEEPALIVE, &seconds, sizeof(seconds));
|
||||
|
||||
return handle_nsapi_error("TCPSocket::setsockopt()", ret);
|
||||
return handle_nsapi_error("Socket::setsockopt()", ret);
|
||||
} else if (COMMAND_IS("getsockopt_keepalive")) {
|
||||
int32_t optval;
|
||||
unsigned optlen = sizeof(optval);
|
||||
|
|
@ -1103,47 +1219,72 @@ static int cmd_socket(int argc, char *argv[])
|
|||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
if (ret < 0) {
|
||||
return handle_nsapi_error("TCPSocket::getsockopt()", ret);
|
||||
return handle_nsapi_error("Socket::getsockopt()", ret);
|
||||
}
|
||||
return handle_nsapi_size_or_error("TCPSocket::getsockopt()", optval);
|
||||
return handle_nsapi_size_or_error("Socket::getsockopt()", optval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Commands for TCPServer
|
||||
* listen, accept
|
||||
*/
|
||||
if ((COMMAND_IS("listen") || COMMAND_IS("accept")) && info->type() != SInfo::TCP_SERVER) {
|
||||
cmd_printf("Not TCPServer\r\n");
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
if (COMMAND_IS("listen")) {
|
||||
int32_t backlog;
|
||||
if (cmd_parameter_int(argc, argv, "listen", &backlog)) {
|
||||
return handle_nsapi_error("TCPServer::listen()", static_cast<TCPServer &>(info->socket()).listen(backlog));
|
||||
return handle_nsapi_error("TCPServer::listen()", info->socket().listen(backlog));
|
||||
} else {
|
||||
return handle_nsapi_error("TCPServer::listen()", static_cast<TCPServer &>(info->socket()).listen());
|
||||
return handle_nsapi_error("TCPServer::listen()", info->socket().listen());
|
||||
}
|
||||
|
||||
} else if (COMMAND_IS("accept")) {
|
||||
SocketAddress addr;
|
||||
int32_t id;
|
||||
if (!cmd_parameter_int(argc, argv, "accept", &id)) {
|
||||
cmd_printf("Need new socket id\r\n");
|
||||
return CMDLINE_RETCODE_INVALID_PARAMETERS;
|
||||
nsapi_error_t ret;
|
||||
|
||||
if (info->type() != SInfo::TCP_SERVER) {
|
||||
Socket *new_sock = info->socket().accept(&ret);
|
||||
if (ret == NSAPI_ERROR_OK) {
|
||||
SInfo *new_info = new SInfo(new_sock, false);
|
||||
m_sockets.push_back(new_info);
|
||||
cmd_printf("Socket::accept() new socket sid: %d\r\n", new_info->id());
|
||||
}
|
||||
return handle_nsapi_error("Socket::accept()", ret);
|
||||
} else { // Old TCPServer API
|
||||
int32_t id;
|
||||
SocketAddress addr;
|
||||
|
||||
if (!cmd_parameter_int(argc, argv, "accept", &id)) {
|
||||
cmd_printf("Need new socket id\r\n");
|
||||
return CMDLINE_RETCODE_INVALID_PARAMETERS;
|
||||
}
|
||||
SInfo *new_info = get_sinfo(id);
|
||||
if (!new_info) {
|
||||
cmd_printf("Invalid socket id\r\n");
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
TCPSocket *new_sock = static_cast<TCPSocket *>(&new_info->socket());
|
||||
nsapi_error_t ret = static_cast<TCPServer &>(info->socket()).accept(new_sock, &addr);
|
||||
if (ret == NSAPI_ERROR_OK) {
|
||||
cmd_printf("TCPServer::accept() new socket sid: %d connection from %s port %d\r\n",
|
||||
new_info->id(), addr.get_ip_address(), addr.get_port());
|
||||
}
|
||||
return handle_nsapi_error("TCPServer::accept()", ret);
|
||||
}
|
||||
SInfo *new_info = get_sinfo(id);
|
||||
if (!new_info) {
|
||||
cmd_printf("Invalid socket id\r\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Commands for TLSSocket
|
||||
* set_root_ca_cert
|
||||
*/
|
||||
#if defined(MBEDTLS_SSL_CLI_C)
|
||||
if (COMMAND_IS("set_root_ca_cert")) {
|
||||
if (info->type() != SInfo::TLS) {
|
||||
cmd_printf("Not a TLS socket.\r\n");
|
||||
return CMDLINE_RETCODE_FAIL;
|
||||
}
|
||||
TCPSocket *new_sock = static_cast<TCPSocket *>(&new_info->socket());
|
||||
nsapi_error_t ret = static_cast<TCPServer &>(info->socket()).accept(new_sock, &addr);
|
||||
if (ret == NSAPI_ERROR_OK) {
|
||||
cmd_printf("TCPServer::accept() new socket sid: %d connection from %s port %d\r\n",
|
||||
new_info->id(), addr.get_ip_address(), addr.get_port());
|
||||
}
|
||||
return handle_nsapi_error("TCPServer::accept()", ret);
|
||||
return handle_nsapi_error("TLSSocket::tls_set_cert", tls_set_cert(argc, argv, info));
|
||||
}
|
||||
#endif
|
||||
|
||||
return CMDLINE_RETCODE_INVALID_PARAMETERS;
|
||||
}
|
||||
|
||||
|
|
@ -1159,7 +1300,7 @@ void print_data(const uint8_t *buf, int len)
|
|||
case PRINT_DISABLED:
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
MBED_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
"""
|
||||
Copyright (c) 2017, 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.
|
||||
"""
|
||||
|
||||
import threading
|
||||
import os,sys
|
||||
from icetea_lib.bench import Bench
|
||||
|
||||
class Testcase(Bench):
|
||||
def __init__(self):
|
||||
Bench.__init__(self, name = "ED_scan",
|
||||
title = "ED scan test",
|
||||
status = "development",
|
||||
type = "smoke",
|
||||
subtype = "",
|
||||
execution = {
|
||||
"skip": {
|
||||
"value": False,
|
||||
"reason": ""
|
||||
}
|
||||
},
|
||||
author = "Valtteri Erkkila",
|
||||
purpose = "Tests reading the ED values from channels 11-16",
|
||||
feature = ["MLME-SCAN (ED)"],
|
||||
component = ["MAC"],
|
||||
requirements = {
|
||||
"duts": {
|
||||
'*': {
|
||||
"count":3,
|
||||
"type": "hardware",
|
||||
"allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"],
|
||||
"application": {
|
||||
"name": "TEST_APPS-device-nanostack_mac_tester"
|
||||
}
|
||||
},
|
||||
"1":{"nick": "First"},
|
||||
"2":{"nick": "Second"},
|
||||
"3":{"nick": "Third"}
|
||||
}}
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
self.channel = 11
|
||||
self.command("First", "addr --64-bit 01:02:03:00:00:00:00:01")
|
||||
self.command("Second", "addr --64-bit 01:02:03:00:00:00:00:02")
|
||||
self.command("Third", "addr --64-bit 01:02:03:00:00:00:00:03")
|
||||
|
||||
def spam_channel(self, event):
|
||||
while not event.wait(0.1):
|
||||
self.lock_th.acquire()
|
||||
self.command("First", "data --dst_addr 01:02:03:00:00:00:00:03 --msdu {} --msdu_length {} --wait_for_confirm false".format(self.payload, len(self.payload)))
|
||||
self.command("Third", "data --dst_addr 01:02:03:00:00:00:00:01 --msdu {} --msdu_length {} --wait_for_confirm false".format(self.payload, len(self.payload)))
|
||||
self.lock_th.release()
|
||||
|
||||
def mask_from_channel_list(self, channels):
|
||||
res = 0
|
||||
for ch in channels:
|
||||
res = res | ( 1 << ch)
|
||||
return hex(res)
|
||||
|
||||
def case(self):
|
||||
self.lock_th = threading.Lock()
|
||||
self.payload = "01234567890123456789012345678901234567890123456789"
|
||||
|
||||
self.command("First", "start --pan_coordinator true --logical_channel {}".format(self.channel))
|
||||
self.command("Second", "start --pan_coordinator false --logical_channel {}".format(self.channel))
|
||||
self.command("Third", "start --pan_coordinator false --logical_channel {}".format(self.channel))
|
||||
|
||||
#No reason to print their spamming
|
||||
self.command("First", "silent-mode on")
|
||||
self.command("Third", "silent-mode on")
|
||||
|
||||
self.stop_event = threading.Event()
|
||||
self.th = threading.Thread(target=self.spam_channel, args=(self.stop_event,))
|
||||
self.th.start()
|
||||
self.stopped = True
|
||||
channels = range(11,27)
|
||||
for i in range(0, 3):
|
||||
self.lock_th.acquire()
|
||||
self.command("First", "mlme-reset")
|
||||
self.command("First", "start --pan_coordinator true --logical_channel {}".format(self.channel))
|
||||
self.command("Third", "mlme-reset")
|
||||
self.command("Third", "start --pan_coordinator false --logical_channel {}".format(self.channel))
|
||||
self.lock_th.release()
|
||||
self.command("Second", "scan --scan_type 0 --scan_duration 7 --channel_mask {}".format(self.mask_from_channel_list(channels)))
|
||||
self.command("Second", "analyze-ed --channel {} --above 100".format(self.channel))
|
||||
|
||||
def tearDown(self):
|
||||
self.command("First", "silent-mode off")
|
||||
self.command("Third", "silent-mode off")
|
||||
self.stop_event.set()
|
||||
self.th.join()
|
||||
del self.th
|
||||
self.reset_dut()
|
||||
|
|
@ -0,0 +1 @@
|
|||
#!/usr/bin/env python
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
"""
|
||||
Copyright (c) 2017, 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.
|
||||
"""
|
||||
|
||||
import os,sys
|
||||
from icetea_lib.bench import Bench
|
||||
|
||||
class Testcase(Bench):
|
||||
def __init__(self):
|
||||
Bench.__init__(self, name = "address_read_and_write",
|
||||
title = "MAC address and PAN id read/write test",
|
||||
status = "development",
|
||||
type = "smoke",
|
||||
subtype = "",
|
||||
execution = {
|
||||
"skip": {
|
||||
"value": False,
|
||||
"reason": ""
|
||||
}
|
||||
},
|
||||
author = "Valtteri Erkkila",
|
||||
purpose = "Tests reading a MAC address from the driver, and writing to the modifiable MAC address",
|
||||
feature = ["MLME-SET"],
|
||||
component = ["MAC"],
|
||||
requirements = {
|
||||
"duts": {
|
||||
'*': {
|
||||
"count":1,
|
||||
"type": "hardware",
|
||||
"allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"],
|
||||
"application": {
|
||||
"name": "TEST_APPS-device-nanostack_mac_tester"
|
||||
}
|
||||
},
|
||||
"1":{"nick": "First"}
|
||||
}}
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def case(self):
|
||||
self.command("First", "addr")
|
||||
self.command("First", "addr --64-bit 01:02:03:00:00:00:00:01")
|
||||
self.command("First", "addr --16-bit 0xABCD")
|
||||
#macPANId
|
||||
self.command("First", "mlme-set --attr 0x50 --value_bytes CD:CD --value_size 2")
|
||||
self.command("First", "addr")
|
||||
self.verify_trace(1, "MAC64: 01:02:03:00:00:00:00:01")
|
||||
|
||||
def tearDown(self):
|
||||
self.reset_dut()
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
"""
|
||||
Copyright (c) 2017, 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.
|
||||
"""
|
||||
|
||||
import os,sys
|
||||
from icetea_lib.bench import Bench
|
||||
|
||||
class Testcase(Bench):
|
||||
def __init__(self):
|
||||
Bench.__init__(self, name = "create_and_join_PAN",
|
||||
title = "Create a PAN and have a device join it",
|
||||
status = "development",
|
||||
type = "smoke",
|
||||
subtype = "",
|
||||
execution = {
|
||||
"skip": {
|
||||
"value": False,
|
||||
"reason": ""
|
||||
}
|
||||
},
|
||||
author = "Valtteri Erkkila",
|
||||
purpose = "",
|
||||
feature = ["MLME-START", "MLME-SCAN (active)"],
|
||||
component = ["MAC"],
|
||||
requirements = {
|
||||
"duts": {
|
||||
'*': {
|
||||
"count":3,
|
||||
"type": "hardware",
|
||||
"allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"],
|
||||
"application": {
|
||||
"name": "TEST_APPS-device-nanostack_mac_tester"
|
||||
}
|
||||
},
|
||||
"1":{"nick": "First"},
|
||||
"2":{"nick": "Second"},
|
||||
"3":{"nick": "Third"}
|
||||
}}
|
||||
)
|
||||
|
||||
def mask_from_channel_list(self, channels):
|
||||
res = 0
|
||||
for ch in channels:
|
||||
res = res | ( 1 << ch)
|
||||
return hex(res)
|
||||
|
||||
def setUp(self):
|
||||
self.channel = 11
|
||||
|
||||
def case(self):
|
||||
#Beacon payload & length
|
||||
self.command("First", "mlme-set --attr 0x45 --value_ascii mac-tester --value_size 10")
|
||||
self.command("First", "mlme-set --attr 0x46 --value_uint8 10 --value_size 1")
|
||||
|
||||
self.command("Second", "mlme-set --attr 0x45 --value_ascii second-mac-tester --value_size 17")
|
||||
self.command("Second", "mlme-set --attr 0x46 --value_uint8 17 --value_size 1")
|
||||
|
||||
self.command("First", "start --pan_coordinator true --logical_channel {}".format(self.channel))
|
||||
self.command("Second", "start --pan_coordinator true --logical_channel {}".format(int(self.channel)+1))
|
||||
self.delay(3)
|
||||
if self.channel == 11:
|
||||
channels = [11,12]
|
||||
elif self.channel == 26:
|
||||
channels = [25,26]
|
||||
else:
|
||||
channels = [self.channel, self.channel+1]
|
||||
self.command("Third", "scan --channel_mask {}".format(self.mask_from_channel_list(channels)))
|
||||
self.delay(0.2)
|
||||
self.command("Third", "find-beacon --data mac-tester")
|
||||
self.command("Third", "find-beacon --data second-mac-tester")
|
||||
|
||||
def tearDown(self):
|
||||
self.reset_dut()
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
"""
|
||||
Copyright (c) 2017, 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.
|
||||
"""
|
||||
|
||||
import os,sys
|
||||
from icetea_lib.bench import Bench
|
||||
|
||||
class Testcase(Bench):
|
||||
def __init__(self):
|
||||
Bench.__init__(self, name = "send_data",
|
||||
title = "Simple data transmission test",
|
||||
status = "development",
|
||||
type = "smoke",
|
||||
subtype = "",
|
||||
execution = {
|
||||
"skip": {
|
||||
"value": False,
|
||||
"reason": ""
|
||||
}
|
||||
},
|
||||
author = "Valtteri Erkkila",
|
||||
purpose = "Tests that sending data works",
|
||||
feature = ["MCPS-DATA"],
|
||||
component = ["MAC"],
|
||||
requirements = {
|
||||
"duts": {
|
||||
'*': {
|
||||
"count":2,
|
||||
"type": "hardware",
|
||||
"allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"],
|
||||
"application": {
|
||||
"name": "TEST_APPS-device-nanostack_mac_tester"
|
||||
}
|
||||
},
|
||||
"1":{"nick": "First"},
|
||||
"2":{"nick": "Second"}
|
||||
}}
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
self.channel = 11
|
||||
self.command("First", "addr --64-bit 01:02:03:00:00:00:00:01")
|
||||
self.command("Second", "addr --64-bit 01:02:03:00:00:00:00:02")
|
||||
|
||||
def case(self):
|
||||
self.command("First", "start --pan_coordinator true --logical_channel {}".format(self.channel))
|
||||
self.command("Second", "start --pan_coordinator false --logical_channel {}".format(self.channel))
|
||||
|
||||
self.command("First", "data --dst_addr 01:02:03:00:00:00:00:02 --msdu_length 5 --msdu abcde")
|
||||
self.command("Second", "data --dst_addr 01:02:03:00:00:00:00:01 --msdu_length 5 --msdu 12345")
|
||||
|
||||
def tearDown(self):
|
||||
self.reset_dut()
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
"""
|
||||
Copyright (c) 2017, 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.
|
||||
"""
|
||||
|
||||
import os,sys
|
||||
from icetea_lib.bench import Bench
|
||||
|
||||
class Testcase(Bench):
|
||||
def __init__(self):
|
||||
Bench.__init__(self, name = "send_data_indirect",
|
||||
title = "Indirect data transmission test",
|
||||
status = "development",
|
||||
type = "smoke",
|
||||
subtype = "",
|
||||
execution = {
|
||||
"skip": {
|
||||
"value": False,
|
||||
"reason": ""
|
||||
}
|
||||
},
|
||||
author = "Valtteri Erkkila",
|
||||
purpose = "Tests sending data indirectly, i.e polling the coordinator for data",
|
||||
feature = ["MCPS-DATA", "MLME-POLL"],
|
||||
component = ["MAC"],
|
||||
requirements = {
|
||||
"duts": {
|
||||
'*': {
|
||||
"count":3,
|
||||
"type": "hardware",
|
||||
"allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"],
|
||||
"application": {
|
||||
"name": "TEST_APPS-device-nanostack_mac_tester"
|
||||
}
|
||||
},
|
||||
"1":{"nick": "First"},
|
||||
"2":{"nick": "Second"},
|
||||
"3":{"nick": "Third"}
|
||||
}}
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
self.channel = 11
|
||||
self.command("First", "addr --64-bit 01:02:03:00:00:00:00:01")
|
||||
self.command("Second", "addr --64-bit 01:02:03:00:00:00:00:02")
|
||||
self.command("Third", "addr --64-bit 01:02:03:00:00:00:00:03")
|
||||
|
||||
def case(self):
|
||||
self.command("First", "start --pan_coordinator true --logical_channel {}".format(self.channel))
|
||||
self.command("Second", "start --pan_coordinator false --logical_channel {}".format(self.channel))
|
||||
self.command("Third", "start --pan_coordinator false --logical_channel {}".format(self.channel))
|
||||
|
||||
#macRxOnWhenIdle
|
||||
self.command("Second", "mlme-set --attr 0x52 --value_uint8 0 --value_size 1")
|
||||
self.command("Third", "mlme-set --attr 0x52 --value_uint8 0 --value_size 1")
|
||||
|
||||
self.command("First", "add-neigh --frame_ctr 0 --mac16 0xFFFF --mac64 01:02:03:00:00:00:00:02 --pan_id 0x1234 --index 0")
|
||||
self.command("First", "add-neigh --frame_ctr 0 --mac16 0xFFFF --mac64 01:02:03:00:00:00:00:03 --pan_id 0x1234 --index 1")
|
||||
self.command("Second", "add-neigh --frame_ctr 0 --mac16 0xFFFF --mac64 01:02:03:00:00:00:00:01 --pan_id 0x1234 --index 0")
|
||||
self.command("Third", "add-neigh --frame_ctr 0 --mac16 0xFFFF --mac64 01:02:03:00:00:00:00:01 --pan_id 0x1234 --index 0")
|
||||
|
||||
self.command("Second", "config-status --data_ind abcde")
|
||||
self.command("Third", "config-status --data_ind 12345")
|
||||
|
||||
#Runs into timing issues if extensive printing is enabled
|
||||
self.command("*", "silent-mode on")
|
||||
self.command("First", "data --dst_addr 01:02:03:00:00:00:00:02 --msdu_length 5 --msdu abcde --indirect_tx true --wait_for_confirm false")
|
||||
self.command("Second", "poll --coord_address 01:02:03:00:00:00:00:01")
|
||||
|
||||
self.command("First", "data")
|
||||
self.command("First", "data")
|
||||
self.command("Second", "poll")
|
||||
self.command("Second", "poll")
|
||||
self.command("Second", "config-status --poll 235")
|
||||
self.command("Second", "poll")
|
||||
|
||||
self.command("Second", "config-status --poll 235")
|
||||
self.command("First", "data --dst_addr 01:02:03:00:00:00:00:03 --msdu 12345")
|
||||
self.command("Second", "poll")
|
||||
self.command("Third", "poll --coord_address 01:02:03:00:00:00:00:01")
|
||||
self.command("*", "silent-mode off")
|
||||
|
||||
def tearDown(self):
|
||||
self.reset_dut()
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
"""
|
||||
Copyright (c) 2017, 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.
|
||||
"""
|
||||
|
||||
import os,sys
|
||||
from icetea_lib.bench import Bench
|
||||
|
||||
class Testcase(Bench):
|
||||
def __init__(self):
|
||||
Bench.__init__(self, name = "send_large_payloads",
|
||||
title = "Data transmission test with large packets",
|
||||
status = "development",
|
||||
type = "reliability",
|
||||
subtype = "",
|
||||
execution = {
|
||||
"skip": {
|
||||
"value": False,
|
||||
"reason": ""
|
||||
}
|
||||
},
|
||||
author = "Valtteri Erkkila",
|
||||
purpose = "Repeatedly sends long packets, checking that the payload is correct in each one",
|
||||
feature = ["MCPS-DATA"],
|
||||
component = ["MAC"],
|
||||
requirements = {
|
||||
"duts": {
|
||||
'*': {
|
||||
"count":2,
|
||||
"type": "hardware",
|
||||
"allowed_platforms": ["K64F", "K66F", "NUCLEO_F429ZI", "KW24D", "UBLOX_EVK_ODIN_W2"],
|
||||
"application": {
|
||||
"name": "TEST_APPS-device-nanostack_mac_tester"
|
||||
}
|
||||
},
|
||||
"1":{"nick": "First"},
|
||||
"2":{"nick": "Second"}
|
||||
}}
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
self.channel = 11
|
||||
self.command("First", "addr --64-bit 01:02:03:00:00:00:00:01")
|
||||
self.command("Second", "addr --64-bit 01:02:03:00:00:00:00:02")
|
||||
|
||||
def case(self):
|
||||
#104 characters, headers are 2+1+2+8+8+2=23 bytes, resulting in a packet size of 127 (max)
|
||||
large_payload = "0123456789abcdefghjiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZZZZZZZZZ0123456789012345678901234567891234"
|
||||
self.command("First", "start --pan_coordinator true --logical_channel {}".format(self.channel))
|
||||
self.command("Second", "start --pan_coordinator false --logical_channel {}".format(self.channel))
|
||||
|
||||
self.command("First", "config-status --data_ind {}".format(large_payload))
|
||||
self.command("Second", "config-status --data_ind {}".format(large_payload))
|
||||
|
||||
self.command("First", "data --dst_addr 01:02:03:00:00:00:00:02 --msdu_length {} --msdu {}".format(len(large_payload), large_payload))
|
||||
self.command("Second", "wait --timeout 500")
|
||||
|
||||
self.command("Second", "data --dst_addr 01:02:03:00:00:00:00:01 --msdu_length {} --msdu {}".format(len(large_payload), large_payload))
|
||||
self.command("First", "wait --timeout 500")
|
||||
for i in range(0, 25):
|
||||
self.command("First", "data")
|
||||
self.command("Second", "wait")
|
||||
self.command("Second", "data")
|
||||
self.command("First", "wait")
|
||||
|
||||
def tearDown(self):
|
||||
self.reset_dut()
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
"""
|
||||
Copyright (c) 2017, 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.
|
||||
"""
|
||||
import os,sys
|
||||
# ensure that test/ directory is first choice for imports
|
||||
test_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
if not test_dir in sys.path:
|
||||
sys.path.insert(0, test_dir)
|
||||
from GenericTestcase import Bench
|
||||
from Error import TestStepFail
|
||||
|
||||
class Testcase(Bench):
|
||||
def __init__(self):
|
||||
Bench.__init__(self, name = "template", # Name should be the same as the filename
|
||||
title = "TITLE",
|
||||
status = "development",
|
||||
type = "TYPE",
|
||||
subtype = "",
|
||||
execution = {
|
||||
"skip": {
|
||||
"value": False,
|
||||
"reason": ""
|
||||
}
|
||||
},
|
||||
author = "Valtteri Erkkila",
|
||||
purpose = "",
|
||||
feature = [""],
|
||||
component = ["MAC"],
|
||||
requirements = {
|
||||
"duts": {
|
||||
'*': {
|
||||
"count":2, # Count must reflect the amount of specified devices below
|
||||
"type": "hardware",
|
||||
"application":{ "name":"generalTestApplication", "version": "1.0"},
|
||||
"rf_channel": 11
|
||||
},
|
||||
"1":{"nick": "First"},
|
||||
"2":{"nick": "Second"}
|
||||
}}
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def case(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
if __name__=='__main__':
|
||||
sys.exit( Testcase().run() )
|
||||
|
|
@ -43,15 +43,15 @@ class MultipleTestcase(Bench):
|
|||
|
||||
def socket_bind_port(self, socket_type):
|
||||
response = self.command("dut1", "socket new " + socket_type)
|
||||
socket_id = int(response.parsed['socket_id'])
|
||||
self.socket_id = int(response.parsed['socket_id'])
|
||||
|
||||
self.command("dut1", "socket " + str(socket_id) + " open")
|
||||
self.command("dut1", "socket " + str(self.socket_id) + " open")
|
||||
|
||||
self.command("dut1", "socket " + str(socket_id) + " bind port 1024")
|
||||
|
||||
self.command("dut1", "socket " + str(socket_id) + " delete")
|
||||
self.command("dut1", "socket " + str(self.socket_id) + " bind port 1024")
|
||||
|
||||
def teardown(self):
|
||||
self.command("dut1", "socket " + str(self.socket_id) + " delete")
|
||||
|
||||
self.command("dut1", "ifdown")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -62,15 +62,15 @@ class Testcase(Bench):
|
|||
self.used_port = 2000
|
||||
|
||||
response = self.command("dut1", "socket new TCPServer")
|
||||
server_base_socket_id = int(response.parsed['socket_id'])
|
||||
self.server_base_socket_id = int(response.parsed['socket_id'])
|
||||
|
||||
self.command("dut1", "socket " + str(server_base_socket_id) + " open")
|
||||
self.command("dut1", "socket " + str(server_base_socket_id) + " bind port " + str(self.used_port))
|
||||
self.command("dut1", "socket " + str(server_base_socket_id) + " listen")
|
||||
self.command("dut1", "socket " + str(self.server_base_socket_id) + " open")
|
||||
self.command("dut1", "socket " + str(self.server_base_socket_id) + " bind port " + str(self.used_port))
|
||||
self.command("dut1", "socket " + str(self.server_base_socket_id) + " listen")
|
||||
|
||||
response = self.command("dut1", "socket new TCPSocket")
|
||||
server_socket_id = int(response.parsed['socket_id'])
|
||||
self.command("dut1", "socket " + str(server_socket_id) + " open")
|
||||
self.server_socket_id = int(response.parsed['socket_id'])
|
||||
self.command("dut1", "socket " + str(self.server_socket_id) + " open")
|
||||
|
||||
response = self.command("dut2", "socket new TCPSocket")
|
||||
zero = response.timedelta
|
||||
|
|
@ -81,7 +81,7 @@ class Testcase(Bench):
|
|||
t.start()
|
||||
|
||||
wait = 5
|
||||
response = self.command("dut1", "socket " + str(server_base_socket_id) + " accept " + str(server_socket_id))
|
||||
response = self.command("dut1", "socket " + str(self.server_base_socket_id) + " accept " + str(self.server_socket_id))
|
||||
response.verify_response_duration(expected=wait, zero=zero, threshold_percent=10, break_in_fail=True)
|
||||
socket_id = int(response.parsed['socket_id'])
|
||||
|
||||
|
|
@ -94,10 +94,10 @@ class Testcase(Bench):
|
|||
if data != "hello":
|
||||
raise TestStepFail("Received data doesn't match the sent data")
|
||||
|
||||
self.command("dut1", "socket " + str(server_socket_id) + " delete")
|
||||
self.command("dut1", "socket " + str(server_base_socket_id) + " delete")
|
||||
self.command("dut2", "socket " + str(self.client_socket_id) + " delete")
|
||||
|
||||
def teardown(self):
|
||||
self.command("dut1", "socket " + str(self.server_socket_id) + " delete")
|
||||
self.command("dut1", "socket " + str(self.server_base_socket_id) + " delete")
|
||||
self.command("dut2", "socket " + str(self.client_socket_id) + " delete")
|
||||
|
||||
interfaceDown(self, ["dut1"])
|
||||
interfaceDown(self, ["dut2"])
|
||||
|
|
|
|||
|
|
@ -0,0 +1,106 @@
|
|||
"""
|
||||
Copyright 2018 ARM Limited
|
||||
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.
|
||||
"""
|
||||
|
||||
import threading
|
||||
import time
|
||||
|
||||
from icetea_lib.bench import Bench
|
||||
from interface import interfaceUp, interfaceDown
|
||||
#from mbed_clitest.tools import test_case
|
||||
#from mbed_clitest.TestStepError import SkippedTestcaseException
|
||||
from icetea_lib.TestStepError import TestStepFail
|
||||
|
||||
class Testcase(Bench):
|
||||
def __init__(self):
|
||||
Bench.__init__(self,
|
||||
name="TCPSOCKET_ACCEPT",
|
||||
title = "TCPSOCKET_ACCEPT",
|
||||
purpose = "Test that TCPSocket::bind(), TCPSocket::listen() and TCPSocket::accept() works",
|
||||
status = "released",
|
||||
component= ["mbed-os", "netsocket"],
|
||||
type="smoke",
|
||||
subtype="socket",
|
||||
requirements={
|
||||
"duts": {
|
||||
'*': { #requirements for all nodes
|
||||
"count":2,
|
||||
"type": "hardware",
|
||||
"application": {
|
||||
"name": "TEST_APPS-device-socket_app"
|
||||
}
|
||||
},
|
||||
"1": {"nick": "dut1"},
|
||||
"2": {"nick": "dut2"}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
def setup(self):
|
||||
interface = interfaceUp(self, ["dut1"])
|
||||
self.server_ip = interface["dut1"]["ip"]
|
||||
interface = interfaceUp(self, ["dut2"])
|
||||
self.client_ip = interface["dut2"]["ip"]
|
||||
|
||||
def clientThread(self):
|
||||
self.logger.info("Starting")
|
||||
time.sleep(5) #wait accept from server
|
||||
self.command("dut2", "socket " + str(self.client_socket_id) + " open")
|
||||
self.command("dut2", "socket " + str(self.client_socket_id) + " connect " + str(self.server_ip) + " " + str(self.used_port))
|
||||
|
||||
|
||||
def case(self):
|
||||
self.used_port = 2000
|
||||
|
||||
response = self.command("dut1", "socket new TCPSocket")
|
||||
self.server_base_socket_id = int(response.parsed['socket_id'])
|
||||
|
||||
self.command("dut1", "socket " + str(self.server_base_socket_id) + " open")
|
||||
response = self.command("dut1", "socket " + str(self.server_base_socket_id) + " bind port " + str(self.used_port), report_cmd_fail = False)
|
||||
if response.retcode == -1:
|
||||
if (response.verify_trace("NSAPI_ERROR_UNSUPPORTED", break_in_fail = False)):
|
||||
raise SkippedTestcaseException("UNSUPPORTED")
|
||||
else:
|
||||
TestStepFail("Bind port failed")
|
||||
self.command("dut1", "socket " + str(self.server_base_socket_id) + " listen")
|
||||
|
||||
response = self.command("dut2", "socket new TCPSocket")
|
||||
self.client_socket_id = int(response.parsed['socket_id'])
|
||||
|
||||
#Create a thread which calls client connect()
|
||||
t = threading.Thread(name='clientThread', target=self.clientThread)
|
||||
t.start()
|
||||
|
||||
response = self.command("dut1", "socket " + str(self.server_base_socket_id) + " accept")
|
||||
|
||||
t.join()
|
||||
self.accept_socket_id = int(response.parsed['socket_id'])
|
||||
if response.timedelta < 5.0: # Check that socket accept call blocks
|
||||
raise TestStepFail("Longer response time expected")
|
||||
|
||||
self.command("dut1", "socket " + str(self.accept_socket_id) + " send hello")
|
||||
|
||||
response = self.command("dut2", "socket " + str(self.client_socket_id) + " recv 5")
|
||||
data = response.parsed['data'].replace(":","")
|
||||
|
||||
if data != "hello":
|
||||
raise TestStepFail("Received data doesn't match the sent data")
|
||||
|
||||
def teardown(self):
|
||||
response = self.command("dut2", "socket " + str(self.client_socket_id) + " delete")
|
||||
response = self.command("dut1", "socket " + str(self.server_base_socket_id) + " delete")
|
||||
response = self.command("dut1", "socket " + str(self.accept_socket_id) + " close")
|
||||
|
||||
interfaceDown(self, ["dut1"])
|
||||
interfaceDown(self, ["dut2"])
|
||||
|
|
@ -48,31 +48,30 @@ class Testcase(Bench):
|
|||
|
||||
def case(self):
|
||||
response = self.command("dut1", "socket new TCPSocket")
|
||||
socket_id = int(response.parsed['socket_id'])
|
||||
self.socket_id = int(response.parsed['socket_id'])
|
||||
|
||||
self.command("dut1", "socket " + str(socket_id) + " open")
|
||||
self.command("dut1", "socket " + str(socket_id) + " connect echo.mbedcloudtesting.com 7")
|
||||
self.command("dut1", "socket " + str(self.socket_id) + " open")
|
||||
self.command("dut1", "socket " + str(self.socket_id) + " connect echo.mbedcloudtesting.com 7")
|
||||
|
||||
for i in range(2):
|
||||
sentData = ""
|
||||
for size in (100, 200, 300, 120, 500):
|
||||
packet = Randomize.random_string(max_len=size, min_len=size, chars=string.ascii_uppercase)
|
||||
sentData += packet
|
||||
response = self.command("dut1", "socket " + str(socket_id) + " send " + str(packet))
|
||||
response.verify_trace("TCPSocket::send() returned: " + str(size))
|
||||
response = self.command("dut1", "socket " + str(self.socket_id) + " send " + str(packet))
|
||||
response.verify_trace("Socket::send() returned: " + str(size))
|
||||
|
||||
received = 0
|
||||
data = ""
|
||||
totalSize = 1220
|
||||
while received < totalSize:
|
||||
response = self.command("dut1", "socket " + str(socket_id) + " recv " + str(totalSize))
|
||||
response = self.command("dut1", "socket " + str(self.socket_id) + " recv " + str(totalSize))
|
||||
data += response.parsed['data'].replace(":", "")
|
||||
received += int(response.parsed['received_bytes'])
|
||||
|
||||
if data != sentData:
|
||||
raise TestStepFail("Received data doesn't match the sent data")
|
||||
|
||||
self.command("dut1", "socket " + str(socket_id) + " delete")
|
||||
|
||||
def teardown(self):
|
||||
self.command("dut1", "socket " + str(self.socket_id) + " delete")
|
||||
self.command("dut1", "ifdown")
|
||||
|
|
|
|||
|
|
@ -119,6 +119,13 @@ set(unittest-includes-base
|
|||
"${PROJECT_SOURCE_DIR}/../features/cellular/framework/AT"
|
||||
"${PROJECT_SOURCE_DIR}/../features/cellular/framework"
|
||||
"${PROJECT_SOURCE_DIR}/../features/cellular/framework/common"
|
||||
"${PROJECT_SOURCE_DIR}/../features/lorawan"
|
||||
"${PROJECT_SOURCE_DIR}/../features/lorawan/lorastack"
|
||||
"${PROJECT_SOURCE_DIR}/../features/lorawan/lorastack/mac"
|
||||
"${PROJECT_SOURCE_DIR}/../features/lorawan/lorastack/phy"
|
||||
"${PROJECT_SOURCE_DIR}/../features/lorawan/system"
|
||||
"${PROJECT_SOURCE_DIR}/../features/mbedtls"
|
||||
"${PROJECT_SOURCE_DIR}/../features/mbedtls/inc"
|
||||
)
|
||||
|
||||
# Create a list for test suites.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
## Unit testing
|
||||
|
||||
This document describes how to write and test unit tests for Mbed OS. To prevent and solve problems, please see the [troubleshooting](#troubleshooting) section.
|
||||
This document describes how to write and test unit tests for Arm Mbed OS. To prevent and solve problems, please see the [troubleshooting](#troubleshooting) section.
|
||||
|
||||
### Introduction
|
||||
|
||||
|
|
@ -11,12 +11,12 @@ Unit tests test code in small sections on a host machine. Unlike other testing t
|
|||
Please install the following dependencies to use Mbed OS unit testing.
|
||||
|
||||
- GNU toolchains.
|
||||
- GCC 6 or later. We recommend you use MinGW-W64 on Windows, but any Windows port of the above GCC versions works.
|
||||
- GCC 6 or later. We recommend you use MinGW-W64 on Windows, but any Windows port of the above GCC versions works. Default compilers can be used on Mac OS instead of GCC to shorten build times, but code coverage results can then differ.
|
||||
- CMake 3.0 or newer.
|
||||
- Python 2.7.x, 3.5 or newer.
|
||||
- Pip 10.0 or newer.
|
||||
- Gcovr 4.1 or newer.
|
||||
- Mbed CLI 1.8.0 or newer.
|
||||
- Arm Mbed CLI 1.8.0 or newer.
|
||||
|
||||
Detailed instructions for supported operating systems are below.
|
||||
|
||||
|
|
@ -30,12 +30,13 @@ Detailed instructions for supported operating systems are below.
|
|||
sudo easy_install pip
|
||||
```
|
||||
|
||||
1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/latest/tools/arm-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`.
|
||||
1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/latest/tools/developing-arm-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`.
|
||||
|
||||
#### Installing dependencies on macOS
|
||||
|
||||
1. Install [Homebrew](https://brew.sh/).
|
||||
1. Install GCC compilers and CMake with: `brew install gcc cmake`.
|
||||
1. Install Xcode Command Line Tools with `xcode-select --install`.
|
||||
1. Install CMake with: `brew install cmake`.
|
||||
1. Install Python and Pip:
|
||||
|
||||
```
|
||||
|
|
@ -43,7 +44,8 @@ Detailed instructions for supported operating systems are below.
|
|||
sudo easy_install pip
|
||||
```
|
||||
|
||||
1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/latest/tools/arm-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`.
|
||||
1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/latest/tools/developing-arm-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`.
|
||||
1. (Optional) Install GCC with `brew install gcc`.
|
||||
|
||||
#### Installing dependencies on Windows
|
||||
|
||||
|
|
@ -51,7 +53,7 @@ Detailed instructions for supported operating systems are below.
|
|||
1. Download CMake binaries from https://cmake.org/download/, and run the installer.
|
||||
1. Download Python 2.7 or Python 3 from https://www.python.org/getit/, and run the installer.
|
||||
1. Add MinGW, CMake and Python into system PATH.
|
||||
1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/latest/tools/arm-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`.
|
||||
1. Install Gcovr and [Mbed CLI](https://os.mbed.com/docs/latest/tools/developing-arm-mbed-cli.html) with `pip install "gcovr>=4.1" mbed-cli`.
|
||||
|
||||
### Test code structure
|
||||
|
||||
|
|
@ -69,7 +71,7 @@ The build system automatically generates names of test suites. The name is const
|
|||
|
||||
### Unit testing with Mbed CLI
|
||||
|
||||
Mbed CLI supports unit tests through `mbed test --unittests` command. For information on using Mbed CLI, please see the [CLI documentation in handbook](https://os.mbed.com/docs/latest/tools/arm-mbed-cli.html).
|
||||
Mbed CLI supports unit tests through `mbed test --unittests` command. For information on using Mbed CLI, please see the [CLI documentation](https://os.mbed.com/docs/latest/tools/developing-arm-mbed-cli.html).
|
||||
|
||||
### Writing unit tests
|
||||
|
||||
|
|
@ -154,7 +156,7 @@ TEST_F(TestSemaphore, constructor)
|
|||
|
||||
### Building and running unit tests
|
||||
|
||||
Use Mbed CLI to build and run unit tests. For advanced use, you can run CMake and a make program directly.
|
||||
Use Mbed CLI to build and run unit tests. For advanced use, you can run CMake and a Make program directly.
|
||||
|
||||
#### Build tests directly with CMake
|
||||
|
||||
|
|
@ -162,9 +164,11 @@ Use Mbed CLI to build and run unit tests. For advanced use, you can run CMake an
|
|||
1. Move to the build directory `cd UNITTESTS/build`.
|
||||
1. Run CMake using a relative path to `UNITTESTS` folder as the argument. So from `UNITTESTS/build` use `cmake ..`:
|
||||
- Add `-g [generator]` if generating other than Unix Makefiles such in case of MinGW use `-g "MinGW Makefiles"`.
|
||||
- Add `-DCOVERAGE:True` to add coverage compiler flags.
|
||||
- Add `-DCMAKE_MAKE_PROGRAM=<value>`, `-DCMAKE_CXX_COMPILER=<value>` and `-DCMAKE_C_COMPILER=<value>` to use a specific Make program and compilers.
|
||||
- Add `-DCMAKE_BUILD_TYPE=Debug` to build a debug build.
|
||||
- Add `-DCOVERAGE=True` to add coverage compiler flags.
|
||||
- See the [CMake manual](https://cmake.org/cmake/help/v3.0/manual/cmake.1.html) for more information.
|
||||
1. Run a make program (Make, Gmake, Mingw32-make and so on) to build the tests.
|
||||
1. Run a Make program to build the tests.
|
||||
|
||||
#### Run tests directly with CTest
|
||||
|
||||
|
|
@ -177,14 +181,27 @@ Run a test binary in the build directory to run a unit test suite. To run multip
|
|||
1. Add test executables into the list.
|
||||
1. Run them.
|
||||
|
||||
### Debugging
|
||||
|
||||
1. Use Mbed CLI to build a debug build. For advanced use, run CMake directly with `-DCMAKE_BUILD_TYPE=Debug`, and then run a Make program.
|
||||
1. Run GDB with a test executable as an argument to debug unit tests.
|
||||
|
||||
### Get code coverage
|
||||
|
||||
Use Mbed CLI to generate code coverage reports. For advanced use, you can run Gcovr or any other code coverage tool directly in the build directory.
|
||||
Use Mbed CLI to generate code coverage reports. For advanced use, follow these steps:
|
||||
|
||||
1. Run CMake with both `-DCMAKE_BUILD_TYPE=Debug` and `-DCOVERAGE=True`.
|
||||
1. Run a Make program to build the tests.
|
||||
1. Run the tests.
|
||||
1. Run Gcovr or any other code coverage tool directly in the build directory.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
**Problem:** Generic problems with CMake or with the build process.
|
||||
* **Solution**: Delete the build directory. Make sure that CMake, g++, gcc and a make program can be found in the path and are correct versions.
|
||||
* **Solution**: Delete the build directory. Make sure that CMake, g++, GCC and a Make program can be found in the path and are correct versions.
|
||||
|
||||
**Problem:** Virus protection identifies files generated by CMake as malicious and quarantines the files on Windows.
|
||||
* **Solution**: Restore the false positive files from the quarantine.
|
||||
|
||||
**Problem:** CMake compiler check fails on Mac OS Mojave when using GCC-8.
|
||||
* **Solution**: Make sure gnm (binutils) is not installed. Uninstall binutils with `brew uninstall binutils`.
|
||||
|
|
|
|||
|
|
@ -26,10 +26,12 @@ using namespace events;
|
|||
class TestAT_CellularDevice : public testing::Test {
|
||||
protected:
|
||||
|
||||
void SetUp() {
|
||||
void SetUp()
|
||||
{
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
void TearDown()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,17 +20,17 @@ set(unittest-sources
|
|||
# Test files
|
||||
set(unittest-test-sources
|
||||
features/cellular/framework/AT/at_cellulardevice/at_cellulardevicetest.cpp
|
||||
stubs/AT_CellularNetwork_stub.cpp
|
||||
stubs/ATHandler_stub.cpp
|
||||
stubs/AT_CellularSMS_stub.cpp
|
||||
stubs/AT_CellularSIM_stub.cpp
|
||||
stubs/AT_CellularPower_stub.cpp
|
||||
stubs/AT_CellularInformation_stub.cpp
|
||||
stubs/CellularUtil_stub.cpp
|
||||
stubs/AT_CellularBase_stub.cpp
|
||||
stubs/NetworkInterface_stub.cpp
|
||||
stubs/EventQueue_stub.cpp
|
||||
stubs/FileHandle_stub.cpp
|
||||
stubs/mbed_assert_stub.cpp
|
||||
stubs/AT_CellularNetwork_stub.cpp
|
||||
stubs/ATHandler_stub.cpp
|
||||
stubs/AT_CellularSMS_stub.cpp
|
||||
stubs/AT_CellularSIM_stub.cpp
|
||||
stubs/AT_CellularPower_stub.cpp
|
||||
stubs/AT_CellularInformation_stub.cpp
|
||||
stubs/CellularUtil_stub.cpp
|
||||
stubs/AT_CellularBase_stub.cpp
|
||||
stubs/NetworkInterface_stub.cpp
|
||||
stubs/EventQueue_stub.cpp
|
||||
stubs/FileHandle_stub.cpp
|
||||
stubs/mbed_assert_stub.c
|
||||
stubs/CellularDevice_stub.cpp
|
||||
)
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ TEST_F(TestAT_CellularInformation, test_AT_CellularInformation_get_manufacturer)
|
|||
AT_CellularInformation aci(ah);
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::read_string_value = "some";
|
||||
ATHandler_stub::read_string_value = (char *)"some";
|
||||
ATHandler_stub::ssize_value = 4;
|
||||
|
||||
char buf[8];
|
||||
|
|
@ -82,7 +82,7 @@ TEST_F(TestAT_CellularInformation, test_AT_CellularInformation_get_model)
|
|||
AT_CellularInformation aci(ah);
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::read_string_value = "model";
|
||||
ATHandler_stub::read_string_value = (char *)"model";
|
||||
ATHandler_stub::ssize_value = 5;
|
||||
char buf[8];
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == aci.get_model(buf, 8));
|
||||
|
|
@ -105,7 +105,7 @@ TEST_F(TestAT_CellularInformation, test_AT_CellularInformation_get_revision)
|
|||
AT_CellularInformation *aci = new AT_CellularInformation(ah);
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::read_string_value = "revision";
|
||||
ATHandler_stub::read_string_value = (char *)"revision";
|
||||
ATHandler_stub::ssize_value = 8;
|
||||
|
||||
char buf[9];
|
||||
|
|
@ -129,7 +129,7 @@ TEST_F(TestAT_CellularInformation, test_AT_CellularInformation_get_serial_number
|
|||
AT_CellularInformation aci(ah);
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::read_string_value = "1234567";
|
||||
ATHandler_stub::read_string_value = (char *)"1234567";
|
||||
ATHandler_stub::ssize_value = 7;
|
||||
char buf[8];
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ TEST_F(TestAT_CellularInformation, test_AT_CellularInformation_get_serial_number
|
|||
EXPECT_TRUE(strlen(buf) == 0);
|
||||
|
||||
ATHandler_stub::nsapi_error_value = NSAPI_ERROR_OK;
|
||||
ATHandler_stub::read_string_value = "1234567";
|
||||
ATHandler_stub::read_string_value = (char *)"1234567";
|
||||
ATHandler_stub::ssize_value = 7;
|
||||
AT_CellularBase_stub::supported_bool = true;
|
||||
EXPECT_TRUE(NSAPI_ERROR_OK == aci.get_serial_number(buf, 8, CellularInformation::IMEI));
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue