Skip to content

Commit 5ce26b1

Browse files
author
Cruz Monrreal
authored
Merge pull request #6927 from AriParkkila/cellular-debug
Cellular: AT debugging improved
2 parents 527f9a1 + 3abfa45 commit 5ce26b1

File tree

11 files changed

+359
-230
lines changed

11 files changed

+359
-230
lines changed

features/cellular/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ You can define the debug tracing level in the `mbed_app.json` configuration file
7272

7373
The `TESTS` folder contains Greentea tests for cellular specific classes. You need to give relevant configuration file with `--app-config` parameter, e.g.:
7474

75-
mbed test -n features-cellular-tests-* --app-config features\cellular\TESTS\socket\udp\template_mbed_app.json -vv
75+
mbed test -n features-cellular-tests-* --app-config features\cellular\TESTS\socket\udp\template_mbed_app.json.txt -v
7676

7777
Note that Greentea tests use SIM PIN so you need to change that or your SIM card may get locked.
7878

features/cellular/TESTS/socket/udp/main.cpp

Lines changed: 155 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -55,73 +55,141 @@ static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SER
5555
static rtos::Semaphore network_semaphore(0);
5656
static CellularConnectionFSM cellular;
5757

58+
#if MBED_CONF_MBED_TRACE_ENABLE
59+
60+
static rtos::Mutex trace_mutex;
61+
62+
void trace_wait()
63+
{
64+
trace_mutex.lock();
65+
}
66+
67+
void trace_release()
68+
{
69+
trace_mutex.unlock();
70+
}
71+
72+
static char time_st[sizeof("[12345678]") + 1];
73+
74+
static char *trace_time(size_t ss)
75+
{
76+
snprintf(time_st, sizeof("[12345678]"), "[%08llu]", rtos::Kernel::get_ms_count());
77+
return time_st;
78+
}
79+
80+
static void trace_open()
81+
{
82+
mbed_trace_init();
83+
mbed_trace_prefix_function_set(&trace_time);
84+
mbed_trace_mutex_wait_function_set(trace_wait);
85+
mbed_trace_mutex_release_function_set(trace_release);
86+
87+
mbed_cellular_trace::mutex_wait_function_set(trace_wait);
88+
mbed_cellular_trace::mutex_release_function_set(trace_release);
89+
}
90+
91+
static void trace_close()
92+
{
93+
mbed_cellular_trace::mutex_wait_function_set(NULL);
94+
mbed_cellular_trace::mutex_release_function_set(NULL);
95+
96+
mbed_trace_free();
97+
}
98+
99+
#endif // MBED_CONF_MBED_TRACE_ENABLE
100+
58101
static SocketAddress echo_server_addr;
59102

103+
static rtos::EventFlags eventFlags;
104+
60105
class EchoSocket : public UDPSocket {
61106
public:
62-
EchoSocket(int size) : UDPSocket(), _async_flag(0), _data(0), _size(size) {
63-
}
64-
virtual ~EchoSocket() {
65-
delete _data;
66-
}
67-
void set_async(int async) {
68-
_async_flag = async;
107+
EchoSocket(int size) : UDPSocket(), _data(0), _size(size), _async_flag(0), _tx_pending(false), _rx_pending(false)
108+
{
109+
}
110+
virtual ~EchoSocket()
111+
{
112+
delete _data;
113+
}
114+
void set_async(int async)
115+
{
116+
_async_flag = async;
69117
if (_async_flag) {
70118
set_blocking(false);
71119
sigio(callback(this, &EchoSocket::async_callback));
120+
}
121+
}
122+
123+
void test_sendto(const char *const hostname = NULL)
124+
{
125+
if (!_data) {
126+
_data = new uint8_t[_size];
127+
for (int i = 0; i < _size; i++) {
128+
_data[i] = (uint8_t)rand();
129+
}
130+
}
131+
nsapi_size_or_error_t ret;
132+
if (hostname) {
133+
ret = sendto(hostname, ECHO_SERVER_UDP_PORT, _data, _size);
72134
} else {
73-
set_blocking(true);
74-
set_timeout(SOCKET_TIMEOUT);
75-
sigio(NULL);
135+
ret = sendto(echo_server_addr, _data, _size);
76136
}
137+
if (ret == _size) { // send successful
138+
_tx_pending = false;
139+
} else {
140+
TEST_ASSERT(_async_flag && ret == NSAPI_ERROR_WOULD_BLOCK);
141+
_tx_pending = true;
142+
}
143+
}
144+
145+
void test_recvfrom()
146+
{
147+
uint8_t *buf = new uint8_t[_size];
148+
memset(buf, 0, _size);
149+
SocketAddress recv_address;
150+
nsapi_size_or_error_t ret = recvfrom(&recv_address, buf, _size);
151+
if (ret == _size) { // recv successful
152+
_rx_pending = false;
153+
TEST_ASSERT(recv_address == echo_server_addr);
154+
TEST_ASSERT(memcmp(_data, buf, _size) == 0);
155+
delete _data;
156+
_data = NULL;
157+
_rx_pending = false;
158+
} else {
159+
TEST_ASSERT(_async_flag && ret == NSAPI_ERROR_WOULD_BLOCK);
160+
_rx_pending = true;
161+
}
162+
delete buf;
163+
}
164+
165+
bool async_process()
166+
{
167+
if (_tx_pending) {
168+
test_sendto();
169+
}
170+
if (_rx_pending) {
171+
test_recvfrom();
172+
}
173+
return _tx_pending | _rx_pending;
174+
}
77175

78-
}
79-
void test_sendto(const char *const hostname = NULL) {
80-
_data = new uint8_t[_size];
81-
for (int i=0; i<_size; i++) {
82-
_data[i] = (uint8_t)rand();
83-
}
84-
// clear pending events
85-
TEST_ASSERT(!(EchoSocket::eventFlags.clear(_async_flag) & osFlagsError));
86-
if (hostname) {
87-
TEST_ASSERT(sendto(hostname, ECHO_SERVER_UDP_PORT, _data, _size) == _size);
88-
} else {
89-
TEST_ASSERT(sendto(echo_server_addr, _data, _size) == _size);
90-
}
91-
}
92-
void test_recvfrom() {
93-
if (_async_flag) {
94-
TEST_ASSERT((EchoSocket::eventFlags.wait_any(_async_flag, SOCKET_TIMEOUT) & (osFlagsError | _async_flag)) == _async_flag);
95-
}
96-
uint8_t *buf = new uint8_t[_size];
97-
memset(buf, 0, _size);
98-
SocketAddress recv_address;
99-
100-
TEST_ASSERT(recvfrom(&recv_address, buf, _size) == _size);
101-
102-
TEST_ASSERT(recv_address == echo_server_addr);
103-
TEST_ASSERT(memcmp(_data, buf, _size) == 0);
104-
delete buf;
105-
delete _data;
106-
_data = 0;
107-
}
108176
private:
109-
void async_callback() {
110-
EchoSocket::eventFlags.set(_async_flag);
111-
}
112-
uint8_t *_data;
113-
int _size;
114-
uint32_t _async_flag; // 0 for blocking socket, signal bit for async
115-
static rtos::EventFlags eventFlags;
177+
void async_callback()
178+
{
179+
eventFlags.set(_async_flag);
180+
}
181+
uint8_t *_data;
182+
int _size;
183+
uint32_t _async_flag; // 0 for blocking socket, signal bit for async
184+
bool _tx_pending;
185+
bool _rx_pending;
116186
};
117187

118-
rtos::EventFlags EchoSocket::eventFlags;
119-
120188
static void network_callback(nsapi_event_t ev, intptr_t ptr)
121189
{
122190
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
123191
if (ptr == NSAPI_STATUS_GLOBAL_UP) {
124-
MBED_ASSERT(network_semaphore.release() == osOK);
192+
MBED_ASSERT(network_semaphore.release() == osOK);
125193
}
126194
}
127195
}
@@ -131,73 +199,92 @@ static void udp_network_stack()
131199
cellular.set_serial(&cellular_serial);
132200
TEST_ASSERT(cellular.init() == NSAPI_ERROR_OK);
133201
#if defined (MDMRTS) && defined (MDMCTS)
134-
cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
202+
cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
135203
#endif
136204
cellular.attach(&network_callback);
137205
TEST_ASSERT(cellular.start_dispatch() == NSAPI_ERROR_OK);
138206
cellular.set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
207+
#ifdef MBED_CONF_APP_APN
208+
CellularNetwork *network = cellular.get_network();
209+
TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN) == NSAPI_ERROR_OK);
210+
#endif
139211
cellular_target_state = CellularConnectionFSM::STATE_CONNECTED;
140212
TEST_ASSERT(cellular.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK);
141-
TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1);
213+
TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1);
142214
}
143215

144216
static void udp_gethostbyname()
145217
{
146218
TEST_ASSERT(cellular.get_network()->gethostbyname(ECHO_SERVER_NAME, &echo_server_addr) == 0);
147-
tr_info("HOST: %s", echo_server_addr.get_ip_address());
148-
echo_server_addr.set_port(7);
149-
wait(1);
219+
tr_info("Echo server IP: %s", echo_server_addr.get_ip_address());
220+
echo_server_addr.set_port(7);
150221
}
151222

152223
static void udp_socket_send_receive()
153224
{
154225
EchoSocket echo_socket(4);
155226
TEST_ASSERT(echo_socket.open(cellular.get_network()) == NSAPI_ERROR_OK);
156-
echo_socket.set_async(0);
227+
echo_socket.set_blocking(true);
228+
echo_socket.set_timeout(SOCKET_TIMEOUT);
157229
echo_socket.test_sendto();
158230
echo_socket.test_recvfrom();
159231
TEST_ASSERT(echo_socket.close() == NSAPI_ERROR_OK);
160-
wait(1);
161232
}
162233

163234
static void udp_socket_send_receive_async()
164235
{
236+
int async_flag = 1;
237+
TEST_ASSERT(!(eventFlags.clear(async_flag) & osFlagsError));
238+
165239
EchoSocket echo_socket(4);
166240
TEST_ASSERT(echo_socket.open(cellular.get_network()) == NSAPI_ERROR_OK);
167-
echo_socket.set_async(1);
241+
echo_socket.set_async(async_flag);
168242
echo_socket.test_sendto();
169243
echo_socket.test_recvfrom();
244+
245+
while (true) {
246+
TEST_ASSERT((eventFlags.wait_any(async_flag, SOCKET_TIMEOUT) & (osFlagsError)) != osFlagsError);
247+
if (!echo_socket.async_process()) {
248+
break;
249+
}
250+
}
170251
TEST_ASSERT(echo_socket.close() == NSAPI_ERROR_OK);
171-
wait(1);
172252
}
173253

174254
using namespace utest::v1;
175255

176256
static utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
177257
{
258+
#if MBED_CONF_MBED_TRACE_ENABLE
259+
trace_close();
260+
#endif
178261
greentea_case_failure_abort_handler(source, reason);
179262
return STATUS_ABORT;
180263
}
181264

182265
static Case cases[] = {
183-
Case("UDP network stack", udp_network_stack, greentea_failure_handler),
184-
Case("UDP gethostbyname", udp_gethostbyname, greentea_failure_handler),
185-
Case("UDP socket send/receive", udp_socket_send_receive, greentea_failure_handler),
186-
Case("UDP socket send/receive async", udp_socket_send_receive_async, greentea_failure_handler),
187-
//Case("UDP socket multiple simultaneous", udp_socket_multiple_simultaneous, greentea_failure_handler),
266+
Case("UDP network stack", udp_network_stack, greentea_failure_handler),
267+
Case("UDP gethostbyname", udp_gethostbyname, greentea_failure_handler),
268+
Case("UDP socket send/receive", udp_socket_send_receive, greentea_failure_handler),
269+
Case("UDP socket send/receive async", udp_socket_send_receive_async, greentea_failure_handler),
188270
};
189271

190272
static utest::v1::status_t test_setup(const size_t number_of_cases)
191273
{
192-
GREENTEA_SETUP(10*60, "default_auto"); // network registration may take up to 180 seconds, DNS query a couple of minutes, etc.
274+
GREENTEA_SETUP(10 * 60, "default_auto"); // network registration may take up to 180 seconds, DNS query a couple of minutes, etc.
193275
return verbose_test_setup_handler(number_of_cases);
194276
}
195277

196278
static Specification specification(test_setup, cases);
197279

198280
int main()
199281
{
200-
mbed_trace_init();
201-
202-
return Harness::run(specification);
282+
#if MBED_CONF_MBED_TRACE_ENABLE
283+
trace_open();
284+
#endif
285+
int ret = Harness::run(specification);
286+
#if MBED_CONF_MBED_TRACE_ENABLE
287+
trace_close();
288+
#endif
289+
return ret;
203290
}

features/cellular/TESTS/socket/udp/template_mbed_app.json.txt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,27 @@
1717
"value": 0
1818
},
1919
"trace-level": {
20-
"help": "Options are TRACE_LEVEL_ERROR,TRACE_LEVEL_WARN,TRACE_LEVEL_INFO,TRACE_LEVEL_DEBUG",
20+
"help": "Note that excessive trace prints may mess up with Greentea parsing",
2121
"macro_name": "MBED_TRACE_MAX_LEVEL",
22-
"value": "TRACE_LEVEL_INFO"
22+
"value": "TRACE_LEVEL_ERROR"
2323
}
2424
},
2525
"target_overrides": {
2626
"*": {
2727
"ppp-cell-iface.apn-lookup": false,
2828
"cellular.use-apn-lookup": false,
29-
"target.features_add": ["LWIP", "COMMON_PAL"],
30-
"mbed-trace.enable": false,
29+
"target.features_add": ["LWIP"],
30+
"mbed-trace.enable": true,
3131
"lwip.ipv4-enabled": true,
3232
"lwip.ipv6-enabled": true,
3333
"lwip.tcp-enabled": false,
3434
"lwip.ppp-enabled": true,
3535
"lwip.ethernet-enabled": false,
3636
"platform.stdio-convert-newlines": true,
37-
"platform.default-serial-baud-rate": 115200
37+
"platform.default-serial-baud-rate": 115200,
38+
"drivers.uart-serial-txbuf-size": 512,
39+
"drivers.uart-serial-rxbuf-size": 1024,
40+
"cellular.debug-at": false
3841
}
3942
}
4043
}

0 commit comments

Comments
 (0)