diff --git a/drivers/at/at.c b/drivers/at/at.c index acb0dc79cd..e42b1f8c6c 100644 --- a/drivers/at/at.c +++ b/drivers/at/at.c @@ -325,7 +325,7 @@ ssize_t at_send_cmd_get_resp(at_dev_t *dev, const char *command, return at_readline_skip_empty(dev, resp_buf, len, false, timeout); } -static ssize_t get_resp_with_prefix(at_dev_t *dev, const char *resp_prefix, +ssize_t at_get_resp_with_prefix(at_dev_t *dev, const char *resp_prefix, char *resp_buf, size_t len, uint32_t timeout) { ssize_t res; @@ -368,7 +368,7 @@ ssize_t at_send_cmd_get_resp_wait_ok(at_dev_t *dev, const char *command, const c if (res) { return res; } - res = get_resp_with_prefix(dev, resp_prefix, resp_buf, len, timeout); + res = at_get_resp_with_prefix(dev, resp_prefix, resp_buf, len, timeout); if (res < 1) { /* error or OK (empty response) */ return res; @@ -438,7 +438,7 @@ ssize_t at_send_cmd_get_lines(at_dev_t *dev, const char *command, char *resp_buf return get_lines(dev, resp_buf, len, timeout); } -static int wait_prompt(at_dev_t *dev, uint32_t timeout) +int at_wait_prompt(at_dev_t *dev, uint32_t timeout) { ssize_t res; do { @@ -467,7 +467,7 @@ int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout if (res) { return (int)res; } - return wait_prompt(dev, timeout); + return at_wait_prompt(dev, timeout); } int at_send_cmd_wait_ok(at_dev_t *dev, const char *command, uint32_t timeout) @@ -665,11 +665,6 @@ ssize_t _emb_read_line_or_echo(at_dev_t *dev, char const *cmd, char *resp_buf, size_t len, uint32_t timeout); __attribute__((alias("get_lines"))) ssize_t _emb_get_lines(at_dev_t *dev, char *resp_buf, size_t len, uint32_t timeout); -__attribute__((alias("get_resp_with_prefix"))) -ssize_t _emb_get_resp_with_prefix(at_dev_t *dev, const char *resp_prefix, - char *resp_buf, size_t len, uint32_t timeout); __attribute__((alias("wait_echo"))) int _emb_wait_echo(at_dev_t *dev, char const *command, uint32_t timeout); -__attribute__((alias("wait_prompt"))) -int _emb_wait_prompt(at_dev_t *dev, uint32_t timeout); #endif diff --git a/drivers/include/at.h b/drivers/include/at.h index b7b73ba711..255f4975d9 100644 --- a/drivers/include/at.h +++ b/drivers/include/at.h @@ -264,7 +264,7 @@ typedef struct { * * @retval string containing the error value. */ -static inline char const *at_get_err_info(at_dev_t *dev) +static inline char const *at_get_err_info(at_dev_t const *dev) { return dev->rp_buf; } @@ -316,6 +316,18 @@ int at_send_cmd_wait_ok(at_dev_t *dev, const char *command, uint32_t timeout); */ int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout); +/** + * Waits for the prompt character (>). + * + * @param[in] dev device to operate on + * @param[in] timeout timeout (in usec) + * + * @retval 0 when prompt is received + * @retval -AT_ERR_EXTENDED if failed and a error code can be retrieved with + * @ref at_get_err_info() (i.e. DCE answered with `CMx ERROR`) + * @retval <0 other failures + */ +int at_wait_prompt(at_dev_t *dev, uint32_t timeout); /** * @brief Send AT command, wait for response * @@ -340,14 +352,44 @@ int at_send_cmd_wait_prompt(at_dev_t *dev, const char *command, uint32_t timeout */ ssize_t at_send_cmd_get_resp(at_dev_t *dev, const char *command, char *resp_buf, size_t len, uint32_t timeout); - +/** + * @brief Wait for a response with a specific prefix. + * + * If the provided prefix is NULL or empty, this behaves just like + * @ref at_readline_skip_empty(). Otherwise, it repeatedly calls @ref + * at_readline_skip_empty() and: + * - if the prefix matches: discards the prefix from the response, copies the + * rest to @p resp_buf, stops and returns the resulting response length + * - if the prefix does not match: + * - if the response is OK: stops and returns 0 + * - if the response is ERROR/CMx ERROR: stops and returns <0 + * - none of the above: handles response as URC and repeats with the next + * line + * + * @param[in] dev device to operate on + * @param[in] resp_prefix expected prefix in the response + * @param[out] resp_buf buffer for storing response + * @param[in] len len of @p buffer + * @param[in] timeout timeout (in usec) + * + * @retval n response length if the prefix of the response matches + * @retval 0 if the response was OK + * @retval -AT_ERR_EXTENDED if failed and a error code can be retrieved with + * @ref at_get_err_info() (i.e. DCE answered with `CMx ERROR`) + * @retval <0 on error + */ +ssize_t at_get_resp_with_prefix(at_dev_t *dev, const char *resp_prefix, + char *resp_buf, size_t len, uint32_t timeout); /** * @brief Send AT command, wait for response plus OK * * This function sends the supplied @p command, then waits and returns one * line of response. The response is guaranteed null-terminated. * - * A possible empty line will be skipped. + * Calls following in order: + * - @ref at_send_cmd() + * - @ref at_get_resp_with_prefix() + * - @ref at_wait_ok() * * URCs are automatically handled. If no prefix is provided, the response * may be an URC. In that case, @ref at_postprocess_urc() can be called with the diff --git a/tests/drivers/at_unit/tests-at.c b/tests/drivers/at_unit/tests-at.c index 4ff32ed72a..e2bedf8b04 100644 --- a/tests/drivers/at_unit/tests-at.c +++ b/tests/drivers/at_unit/tests-at.c @@ -106,10 +106,7 @@ static void assert_urc_count(unsigned expected) int _emb_read_line_or_echo(at_dev_t *dev, char const *cmd, char *resp_buf, size_t len, uint32_t timeout); ssize_t _emb_get_lines(at_dev_t *dev, char *resp_buf, size_t len, uint32_t timeout); -ssize_t _emb_get_resp_with_prefix(at_dev_t *dev, const char *resp_prefix, - char *resp_buf, size_t len, uint32_t timeout); int _emb_wait_echo(at_dev_t *dev, char const *command, uint32_t timeout); -int _emb_wait_prompt(at_dev_t *dev, uint32_t timeout); static void inject_resp_str(at_dev_t *dev, char const *str) { @@ -344,7 +341,7 @@ void test_get_resp_with_prefix(void) AT_RECV_EOL "+RESPONSE: 123" AT_RECV_EOL); - res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + res = at_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); TEST_ASSERT(res > 0); res = strcmp("123", resp_buf); TEST_ASSERT(res == 0); @@ -356,7 +353,7 @@ void test_get_resp_with_prefix(void) AT_RECV_EOL "OK" AT_RECV_EOL); - res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + res = at_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); TEST_ASSERT(res == 0); inject_resp_str(dev, @@ -365,7 +362,7 @@ void test_get_resp_with_prefix(void) AT_RECV_EOL AT_RECV_EOL "+CME ERROR: 1" AT_RECV_EOL); - res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + res = at_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); TEST_ASSERT(res == -AT_ERR_EXTENDED); res = strncmp("1", dev->rp_buf, 1); TEST_ASSERT(res == 0); @@ -377,14 +374,14 @@ void test_get_resp_with_prefix(void) AT_RECV_EOL "ERROR" AT_RECV_EOL); - res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + res = at_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); TEST_ASSERT(res == -1); inject_resp_str(dev, AT_RECV_EOL UNIT_TEST_SHORT_URC AT_RECV_EOL); - res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + res = at_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); TEST_ASSERT(res == -ETIMEDOUT); inject_resp_str(dev, @@ -392,7 +389,7 @@ void test_get_resp_with_prefix(void) AT_RECV_EOL "+RESPONSE: 123" AT_RECV_EOL); - res = _emb_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); + res = at_get_resp_with_prefix(dev, "+RESPONSE: ", resp_buf, sizeof(resp_buf), 10000); TEST_ASSERT(res > 0); res = strcmp("123", resp_buf); TEST_ASSERT(res == 0); @@ -500,7 +497,7 @@ void test_wait_prompt(void) AT_RECV_EOL ">" "123"); - res = _emb_wait_prompt(dev, 1000); + res = at_wait_prompt(dev, 1000); TEST_ASSERT(res == 0); res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, sizeof(resp_buf), 1000); TEST_ASSERT(res == 3); @@ -512,7 +509,7 @@ void test_wait_prompt(void) AT_RECV_EOL ">" "456"); - res = _emb_wait_prompt(dev, 1000); + res = at_wait_prompt(dev, 1000); TEST_ASSERT(res == 0); res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, sizeof(resp_buf), 1000); TEST_ASSERT(res == 3); @@ -525,13 +522,13 @@ void test_wait_prompt(void) AT_RECV_EOL "ERROR" AT_RECV_EOL); - res = _emb_wait_prompt(dev, 1000); + res = at_wait_prompt(dev, 1000); TEST_ASSERT(res == -1); inject_resp_str(dev, ">" "123"); - res = _emb_wait_prompt(dev, 1000); + res = at_wait_prompt(dev, 1000); TEST_ASSERT(res == 0); res = isrpipe_read_timeout(&dev->isrpipe, (unsigned char *)resp_buf, sizeof(resp_buf), 1000); TEST_ASSERT(res == 3);