Skip to content
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

Adding attempts to readLine and state marker if radio module is unres… #244

Merged
merged 24 commits into from Jan 14, 2019

Conversation

savnik
Copy link
Contributor

@savnik savnik commented Aug 17, 2018

Proposal to fix issue #242

@CLAassistant
Copy link

CLAassistant commented Aug 17, 2018

CLA assistant check
All committers have signed the CLA.

@johanstokking johanstokking self-requested a review August 21, 2018 09:16
@johanstokking johanstokking self-assigned this Aug 21, 2018
Copy link
Member

@johanstokking johanstokking left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

this->radioModuleInvalidState = true; // Inform the application about the radio module is not responsive.
return 0;
}
else{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make spacing consistent around braces and brackets. Also no need for else after a return.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@@ -357,15 +357,21 @@ void TheThingsNetwork::clearReadBuffer()
}
}

size_t TheThingsNetwork::readLine(char *buffer, size_t size)
size_t TheThingsNetwork::readLine(char *buffer, size_t size, uint8_t attempts = 3) // Default timeout value 10s and is set in class initiator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is it set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeout is set in:

this->modemStream->setTimeout(10000);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set defaults in the header file

@savnik
Copy link
Contributor Author

savnik commented Sep 14, 2018

@johanstokking did you have time to review the changes?

@@ -357,15 +357,21 @@ void TheThingsNetwork::clearReadBuffer()
}
}

size_t TheThingsNetwork::readLine(char *buffer, size_t size)
size_t TheThingsNetwork::readLine(char *buffer, size_t size, uint8_t attempts = 3) // Default timeout value 10s and is set in class initiator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set defaults in the header file

{
size_t read = 0;
while (read == 0)
while (read == 0 && attempts>0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spacing; attempts > 0

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't you be decrementing attempts somewhere? Like while (!read && attempts--) ?

{
read = modemStream->readBytesUntil('\n', buffer, size);
}
if(attempts<=0)
{ // If attempts is activated return 0 and set RN state marker
this->radioModuleInvalidState = true; // Inform the application about the radio module is not responsive.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this is a way to signal, still it requires action from the application. I don't really know if application developers know how to resolve this.

The best way to resolve this is to reset the RN module through the reset pin. Would it be a good idea to configure (optionally) the reset pin, and engage a soft reset in the library at this point?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your valid point. Now a good question is should we let the library handle the reset or give the decision to the application. If the library is resetting the RN module we will need to let the application know so the application can handle this, eg. by re-joining the network.
But in either way we must raise a flag to the application and abort the current task.
If we reset the RN module in the library we can do a soft-reset by sending a sys_reset cmd or a hard-reset using the reset pin. In either way the library needs to rejoin the network and then re-execute the function. Should the module then retry for infinity or a limited tries?

One option could be to soft/hard reset the module every time this error occur, print a debug message with details and raise the flag. In this way we have raised awareness of a problem and tried to resolve it while giving power over the exception handling to the application.

readLine is used in:

  • readResponse
  • personalize
  • join
  • sendBytes
  • waitForOk

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However maybe the simple solution is the best. On error exit with debug message and error flag. Then update documentation and make a good example on how to handle the error on application level.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My wording was wrong; I meant hard reset, by using the reset pin. Sending the soft reset command is not going to work as the serial is broken already.

And you're right, doing a hard reset in the midst of a join or TX operation, and restoring the state (i.e. joining again) is not going to work either.

So I'm good with the signaling to the application. Please rename to needsHardReset, introduce a resetHard() that takes a pin number as parameter, and reset the needsHardReset after hard resetting. Also documentation would be helpful. Thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I will work on this and come back soon.

void (*messageCallback)(const uint8_t *payload, size_t size, port_t port);

void clearReadBuffer();
size_t readLine(char *buffer, size_t size);
size_t readLine(char *buffer, size_t size, uint8_t attempts);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So add the default always in the header file

Copy link
Member

@johanstokking johanstokking left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good. Almost there

src/TheThingsNetwork.cpp Outdated Show resolved Hide resolved
src/TheThingsNetwork.cpp Outdated Show resolved Hide resolved
src/TheThingsNetwork.cpp Outdated Show resolved Hide resolved
unsigned long time_now = milis();
int period = 1000;
while(millis() < time_now + period){
// wait
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use delay(), and do we need a whole second?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was just to make it non-blocking in case the application is using interrupt. The reset function is not time critical.
I have looked in the datasheet and there is no advice on minimum time for the signal for a reset to be triggered. I know that 1s works by test, but I have not tested <1s.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually delay() is the better one to use. On some platforms where it is necessary delay() will call yield(), while a while loop will not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you implement this @savnik ?

Copy link
Member

@johanstokking johanstokking left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rest is good.

I would like to see consistent spacing, i.e. before and after (...) and around operators, though.

docs/TheThingsNetwork.md Outdated Show resolved Hide resolved
docs/TheThingsNetwork.md Outdated Show resolved Hide resolved
unsigned long time_now = milis();
int period = 1000;
while(millis() < time_now + period){
// wait
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you implement this @savnik ?

@savnik
Copy link
Contributor Author

savnik commented Dec 5, 2018

So the wait function is implemented. I have tried to make it more clear now.
Maybe we do not see the same regarding spacing - but i can not see where the spacing is wrong now?

@jpmeijers
Copy link
Collaborator

Only saw the review request now. I'll try and give this PR a proper look and review during the coming week.

Copy link
Collaborator

@jpmeijers jpmeijers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only two small changes please. For the rest I am happy with this PR.

src/TheThingsNetwork.cpp Show resolved Hide resolved
docs/TheThingsNetwork.md Show resolved Hide resolved
@ElectronicallyE
Copy link

ElectronicallyE commented Dec 28, 2018

Thanks guys on making progress on this. I was about to write up an issue about this, but seems like you've got a handle on it already. Would be glad to start using TTN as soon as this is resolved as I have be unable to because of this hanging problem.

@johanstokking
Copy link
Member

@jpmeijers good to go now?

@savnik
Copy link
Contributor Author

savnik commented Jan 9, 2019

@jpmeijers have you had time to take a look at the two changes you sugested?

Copy link
Collaborator

@jpmeijers jpmeijers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@johanstokking johanstokking merged commit 389ab70 into TheThingsNetwork:master Jan 14, 2019
@johanstokking
Copy link
Member

Released in https://github.com/TheThingsNetwork/arduino-device-lib/releases/tag/v2.5.14

Thanks @savnik and @jpmeijers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants