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

Implement generic command for parsing AT command responses #12

Open
mdbartos opened this issue May 29, 2017 · 0 comments
Open

Implement generic command for parsing AT command responses #12

mdbartos opened this issue May 29, 2017 · 0 comments

Comments

@mdbartos
Copy link
Member

mdbartos commented May 29, 2017

modem.c should have a generic method for parsing output of AT command queries.

Here's my quick (unsafe) first attempt. identify_command parses the original command from the response (probably not needed, but could be useful). parse_at_command extracts the body from an AT command response. Could use some error checking, though (need to be careful with handling NULL string pointers).

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char clocktime[100] = "AT+CCLK?\r\r\n+CCLK: \"17/05/29,01:56:06-16\"\r\n\r\nOK\r\n";
char device[100] = "AT+CGMM\r\r\nDE910-DUAL\r\n\r\nOK\r\n";
char sw_version[100] = "AT+CGMR\r\r\n15.00.006\r\n\r\nOK\r\n";
char empty_buffer[100] = "\0";
int has_read;

int identify_command(char *input_str, char *output_str, int *has_read);
int parse_at_command(char *input_str, char *output_str, char *command);

int parse_at_command(char *input_str, char *output_str, char *command, int has_read) {
    char *a, *b;
    char searchstr[20] = "\0";
    char modifier[1];
    char cmd[15] = {'\0'};
    
    if (has_read){
        sprintf(searchstr, "%s: ", command);
    }
    else {
        sprintf(searchstr, "%s", "\r\r\n");
    }
    a = strstr(input_str, searchstr) + strlen(searchstr);
    b = strstr(a, "\r\n");
    strncpy(output_str, a, b-a);
    output_str[b-a] = '\0';
    printf(output_str);
    return 1;
}

int identify_command(char *input_str, char *output_str, int *has_read) {
    char *a, *b;
    int has_eq = 0;
    int has_at = 0;
    char searchstr[20] = "\0";
    char modifier[1];
    char cmd[15] = {'\0'};
    
    // Isolate command
    a = &input_str[0];
    b = strstr(input_str, "\r\r\n");
    strncpy(searchstr,a,b-a);

    //Parse command
    a = &searchstr[0];
    b = a + strlen(searchstr);

    a = strstr(searchstr, "?");
    if (a != NULL){
        *has_read = 1;
        b -= 1;
    }
    else{
        *has_read = 0;
    }

    a = strstr(searchstr, "=");
    if (a != NULL){
        has_eq = 1;
        b -= 1;
    }    

    a = strstr(searchstr, "AT");
    if (a != NULL){
        has_at = 1;
        a += 2;
    }
    
    strncpy(output_str, a, b-a);
    output_str[b-a] = '\0';
    printf(output_str);
    printf("\n");
    printf("Has read: %d\n", *has_read);

    return 1;
    }

int main(void) {
	// your code goes here
	printf("Identify clocktime command from response\n");
	identify_command(clocktime, empty_buffer, &has_read);
	memset(empty_buffer, '\0', sizeof(empty_buffer));
	printf("Parse clocktime response\n");
	parse_at_command(clocktime, empty_buffer, "+CCLK", has_read);
	memset(empty_buffer, '\0', sizeof(empty_buffer));
	printf("\n");
	printf("Identify device model command from response\n");
	identify_command(device, empty_buffer, &has_read);
	memset(empty_buffer, '\0', sizeof(empty_buffer));
	printf("Parse device model response\n");
	parse_at_command(device, empty_buffer, "+CGMM", has_read);
	memset(empty_buffer, '\0', sizeof(empty_buffer));
	printf("\n");
	printf("Identify SW version command from response\n");
	identify_command(sw_version, empty_buffer, &has_read);
	memset(empty_buffer, '\0', sizeof(empty_buffer));
	printf("Parse SW version response\n");
	parse_at_command(sw_version, empty_buffer, "+CGMR", has_read);
	memset(empty_buffer, '\0', sizeof(empty_buffer));
	printf("\n");
	return 0;
}

Output:

Identify clocktime command from response
+CCLK
Has read: 1
Parse clocktime response
"17/05/29,01:56:06-16"
Identify device model command from response
+CGMM
Has read: 0
Parse device model response
DE910-DUAL
Identify SW version command from response
+CGMR
Has read: 0
Parse SW version response
15.00.006

A more minimal version:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char clocktime[100] = "AT+CCLK?\r\r\n+CCLK: \"17/05/29,01:56:06-16\"\r\n\r\nOK\r\n";
char device[100] = "AT+CGMM\r\r\nDE910-DUAL\r\n\r\nOK\r\n";
char sw_version[100] = "AT+CGMR\r\r\n15.00.006\r\n\r\nOK\r\n";
char empty_buffer[100] = "\0";

int parse_at_command(char *input_str, char *output_str, char *search_start, char *search_end);

int parse_at_command(char *input_str, char *output_str, char *search_start, char *search_end) {
    char *a, *b;

    a = strstr(input_str, search_start);
    if (a == NULL){
        printf("a null");
        return 0u;
    }
    a += strlen(search_start);
    b = strstr(a, search_end);
    if (b == NULL){
        printf("b null");
        return 0u;
    }
    strncpy(output_str, a, b-a);
    output_str[b-a] = '\0';
    printf(output_str);
    return 1u;
}

int main(void) {
	// your code goes here
	parse_at_command(clocktime, empty_buffer, "+CCLK: ", "\r\n");
	memset(empty_buffer, '\0', sizeof(empty_buffer));
	printf("\n");
	parse_at_command(device, empty_buffer, "\r\r\n", "\r\n");
	memset(empty_buffer, '\0', sizeof(empty_buffer));
	printf("\n");
	parse_at_command(sw_version, empty_buffer, "\r\r\n", "\r\n");
	memset(empty_buffer, '\0', sizeof(empty_buffer));
	printf("\n");
	return 0;
}
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

1 participant