If I extract a single variable from the response buffer both (by line number or keyword) methods are working ok. But if I am trying to extract multiple variables of multiple types like string, int, and float it's not working after a string extraction successfully. (commented unnessury code) godbolt link is here
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
uint8_t res_buf[2048];
uint8_t line_counts;
} MODULE_Typedef; //module buffer
// validate and get response pointer by line number
uint8_t *MODULE_ATRespGetByLineNumber(MODULE_Typedef *module, uint8_t resp_line) {
uint8_t *resp_buf = module->res_buf;
uint8_t *resp_line_buf = 0;
uint8_t line_num = 1;
if (resp_line > module->line_counts || resp_line <= 0) {
return 0;
}
for (line_num = 1; line_num <= module->line_counts; line_num ) {
if (resp_line == line_num) {
resp_line_buf = resp_buf;
return resp_line_buf;
}
resp_buf = strlen(resp_buf) 1;
}
return 0;
}
//parse response by line number
uint16_t MODULE_ATRespParseLine(MODULE_Typedef *module, uint8_t resp_line, const char *resp_expr, ...) {
va_list args;
int resp_args_num = 0;
const char *resp_line_buf = 0;
if ((resp_line_buf = MODULE_ATRespGetByLineNumber(module, resp_line)) == 0) {
return -1;
}
// printf("\r\nOK = %s\r\n",resp_line_buf);
va_start(args, resp_expr);
resp_args_num = vsscanf(resp_line_buf, resp_expr, args);
va_end(args);
return resp_args_num;
}
//validate and get response pointer by keyword
uint8_t *MODULE_ATRespGetByKeyword(MODULE_Typedef *module, uint8_t *keyword) {
char *resp_buf = module->res_buf;
char *resp_line_buf = 0;
uint16_t line_num = 1;
for (line_num = 1; line_num <= module->line_counts; line_num ) {
if (strstr(resp_buf, keyword)) {
resp_line_buf = resp_buf;
return resp_line_buf;
}
resp_buf = strlen(resp_buf) 1;
}
return 0;
}
//parse response using keyword
uint16_t MODULE_ATRespParse(MODULE_Typedef *module, uint8_t *keyword, uint8_t *resp_expr, ...)
{
uint16_t resp_args_num = 0;
char *resp_line_buf = MODULE_ATRespGetByKeyword(module, keyword);
va_list args;
if (resp_line_buf) {
va_start(args, resp_expr);
resp_args_num = vsscanf(resp_line_buf, resp_expr, args);
va_end(args);
return resp_args_num;
}
}
int main() {
char opr[20] = {"ERROR"};
uint8_t gpsv1 = 0,gpsv2 = 0,gpsv3 = 0,gpsv4 = 0,gpsv5 = 0,gpsv6 = 0,gpsv7 = 0,gpsv8 = 0,gpsv9 = 0,gpsv10 = 0,gpsv11=0;
uint8_t mode = -1,format = -1,act = -1;
MODULE_Typedef resp1 = {
.res_buf = {" CREG: 0,2,AIRTEL,45"},
.line_counts = 1,
};
printf("\r\n\r\n\r\nbuffer res1 = %s\r\n",resp1.res_buf);
MODULE_ATRespParse(&resp1," CREG:"," CREG: %d, %d, %[^,]s,%d",&mode,&format,opr,&act);
printf("\r\nmode = %d\nformat = %d\noperator = %s\nnwk = %d\n",mode,format,opr,act);
}
my input buffer:
buffer res1 = CREG: 0,2,AIRTEL,45
extracted variables from it :
mode = 0 format = 2 operator = AIRTEL nwk = 255
CodePudding user response:
You have to pass the correct variable pointer according to format specifiers. If you are using %d, It means your argument type shall be int *.
- Change your variables type
uint8_ttoint(for%d) - Change
%dto%2SCNu8(foruint8_t)
These solutions should be fixed your problem. godbolt
