Skip to content

Commit

Permalink
drivers/at: add a function read a response plus the OK
Browse files Browse the repository at this point in the history
There are many modem commands for which you get a line of response followed
by an OK. Take for example the AT+CGSN command to get the IMEI of a Ublox
G350.
  >> AT+CGSN
  << 004999010640000
  << OK
  • Loading branch information
keestux committed Oct 16, 2022
1 parent 72d16e1 commit 9447423
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
50 changes: 50 additions & 0 deletions drivers/at/at.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,56 @@ ssize_t at_send_cmd_get_resp(at_dev_t *dev, const char *command,
return res;
}

ssize_t at_send_cmd_get_resp_wait_ok(at_dev_t *dev, const char *command, const char *resp_prefix,
char *resp_buf, size_t len, uint32_t timeout)
{
ssize_t res;
ssize_t res_ok;
char ok_buf[64];

at_drain(dev);

res = at_send_cmd(dev, command, timeout);
if (res) {
goto out;
}

res = at_readline(dev, resp_buf, len, false, timeout);
if (res == 0) {
/* skip possible empty line */
res = at_readline(dev, resp_buf, len, false, timeout);
}

/* Strip the expected prefix */
if (res > 0 && resp_prefix && *resp_prefix) {
size_t prefix_len = strlen(resp_prefix);
if (strncmp(resp_buf, resp_prefix, prefix_len) == 0) {
size_t remaining_len = strlen(resp_buf) - prefix_len;
/* The one extra byte in the copy is the terminating nul byte */
memmove(resp_buf, resp_buf + prefix_len, remaining_len + 1);
res -= prefix_len;
}
}

/* wait for OK */
if (res >= 0) {
res_ok = at_readline(dev, ok_buf, sizeof(ok_buf), false, timeout);
if (res_ok == 0) {
/* skip possible empty line */
res_ok = at_readline(dev, ok_buf, sizeof(ok_buf), false, timeout);
}
ssize_t len_ok = sizeof(CONFIG_AT_RECV_OK) - 1;
if ((len_ok != 0) && (strcmp(ok_buf, CONFIG_AT_RECV_OK) == 0)) {
}
else {
/* Something else then OK */
res = -1;
}
}
out:
return res;
}

ssize_t at_send_cmd_get_lines(at_dev_t *dev, const char *command,
char *resp_buf, size_t len, bool keep_eol, uint32_t timeout)
{
Expand Down
21 changes: 21 additions & 0 deletions drivers/include/at.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,27 @@ 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 Send AT command, wait for response plus OK
*
* This function sends the supplied @p command, then waits and returns one
* line of response.
*
* A possible empty line will be skipped.
*
* @param[in] dev device to operate on
* @param[in] command command to send
* @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)
*
* @returns length of response on success
* @returns <0 on error
*/
ssize_t at_send_cmd_get_resp_wait_ok(at_dev_t *dev, const char *command, const char *resp_prefix,
char *resp_buf, size_t len, uint32_t timeout);

/**
* @brief Send AT command, wait for multiline response
*
Expand Down

0 comments on commit 9447423

Please sign in to comment.