-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers/at: fix URC handling and add better testing #20423
Conversation
@@ -465,7 +503,7 @@ ssize_t at_readline(at_dev_t *dev, char *resp_buf, size_t len, bool keep_eol, ui | |||
* @param[in] dev device to operate on | |||
* @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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as in at_readline()
* @param[in] dev device to operate on | ||
* @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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
} while (*p); | ||
} | ||
#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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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_eol
will 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like a leftover
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why use the test to build the compile-commands.json ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I changed this so that compile-commands.json
is built whenever the test fails.
drivers/at/at.c
Outdated
{ | ||
ssize_t res; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
atm this seems a little mixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be ssize_t
everywhere a size is returned but isrpipe_read_timeout()
returns int
too...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
may return size_t ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return 0 or negative error -> stays int
9304d3f
to
20a0480
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mostly good ( derMihai wants to do some minor changes) unless other reviewers chime in i would approve this
074e868
to
4ab5bc1
Compare
minor api change ( the keep_eol is gone) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commit messages need to be rewritten / commits squashed
maybe have one of them contain remove keep_eol
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.py
tests/drivers/tests-with-config/test_all_configs.sh
. This will compile theat_tests
program and run the unit tests with all possible configuration options. No actual modem is needed.Issues/PRs references
addresses #20059
removes #14327 (comment)