Skip to content

Commit 14e229e

Browse files
committed
Cordio: Add tests that validates a cordio port.
The first test focuse on the transport by testing that the reset sequence is correctly sent to the controller and properly received. The second test validates that the reset sequence fullfill the right state of the stack and ensure that bluetooth initialization succeed.
1 parent 799ba08 commit 14e229e

File tree

2 files changed

+288
-0
lines changed
  • features/FEATURE_BLE/targets/TARGET_CORDIO/TESTS/cordio_hci

2 files changed

+288
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <stdio.h>
18+
19+
#include "events/mbed_events.h"
20+
#include "platform/Callback.h"
21+
22+
#include "ble/BLE.h"
23+
24+
#include "greentea-client/test_env.h"
25+
#include "utest/utest.h"
26+
#include "unity/unity.h"
27+
28+
#include "hci_api.h"
29+
#include "hci_cmd.h"
30+
#include "hci_core.h"
31+
#include "dm_api.h"
32+
#include "bstream.h"
33+
34+
using namespace utest::v1;
35+
using mbed::callback;
36+
37+
#define INITIALIZATION_TIMEOUT (10 * 1000)
38+
39+
static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE);
40+
41+
enum initialization_state_t {
42+
WAITING_FOR_INITIALIZATION,
43+
INITIALIZATION_FAILURE,
44+
INITIALIZATION_SUCCESS
45+
};
46+
47+
static initialization_state_t initialization_state = WAITING_FOR_INITIALIZATION;
48+
49+
static void process_ble_events(BLE::OnEventsToProcessCallbackContext* context) {
50+
BLE &ble = BLE::Instance();
51+
event_queue.call(callback(&ble, &BLE::processEvents));
52+
}
53+
54+
static void on_initialization_complete(BLE::InitializationCompleteCallbackContext *params) {
55+
if (params->error == BLE_ERROR_NONE) {
56+
initialization_state = INITIALIZATION_SUCCESS;
57+
} else {
58+
initialization_state = INITIALIZATION_SUCCESS;
59+
}
60+
61+
event_queue.break_dispatch();
62+
}
63+
64+
static void test_stack_initialization() {
65+
BLE &ble = BLE::Instance();
66+
ble.onEventsToProcess(process_ble_events);
67+
ble.init(on_initialization_complete);
68+
event_queue.dispatch(INITIALIZATION_TIMEOUT);
69+
70+
// At this point ble is suppose to be initialized; inspect the various state
71+
// of the stack.
72+
TEST_ASSERT_EQUAL(INITIALIZATION_SUCCESS, initialization_state);
73+
TEST_ASSERT_NOT_EQUAL(0, hciCoreCb.bufSize);
74+
TEST_ASSERT_NOT_EQUAL(0, hciCoreCb.numBufs);
75+
TEST_ASSERT_NOT_EQUAL(0, hciCoreCb.availBufs);
76+
77+
uint8_t invalid_le_states[HCI_LE_STATES_LEN] = { 0 };
78+
TEST_ASSERT_NOT_EQUAL(0, memcmp(invalid_le_states, hciCoreCb.leStates, HCI_LE_STATES_LEN));
79+
TEST_ASSERT_NOT_EQUAL(0, hciCoreCb.whiteListSize);
80+
81+
// Note: cannot test supported features are the list may be null
82+
// Note: cannot test resolving list size as this may be null
83+
}
84+
85+
Case cases[] = {
86+
Case("Test cordio stack reset sequence", test_stack_initialization),
87+
};
88+
89+
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
90+
GREENTEA_SETUP(15, "default_auto");
91+
return verbose_test_setup_handler(number_of_cases);
92+
}
93+
94+
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
95+
96+
int main() {
97+
return !Harness::run(specification);
98+
}
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2018 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#include <stdio.h>
18+
19+
#include "driver/CordioHCITransportDriver.h"
20+
#include "driver/CordioHCIDriver.h"
21+
#include "hci_defs.h"
22+
#include "rtos/Semaphore.h"
23+
24+
#include "greentea-client/test_env.h"
25+
#include "utest/utest.h"
26+
#include "unity/unity.h"
27+
28+
using namespace utest::v1;
29+
30+
using ble::vendor::cordio::CordioHCIDriver;
31+
using ble::vendor::cordio::CordioHCITransportDriver;
32+
33+
extern ble::vendor::cordio::CordioHCIDriver& ble_cordio_get_hci_driver();
34+
35+
namespace ble {
36+
namespace vendor {
37+
namespace cordio {
38+
39+
struct CordioHCIHook {
40+
static CordioHCIDriver& get_driver() {
41+
return ble_cordio_get_hci_driver();
42+
}
43+
44+
static CordioHCITransportDriver& get_transport_driver() {
45+
return get_driver()._transport_driver;
46+
}
47+
48+
static void set_data_received_handler(void (*handler)(uint8_t*, uint8_t)) {
49+
get_transport_driver().set_data_received_handler(handler);
50+
}
51+
};
52+
53+
} // namespace cordio
54+
} // namespace vendor
55+
} // namespace ble
56+
57+
using ble::vendor::cordio::CordioHCIHook;
58+
59+
#define RESET_COMMAND_TIMEOUT (10 * 1000)
60+
#define RESET_PARAMETER_LENGTH 4
61+
#define RESET_EXPECTED_STATUS 0
62+
#define HCI_OPCODE_RESET_LSB (HCI_OPCODE_RESET & 0xFF)
63+
#define HCI_OPCODE_RESET_MSB (HCI_OPCODE_RESET >> 8)
64+
65+
enum test_result_t {
66+
TEST_RESULT_TIMEOUT_FAILURE,
67+
TEST_RESULT_FAILURE,
68+
TEST_RESULT_SUCCESS
69+
};
70+
71+
enum state_t {
72+
WAITING_EVENT_PACKET,
73+
WAITING_EVENT_CODE_COMPLETE,
74+
WAITING_PARAMETER_LENGTH,
75+
WAITING_STATUS,
76+
WAITING_NUM_HCI_EVT_PACKET,
77+
WAITING_OPCODE_LSB,
78+
WAITING_OPCODE_MSB,
79+
DONE
80+
};
81+
82+
static state_t state = WAITING_EVENT_PACKET;
83+
static test_result_t test_result = TEST_RESULT_TIMEOUT_FAILURE;
84+
85+
static rtos::Semaphore sem;
86+
87+
static uint8_t reset_cmd[] = {
88+
HCI_OPCODE_RESET_LSB, HCI_OPCODE_RESET_MSB, // reset opcode
89+
0 // parameter length
90+
};
91+
92+
static void hci_driver_rx_dummy_handler(uint8_t* data, uint8_t len) { }
93+
94+
static void hci_driver_rx_reset_handler(uint8_t* data, uint8_t len) {
95+
for (size_t i = 0; i < len; ++i) {
96+
switch (state) {
97+
case WAITING_EVENT_PACKET:
98+
if (data[i] == HCI_EVT_TYPE) {
99+
state = WAITING_EVENT_CODE_COMPLETE;
100+
} else {
101+
test_result = TEST_RESULT_FAILURE;
102+
}
103+
break;
104+
105+
case WAITING_EVENT_CODE_COMPLETE:
106+
if (data[i] == HCI_CMD_CMPL_EVT) {
107+
state = WAITING_PARAMETER_LENGTH;
108+
} else {
109+
test_result = TEST_RESULT_FAILURE;
110+
}
111+
break;
112+
113+
case WAITING_PARAMETER_LENGTH:
114+
if (data[i] == RESET_PARAMETER_LENGTH) {
115+
state = WAITING_NUM_HCI_EVT_PACKET;
116+
} else {
117+
test_result = TEST_RESULT_FAILURE;
118+
}
119+
break;
120+
121+
case WAITING_NUM_HCI_EVT_PACKET:
122+
// controler dependent; can be any value, pass on to the next token
123+
state = WAITING_OPCODE_LSB;
124+
break;
125+
126+
case WAITING_OPCODE_LSB:
127+
if (data[i] == HCI_OPCODE_RESET_LSB) {
128+
state = WAITING_OPCODE_MSB;
129+
} else {
130+
test_result = TEST_RESULT_FAILURE;
131+
}
132+
break;
133+
134+
case WAITING_OPCODE_MSB:
135+
if (data[i] == HCI_OPCODE_RESET_MSB) {
136+
state = WAITING_STATUS;
137+
} else {
138+
test_result = TEST_RESULT_FAILURE;
139+
}
140+
break;
141+
142+
case WAITING_STATUS:
143+
if (data[i] == RESET_EXPECTED_STATUS) {
144+
test_result = TEST_RESULT_SUCCESS;
145+
state = DONE;
146+
} else {
147+
test_result = TEST_RESULT_FAILURE;
148+
}
149+
break;
150+
}
151+
152+
if (test_result != TEST_RESULT_TIMEOUT_FAILURE) {
153+
CordioHCIHook::set_data_received_handler(hci_driver_rx_dummy_handler);
154+
sem.release();
155+
return;
156+
}
157+
}
158+
}
159+
160+
void test_reset_command() {
161+
CordioHCIDriver& driver = CordioHCIHook::get_driver();
162+
CordioHCITransportDriver& transport_driver = CordioHCIHook::get_transport_driver();
163+
164+
driver.initialize();
165+
166+
CordioHCIHook::set_data_received_handler(hci_driver_rx_reset_handler);
167+
transport_driver.write(HCI_CMD_TYPE, sizeof(reset_cmd), reset_cmd);
168+
sem.wait(RESET_COMMAND_TIMEOUT);
169+
CordioHCIHook::set_data_received_handler(hci_driver_rx_dummy_handler);
170+
171+
driver.terminate();
172+
173+
TEST_ASSERT_EQUAL(TEST_RESULT_SUCCESS, test_result);
174+
TEST_ASSERT_EQUAL(DONE, state);
175+
}
176+
177+
Case cases[] = {
178+
Case("Test reset command", test_reset_command),
179+
};
180+
181+
utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
182+
GREENTEA_SETUP(15, "default_auto");
183+
return verbose_test_setup_handler(number_of_cases);
184+
}
185+
186+
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
187+
188+
int main() {
189+
return !Harness::run(specification);
190+
}

0 commit comments

Comments
 (0)