函数需要的背景
在最近的串口读写中, 我们需要对从串口出来的数据进行精准查找, 和正确的数据进行判.
注: 在EC20F4G模块下发送AT指令!
比如给串口发送"AT", 成功会返回"OK", 失败返回"ERROR".
给串口发送"AT+CPIN", 查找返回字符串中是否收到READY……
函数想法
由于发送AT指令, 从串口中读取的都是一个字符串, 从该字符串中进行精准查找关键字来进行判断是否成功, 符合需求, 每次都要使用strstr来进行查找, 发现查找的方法都是大致一样的, 代码完全是搬来搬去, 所以封装成一个字符串查找函数, 方便使用.
函数实现
at_fetch.c
/*********************************************************************************
* Copyright: (C) 2021 guanyunpeng
* All rights reserved.
*
* Filename: at_fetch.c
* Description: This file
*
* Version: 1.0.0(22/05/21)
* Author: guanyunpeng <364521112qq.com>
* ChangeLog: 1, Release initial version on "22/05/21 18:23:30"
*
********************************************************************************/
#include "at_fetch.h"
int at_fetch(char *atreply, char *start_key, char *end_key, char *rbuf, int size)
{
if( !atreply || !start_key)
{
return -1;
}
char *rbuf_stat; //返回字符串的首地址
char *rbuf_end; //返回字符串的尾地址
int rv = -1;
if( rbuf != NULL )
{
memset(rbuf, 0, sizeof(*rbuf));
}
rbuf_stat = strstr(atreply, start_key);
if( rbuf_stat == NULL )
{
//printf("strstr start_key :%s failure\n", start_key);
return -1;
}
rbuf_stat += strlen(start_key);
if( end_key != NULL )
{
rbuf_end = strstr(rbuf_stat, end_key);
if( rbuf_end == NULL )
{
//printf("strstr end_key %s failure\n", rbuf_end);
return -2;
}
}
if( rbuf != NULL && ((rbuf_end-rbuf_stat) <= size) )
{
strncpy(rbuf, rbuf_stat, rbuf_end-rbuf_stat);
}
return 0;
}
at_fetch.h
/********************************************************************************
* Copyright: (C) 2021 guanyunpeng
* All rights reserved.
*
* Filename: at_fetch.h
* Description: This head file
*
* Version: 1.0.0(22/05/21)
* Author: guanyunpeng <364521112qq.com>
* ChangeLog: 1, Release initial version on "22/05/21 18:23:55"
*
********************************************************************************/
#ifndef __AT_FETCH_H__
#define __AT_FETCH_H__
#include <stdio.h>
#include <stddef.h>
#include <string.h>
/***************************************************************************************************************
* 功能:
* 如果传入atreply, start_key, end_key, buf : 再传入字符串中找到start_key与end_key之间的字符串返回出去
* 如果传入atreply, start_key, end_key, NULL : 则负责查找该区间的字符串, 不将找到的字符串返回出去
* 如果传入atreply, start_key, NULL, NULL : 则只负责查找start_key这个字符串
*
* 参数:
* atreply : 要解析的字符串
* start_key : 需要返回字符串的前一个或多个索引
* end_key : 需要返回字符串的后一个或多个索引
* buf : 返回的字符串
* size : 防止溢出
*
* 返回值:
* rv = 0 成功; rv <0 失败; rv = -1 输入参数不正确; rv = -2 没找到start_key; rv = -3 没找到end_key
*
*************************************************************************************************************/
int at_fetch(char *atreply, char *start_key, char *end_key, char *rbuf, int size);
#endif
测试用例
测试代码
/*******************************************************
* 发送AT+CGMM 查询模型识别(型号) 并保存到结构体中
* 发送AT+CIMI 查询国际移动用户识别码 并保存到结构体中
* ******************************************************/
typedef struct module_ctx_s
{
char *manufacturer[128]; //制造商, AT+CGMI
char *information[128]; //模型识别(型号), AT+CGMM
char *software_version[128]; //软件版本修订标识, AT+CGMR
char *serial_number[128]; //IMEI号(手机序列号), AT+CGSN
char *user_identifier[128]; //国际移动用户识别码, AT+CIMI
}module_ctx_t;
int atcmd_check_cgmm(comport_t *comport, module_ctx_t *ctx)
{
char buf[512];
char rbuf[128];
char *ptr = NULL;
memset(buf, 0, sizeof(buf));
memset(rbuf, 0, sizeof(rbuf));
if( send_atcmd(comport, "AT+CGMM\r", buf, sizeof(buf), 300) < 0 )
{
printf("send_atcmd AT+CGMM failure!\n");
return -1;
}
printf("AT+CGMM:%s\n", buf);
if( at_fetch(buf, "\r\n", "\r\n", (char *)ctx->information, 128) != 0)
{
printf("at_fetch AT+CGMM failure\n");
return -2;
}
//printf("rbuf:%s\n", rbuf);
return 0;
}
int atcmd_check_cimi(comport_t *comport, module_ctx_t *ctx)
{
char buf[512];
memset(buf, 0, sizeof(buf));
if( send_atcmd(comport, "AT+CIMI\r", buf, sizeof(buf), 300) < 0 )
{
printf("send_atcmd at+cgmr failure!\n");
return -1;
}
printf("AT+CIMI:%s\n", buf);
if( at_fetch(buf, "\r\n", "\r\n", (char *)ctx->user_identifier, 128) != 0)
{
printf("at_fetch at+cimi failure\n");
return -2;
}
return 0;
}
int main (int argc, char **argv)
{
int rv = -1;
int n = -1;
int stat = -1;
comport_t comport;
char rbuf[512];
module_ctx_t ctx;
memset(rbuf, 0, sizeof(rbuf));
memset(&ctx, 0, sizeof(ctx));
comport_open(&comport, "/dev/ttyUSB3", 115200, "8n1n");
atcmd_check_cgmm(&comport, &ctx);
printf("ctx.information:%s\n", ctx.information);
atcmd_check_cimi(&comport, &ctx);
printf("ctx.user_identifier:%s\n", ctx.user_identifier);
comport_close(&comport);
return 0;
}