drivers/at: fix URC handling and add better testing#20423
drivers/at: fix URC handling and add better testing#20423kfessel merged 3 commits intoRIOT-OS:masterfrom
Conversation
| * @param[in] resp_buf buffer to store line | ||
| * @param[in] len size of @p resp_buf | ||
| * @param[in] keep_eol true to keep the CR character in the response | ||
| * @param[in] keep_eol true to keep the trailing EOL sequence in the response |
There was a problem hiding this comment.
same as in at_readline()
| * @param[in] resp_buf buffer to store line | ||
| * @param[in] len size of @p resp_buf | ||
| * @param[in] keep_eol true to keep the CR character in the response | ||
| * @param[in] keep_eol true to keep the trailing EOL sequence in the response |
There was a problem hiding this comment.
This used to keep only the first character in the EOL sequence whenever keep_eol was true, which I find kind of arbitrary and creates a lot of edge cases to think about. Now you can either have the whole trailing EOL sequence or nothing. If e.g. the EOL is composite (\r\n), individual EOL characters will always be kept.
drivers/at/at.c
Outdated
| } | ||
| #endif | ||
|
|
||
| static ssize_t get_lines(at_dev_t *dev, char *resp_buf, size_t len, bool keep_eol, |
There was a problem hiding this comment.
I didn't change the behavior, but I'm voting to change it s.t.:
- EOL between lines should always be included in their original form - this means
keep_eolwill be unnecessary and always true - discard empty lines - which means leading EOLs or multiple in a row will get discarded
I think this will be much leaner and predictable for the user.
Any arguments against these changes?
There was a problem hiding this comment.
how does this pr seperate multiple lines one gets through this function with keep_eol=false? (previously the at_readline would have had left the '/n' in )
-> this function would have returned multiple lines seperated by newline prior to this
There was a problem hiding this comment.
I didn't change this, so I don't get what you are referring to. If you mean what I propose to change, then keep_eol will be removed (i.e. will always be true), and the original EOL sequences will stay in, except for multiple in a row. In other words, by my proposal, this function will return a list of non-empty lines separated by the original EOL sequence. Basically just call at_readline_skip_empty(keep_eol=true) untile timeout, OK or ERROR happens. I think this behavior is simpler and in line with what a user would expect.
Moreover, I really can't make up any use-case where throwing out the \r is necessary, and in the current implementation this creates some weird edge-cases, e.g. if a single \r is encountered, but no \n follows it, it is silently dropped.
There was a problem hiding this comment.
you changed the behavior of 'at_readline_skip_empty' (at least that is what the comment change to drivers/include/at.h:494
is indicating to no longer return the /n of the /r/n sequence
since this function uses 'at_readline_skip_empty' there might be no line separation ( neither /n nor /r ) while it gets multiple lines.
so without changing this function you changed its behavior ( didn't you ?)
There was a problem hiding this comment.
But this wouldn't have happened before either. at_readline_skip_empty(keep_eol=false) (which is only called until the first non-empty line is encountered) would have replaced the trailing \n with \0 anyway. And in case an empty line is returned, a \n or whatever is the last character in EOL is inserted.
Seems that this discussion reinforces my point that the EOL handling of this function needs to be simpified. ;)
There was a problem hiding this comment.
I changed this behavior to the one proposed. This also includes some small changes in line parsing -- mainly that response buffer overflow is returned with -ENOBUFS and not silently ignored. I packed these changes in a separate commit.
1d2efdf to
a531ae1
Compare
779b0b7 to
9ed3725
Compare
| echo " rcv EOL 1 = $rcv_eol_1" | ||
| echo " rcv EOL 2 = $rcv_eol_2" | ||
|
|
||
| # make -j BOARD=native "HANDLE_URC=$handle_urc" "ECHO_ON=$echo" "SEND_EOL=\"$send_eol\"" "RECV_EOL_1=\"$rcv_eol_1\"" "RECV_EOL_2=\"$rcv_eol_2\"" compile-commands |
There was a problem hiding this comment.
No, I left this in on purpose to have the compile-commands.json of the first build that failes.
There was a problem hiding this comment.
why use the test to build the compile-commands.json ?
There was a problem hiding this comment.
The test runs through various build configurations, and I want the compile-commands.json of the particular build that failed, without having to re-build that per hand.
Alternatively, I can always build compile-commands whenever a test fails, with that particular build settings.
There was a problem hiding this comment.
Ok I changed this so that compile-commands.json is built whenever the test fails.
drivers/at/at.c
Outdated
| 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) | ||
| { | ||
| ssize_t res; |
There was a problem hiding this comment.
seem like this could just be int;
at_send_cmd() returns int;
get_lines probaly returns an int to that it turned into an ssize;
this might be the other way around since some of the other functions also seem to return int even though they return size data
There was a problem hiding this comment.
atm this seems a little mixed
There was a problem hiding this comment.
should be ssize_t everywhere a size is returned but isrpipe_read_timeout() returns int too...
There was a problem hiding this comment.
right, so I changed everything like this:
- fn that return 0 or negative error return
int - fn that return a size or negative error return
ssize_t - fn that return a size return
size_t
| return get_lines(dev, resp_buf, len, keep_eol, timeout); | ||
| } | ||
|
|
||
| static int wait_prompt(at_dev_t *dev, uint32_t timeout) |
There was a problem hiding this comment.
return 0 or negative error -> stays int
9304d3f to
20a0480
Compare
074e868 to
4ab5bc1
Compare
|
minor api change ( the keep_eol is gone) |
|
Error: Commit message is longer than 72 characters: "drivers/at: Added robust, synchronous URC handling. Added unit tests. - API change: at_send_cmd_get_lines() now always keeps the whole EOL sequence between lines" added -> add removed -> remove |
benpicco
left a comment
There was a problem hiding this comment.
Sorry, forgot about this one.
Looks good from my side!
Contribution description
Changes in this PR:
At the first glance, the diffs in this PR are huge. However, much of it comes from refactoring. Therefore, I have split this PR in three commits:
Testing procedure
tests/drivers/at/tests-with-config/emulate_dce.pytests/drivers/tests-with-config/test_all_configs.sh. This will compile theat_testsprogram and run the unit tests with all possible configuration options. No actual modem is needed.Issues/PRs references
addresses #20059
removes #14327 (comment)