mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #6927 from AriParkkila/cellular-debug
Cellular: AT debugging improvedpull/7011/head
commit
5ce26b1306
|
@ -72,7 +72,7 @@ You can define the debug tracing level in the `mbed_app.json` configuration file
|
|||
|
||||
The `TESTS` folder contains Greentea tests for cellular specific classes. You need to give relevant configuration file with `--app-config` parameter, e.g.:
|
||||
|
||||
mbed test -n features-cellular-tests-* --app-config features\cellular\TESTS\socket\udp\template_mbed_app.json -vv
|
||||
mbed test -n features-cellular-tests-* --app-config features\cellular\TESTS\socket\udp\template_mbed_app.json.txt -v
|
||||
|
||||
Note that Greentea tests use SIM PIN so you need to change that or your SIM card may get locked.
|
||||
|
||||
|
|
|
@ -55,73 +55,141 @@ static UARTSerial cellular_serial(MDMTXD, MDMRXD, MBED_CONF_PLATFORM_DEFAULT_SER
|
|||
static rtos::Semaphore network_semaphore(0);
|
||||
static CellularConnectionFSM cellular;
|
||||
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
|
||||
static rtos::Mutex trace_mutex;
|
||||
|
||||
void trace_wait()
|
||||
{
|
||||
trace_mutex.lock();
|
||||
}
|
||||
|
||||
void trace_release()
|
||||
{
|
||||
trace_mutex.unlock();
|
||||
}
|
||||
|
||||
static char time_st[sizeof("[12345678]") + 1];
|
||||
|
||||
static char *trace_time(size_t ss)
|
||||
{
|
||||
snprintf(time_st, sizeof("[12345678]"), "[%08llu]", rtos::Kernel::get_ms_count());
|
||||
return time_st;
|
||||
}
|
||||
|
||||
static void trace_open()
|
||||
{
|
||||
mbed_trace_init();
|
||||
mbed_trace_prefix_function_set(&trace_time);
|
||||
mbed_trace_mutex_wait_function_set(trace_wait);
|
||||
mbed_trace_mutex_release_function_set(trace_release);
|
||||
|
||||
mbed_cellular_trace::mutex_wait_function_set(trace_wait);
|
||||
mbed_cellular_trace::mutex_release_function_set(trace_release);
|
||||
}
|
||||
|
||||
static void trace_close()
|
||||
{
|
||||
mbed_cellular_trace::mutex_wait_function_set(NULL);
|
||||
mbed_cellular_trace::mutex_release_function_set(NULL);
|
||||
|
||||
mbed_trace_free();
|
||||
}
|
||||
|
||||
#endif // MBED_CONF_MBED_TRACE_ENABLE
|
||||
|
||||
static SocketAddress echo_server_addr;
|
||||
|
||||
static rtos::EventFlags eventFlags;
|
||||
|
||||
class EchoSocket : public UDPSocket {
|
||||
public:
|
||||
EchoSocket(int size) : UDPSocket(), _async_flag(0), _data(0), _size(size) {
|
||||
}
|
||||
virtual ~EchoSocket() {
|
||||
delete _data;
|
||||
}
|
||||
void set_async(int async) {
|
||||
_async_flag = async;
|
||||
EchoSocket(int size) : UDPSocket(), _data(0), _size(size), _async_flag(0), _tx_pending(false), _rx_pending(false)
|
||||
{
|
||||
}
|
||||
virtual ~EchoSocket()
|
||||
{
|
||||
delete _data;
|
||||
}
|
||||
void set_async(int async)
|
||||
{
|
||||
_async_flag = async;
|
||||
if (_async_flag) {
|
||||
set_blocking(false);
|
||||
sigio(callback(this, &EchoSocket::async_callback));
|
||||
} else {
|
||||
set_blocking(true);
|
||||
set_timeout(SOCKET_TIMEOUT);
|
||||
sigio(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void test_sendto(const char *const hostname = NULL) {
|
||||
_data = new uint8_t[_size];
|
||||
for (int i=0; i<_size; i++) {
|
||||
_data[i] = (uint8_t)rand();
|
||||
}
|
||||
// clear pending events
|
||||
TEST_ASSERT(!(EchoSocket::eventFlags.clear(_async_flag) & osFlagsError));
|
||||
if (hostname) {
|
||||
TEST_ASSERT(sendto(hostname, ECHO_SERVER_UDP_PORT, _data, _size) == _size);
|
||||
} else {
|
||||
TEST_ASSERT(sendto(echo_server_addr, _data, _size) == _size);
|
||||
}
|
||||
}
|
||||
void test_recvfrom() {
|
||||
if (_async_flag) {
|
||||
TEST_ASSERT((EchoSocket::eventFlags.wait_any(_async_flag, SOCKET_TIMEOUT) & (osFlagsError | _async_flag)) == _async_flag);
|
||||
}
|
||||
uint8_t *buf = new uint8_t[_size];
|
||||
memset(buf, 0, _size);
|
||||
SocketAddress recv_address;
|
||||
void test_sendto(const char *const hostname = NULL)
|
||||
{
|
||||
if (!_data) {
|
||||
_data = new uint8_t[_size];
|
||||
for (int i = 0; i < _size; i++) {
|
||||
_data[i] = (uint8_t)rand();
|
||||
}
|
||||
}
|
||||
nsapi_size_or_error_t ret;
|
||||
if (hostname) {
|
||||
ret = sendto(hostname, ECHO_SERVER_UDP_PORT, _data, _size);
|
||||
} else {
|
||||
ret = sendto(echo_server_addr, _data, _size);
|
||||
}
|
||||
if (ret == _size) { // send successful
|
||||
_tx_pending = false;
|
||||
} else {
|
||||
TEST_ASSERT(_async_flag && ret == NSAPI_ERROR_WOULD_BLOCK);
|
||||
_tx_pending = true;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ASSERT(recvfrom(&recv_address, buf, _size) == _size);
|
||||
void test_recvfrom()
|
||||
{
|
||||
uint8_t *buf = new uint8_t[_size];
|
||||
memset(buf, 0, _size);
|
||||
SocketAddress recv_address;
|
||||
nsapi_size_or_error_t ret = recvfrom(&recv_address, buf, _size);
|
||||
if (ret == _size) { // recv successful
|
||||
_rx_pending = false;
|
||||
TEST_ASSERT(recv_address == echo_server_addr);
|
||||
TEST_ASSERT(memcmp(_data, buf, _size) == 0);
|
||||
delete _data;
|
||||
_data = NULL;
|
||||
_rx_pending = false;
|
||||
} else {
|
||||
TEST_ASSERT(_async_flag && ret == NSAPI_ERROR_WOULD_BLOCK);
|
||||
_rx_pending = true;
|
||||
}
|
||||
delete buf;
|
||||
}
|
||||
|
||||
bool async_process()
|
||||
{
|
||||
if (_tx_pending) {
|
||||
test_sendto();
|
||||
}
|
||||
if (_rx_pending) {
|
||||
test_recvfrom();
|
||||
}
|
||||
return _tx_pending | _rx_pending;
|
||||
}
|
||||
|
||||
TEST_ASSERT(recv_address == echo_server_addr);
|
||||
TEST_ASSERT(memcmp(_data, buf, _size) == 0);
|
||||
delete buf;
|
||||
delete _data;
|
||||
_data = 0;
|
||||
}
|
||||
private:
|
||||
void async_callback() {
|
||||
EchoSocket::eventFlags.set(_async_flag);
|
||||
}
|
||||
uint8_t *_data;
|
||||
int _size;
|
||||
uint32_t _async_flag; // 0 for blocking socket, signal bit for async
|
||||
static rtos::EventFlags eventFlags;
|
||||
void async_callback()
|
||||
{
|
||||
eventFlags.set(_async_flag);
|
||||
}
|
||||
uint8_t *_data;
|
||||
int _size;
|
||||
uint32_t _async_flag; // 0 for blocking socket, signal bit for async
|
||||
bool _tx_pending;
|
||||
bool _rx_pending;
|
||||
};
|
||||
|
||||
rtos::EventFlags EchoSocket::eventFlags;
|
||||
|
||||
static void network_callback(nsapi_event_t ev, intptr_t ptr)
|
||||
{
|
||||
if (ev == NSAPI_EVENT_CONNECTION_STATUS_CHANGE) {
|
||||
if (ptr == NSAPI_STATUS_GLOBAL_UP) {
|
||||
MBED_ASSERT(network_semaphore.release() == osOK);
|
||||
MBED_ASSERT(network_semaphore.release() == osOK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,65 +199,79 @@ static void udp_network_stack()
|
|||
cellular.set_serial(&cellular_serial);
|
||||
TEST_ASSERT(cellular.init() == NSAPI_ERROR_OK);
|
||||
#if defined (MDMRTS) && defined (MDMCTS)
|
||||
cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
cellular_serial.set_flow_control(SerialBase::RTSCTS, MDMRTS, MDMCTS);
|
||||
#endif
|
||||
cellular.attach(&network_callback);
|
||||
TEST_ASSERT(cellular.start_dispatch() == NSAPI_ERROR_OK);
|
||||
cellular.set_sim_pin(MBED_CONF_APP_CELLULAR_SIM_PIN);
|
||||
#ifdef MBED_CONF_APP_APN
|
||||
CellularNetwork *network = cellular.get_network();
|
||||
TEST_ASSERT(network->set_credentials(MBED_CONF_APP_APN) == NSAPI_ERROR_OK);
|
||||
#endif
|
||||
cellular_target_state = CellularConnectionFSM::STATE_CONNECTED;
|
||||
TEST_ASSERT(cellular.continue_to_state(cellular_target_state) == NSAPI_ERROR_OK);
|
||||
TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1);
|
||||
TEST_ASSERT(network_semaphore.wait(NETWORK_TIMEOUT) == 1);
|
||||
}
|
||||
|
||||
static void udp_gethostbyname()
|
||||
{
|
||||
TEST_ASSERT(cellular.get_network()->gethostbyname(ECHO_SERVER_NAME, &echo_server_addr) == 0);
|
||||
tr_info("HOST: %s", echo_server_addr.get_ip_address());
|
||||
echo_server_addr.set_port(7);
|
||||
wait(1);
|
||||
tr_info("Echo server IP: %s", echo_server_addr.get_ip_address());
|
||||
echo_server_addr.set_port(7);
|
||||
}
|
||||
|
||||
static void udp_socket_send_receive()
|
||||
{
|
||||
EchoSocket echo_socket(4);
|
||||
TEST_ASSERT(echo_socket.open(cellular.get_network()) == NSAPI_ERROR_OK);
|
||||
echo_socket.set_async(0);
|
||||
echo_socket.set_blocking(true);
|
||||
echo_socket.set_timeout(SOCKET_TIMEOUT);
|
||||
echo_socket.test_sendto();
|
||||
echo_socket.test_recvfrom();
|
||||
TEST_ASSERT(echo_socket.close() == NSAPI_ERROR_OK);
|
||||
wait(1);
|
||||
}
|
||||
|
||||
static void udp_socket_send_receive_async()
|
||||
{
|
||||
int async_flag = 1;
|
||||
TEST_ASSERT(!(eventFlags.clear(async_flag) & osFlagsError));
|
||||
|
||||
EchoSocket echo_socket(4);
|
||||
TEST_ASSERT(echo_socket.open(cellular.get_network()) == NSAPI_ERROR_OK);
|
||||
echo_socket.set_async(1);
|
||||
echo_socket.set_async(async_flag);
|
||||
echo_socket.test_sendto();
|
||||
echo_socket.test_recvfrom();
|
||||
|
||||
while (true) {
|
||||
TEST_ASSERT((eventFlags.wait_any(async_flag, SOCKET_TIMEOUT) & (osFlagsError)) != osFlagsError);
|
||||
if (!echo_socket.async_process()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
TEST_ASSERT(echo_socket.close() == NSAPI_ERROR_OK);
|
||||
wait(1);
|
||||
}
|
||||
|
||||
using namespace utest::v1;
|
||||
|
||||
static utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason)
|
||||
{
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
trace_close();
|
||||
#endif
|
||||
greentea_case_failure_abort_handler(source, reason);
|
||||
return STATUS_ABORT;
|
||||
}
|
||||
|
||||
static Case cases[] = {
|
||||
Case("UDP network stack", udp_network_stack, greentea_failure_handler),
|
||||
Case("UDP gethostbyname", udp_gethostbyname, greentea_failure_handler),
|
||||
Case("UDP socket send/receive", udp_socket_send_receive, greentea_failure_handler),
|
||||
Case("UDP socket send/receive async", udp_socket_send_receive_async, greentea_failure_handler),
|
||||
//Case("UDP socket multiple simultaneous", udp_socket_multiple_simultaneous, greentea_failure_handler),
|
||||
Case("UDP network stack", udp_network_stack, greentea_failure_handler),
|
||||
Case("UDP gethostbyname", udp_gethostbyname, greentea_failure_handler),
|
||||
Case("UDP socket send/receive", udp_socket_send_receive, greentea_failure_handler),
|
||||
Case("UDP socket send/receive async", udp_socket_send_receive_async, greentea_failure_handler),
|
||||
};
|
||||
|
||||
static utest::v1::status_t test_setup(const size_t number_of_cases)
|
||||
{
|
||||
GREENTEA_SETUP(10*60, "default_auto"); // network registration may take up to 180 seconds, DNS query a couple of minutes, etc.
|
||||
GREENTEA_SETUP(10 * 60, "default_auto"); // network registration may take up to 180 seconds, DNS query a couple of minutes, etc.
|
||||
return verbose_test_setup_handler(number_of_cases);
|
||||
}
|
||||
|
||||
|
@ -197,7 +279,12 @@ static Specification specification(test_setup, cases);
|
|||
|
||||
int main()
|
||||
{
|
||||
mbed_trace_init();
|
||||
|
||||
return Harness::run(specification);
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
trace_open();
|
||||
#endif
|
||||
int ret = Harness::run(specification);
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
trace_close();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -17,24 +17,27 @@
|
|||
"value": 0
|
||||
},
|
||||
"trace-level": {
|
||||
"help": "Options are TRACE_LEVEL_ERROR,TRACE_LEVEL_WARN,TRACE_LEVEL_INFO,TRACE_LEVEL_DEBUG",
|
||||
"help": "Note that excessive trace prints may mess up with Greentea parsing",
|
||||
"macro_name": "MBED_TRACE_MAX_LEVEL",
|
||||
"value": "TRACE_LEVEL_INFO"
|
||||
"value": "TRACE_LEVEL_ERROR"
|
||||
}
|
||||
},
|
||||
"target_overrides": {
|
||||
"*": {
|
||||
"ppp-cell-iface.apn-lookup": false,
|
||||
"cellular.use-apn-lookup": false,
|
||||
"target.features_add": ["LWIP", "COMMON_PAL"],
|
||||
"mbed-trace.enable": false,
|
||||
"target.features_add": ["LWIP"],
|
||||
"mbed-trace.enable": true,
|
||||
"lwip.ipv4-enabled": true,
|
||||
"lwip.ipv6-enabled": true,
|
||||
"lwip.tcp-enabled": false,
|
||||
"lwip.ppp-enabled": true,
|
||||
"lwip.ethernet-enabled": false,
|
||||
"platform.stdio-convert-newlines": true,
|
||||
"platform.default-serial-baud-rate": 115200
|
||||
"platform.default-serial-baud-rate": 115200,
|
||||
"drivers.uart-serial-txbuf-size": 512,
|
||||
"drivers.uart-serial-rxbuf-size": 1024,
|
||||
"cellular.debug-at": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,12 +35,6 @@ using namespace mbed_cellular_util;
|
|||
|
||||
#include "CellularLog.h"
|
||||
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
#define at_debug(format, ...) do { if (_debug_on) debug(format, ## __VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define at_debug(...)
|
||||
#endif
|
||||
|
||||
// URCs should be handled fast, if you add debug traces within URC processing then you also need to increase this time
|
||||
#define PROCESS_URC_TIME 20
|
||||
|
||||
|
@ -86,12 +80,10 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char
|
|||
_urc_matched(false),
|
||||
_error_found(false),
|
||||
_max_resp_length(MAX_RESP_LENGTH),
|
||||
_debug_on(false),
|
||||
_debug_on(MBED_CONF_CELLULAR_DEBUG_AT),
|
||||
_cmd_start(false),
|
||||
_start_time(0)
|
||||
{
|
||||
//enable_debug(true);
|
||||
|
||||
clear_error();
|
||||
|
||||
if (output_delimiter) {
|
||||
|
@ -119,9 +111,9 @@ ATHandler::ATHandler(FileHandle *fh, EventQueue &queue, int timeout, const char
|
|||
set_filehandle_sigio();
|
||||
}
|
||||
|
||||
void ATHandler::enable_debug(bool enable)
|
||||
void ATHandler::set_debug(bool debug_on)
|
||||
{
|
||||
_debug_on = enable;
|
||||
_debug_on = debug_on;
|
||||
}
|
||||
|
||||
ATHandler::~ATHandler()
|
||||
|
@ -273,14 +265,14 @@ void ATHandler::set_at_timeout(uint32_t timeout_milliseconds, bool default_timeo
|
|||
void ATHandler::restore_at_timeout()
|
||||
{
|
||||
if (_previous_at_timeout != _at_timeout) {
|
||||
_at_timeout =_previous_at_timeout;
|
||||
_at_timeout = _previous_at_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
void ATHandler::process_oob()
|
||||
{
|
||||
lock();
|
||||
tr_debug("process_oob %d", (_fileHandle->readable() || (_recv_pos < _recv_len)));
|
||||
tr_debug("process_oob readable=%d, pos=%u, len=%u", _fileHandle->readable(), _recv_pos, _recv_len);
|
||||
if (_fileHandle->readable() || (_recv_pos < _recv_len)) {
|
||||
_current_scope = NotSet;
|
||||
uint32_t timeout = _at_timeout;
|
||||
|
@ -319,14 +311,12 @@ void ATHandler::set_filehandle_sigio()
|
|||
|
||||
void ATHandler::reset_buffer()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
_recv_pos = 0;
|
||||
_recv_len = 0;
|
||||
}
|
||||
|
||||
void ATHandler::rewind_buffer()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
if (_recv_pos > 0 && _recv_len >= _recv_pos) {
|
||||
_recv_len -= _recv_pos;
|
||||
// move what is not read to beginning of buffer
|
||||
|
@ -342,7 +332,7 @@ int ATHandler::poll_timeout(bool wait_for_timeout)
|
|||
uint64_t now = rtos::Kernel::get_ms_count();
|
||||
if (now >= _start_time + _at_timeout) {
|
||||
timeout = 0;
|
||||
} else if ( _start_time + _at_timeout - now > INT_MAX) {
|
||||
} else if (_start_time + _at_timeout - now > INT_MAX) {
|
||||
timeout = INT_MAX;
|
||||
} else {
|
||||
timeout = _start_time + _at_timeout - now;
|
||||
|
@ -355,7 +345,6 @@ int ATHandler::poll_timeout(bool wait_for_timeout)
|
|||
|
||||
bool ATHandler::fill_buffer(bool wait_for_timeout)
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
// Reset buffer when full
|
||||
if (sizeof(_recv_buff) == _recv_len) {
|
||||
tr_error("AT overflow");
|
||||
|
@ -369,6 +358,7 @@ bool ATHandler::fill_buffer(bool wait_for_timeout)
|
|||
if (count > 0 && (fhs.revents & POLLIN)) {
|
||||
ssize_t len = _fileHandle->read(_recv_buff + _recv_len, sizeof(_recv_buff) - _recv_len);
|
||||
if (len > 0) {
|
||||
debug_print(_recv_buff + _recv_len, len);
|
||||
_recv_len += len;
|
||||
return true;
|
||||
}
|
||||
|
@ -380,7 +370,6 @@ bool ATHandler::fill_buffer(bool wait_for_timeout)
|
|||
int ATHandler::get_char()
|
||||
{
|
||||
if (_recv_pos == _recv_len) {
|
||||
tr_debug("%s", __func__);
|
||||
reset_buffer(); // try to read as much as possible
|
||||
if (!fill_buffer()) {
|
||||
tr_warn("AT timeout");
|
||||
|
@ -389,14 +378,11 @@ int ATHandler::get_char()
|
|||
}
|
||||
}
|
||||
|
||||
tr_debug("%s: %c", __func__, _recv_buff[_recv_pos]);
|
||||
|
||||
return _recv_buff[_recv_pos++];
|
||||
}
|
||||
|
||||
void ATHandler::skip_param(uint32_t count)
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
if (_last_err || !_stop_tag || _stop_tag->found) {
|
||||
return;
|
||||
}
|
||||
|
@ -426,7 +412,6 @@ void ATHandler::skip_param(uint32_t count)
|
|||
|
||||
void ATHandler::skip_param(ssize_t len, uint32_t count)
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
if (_last_err || !_stop_tag || _stop_tag->found) {
|
||||
return;
|
||||
}
|
||||
|
@ -447,7 +432,6 @@ void ATHandler::skip_param(ssize_t len, uint32_t count)
|
|||
|
||||
ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len)
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
if (_last_err) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -466,19 +450,12 @@ ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len)
|
|||
|
||||
ssize_t ATHandler::read(char *buf, size_t size, bool read_even_stop_tag, bool hex)
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
at_debug("\n----------read buff:----------\n");
|
||||
for (size_t i = _recv_pos; i < _recv_len; i++) {
|
||||
at_debug("%c", _recv_buff[i]);
|
||||
}
|
||||
at_debug("\n----------read end----------\n");
|
||||
|
||||
if (_last_err || !_stop_tag || (_stop_tag->found && read_even_stop_tag == false)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t match_pos = 0;
|
||||
size_t read_size = hex ? size*2 : size;
|
||||
size_t read_size = hex ? size * 2 : size;
|
||||
|
||||
consume_char('\"');
|
||||
|
||||
|
@ -488,19 +465,18 @@ ssize_t ATHandler::read(char *buf, size_t size, bool read_even_stop_tag, bool he
|
|||
|
||||
for (; read_idx < (read_size + match_pos); read_idx++) {
|
||||
int c = get_char();
|
||||
buf_idx = hex ? read_idx/2 : read_idx;
|
||||
buf_idx = hex ? read_idx / 2 : read_idx;
|
||||
if (c == -1) {
|
||||
buf[buf_idx] = '\0';
|
||||
set_error(NSAPI_ERROR_DEVICE_ERROR);
|
||||
return -1;
|
||||
} else if (c == _delimiter) {
|
||||
}
|
||||
if (c == _delimiter) {
|
||||
buf[buf_idx] = '\0';
|
||||
break;
|
||||
} else if (c == '\"') {
|
||||
match_pos = 0;
|
||||
if (read_idx > 0) {
|
||||
read_idx--;
|
||||
}
|
||||
read_idx--;
|
||||
continue;
|
||||
} else if (_stop_tag->len && c == _stop_tag->tag[match_pos]) {
|
||||
match_pos++;
|
||||
|
@ -520,7 +496,7 @@ ssize_t ATHandler::read(char *buf, size_t size, bool read_even_stop_tag, bool he
|
|||
} else {
|
||||
hexbuf[read_idx % 2] = c;
|
||||
if (read_idx % 2 == 1) {
|
||||
hex_str_to_char_str(hexbuf, 2, buf+buf_idx);
|
||||
hex_str_to_char_str(hexbuf, 2, buf + buf_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -540,8 +516,6 @@ ssize_t ATHandler::read_hex_string(char *buf, size_t size)
|
|||
|
||||
int32_t ATHandler::read_int()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
|
||||
if (_last_err || !_stop_tag || _stop_tag->found) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -566,7 +540,7 @@ void ATHandler::set_default_delimiter()
|
|||
_delimiter = DEFAULT_DELIMITER;
|
||||
}
|
||||
|
||||
void ATHandler::set_tag(tag_t* tag_dst, const char *tag_seq)
|
||||
void ATHandler::set_tag(tag_t *tag_dst, const char *tag_seq)
|
||||
{
|
||||
if (tag_seq) {
|
||||
size_t tag_len = strlen(tag_seq);
|
||||
|
@ -589,7 +563,6 @@ void ATHandler::set_stop_tag(const char *stop_tag_seq)
|
|||
|
||||
void ATHandler::set_scope(ScopeType scope_type)
|
||||
{
|
||||
tr_debug("%s: %d", __func__, scope_type);
|
||||
if (_current_scope != scope_type) {
|
||||
_current_scope = scope_type;
|
||||
switch (_current_scope) {
|
||||
|
@ -616,9 +589,8 @@ void ATHandler::set_scope(ScopeType scope_type)
|
|||
}
|
||||
|
||||
// should match from recv_pos?
|
||||
bool ATHandler::match(const char* str, size_t size)
|
||||
bool ATHandler::match(const char *str, size_t size)
|
||||
{
|
||||
tr_debug("%s: %s", __func__, str);
|
||||
rewind_buffer();
|
||||
|
||||
if ((_recv_len - _recv_pos) < size) {
|
||||
|
@ -635,14 +607,12 @@ bool ATHandler::match(const char* str, size_t size)
|
|||
|
||||
bool ATHandler::match_urc()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
rewind_buffer();
|
||||
size_t prefix_len = 0;
|
||||
for (struct oob_t *oob = _oobs; oob; oob = oob->next) {
|
||||
prefix_len = oob->prefix_len;
|
||||
if (_recv_len >= prefix_len) {
|
||||
if (match(oob->prefix, prefix_len)) {
|
||||
tr_debug("URC! %s\n", oob->prefix);
|
||||
set_scope(InfoType);
|
||||
if (oob->cb) {
|
||||
oob->cb();
|
||||
|
@ -657,8 +627,6 @@ bool ATHandler::match_urc()
|
|||
|
||||
bool ATHandler::match_error()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
|
||||
if (match(CME_ERROR, CME_ERROR_LENGTH)) {
|
||||
at_error(true, DeviceErrorTypeErrorCME);
|
||||
return true;
|
||||
|
@ -717,7 +685,7 @@ void ATHandler::set_3gpp_error(int err, DeviceErrorType error_type)
|
|||
// CMS errors 0-127 maps straight to 3GPP errors
|
||||
_last_3gpp_error = err;
|
||||
} else {
|
||||
for (size_t i = 0; i<sizeof(map_3gpp_errors)/sizeof(map_3gpp_errors[0]); i++) {
|
||||
for (size_t i = 0; i < sizeof(map_3gpp_errors) / sizeof(map_3gpp_errors[0]); i++) {
|
||||
if (map_3gpp_errors[i][0] == err) {
|
||||
_last_3gpp_error = map_3gpp_errors[i][1];
|
||||
tr_debug("AT3GPP error code %d", get_3gpp_error());
|
||||
|
@ -737,25 +705,17 @@ void ATHandler::at_error(bool error_code_expected, DeviceErrorType error_type)
|
|||
set_3gpp_error(err, error_type);
|
||||
_last_at_err.errCode = err;
|
||||
_last_at_err.errType = error_type;
|
||||
tr_debug("ATHandler ERROR: %d", err);
|
||||
tr_error("AT error code %ld", err);
|
||||
} else {
|
||||
tr_debug("ATHandler ERROR reading failed");
|
||||
tr_warn("ATHandler ERROR reading failed");
|
||||
}
|
||||
}
|
||||
|
||||
_last_err = NSAPI_ERROR_DEVICE_ERROR;
|
||||
set_error(NSAPI_ERROR_DEVICE_ERROR);
|
||||
}
|
||||
|
||||
void ATHandler::resp(const char *prefix, bool check_urc)
|
||||
{
|
||||
tr_debug("%s: %s", __func__, prefix);
|
||||
|
||||
at_debug("\n----------resp buff:----------\n");
|
||||
for (size_t i = _recv_pos; i < _recv_len; i++) {
|
||||
at_debug("%c", _recv_buff[i]);
|
||||
}
|
||||
at_debug("\n----------buff----------\n");
|
||||
|
||||
_prefix_matched = false;
|
||||
_urc_matched = false;
|
||||
_error_found = false;
|
||||
|
@ -794,7 +754,7 @@ void ATHandler::resp(const char *prefix, bool check_urc)
|
|||
} else {
|
||||
// If no prefix, no CRLF and no more chance to match for OK, ERROR or URC(since max resp length is already in buffer)
|
||||
// return so data could be read
|
||||
if (!prefix && ((_recv_len-_recv_pos) >= _max_resp_length)) {
|
||||
if (!prefix && ((_recv_len - _recv_pos) >= _max_resp_length)) {
|
||||
return;
|
||||
}
|
||||
if (!fill_buffer()) {
|
||||
|
@ -810,8 +770,6 @@ void ATHandler::resp(const char *prefix, bool check_urc)
|
|||
|
||||
void ATHandler::resp_start(const char *prefix, bool stop)
|
||||
{
|
||||
tr_debug("%s: %s", __func__, prefix);
|
||||
|
||||
if (_last_err) {
|
||||
return;
|
||||
}
|
||||
|
@ -837,7 +795,6 @@ void ATHandler::resp_start(const char *prefix, bool stop)
|
|||
// check urc because of error as urc
|
||||
bool ATHandler::info_resp()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
if (_last_err || _resp_stop.found) {
|
||||
return false;
|
||||
}
|
||||
|
@ -868,7 +825,6 @@ bool ATHandler::info_resp()
|
|||
|
||||
bool ATHandler::info_elem(char start_tag)
|
||||
{
|
||||
tr_debug("%s: %c", __func__, start_tag);
|
||||
if (_last_err) {
|
||||
return false;
|
||||
}
|
||||
|
@ -894,7 +850,6 @@ bool ATHandler::info_elem(char start_tag)
|
|||
|
||||
bool ATHandler::consume_char(char ch)
|
||||
{
|
||||
tr_debug("%s: %c", __func__, ch);
|
||||
int read_char = get_char();
|
||||
if (read_char == -1) {
|
||||
return false;
|
||||
|
@ -909,7 +864,6 @@ bool ATHandler::consume_char(char ch)
|
|||
|
||||
bool ATHandler::consume_to_tag(const char *tag, bool consume_tag)
|
||||
{
|
||||
tr_debug("%s: %s", __func__, tag);
|
||||
size_t match_pos = 0;
|
||||
|
||||
while (true) {
|
||||
|
@ -934,17 +888,15 @@ bool ATHandler::consume_to_tag(const char *tag, bool consume_tag)
|
|||
|
||||
bool ATHandler::consume_to_stop_tag()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
|
||||
if (!_stop_tag || (_stop_tag && _stop_tag->found) || _error_found) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (consume_to_tag((const char*)_stop_tag->tag, true)) {
|
||||
if (consume_to_tag((const char *)_stop_tag->tag, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
tr_debug("consume_to_stop_tag not found");
|
||||
tr_warn("AT stop tag not found");
|
||||
set_error(NSAPI_ERROR_DEVICE_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
@ -955,8 +907,6 @@ void ATHandler::resp_stop()
|
|||
{
|
||||
// Do not return on error so that we can consume whatever there is in the buffer
|
||||
|
||||
tr_debug("%s", __func__);
|
||||
|
||||
if (_current_scope == ElemType) {
|
||||
information_response_element_stop();
|
||||
set_scope(InfoType);
|
||||
|
@ -981,7 +931,6 @@ void ATHandler::resp_stop()
|
|||
|
||||
void ATHandler::information_response_stop()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
if (consume_to_stop_tag()) {
|
||||
set_scope(RespType);
|
||||
}
|
||||
|
@ -989,7 +938,6 @@ void ATHandler::information_response_stop()
|
|||
|
||||
void ATHandler::information_response_element_stop()
|
||||
{
|
||||
tr_debug("%s", __func__);
|
||||
if (consume_to_stop_tag()) {
|
||||
set_scope(InfoType);
|
||||
}
|
||||
|
@ -1006,27 +954,25 @@ void ATHandler::set_string(char *dest, const char *src, size_t src_len)
|
|||
dest[src_len] = '\0';
|
||||
}
|
||||
|
||||
const char* ATHandler::mem_str(const char* dest, size_t dest_len, const char* src, size_t src_len)
|
||||
const char *ATHandler::mem_str(const char *dest, size_t dest_len, const char *src, size_t src_len)
|
||||
{
|
||||
if (dest_len > src_len) {
|
||||
for(size_t i = 0; i < dest_len-src_len+1; ++i) {
|
||||
if(memcmp(dest+i, src, src_len) == 0) {
|
||||
return dest+i;
|
||||
for(size_t i = 0; i < dest_len - src_len + 1; ++i) {
|
||||
if(memcmp(dest + i, src, src_len) == 0) {
|
||||
return dest + i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ATHandler::cmd_start(const char* cmd)
|
||||
void ATHandler::cmd_start(const char *cmd)
|
||||
{
|
||||
|
||||
if (_at_send_delay) {
|
||||
rtos::Thread::wait_until(_last_response_stop + _at_send_delay);
|
||||
}
|
||||
|
||||
at_debug("AT cmd %s (err %d)\n", cmd, _last_err);
|
||||
|
||||
if (_last_err != NSAPI_ERROR_OK) {
|
||||
return;
|
||||
}
|
||||
|
@ -1038,7 +984,6 @@ void ATHandler::cmd_start(const char* cmd)
|
|||
|
||||
void ATHandler::write_int(int32_t param)
|
||||
{
|
||||
at_debug("AT int %d\n", param);
|
||||
// do common checks before sending subparameter
|
||||
if (check_cmd_send() == false) {
|
||||
return;
|
||||
|
@ -1053,9 +998,8 @@ void ATHandler::write_int(int32_t param)
|
|||
}
|
||||
}
|
||||
|
||||
void ATHandler::write_string(const char* param, bool useQuotations)
|
||||
void ATHandler::write_string(const char *param, bool useQuotations)
|
||||
{
|
||||
at_debug("AT str %s (with quotes %d)\n", param, useQuotations);
|
||||
// do common checks before sending subparameter
|
||||
if (check_cmd_send() == false) {
|
||||
return;
|
||||
|
@ -1076,7 +1020,6 @@ void ATHandler::write_string(const char* param, bool useQuotations)
|
|||
|
||||
void ATHandler::cmd_stop()
|
||||
{
|
||||
at_debug("AT stop %s (err %d)\n", _output_delimiter, _last_err);
|
||||
if (_last_err != NSAPI_ERROR_OK) {
|
||||
return;
|
||||
}
|
||||
|
@ -1086,8 +1029,6 @@ void ATHandler::cmd_stop()
|
|||
|
||||
size_t ATHandler::write_bytes(const uint8_t *data, size_t len)
|
||||
{
|
||||
at_debug("AT write bytes %d (err %d)\n", len, _last_err);
|
||||
|
||||
if (_last_err != NSAPI_ERROR_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1101,17 +1042,18 @@ size_t ATHandler::write(const void *data, size_t len)
|
|||
fhs.fh = _fileHandle;
|
||||
fhs.events = POLLOUT;
|
||||
size_t write_len = 0;
|
||||
for (; write_len < len; ) {
|
||||
for (; write_len < len;) {
|
||||
int count = poll(&fhs, 1, poll_timeout());
|
||||
if (count <= 0 || !(fhs.revents & POLLOUT)) {
|
||||
set_error(NSAPI_ERROR_DEVICE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
ssize_t ret = _fileHandle->write((uint8_t*)data + write_len, len - write_len);
|
||||
ssize_t ret = _fileHandle->write((uint8_t *)data + write_len, len - write_len);
|
||||
if (ret < 0) {
|
||||
set_error(NSAPI_ERROR_DEVICE_ERROR);
|
||||
return 0;
|
||||
}
|
||||
debug_print((char *)data + write_len, ret);
|
||||
write_len += (size_t)ret;
|
||||
}
|
||||
|
||||
|
@ -1145,3 +1087,26 @@ void ATHandler::flush()
|
|||
reset_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
void ATHandler::debug_print(char *p, int len)
|
||||
{
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
if (_debug_on) {
|
||||
mbed_cellular_trace::mutex_wait();
|
||||
for (ssize_t i = 0; i < len; i++) {
|
||||
char c = *p++;
|
||||
if (!isprint(c)) {
|
||||
if (c == '\r') {
|
||||
} else if (c == '\n') {
|
||||
debug("%c", c);
|
||||
} else {
|
||||
debug("[%d]", c);
|
||||
}
|
||||
} else {
|
||||
debug("%c", c);
|
||||
}
|
||||
}
|
||||
mbed_cellular_trace::mutex_release();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -28,8 +28,7 @@
|
|||
#include "Callback.h"
|
||||
#include "EventQueue.h"
|
||||
|
||||
namespace mbed
|
||||
{
|
||||
namespace mbed {
|
||||
|
||||
class FileHandle;
|
||||
|
||||
|
@ -64,8 +63,7 @@ struct device_err_t {
|
|||
*
|
||||
* Class for sending AT commands and parsing AT responses.
|
||||
*/
|
||||
class ATHandler
|
||||
{
|
||||
class ATHandler {
|
||||
|
||||
public:
|
||||
/** Constructor
|
||||
|
@ -220,7 +218,7 @@ public:
|
|||
*
|
||||
* @param cmd AT command to be written to modem
|
||||
*/
|
||||
void cmd_start(const char* cmd);
|
||||
void cmd_start(const char *cmd);
|
||||
|
||||
/** Writes integer type AT command subparameter. Starts with the delimiter if not the first param after cmd_start.
|
||||
* In case of failure when writing, the last error is set to NSAPI_ERROR_DEVICE_ERROR.
|
||||
|
@ -236,7 +234,7 @@ public:
|
|||
* @param param string to be written to modem as AT command subparameter
|
||||
* @param useQuotations flag indicating whether the string should be included in quotation marks
|
||||
*/
|
||||
void write_string(const char* param, bool useQuotations = true);
|
||||
void write_string(const char *param, bool useQuotations = true);
|
||||
|
||||
/** Stops the AT command by writing command-line terminator CR to mark command as finished.
|
||||
*/
|
||||
|
@ -360,17 +358,23 @@ public:
|
|||
*/
|
||||
bool consume_to_stop_tag();
|
||||
|
||||
/** Sets _debug_on flag.
|
||||
*
|
||||
* @param enable value to be set for _debug_on flag
|
||||
*/
|
||||
void enable_debug(bool enable);
|
||||
|
||||
/** Return the last 3GPP error code.
|
||||
* @return last 3GPP error code
|
||||
*/
|
||||
int get_3gpp_error();
|
||||
|
||||
public: // just for debugging
|
||||
/**
|
||||
* AT debugging, when enabled will print all data read and written,
|
||||
* non-printable chars are printed as "[%d]".
|
||||
*
|
||||
* AT debug can be enabled at compile time using MBED_CONF_CELLULAR_DEBUG_AT flag or at runtime
|
||||
* calling set_debug(). Note that MBED_CONF_MBED_TRACE_ENABLE must also be enabled.
|
||||
*
|
||||
* @param debug_on Enable/disable debugging
|
||||
*/
|
||||
void set_debug(bool debug_on);
|
||||
|
||||
private:
|
||||
|
||||
// should fit any prefix and int
|
||||
|
@ -438,10 +442,10 @@ private:
|
|||
// Returns true on successful read OR false on timeout.
|
||||
bool fill_buffer(bool wait_for_timeout = true);
|
||||
|
||||
void set_tag(tag_t* tag_dest, const char *tag_seq);
|
||||
void set_tag(tag_t *tag_dest, const char *tag_seq);
|
||||
|
||||
// Rewinds the receiving buffer and compares it against given str.
|
||||
bool match(const char* str, size_t size);
|
||||
bool match(const char *str, size_t size);
|
||||
// Iterates URCs and checks if they match the receiving buffer content.
|
||||
// If URC match sets the scope to information response and after urc's cb returns
|
||||
// finishes the information response scope(consumes to CRLF).
|
||||
|
@ -495,12 +499,15 @@ private:
|
|||
*
|
||||
* @return pointer to first occurrence of src in dest
|
||||
*/
|
||||
const char* mem_str(const char* dest, size_t dest_len, const char* src, size_t src_len);
|
||||
const char *mem_str(const char *dest, size_t dest_len, const char *src, size_t src_len);
|
||||
|
||||
// check is urc is already added
|
||||
bool find_urc_handler(const char *prefix, mbed::Callback<void()> callback);
|
||||
|
||||
ssize_t read(char *buf, size_t size, bool read_even_stop_tag, bool hex);
|
||||
|
||||
// print contents of a buffer to trace log
|
||||
void debug_print(char *p, int len);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -45,7 +45,7 @@ AT_CellularDevice::~AT_CellularDevice()
|
|||
}
|
||||
|
||||
// each parser is associated with one filehandle (that is UART)
|
||||
ATHandler* AT_CellularDevice::get_at_handler(FileHandle *fileHandle)
|
||||
ATHandler *AT_CellularDevice::get_at_handler(FileHandle *fileHandle)
|
||||
{
|
||||
if (!fileHandle) {
|
||||
return NULL;
|
||||
|
@ -62,7 +62,7 @@ ATHandler* AT_CellularDevice::get_at_handler(FileHandle *fileHandle)
|
|||
atHandler = new ATHandler(fileHandle, _queue, _default_timeout, "\r", get_send_delay());
|
||||
if (atHandler) {
|
||||
if (_modem_debug_on) {
|
||||
atHandler->enable_debug(_modem_debug_on);
|
||||
atHandler->set_debug(_modem_debug_on);
|
||||
}
|
||||
atHandler->_nextATHandler = _atHandlers;
|
||||
_atHandlers = atHandler;
|
||||
|
@ -71,7 +71,7 @@ ATHandler* AT_CellularDevice::get_at_handler(FileHandle *fileHandle)
|
|||
return atHandler;
|
||||
}
|
||||
|
||||
void AT_CellularDevice::release_at_handler(ATHandler* at_handler)
|
||||
void AT_CellularDevice::release_at_handler(ATHandler *at_handler)
|
||||
{
|
||||
if (!at_handler) {
|
||||
return;
|
||||
|
@ -92,7 +92,7 @@ void AT_CellularDevice::release_at_handler(ATHandler* at_handler)
|
|||
break;
|
||||
} else {
|
||||
prev = atHandler;
|
||||
atHandler =atHandler->_nextATHandler;
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ void AT_CellularDevice::modem_debug_on(bool on)
|
|||
|
||||
ATHandler *atHandler = _atHandlers;
|
||||
while (atHandler) {
|
||||
atHandler->enable_debug(_modem_debug_on);
|
||||
atHandler->set_debug(_modem_debug_on);
|
||||
atHandler = atHandler->_nextATHandler;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,13 +115,13 @@ void AT_CellularNetwork::read_reg_params_and_compare(RegistrationType type)
|
|||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
switch (reg_status) {
|
||||
case NotRegistered:
|
||||
tr_error("not registered");
|
||||
tr_warn("not registered");
|
||||
break;
|
||||
case RegistrationDenied:
|
||||
tr_error("registration denied");
|
||||
tr_warn("registration denied");
|
||||
break;
|
||||
case Unknown:
|
||||
tr_error("registration status unknown");
|
||||
tr_warn("registration status unknown");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -168,27 +168,27 @@ nsapi_error_t AT_CellularNetwork::set_credentials(const char *apn,
|
|||
{
|
||||
size_t len;
|
||||
if (apn && (len = strlen(apn)) > 0) {
|
||||
_apn = (char*)malloc(len*sizeof(char)+1);
|
||||
_apn = (char *)malloc(len * sizeof(char) + 1);
|
||||
if (_apn) {
|
||||
memcpy(_apn, apn, len+1);
|
||||
memcpy(_apn, apn, len + 1);
|
||||
} else {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (username && (len = strlen(username)) > 0) {
|
||||
_uname = (char*)malloc(len*sizeof(char)+1);
|
||||
_uname = (char *)malloc(len * sizeof(char) + 1);
|
||||
if (_uname) {
|
||||
memcpy(_uname, username, len+1);
|
||||
memcpy(_uname, username, len + 1);
|
||||
} else {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
if (password && (len = strlen(password)) > 0) {
|
||||
_pwd = (char*)malloc(len*sizeof(char)+1);
|
||||
_pwd = (char *)malloc(len * sizeof(char) + 1);
|
||||
if (_pwd) {
|
||||
memcpy(_pwd, password, len+1);
|
||||
memcpy(_pwd, password, len + 1);
|
||||
} else {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ nsapi_error_t AT_CellularNetwork::activate_context()
|
|||
_at.resp_stop();
|
||||
|
||||
if (!_is_context_active) {
|
||||
tr_info("Activate PDP context %d",_cid);
|
||||
tr_info("Activate PDP context %d", _cid);
|
||||
_at.cmd_start("AT+CGACT=1,");
|
||||
_at.write_int(_cid);
|
||||
_at.cmd_stop();
|
||||
|
@ -462,7 +462,7 @@ bool AT_CellularNetwork::set_new_context(int cid)
|
|||
}
|
||||
}
|
||||
|
||||
char pdp_type[8+1] = {0};
|
||||
char pdp_type[8 + 1] = {0};
|
||||
|
||||
switch (tmp_stack) {
|
||||
case IPV4_STACK:
|
||||
|
@ -541,7 +541,7 @@ bool AT_CellularNetwork::get_context()
|
|||
if (pdp_type_len > 0) {
|
||||
apn_len = _at.read_string(apn, sizeof(apn) - 1);
|
||||
if (apn_len >= 0) {
|
||||
if (_apn && (strcmp(apn, _apn) != 0) ) {
|
||||
if (_apn && (strcmp(apn, _apn) != 0)) {
|
||||
continue;
|
||||
}
|
||||
nsapi_ip_stack_t pdp_stack = string_to_stack_type(pdp_type_from_context);
|
||||
|
@ -571,7 +571,7 @@ bool AT_CellularNetwork::get_context()
|
|||
_cid = cid;
|
||||
break;
|
||||
}
|
||||
// If PDP is IPV4 or IPV6 they are already checked if supported
|
||||
// If PDP is IPV4 or IPV6 they are already checked if supported
|
||||
} else {
|
||||
_ip_stack_type = pdp_stack;
|
||||
_cid = cid;
|
||||
|
@ -590,16 +590,16 @@ bool AT_CellularNetwork::get_context()
|
|||
}
|
||||
_at.resp_stop();
|
||||
if (_cid == -1) { // no suitable context was found so create a new one
|
||||
if (!set_new_context(cid_max+1)) {
|
||||
if (!set_new_context(cid_max + 1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// save the apn
|
||||
if (apn_len > 0 && !_apn) {
|
||||
_apn = (char*)malloc(apn_len*sizeof(char)+1);
|
||||
_apn = (char *)malloc(apn_len * sizeof(char) + 1);
|
||||
if (_apn) {
|
||||
memcpy(_apn, apn, apn_len+1);
|
||||
memcpy(_apn, apn, apn_len + 1);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -609,7 +609,7 @@ bool AT_CellularNetwork::get_context()
|
|||
return true;
|
||||
}
|
||||
|
||||
nsapi_ip_stack_t AT_CellularNetwork::string_to_stack_type(const char* pdp_type)
|
||||
nsapi_ip_stack_t AT_CellularNetwork::string_to_stack_type(const char *pdp_type)
|
||||
{
|
||||
nsapi_ip_stack_t stack = DEFAULT_STACK;
|
||||
int len = strlen(pdp_type);
|
||||
|
@ -649,7 +649,7 @@ nsapi_error_t AT_CellularNetwork::set_registration_urc(RegistrationType type, bo
|
|||
}
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode& mode)
|
||||
nsapi_error_t AT_CellularNetwork::get_network_registering_mode(NWRegisteringMode &mode)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+COPS?");
|
||||
|
@ -700,12 +700,12 @@ void AT_CellularNetwork::read_reg_params(RegistrationType type, RegistrationStat
|
|||
reg_status = (RegistrationStatus)_at.read_int();
|
||||
|
||||
int len = _at.read_string(lac_string, LAC_LENGTH);
|
||||
if (memcmp(lac_string, "ffff", LAC_LENGTH-1) && len >= 0) {
|
||||
if (memcmp(lac_string, "ffff", LAC_LENGTH - 1) && len >= 0) {
|
||||
lac_read = true;
|
||||
}
|
||||
|
||||
len = _at.read_string(cell_id_string, CELL_ID_LENGTH);
|
||||
if (memcmp(cell_id_string, "ffffffff", CELL_ID_LENGTH-1) && len >= 0) {
|
||||
if (memcmp(cell_id_string, "ffffffff", CELL_ID_LENGTH - 1) && len >= 0) {
|
||||
cell_id_read = true;
|
||||
}
|
||||
|
||||
|
@ -713,12 +713,12 @@ void AT_CellularNetwork::read_reg_params(RegistrationType type, RegistrationStat
|
|||
|
||||
if (lac_read) {
|
||||
lac = hex_str_to_int(lac_string, LAC_LENGTH);
|
||||
tr_debug("lac %s %d", lac_string, lac );
|
||||
tr_debug("lac %s %d", lac_string, lac);
|
||||
}
|
||||
|
||||
if (cell_id_read) {
|
||||
cell_id = hex_str_to_int(cell_id_string, CELL_ID_LENGTH);
|
||||
tr_debug("cell_id %s %d", cell_id_string, cell_id );
|
||||
tr_debug("cell_id %s %d", cell_id_string, cell_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -892,7 +892,7 @@ nsapi_error_t AT_CellularNetwork::set_access_technology_impl(RadioAccessTechnolo
|
|||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_access_technology(RadioAccessTechnology& rat)
|
||||
nsapi_error_t AT_CellularNetwork::get_access_technology(RadioAccessTechnology &rat)
|
||||
{
|
||||
rat = _current_act;
|
||||
return NSAPI_ERROR_OK;
|
||||
|
@ -942,7 +942,7 @@ nsapi_error_t AT_CellularNetwork::scan_plmn(operList_t &operators, int &opsCount
|
|||
|
||||
// Optional - try read an int
|
||||
ret = _at.read_int();
|
||||
op->op_rat = (ret == error_code) ? RAT_UNKNOWN:(RadioAccessTechnology)ret;
|
||||
op->op_rat = (ret == error_code) ? RAT_UNKNOWN : (RadioAccessTechnology)ret;
|
||||
|
||||
if ((_op_act == RAT_UNKNOWN) ||
|
||||
((op->op_rat != RAT_UNKNOWN) && (op->op_rat == _op_act))) {
|
||||
|
@ -975,8 +975,8 @@ nsapi_error_t AT_CellularNetwork::set_ciot_optimization_config(Supported_UE_Opt
|
|||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt& supported_opt,
|
||||
Preferred_UE_Opt& preferred_opt)
|
||||
nsapi_error_t AT_CellularNetwork::get_ciot_optimization_config(Supported_UE_Opt &supported_opt,
|
||||
Preferred_UE_Opt &preferred_opt)
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
|
@ -1013,7 +1013,7 @@ nsapi_error_t AT_CellularNetwork::get_rate_control(
|
|||
int next_element = _at.read_int();
|
||||
if (next_element >= 0) {
|
||||
reports = (RateControlExceptionReports)next_element;
|
||||
tr_debug("reports %d",reports);
|
||||
tr_debug("reports %d", reports);
|
||||
next_element = _at.read_int();
|
||||
} else {
|
||||
comma_found = false;
|
||||
|
@ -1021,7 +1021,7 @@ nsapi_error_t AT_CellularNetwork::get_rate_control(
|
|||
|
||||
if (comma_found && next_element >= 0) {
|
||||
timeUnit = (RateControlUplinkTimeUnit)next_element;
|
||||
tr_debug("time %d",timeUnit);
|
||||
tr_debug("time %d", timeUnit);
|
||||
next_element = _at.read_int();
|
||||
} else {
|
||||
comma_found = false;
|
||||
|
@ -1029,7 +1029,7 @@ nsapi_error_t AT_CellularNetwork::get_rate_control(
|
|||
|
||||
if (comma_found && next_element >= 0) {
|
||||
uplinkRate = next_element;
|
||||
tr_debug("rate %d",uplinkRate);
|
||||
tr_debug("rate %d", uplinkRate);
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
@ -1039,16 +1039,16 @@ nsapi_error_t AT_CellularNetwork::get_rate_control(
|
|||
return (ret == NSAPI_ERROR_OK) ? NSAPI_ERROR_OK : NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularNetwork::get_pdpcontext_params(pdpContextList_t& params_list)
|
||||
nsapi_error_t AT_CellularNetwork::get_pdpcontext_params(pdpContextList_t ¶ms_list)
|
||||
{
|
||||
const int ipv6_subnet_size = 128;
|
||||
const int max_ipv6_size = 64;
|
||||
char* ipv6_and_subnetmask = (char*)malloc(ipv6_subnet_size);
|
||||
char *ipv6_and_subnetmask = (char *)malloc(ipv6_subnet_size);
|
||||
if (!ipv6_and_subnetmask) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
char* temp = (char*)malloc(max_ipv6_size);
|
||||
char *temp = (char *)malloc(max_ipv6_size);
|
||||
if (!temp) {
|
||||
free(ipv6_and_subnetmask);
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
|
|
|
@ -38,7 +38,7 @@ nsapi_error_t AT_CellularSIM::get_sim_state(SimState &state)
|
|||
_at.cmd_start("AT+CPIN?");
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("+CPIN:");
|
||||
ssize_t len = _at.read_string(simstr, sizeof (simstr));
|
||||
ssize_t len = _at.read_string(simstr, sizeof(simstr));
|
||||
if (len != -1) {
|
||||
if (len >= 5 && memcmp(simstr, "READY", 5) == 0) {
|
||||
state = SimStateReady;
|
||||
|
@ -61,13 +61,13 @@ nsapi_error_t AT_CellularSIM::get_sim_state(SimState &state)
|
|||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
switch (state) {
|
||||
case SimStatePinNeeded:
|
||||
tr_error("SIM PIN required");
|
||||
tr_info("SIM PIN required");
|
||||
break;
|
||||
case SimStatePukNeeded:
|
||||
tr_error("SIM PUK required");
|
||||
break;
|
||||
case SimStateUnknown:
|
||||
tr_error("SIM state unknown");
|
||||
tr_warn("SIM state unknown");
|
||||
break;
|
||||
default:
|
||||
tr_info("SIM is ready");
|
||||
|
@ -134,7 +134,7 @@ nsapi_error_t AT_CellularSIM::set_pin_query(const char *sim_pin, bool query_pin)
|
|||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t AT_CellularSIM::get_imsi(char* imsi)
|
||||
nsapi_error_t AT_CellularSIM::get_imsi(char *imsi)
|
||||
{
|
||||
_at.lock();
|
||||
_at.cmd_start("AT+CIMI");
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) , 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 "CellularLog.h"
|
||||
|
||||
#if MBED_CONF_MBED_TRACE_ENABLE
|
||||
|
||||
namespace mbed_cellular_trace {
|
||||
|
||||
typedef struct trace_s {
|
||||
void (*mutex_wait_f)(void);
|
||||
void (*mutex_release_f)(void);
|
||||
} trace_t;
|
||||
|
||||
static trace_t m_trace = {
|
||||
.mutex_wait_f = 0,
|
||||
.mutex_release_f = 0,
|
||||
};
|
||||
|
||||
void mutex_wait_function_set(void (*mutex_wait_f)(void))
|
||||
{
|
||||
m_trace.mutex_wait_f = mutex_wait_f;
|
||||
}
|
||||
|
||||
void mutex_release_function_set(void (*mutex_release_f)(void))
|
||||
{
|
||||
m_trace.mutex_release_f = mutex_release_f;
|
||||
}
|
||||
|
||||
|
||||
void mutex_wait()
|
||||
{
|
||||
if (m_trace.mutex_wait_f) {
|
||||
m_trace.mutex_wait_f();
|
||||
}
|
||||
}
|
||||
|
||||
void mutex_release()
|
||||
{
|
||||
if (m_trace.mutex_release_f) {
|
||||
m_trace.mutex_release_f();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbed_cellular_trace
|
||||
|
||||
#endif // MBED_CONF_MBED_TRACE_ENABLE
|
|
@ -18,24 +18,26 @@
|
|||
#ifndef CELLULAR_LOG_H_
|
||||
#define CELLULAR_LOG_H_
|
||||
|
||||
#include "rtos.h"
|
||||
|
||||
#if defined(HAVE_DEBUG) && !defined(FEA_TRACE_SUPPORT)
|
||||
#define FEA_TRACE_SUPPORT
|
||||
#endif
|
||||
|
||||
#if defined(FEATURE_COMMON_PAL)
|
||||
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
#ifndef TRACE_GROUP
|
||||
#define TRACE_GROUP "cellular"
|
||||
#define TRACE_GROUP "CELL"
|
||||
#endif // TRACE_GROUP
|
||||
|
||||
#else
|
||||
|
||||
#define tr_debug(...) (void(0))
|
||||
#define tr_info(...) (void(0))
|
||||
#define tr_error(...) (void(0))
|
||||
#define tr_warn(...) (void(0))
|
||||
|
||||
#endif // FEATURE_COMMON_PAL
|
||||
/**
|
||||
* Set mutex wait/release functions for 'tr_' macros,
|
||||
* implementation here is modified from that found from mbed_trace.
|
||||
*/
|
||||
namespace mbed_cellular_trace {
|
||||
void mutex_wait_function_set(void (*mutex_wait_f)(void));
|
||||
void mutex_release_function_set(void (*mutex_release_f)(void));
|
||||
void mutex_wait();
|
||||
void mutex_release();
|
||||
}
|
||||
|
||||
#endif // CELLULAR_LOG_H_
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
"random_max_start_delay": {
|
||||
"help": "Maximum random delay value used in start-up sequence in milliseconds",
|
||||
"value": 0
|
||||
},
|
||||
"debug-at": {
|
||||
"help": "Enable AT debug prints",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue