Skip to content

Implement generic command for parsing AT command responses #12

@mdbartos

Description

@mdbartos

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;
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions