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

ATParser could not support some strings very well. #7

Open
tz-arm opened this issue Jul 17, 2017 · 4 comments
Open

ATParser could not support some strings very well. #7

tz-arm opened this issue Jul 17, 2017 · 4 comments

Comments

@tz-arm
Copy link

tz-arm commented Jul 17, 2017

I am working to integrate a NBIoT module and found that this ATParser could not support some strings.
After debugging, I found it is caused by the poor sscanf().

For example,
_parser.recv("\"%15[^\n]\"", dev_info.imsi); from ESP8266 driver as reference , it could work.
_parser.recv("%15[^\n]", dev_info.imsi); with no quotes does not work well. it will return the first char in the string to imsi.

Below is a simple test code, would you help to share comments if any idea?

void verify_sscanf()
{
   //Verify the AT format for esp8266 with quotes
    int count = -1;
    char test[] = "0\"123456789\"";
    char test1[] = "0\"%*9[^\n]\"%n0";
    char test2[] = "0\"1234\"";
    sscanf(test2, test1, &count);
    printf("\nESP8266: expect -1 -  count = %d\n", count);
    count = -1;
    sscanf(test, test1, &count);
    printf("\nESP8266: expect 12 -  count = %d\n", count);
    //Verify the AT format for BC95 without quotes
    char test_bc95[] = "0123456789";
    char test1_bc95[] = "0%*9[^\n]%n0";
    char test2_bc95[] = "01234";
    count = -1;
    sscanf(test2_bc95, test1_bc95, &count);
    printf("\nBC95: expect -1 - count = %d\n", count);
    count = -1;
    sscanf(test_bc95, test1_bc95, &count);
    printf("\nBC95: expect 10 BUT fail- count = %d\n", count);
}

@tz-arm
Copy link
Author

tz-arm commented Jul 18, 2017

Duplicated issue with #1:
Got the solution from the reference:
https://github.com/sarahmarshy/mxchip-wifi-driver/blob/at-parser-port/mxchip/MXCHIP.cpp#L165
Use _parser.recv("%[^\r]%*[\r]%*[\n]") instead of _parser.recv("%15[^\r\n]")

@sarahmarshy
Copy link
Contributor

@tz-arm According to this (http://www.cplusplus.com/reference/cstdio/scanf/), it looks like the 15 in that formatter is considered the "width." This is what that document says about width:

Specifies the maximum number of characters to be read in the current reading operation (optional).

So, this operation is not greedy.

@tz-arm
Copy link
Author

tz-arm commented Jul 19, 2017

I saw ESP8266 driver and PPPCellularInterface are using this "width" parameters.
Since the esp8266 use quotes in the string, it works well. but I really adapt if it is working well in PPPCellularInterface reference.
Maybe we can propose to unify all usages?

@geky
Copy link
Contributor

geky commented Jul 19, 2017

I would actually use this:

_parser.recv("%15[^\r]%*[\r]%*[\n]")

The 15 protects against buffer overflow if you accidentally end up reading corrupt data. But @sarahmarshy is right this only specifies the max. The way the ATParser calls scanf makes the match non-greedy, which is a bit counter-intuitive if you're familiar with regex, where greedy matches are the norm.

Non-greedy matching means you will need to explicitly indicate what stops the pattern, in this case the pattern %*[\r]%*[\n] works fine.

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

No branches or pull requests

3 participants