From aff55462f5f36b8793f99a51387c20496eb000f9 Mon Sep 17 00:00:00 2001 From: Mirela Chirica Date: Thu, 28 Jun 2018 14:50:37 +0300 Subject: [PATCH] Cellular: Fix for ATHandler's read string and hexstring NULL termination --- features/cellular/framework/AT/ATHandler.cpp | 86 ++++++++++++++++---- features/cellular/framework/AT/ATHandler.h | 4 +- 2 files changed, 69 insertions(+), 21 deletions(-) diff --git a/features/cellular/framework/AT/ATHandler.cpp b/features/cellular/framework/AT/ATHandler.cpp index 5dbc834609..eaba46dfdc 100644 --- a/features/cellular/framework/AT/ATHandler.cpp +++ b/features/cellular/framework/AT/ATHandler.cpp @@ -454,31 +454,88 @@ ssize_t ATHandler::read_bytes(uint8_t *buf, size_t len) return read_len; } -ssize_t ATHandler::read(char *buf, size_t size, bool read_even_stop_tag, bool hex) +ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag) { if (_last_err || !_stop_tag || (_stop_tag->found && read_even_stop_tag == false)) { return -1; } + consume_char('\"'); + + if (_last_err) { + return -1; + } + + size_t len = 0; + size_t match_pos = 0; + + for (; len < (size - 1 + match_pos); len++) { + int c = get_char(); + if (c == -1) { + set_error(NSAPI_ERROR_DEVICE_ERROR); + return -1; + } else if (c == _delimiter) { + buf[len] = '\0'; + break; + } else if (c == '\"') { + match_pos = 0; + len--; + continue; + } else if (_stop_tag->len && c == _stop_tag->tag[match_pos]) { + match_pos++; + if (match_pos == _stop_tag->len) { + _stop_tag->found = true; + // remove tag from string if it was matched + len -= (_stop_tag->len - 1); + buf[len] = '\0'; + break; + } + } else if (match_pos) { + match_pos = 0; + } + + buf[len] = c; + } + + if (len && (len == size - 1 + match_pos)) { + buf[len] = '\0'; + } + + return len; +} + +ssize_t ATHandler::read_hex_string(char *buf, size_t size) +{ + if (_last_err || !_stop_tag || _stop_tag->found) { + return -1; + } + size_t match_pos = 0; - size_t read_size = hex ? size * 2 : size; consume_char('\"'); + if (_last_err) { + return -1; + } + size_t read_idx = 0; size_t buf_idx = 0; char hexbuf[2]; - for (; read_idx < (read_size + match_pos); read_idx++) { + for (; read_idx < size * 2 + match_pos; read_idx++) { int c = get_char(); - buf_idx = hex ? read_idx / 2 : read_idx; + + if (match_pos) { + buf_idx++; + } else { + buf_idx = read_idx / 2; + } + if (c == -1) { - buf[buf_idx] = '\0'; set_error(NSAPI_ERROR_DEVICE_ERROR); return -1; } if (c == _delimiter) { - buf[buf_idx] = '\0'; break; } else if (c == '\"') { match_pos = 0; @@ -490,14 +547,13 @@ ssize_t ATHandler::read(char *buf, size_t size, bool read_even_stop_tag, bool he _stop_tag->found = true; // remove tag from string if it was matched buf_idx -= (_stop_tag->len - 1); - buf[buf_idx] = '\0'; break; } } else if (match_pos) { match_pos = 0; } - if (!hex) { + if (match_pos) { buf[buf_idx] = c; } else { hexbuf[read_idx % 2] = c; @@ -507,19 +563,13 @@ ssize_t ATHandler::read(char *buf, size_t size, bool read_even_stop_tag, bool he } } + if (read_idx && (read_idx == size * 2 + match_pos)) { + buf_idx++; + } + return buf_idx; } -ssize_t ATHandler::read_string(char *buf, size_t size, bool read_even_stop_tag) -{ - return read(buf, size, read_even_stop_tag, false); -} - -ssize_t ATHandler::read_hex_string(char *buf, size_t size) -{ - return read(buf, size, false, true); -} - int32_t ATHandler::read_int() { if (_last_err || !_stop_tag || _stop_tag->found) { diff --git a/features/cellular/framework/AT/ATHandler.h b/features/cellular/framework/AT/ATHandler.h index 93e5053598..6ae417a3d6 100644 --- a/features/cellular/framework/AT/ATHandler.h +++ b/features/cellular/framework/AT/ATHandler.h @@ -302,7 +302,7 @@ public: * Stops on delimiter or stop tag. * * @param str output buffer for the read - * @param size maximum number of chars to output + * @param size maximum number of chars to output including NULL * @param read_even_stop_tag if true then try to read even if the stop tag was found previously * @return length of output string or -1 in case of read timeout before delimiter or stop tag is found */ @@ -512,8 +512,6 @@ private: // check is urc is already added bool find_urc_handler(const char *prefix, mbed::Callback 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); };