Closed Jurek822 closed 6 years ago
Does it cause issues for you? It looks like if this is really a bug, it would just never work (but it currently works on AVR)
Yes, it is an issue for me. It is especially noticed in Diagnostic.ino
example, because in this example results of waitResponse()
are checked several times, for example:
if (!modem.restart()) {
SerialMon.println(" fail");
But in BlynkClient.ino
the result of modem.restart()
is not checked and in case of unrecognized response a timeout will work. Moreover, I think that #60 is caused by this issue.
@Jurek822 , let me invite you to our chat: https://gitter.im/tinygsm/Developers
@Jurek822 any ideas how to fix this?
I see two ways:
endsWith()
but comparing RAM string with Flash String (without using RAM).waitResponse()
and using existing endsWith()
.Ad. 1. The function may look like:
unsigned char endsWith2(const String & ramStr, GsmConstStr flashStr) {
if (!flashStr)
return 0;
const char * flashStr2 = (PGM_P) flashStr;
int flashLen = strlen_P(flashStr2);
int ramLen = ramStr.length();
if (ramLen < flashLen)
return 0;
String substring = ramStr.substring(ramLen - flashLen);
return strncmp_P(substring.c_str(), flashStr2, flashLen) == 0;
}
Ad. 2. Look at the code in my first post.
@Jurek822, it should be very easy to validate that this is really causing your problems. Just switch it off with #if 0
:
https://github.com/vshymanskyy/TinyGSM/blob/master/TinyGsmCommon.h#L32
I have done some deep analysis. It turned out that:
1) GSM_OK
from 24 line of TinyGsmClientSIM800.h
is located at address 1068 (probably Flash);
2) during execution of waitResponse()
variable data
has address 2248 and r1
equals to GSM_OK
has address 2216 - both probably in RAM;
3) the address of r1=GSM_OK
is not the same for every call of waitResponse()
Conclusion: during calling waitRespponse()
variable r1
is converted from Flash string into RAM string.
So at least it is not a bug - just something we can improve on.
Yes, it is not a bug.
In
waitResponse()
there is usingString::endsWith(const String &s2 )
. Every time as an argumentconst __FlashStringHelper*
object is used, and it is comparing with a string from RAM. However, in AVRendsWith()
usesstrcmp()
to compare strings. This is a problem because for comparingconst char *
placed in RAM withconst char *
placed in FLASHstrcmp_P()
should be used. Alternatively, aconst __FlashStringHelper*
string may be cast to RAM string, for example: