mirror of
https://gitee.com/moluo-tech/AT-Command.git
synced 2025-01-29 17:22:57 +08:00
增加OS版本的AT通信模块
This commit is contained in:
parent
34f1ec0a41
commit
88d9b816c8
201
LICENSE
Normal file
201
LICENSE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [2015~2020] [master_roger@sina.com]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
67
README.md
67
README.md
@ -1,7 +1,7 @@
|
||||
# AT Command
|
||||
|
||||
#### 介绍
|
||||
一种AT命令通信管理模块(支持单行发),支持裸机和OS版本。适用于modem、WIFI模块、蓝牙通信。
|
||||
一种AT命令通信解析模块,支持裸机(at_chat)和OS版本(at)。适用于modem、WIFI模块、蓝牙通信。
|
||||
|
||||
#### 软件架构
|
||||
软件架构说明
|
||||
@ -56,4 +56,69 @@ static void read_csq_callback(at_response_t *r)
|
||||
at_send_singlline(&at, read_csq_callback, "AT+CSQ");
|
||||
```
|
||||
|
||||
##### at 模块(OS版本)
|
||||
|
||||
|
||||
```
|
||||
|
||||
static at_obj_t at; //定义AT管理器
|
||||
|
||||
char urc_buf[128]; //URC主动上报缓冲区
|
||||
|
||||
utc_item_t utc_tbl[] = { //定义URC表
|
||||
"+CSQ: ", csq_updated_handler
|
||||
}
|
||||
|
||||
const at_conf_t conf = { //AT管理器配置参数
|
||||
.urc_buf = urc_buf,
|
||||
.urc_bufsize = sizeof(urc_buf),
|
||||
.utc_tbl = utc_tbl,
|
||||
.urc_tbl_count = sizeof(utc_tbl) / sizeof(utc_item_t),
|
||||
|
||||
//适配GPRS模块的串口读写接口
|
||||
.write = uart_write,
|
||||
.read = uart_read
|
||||
};
|
||||
```
|
||||
|
||||
3. 初始化AT管理器并创建AT线程
|
||||
|
||||
```
|
||||
void at_thread(void)
|
||||
{
|
||||
at_obj_create(&at, &conf);
|
||||
while (1) {
|
||||
/*do something ...*/
|
||||
at_thread(&at);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
4. 使用例子
|
||||
查询GPRS模块信号质量:
|
||||
=> AT+CSQ
|
||||
|
||||
<= +CSQ: 24, 0
|
||||
<= OK
|
||||
```
|
||||
/*
|
||||
* @brief 获取csq值
|
||||
*/
|
||||
bool read_csq_value(at_obj_t *at, int *rssi, int *error_rate)
|
||||
{
|
||||
//接收缓冲区
|
||||
unsigned char recvbuf[32];
|
||||
//AT响应
|
||||
at_respond_t r = {"OK", recvbuf, sizeof(recvbuf), 3000};
|
||||
//
|
||||
if (at_do_cmd(at, &r, "AT+CSQ") != AT_RET_OK)
|
||||
return false;
|
||||
//解析响应响应
|
||||
return (sscanf(recv, "%*[^+]+CSQ: %d,%d", rssi, error_rate) == 2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
366
at.c
Normal file
366
at.c
Normal file
@ -0,0 +1,366 @@
|
||||
/*******************************************************************************
|
||||
* @file at.h
|
||||
* @brief AT<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD>Ź<EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @version 5.0
|
||||
* @date 2020-05-11
|
||||
* @author roger.luo
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 roger.luo Initial version.
|
||||
* 2017-05-21 roger.luo 1.1 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* 2018-02-11 roger.luo 3.0
|
||||
* 2020-01-02 roger.luo 4.0 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>os<EFBFBD>汾
|
||||
*******************************************************************************/
|
||||
#include "at.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//<2F><>ʱ<EFBFBD>ж<EFBFBD>
|
||||
#define AT_IS_TIMEOUT(start, time) (at_get_ms() - (start) > (time))
|
||||
|
||||
static LIST_HEAD(atlist); /*<2A><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD> ----------------*/
|
||||
|
||||
/*
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static void put_string(at_obj_t *at, const char *s)
|
||||
{
|
||||
while (*s != '\0')
|
||||
at->cfg.write(s++, 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>(<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||||
*/
|
||||
static void put_line(at_obj_t *at, const char *s)
|
||||
{
|
||||
put_string(at, s);
|
||||
put_string(at, "\r\n");
|
||||
at->cfg.debug("->\r\n%s\r\n", s);
|
||||
}
|
||||
|
||||
//<2F><>ӡ<EFBFBD><D3A1><EFBFBD><EFBFBD>
|
||||
static void at_print(at_obj_t *at, const char *cmd, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, cmd);
|
||||
char buf[MAX_AT_CMD_LEN];
|
||||
vsnprintf(buf, sizeof(buf), cmd, args);
|
||||
put_line(at, buf);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
static void recvbuf_clr(at_obj_t *at)
|
||||
{
|
||||
at->rcv_cnt = 0;
|
||||
}
|
||||
|
||||
//<2F>ȴ<EFBFBD>AT<41><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ
|
||||
static at_return wait_resp(at_obj_t *at, at_respond_t *r)
|
||||
{
|
||||
at->resp = r;
|
||||
at->ret = AT_RET_TIMEOUT;
|
||||
at->resp_timer = at_get_ms();
|
||||
recvbuf_clr(at); //<2F><><EFBFBD>ս<EFBFBD><D5BD>ջ<EFBFBD><D5BB><EFBFBD>
|
||||
at->wait = 1;
|
||||
at_sem_wait(&at->completed, r->timeout);
|
||||
at->cfg.debug("<-\r\n%s\r\n", r->recvbuf);
|
||||
at->resp = NULL;
|
||||
at->wait = 0;
|
||||
return at->ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӦAT<EFBFBD><EFBFBD>Ӧ
|
||||
* @param[in] resp - <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>մ<EFBFBD>(<EFBFBD><EFBFBD>"OK",">")
|
||||
* @param[in] timeout - <EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD>ʱʱ<EFBFBD><EFBFBD>
|
||||
*/
|
||||
at_return wait_resp_sync(struct at_obj *at, const char *resp,
|
||||
unsigned int timeout)
|
||||
{
|
||||
char buf[64];
|
||||
int cnt = 0, len;
|
||||
at_return ret = AT_RET_TIMEOUT;
|
||||
unsigned int timer = at_get_ms();
|
||||
while (at_get_ms() - timer < timeout) {
|
||||
len = at->cfg.read(buf, sizeof(buf) - cnt);
|
||||
cnt += len;
|
||||
buf[cnt] = '\0';
|
||||
if (strstr(buf, resp)) {
|
||||
ret = AT_RET_OK;
|
||||
break;
|
||||
} else if (strstr(buf, "ERROR")) {
|
||||
ret = AT_RET_ERROR;
|
||||
break;
|
||||
}
|
||||
at_delay(10);
|
||||
}
|
||||
at->cfg.debug("%s", buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @brief AT<EFBFBD>ں<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
void at_obj_create(at_obj_t *at, const at_conf_t cfg)
|
||||
{
|
||||
at_work_env_t *e;
|
||||
at->cfg = cfg;
|
||||
at->rcv_cnt = 0;
|
||||
|
||||
at_sem_init(&at->cmd_lock, 1);
|
||||
at_sem_init(&at->completed, 0);
|
||||
e = &at->env;
|
||||
e->at = at;
|
||||
e->printf = at_print;
|
||||
e->recvclr = recvbuf_clr;
|
||||
e->read = cfg.read;
|
||||
e->write = cfg.write;
|
||||
e->wait_resp = wait_resp_sync;
|
||||
|
||||
list_add_tail(&at->node, &atlist);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>AT
|
||||
*/
|
||||
void at_obj_destroy(at_obj_t *at)
|
||||
{
|
||||
list_del(&at->node);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param[in] fmt - <EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param[in] r - <EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>NULL, Ĭ<EFBFBD>Ϸ<EFBFBD><EFBFBD><EFBFBD>OK<EFBFBD><EFBFBD>ʾ<EFBFBD>ɹ<EFBFBD>,<EFBFBD>ȴ<EFBFBD>3s
|
||||
* @param[in] args - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
|
||||
*/
|
||||
at_return at_do_cmd(at_obj_t *at, at_respond_t *r, const char *cmd)
|
||||
{
|
||||
at_return ret;
|
||||
char defbuf[64];
|
||||
at_respond_t default_resp = {"OK", defbuf, sizeof(defbuf), 3000};
|
||||
if (r == NULL) {
|
||||
r = &default_resp; //Ĭ<><C4AC><EFBFBD><EFBFBD>Ӧ
|
||||
}
|
||||
if (!at_sem_wait(&at->cmd_lock, r->timeout)) {
|
||||
return AT_RET_TIMEOUT;
|
||||
}
|
||||
while (at->urc_cnt) {
|
||||
at_delay(10);
|
||||
}
|
||||
put_line(at, cmd);
|
||||
ret = wait_resp(at, r);
|
||||
at_sem_post(&at->cmd_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief ִ<EFBFBD><EFBFBD>AT<EFBFBD><EFBFBD>ҵ
|
||||
* @param[in] urc
|
||||
* @return none
|
||||
*/
|
||||
int at_do_work(at_obj_t *at, at_work work, void *params)
|
||||
{
|
||||
int ret;
|
||||
if (!at_sem_wait(&at->cmd_lock, 150 * 1000)) {
|
||||
return AT_RET_TIMEOUT;
|
||||
}
|
||||
at->env.params = params;
|
||||
at->dowork = true;
|
||||
ret = work(&at->env);
|
||||
at->dowork = false;
|
||||
at_sem_post(&at->cmd_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief <EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>
|
||||
* @param[in] recvbuf - <EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param[out] lines - <EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @return <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
int at_split_respond_lines(char *recvbuf, char *lines[], int count)
|
||||
{
|
||||
char *s = recvbuf;
|
||||
size_t i = 0;
|
||||
if (s == NULL || lines == NULL)
|
||||
return 0;
|
||||
|
||||
lines[i++] = s;
|
||||
while(*s && i < count) {
|
||||
if (*s == ',') {
|
||||
*s = '\0';
|
||||
lines[i++] = s + 1; /*ָ<><D6B8><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Ӵ<EFBFBD>*/
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief urc <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param[in] urcline - URC<EFBFBD><EFBFBD>
|
||||
* @return none
|
||||
*/
|
||||
static void urc_handler_entry(at_obj_t *at, char *urcline, unsigned int size)
|
||||
{
|
||||
int i, n;
|
||||
utc_item_t *tbl = at->cfg.utc_tbl;
|
||||
|
||||
for (i = 0; i < at->cfg.urc_tbl_count; i++){
|
||||
n = strlen(tbl->prefix);
|
||||
if (n > 0 && strncmp(urcline, tbl->prefix, n) == 0) {
|
||||
tbl->handler(urcline, size);
|
||||
at->cfg.debug("<=\r\n%s\r\n", urcline);
|
||||
return;
|
||||
}
|
||||
tbl++;
|
||||
}
|
||||
|
||||
if (size >= 2 && !at->wait) //<2F>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
at->cfg.debug("%s\r\n", urcline);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief urc <EFBFBD><EFBFBD><EFBFBD>մ<EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param[in] buf - <EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD>
|
||||
* @return none
|
||||
*/
|
||||
static void urc_recv_process(at_obj_t *at, const char *buf, unsigned int size)
|
||||
{
|
||||
char *urc_buf;
|
||||
unsigned short urc_size;
|
||||
unsigned char c;
|
||||
urc_buf = (char *)at->cfg.urc_buf;
|
||||
urc_size = at->cfg.urc_bufsize;
|
||||
if (at->urc_cnt > 0 && size == 0) {
|
||||
if (AT_IS_TIMEOUT(at->urc_timer, 100)) { //100ms<6D><73>ʱ
|
||||
urc_buf[at->urc_cnt] = '\0';
|
||||
at->urc_cnt = 0;
|
||||
at->cfg.debug("urc recv timeout=>%s\r\n", urc_buf);
|
||||
}
|
||||
} else {
|
||||
at->urc_timer = at_get_ms();
|
||||
while (size--) {
|
||||
c = *buf++;
|
||||
if (c == '\r' || c == '\n') { //<2F>յ<EFBFBD>1<EFBFBD><31>
|
||||
urc_buf[at->urc_cnt] = '\0';
|
||||
if (at->urc_cnt > 2)
|
||||
urc_handler_entry(at, urc_buf, at->urc_cnt);
|
||||
at->urc_cnt = 0;
|
||||
} else {
|
||||
urc_buf[at->urc_cnt++] = c;
|
||||
if (at->urc_cnt >= urc_size) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
at->urc_cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD>մ<EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param[in] buf - <EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param[in] size - <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><EFBFBD><EFBFBD>
|
||||
* @return none
|
||||
*/
|
||||
static void resp_recv_process(at_obj_t *at, const char *buf, unsigned int size)
|
||||
{
|
||||
char *rcv_buf;
|
||||
unsigned short rcv_size;
|
||||
at_respond_t *resp = at->resp;
|
||||
|
||||
if (resp == NULL || size == 0)
|
||||
return;
|
||||
|
||||
rcv_buf = (char *)resp->recvbuf;
|
||||
rcv_size = resp->bufsize;
|
||||
|
||||
if (at->rcv_cnt + size >= rcv_size) { //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
at->rcv_cnt = 0;
|
||||
at->cfg.debug("Receive overflow:%s", rcv_buf);
|
||||
}
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݷ<EFBFBD><DDB7><EFBFBD>rcv_buf<75><66> ---------------------------------------------*/
|
||||
memcpy(rcv_buf + at->rcv_cnt, buf, size);
|
||||
at->rcv_cnt += size;
|
||||
rcv_buf[at->rcv_cnt] = '\0';
|
||||
|
||||
|
||||
if (!at->wait)
|
||||
return;
|
||||
if (strstr(rcv_buf, resp->matcher)) { //<2F><><EFBFBD><EFBFBD>ƥ<EFBFBD><C6A5>
|
||||
at->ret = AT_RET_OK;
|
||||
} else if (strstr(rcv_buf, "ERROR")) {
|
||||
at->ret = AT_RET_ERROR;
|
||||
} else if (AT_IS_TIMEOUT(at->resp_timer, resp->timeout)) {
|
||||
at->ret = AT_RET_TIMEOUT;
|
||||
} else if (at->suspend) //ǿ<><C7BF><EFBFBD><EFBFBD>ֹ
|
||||
at->ret = AT_RET_ABORT;
|
||||
else
|
||||
return;
|
||||
|
||||
at_sem_post(&at->completed);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief ATæ<EFBFBD>ж<EFBFBD>
|
||||
* @return true - <EFBFBD><EFBFBD>ATָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
bool at_obj_busy(at_obj_t *at)
|
||||
{
|
||||
return at->wait == 0 && AT_IS_TIMEOUT(at->urc_timer, 2000);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>AT<EFBFBD><EFBFBD>ҵ
|
||||
* @return none
|
||||
*/
|
||||
void at_suspend(at_obj_t *at)
|
||||
{
|
||||
at->suspend = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief <EFBFBD>ָ<EFBFBD>AT<EFBFBD><EFBFBD>ҵ
|
||||
* @return none
|
||||
*/
|
||||
void at_resume(at_obj_t *at)
|
||||
{
|
||||
at->suspend = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief AT<EFBFBD><EFBFBD>ѯ<EFBFBD>߳<EFBFBD>
|
||||
* @return none
|
||||
*/
|
||||
void at_thread(void)
|
||||
{
|
||||
at_obj_t *at;
|
||||
struct list_head *list ,*n = NULL;
|
||||
int len;
|
||||
char buf[32];
|
||||
while (1) {
|
||||
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>at_obj<62><6A><EFBFBD><EFBFBD>*/
|
||||
list_for_each_safe(list, n, &atlist) {
|
||||
at = list_entry(list, at_obj_t, node);
|
||||
if (!at->dowork) {
|
||||
#warning "<22><>ȡ<EFBFBD>Ż<EFBFBD>(readline) ..."
|
||||
len = at->cfg.read(buf, sizeof(buf));
|
||||
urc_recv_process(at, (char *)buf, len);
|
||||
if (len > 0) {
|
||||
resp_recv_process(at, buf, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
at_delay(1);
|
||||
}
|
||||
}
|
111
at.h
Normal file
111
at.h
Normal file
@ -0,0 +1,111 @@
|
||||
/*******************************************************************************
|
||||
* @file at.h
|
||||
* @brief AT<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD>Ź<EFBFBD><EFBFBD><EFBFBD>
|
||||
*
|
||||
* @version 5.0
|
||||
* @date 2020-05-11
|
||||
* @author roger.luo
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 roger.luo Initial version.
|
||||
* 2017-05-21 roger.luo 1.1 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* 2018-02-11 roger.luo 3.0
|
||||
* 2020-01-02 roger.luo 4.0 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>os<EFBFBD>汾
|
||||
*******************************************************************************/
|
||||
#ifndef _AT_H_
|
||||
#define _AT_H_
|
||||
|
||||
#include "at_util.h"
|
||||
#include "list.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MAX_AT_CMD_LEN 64
|
||||
|
||||
struct at_obj; /*AT<41><54><EFBFBD><EFBFBD>*/
|
||||
|
||||
/*urc<72><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -----------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
const char *prefix; //URCǰ
|
||||
void (*handler)(char *recvbuf, int size);
|
||||
}utc_item_t;
|
||||
|
||||
/*AT<41><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD> -------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
/*<2A><><EFBFBD>ݶ<EFBFBD>д<EFBFBD>ӿ<EFBFBD> -----------------------------------------------------------*/
|
||||
unsigned int (*read)(void *buf, unsigned int len);
|
||||
unsigned int (*write)(const void *buf, unsigned int len);
|
||||
void (*debug)(const char *fmt, ...);
|
||||
utc_item_t *utc_tbl; /*utc <20><>*/
|
||||
char *urc_buf; /*urc<72><63><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
unsigned short urc_tbl_count;
|
||||
unsigned short urc_bufsize; /*urc<72><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С*/
|
||||
}at_conf_t;
|
||||
|
||||
/*AT<41><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6> ---------------------------------------------------------------*/
|
||||
typedef enum {
|
||||
AT_RET_OK = 0, /*ִ<>гɹ<D0B3>*/
|
||||
AT_RET_ERROR, /*ִ<>д<EFBFBD><D0B4><EFBFBD>*/
|
||||
AT_RET_TIMEOUT, /*<2A><>Ӧ<EFBFBD><D3A6>ʱ*/
|
||||
AT_RET_ABORT, /*δ֪<CEB4><D6AA><EFBFBD><EFBFBD>*/
|
||||
}at_return;
|
||||
|
||||
/*AT<41><54>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD> -----------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
const char *matcher; /*<2A><><EFBFBD><EFBFBD>ƥ<EFBFBD>䴮*/
|
||||
char *recvbuf; /*<2A><><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
unsigned short bufsize; /*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ճ<EFBFBD><D5B3><EFBFBD>*/
|
||||
unsigned int timeout; /*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱʱ<CAB1><CAB1> */
|
||||
}at_respond_t;
|
||||
|
||||
/*AT<41><54>ҵ ---------------------------------------------------------------------*/
|
||||
typedef struct at_work_env{
|
||||
struct at_obj *at;
|
||||
void *params;
|
||||
unsigned int (*write)(const void *buf, unsigned int len);
|
||||
unsigned int (*read)(void *buf, unsigned int len);
|
||||
|
||||
void (*printf)(struct at_obj *at, const char *frm, ...);
|
||||
at_return (*wait_resp)(struct at_obj *at, const char *resp, unsigned int timeout);
|
||||
void (*recvclr)(struct at_obj *at); /*<2A><><EFBFBD>ս<EFBFBD><D5BD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
}at_work_env_t;
|
||||
|
||||
/*AT<41><54><EFBFBD><EFBFBD> ---------------------------------------------------------------------*/
|
||||
typedef struct at_obj {
|
||||
struct list_head node;
|
||||
at_conf_t cfg;
|
||||
at_work_env_t env;
|
||||
at_sem_t cmd_lock; /*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
at_sem_t completed; /*<2A><><EFBFBD><EFBFBD><EEB4A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
at_respond_t *resp;
|
||||
unsigned int resp_timer;
|
||||
unsigned int urc_timer;
|
||||
at_return ret;
|
||||
//urc<72><63><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>
|
||||
unsigned short urc_cnt, rcv_cnt;
|
||||
unsigned char wait : 1;
|
||||
unsigned char suspend: 1;
|
||||
unsigned char dowork : 1;
|
||||
}at_obj_t;
|
||||
|
||||
typedef int (*at_work)(at_work_env_t *);
|
||||
|
||||
void at_obj_create(at_obj_t *at, const at_conf_t cfg); /*AT<41><54>ʼ<EFBFBD><CABC>*/
|
||||
|
||||
void at_obj_destroy(at_obj_t *at);
|
||||
|
||||
bool at_obj_busy(at_obj_t *at);
|
||||
|
||||
void at_suspend(at_obj_t *at); /*<2A><><EFBFBD><EFBFBD>*/
|
||||
|
||||
void at_resume(at_obj_t *at); /*<2A>ָ<EFBFBD>*/
|
||||
|
||||
at_return at_do_cmd(at_obj_t *at, at_respond_t *r, const char *cmd);
|
||||
|
||||
int at_split_respond_lines(char *recvbuf, char *lines[], int count);
|
||||
|
||||
int at_do_work(at_obj_t *at, at_work work, void *params); /*ִ<><D6B4>AT<41><54>ҵ*/
|
||||
|
||||
void at_thread(void); /*AT<41>߳<EFBFBD>*/
|
||||
|
||||
#endif
|
64
at_chat.c
64
at_chat.c
@ -1,17 +1,19 @@
|
||||
/******************************************************************************
|
||||
* @brief AT ͨ<EFBFBD>Ź<EFBFBD><EFBFBD><EFBFBD>(<EFBFBD><EFBFBD>OS<EFBFBD>汾)
|
||||
*
|
||||
* Copyright (c) 2019, <master_roger@sina.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 Morro Initial version.
|
||||
* 2018-02-11 Morro ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>й<EFBFBD><EFBFBD><EFBFBD>AT<EFBFBD><EFBFBD>ҵ
|
||||
* 2020-05-21 Morro ֧<EFBFBD><EFBFBD>at_core<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
* @file at_core.h
|
||||
* @brief AT command communications.
|
||||
*
|
||||
* @version 5.0
|
||||
* @date 2020-05-11
|
||||
* @author roger.luo
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 roger.luo Initial version.
|
||||
* 2017-05-21 roger.luo 1.1 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* 2018-02-11 roger.luo 3.0
|
||||
* 2020-01-02 roger.luo 4.0 os version
|
||||
* 2020-05-21 roger.luo 5.0 <EFBFBD><EFBFBD>OS<EFBFBD>汾
|
||||
*******************************************************************************/
|
||||
#include "at_chat.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
@ -52,10 +54,10 @@ static void send_data(at_core_t *ac, const void *buf, unsigned int len)
|
||||
*/
|
||||
static void print(at_core_t *ac, const char *cmd, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_list args;
|
||||
va_start(args, cmd);
|
||||
at_send_line(ac, cmd, args);
|
||||
va_end(args);
|
||||
va_end(args);
|
||||
}
|
||||
/*
|
||||
* @brief <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><EFBFBD>ճ<EFBFBD><EFBFBD><EFBFBD>
|
||||
@ -90,7 +92,7 @@ static char *search_string(at_core_t *ac, const char *str)
|
||||
/*ǰ<><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>*/
|
||||
static bool at_isabort(at_core_t *ac)
|
||||
{
|
||||
return ac->cursor ? ac->cursor->abort : 1;
|
||||
return ac->cursor ? ac->cursor->abort : 1;
|
||||
}
|
||||
|
||||
|
||||
@ -164,7 +166,7 @@ static int do_cmd_handler(at_core_t *a)
|
||||
{
|
||||
at_item_t *i = a->cursor;
|
||||
at_env_t *e = &a->env;
|
||||
const at_cmd_t *c = (at_cmd_t *)i->info;
|
||||
const at_respond_t *c = (at_respond_t *)i->info;
|
||||
switch(e->state) {
|
||||
case 0: /*<2A><><EFBFBD><EFBFBD>״̬ ------------------------------------------------------*/
|
||||
c->sender(e);
|
||||
@ -173,7 +175,7 @@ static int do_cmd_handler(at_core_t *a)
|
||||
e->recvclr(a);
|
||||
break;
|
||||
case 1: /*<2A><><EFBFBD><EFBFBD>״̬ ------------------------------------------------------*/
|
||||
if (search_string(a, c->matcher)) {
|
||||
if (search_string(a, c->matcher)) {
|
||||
do_at_callback(a, i, c->cb, AT_RET_OK);
|
||||
return true;
|
||||
} else if (search_string(a, "ERROR")) {
|
||||
@ -221,7 +223,7 @@ static int send_signlline_handler(at_core_t *a)
|
||||
e->recvclr(a);
|
||||
break;
|
||||
case 1: /*<2A><><EFBFBD><EFBFBD>״̬ ------------------------------------------------------*/
|
||||
if (search_string(a, "OK")) {
|
||||
if (search_string(a, "OK")) {
|
||||
do_at_callback(a, i, cb, AT_RET_OK);
|
||||
return true;
|
||||
} else if (search_string(a, "ERROR")) {
|
||||
@ -332,10 +334,10 @@ static void urc_handler_entry(at_core_t *ac, char *urc, unsigned int size)
|
||||
*/
|
||||
static void urc_recv_process(at_core_t *ac, char *buf, unsigned int size)
|
||||
{
|
||||
char *urc_buf;
|
||||
char *urc_buf;
|
||||
unsigned short urc_size;
|
||||
urc_buf = (char *)ac->cfg.urc_buf;
|
||||
urc_size = ac->cfg.urc_bufsize;
|
||||
urc_size = ac->cfg.urc_bufsize;
|
||||
if (size == 0 && ac->urc_cnt > 0) {
|
||||
if (AT_IS_TIMEOUT(ac->urc_timer, 2000)){
|
||||
urc_handler_entry(ac, urc_buf, ac->urc_cnt);
|
||||
@ -364,7 +366,7 @@ static void urc_recv_process(at_core_t *ac, char *buf, unsigned int size)
|
||||
static void resp_recv_process(at_core_t *ac, const char *buf, unsigned int size)
|
||||
{
|
||||
char *rcv_buf;
|
||||
unsigned short rcv_size;
|
||||
unsigned short rcv_size;
|
||||
|
||||
rcv_buf = (char *)ac->cfg.rcv_buf;
|
||||
rcv_size = ac->cfg.rcv_bufsize;
|
||||
@ -372,7 +374,7 @@ static void resp_recv_process(at_core_t *ac, const char *buf, unsigned int size)
|
||||
if (ac->rcv_cnt + size >= rcv_size) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
ac->rcv_cnt = 0;
|
||||
|
||||
memcpy(rcv_buf, buf, size);
|
||||
memcpy(rcv_buf + rcv_cnt, buf, size);
|
||||
ac->rcv_cnt += size;
|
||||
rcv_buf[ac->rcv_cnt] = '\0';
|
||||
|
||||
@ -394,7 +396,7 @@ bool at_do_work(at_core_t *ac, int (*work)(at_env_t *e), void *params)
|
||||
* @param[in] a - AT<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* @param[in] cmd - cmd<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
*/
|
||||
bool at_do_cmd(at_core_t *ac, void *params, const at_cmd_t *cmd)
|
||||
bool at_do_cmd(at_core_t *ac, void *params, const at_respond_t *cmd)
|
||||
{
|
||||
return add_work(ac, params, (void *)cmd, AT_TYPE_CMD);
|
||||
}
|
||||
@ -429,7 +431,7 @@ bool at_send_multiline(at_core_t *ac, at_callback_t cb, const char **multiline)
|
||||
|
||||
void at_item_abort(at_item_t *i)
|
||||
{
|
||||
i->abort = 1;
|
||||
i->abort = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -450,7 +452,7 @@ static void at_work_manager(at_core_t *ac)
|
||||
at_env_t *e = &ac->env;
|
||||
/*ͨ<>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---------------------------------------------------------*/
|
||||
static int (*const work_handler_table[])(at_core_t *) = {
|
||||
do_work_handler,
|
||||
do_work_handler,
|
||||
do_cmd_handler,
|
||||
send_signlline_handler,
|
||||
send_multiline_handler
|
||||
@ -468,10 +470,10 @@ static void at_work_manager(at_core_t *ac)
|
||||
}
|
||||
/*<2A><><EFBFBD><EFBFBD>ִ<EFBFBD><D6B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>뵽<EFBFBD><EBB5BD><EFBFBD>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD> ------------------------------------*/
|
||||
if (work_handler_table[cursor->type](ac) || cursor->abort) {
|
||||
ac->cfg.lock();
|
||||
list_move_tail(&ac->cursor->node, &ac->ls_idle);
|
||||
ac->cursor = NULL;
|
||||
ac->cfg.unlock();
|
||||
ac->cfg.lock();
|
||||
list_move_tail(&ac->cursor->node, &ac->ls_idle);
|
||||
ac->cursor = NULL;
|
||||
ac->cfg.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
72
at_chat.h
72
at_chat.h
@ -1,16 +1,20 @@
|
||||
/******************************************************************************
|
||||
* @brief AT ͨ<EFBFBD>Ź<EFBFBD><EFBFBD><EFBFBD>(<EFBFBD><EFBFBD>OS<EFBFBD>汾)
|
||||
*
|
||||
* Copyright (c) 2019, <master_roger@sina.com>
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 Morro Initial version.
|
||||
* 2018-02-11 Morro ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD>й<EFBFBD><EFBFBD><EFBFBD>AT<EFBFBD><EFBFBD>ҵ
|
||||
* 2020-05-21 Morro ֧<EFBFBD><EFBFBD>at_core<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
******************************************************************************/
|
||||
/*******************************************************************************
|
||||
* Copyright(C)20 roger.luo
|
||||
* All rights reserved.
|
||||
* @file atchat.h
|
||||
* @brief AT command communications.
|
||||
*
|
||||
* @version 3.0
|
||||
* @date 2018-02-11
|
||||
* @author roger.luo
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2016-01-22 roger.luo Initial version.
|
||||
* 2017-05-21 roger.luo 1.1 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
* 2018-02-11 roger.luo 3.0
|
||||
* 2020-01-02 roger.luo 4.0 os version
|
||||
*******************************************************************************/
|
||||
#ifndef _ATCHAT_H_
|
||||
#define _ATCHAT_H_
|
||||
|
||||
@ -37,22 +41,22 @@ typedef struct {
|
||||
void (*before_at)(void); /*<2A><>ʼִ<CABC><D6B4>AT*/
|
||||
void (*after_at)(void);
|
||||
void (*error)(void);
|
||||
utc_item_t *utc_tbl; /*utc <20><>*/
|
||||
unsigned char *urc_buf; /*urc<72><63><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
utc_item_t *utc_tbl; /*utc <20><>*/
|
||||
unsigned char *urc_buf; /*urc<72><63><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
unsigned char *rcv_buf;
|
||||
unsigned short urc_tbl_count;
|
||||
unsigned short urc_bufsize; /*urc<72><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С*/
|
||||
unsigned short urc_tbl_count;
|
||||
unsigned short urc_bufsize; /*urc<72><63><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С*/
|
||||
unsigned short rcv_bufsize; /*<2A><><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
}at_core_conf_t;
|
||||
|
||||
/*AT<41><54>ҵ<EFBFBD><D2B5><EFBFBD>л<EFBFBD><D0BB><EFBFBD>*/
|
||||
typedef struct {
|
||||
int i,j,state;
|
||||
void *params;
|
||||
int i,j,state;
|
||||
void *params;
|
||||
void (*reset_timer)(struct at_core *ac);
|
||||
bool (*is_timeout)(struct at_core *ac, unsigned int ms); /*ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>*/
|
||||
void (*printf)(struct at_core *ac, const char *fmt, ...);
|
||||
char * (*find)(struct at_core *ac, const char *expect);
|
||||
bool (*is_timeout)(struct at_core *ac, unsigned int ms); /*ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>*/
|
||||
void (*printf)(struct at_core *ac, const char *fmt, ...);
|
||||
char * (*find)(struct at_core *ac, const char *expect);
|
||||
char * (*recvbuf)(struct at_core *ac); /*ָ<><D6B8><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
unsigned int(*recvlen)(struct at_core *ac); /*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>*/
|
||||
void (*recvclr)(struct at_core *ac); /*<2A><><EFBFBD>ս<EFBFBD><D5BD>ջ<EFBFBD><D5BB><EFBFBD><EFBFBD><EFBFBD>*/
|
||||
@ -64,14 +68,14 @@ typedef enum {
|
||||
AT_RET_OK = 0, /*ִ<>гɹ<D0B3>*/
|
||||
AT_RET_ERROR, /*ִ<>д<EFBFBD><D0B4><EFBFBD>*/
|
||||
AT_RET_TIMEOUT, /*<2A><>Ӧ<EFBFBD><D3A6>ʱ*/
|
||||
AT_RET_ABORT, /*ǿ<><C7BF><EFBFBD><EFBFBD>ֹ*/
|
||||
AT_RET_ABORT, /*ǿ<><C7BF><EFBFBD><EFBFBD>ֹ*/
|
||||
}at_return;
|
||||
|
||||
/*AT<41><54>Ӧ */
|
||||
typedef struct {
|
||||
void *param;
|
||||
char *recvbuf;
|
||||
unsigned short recvcnt;
|
||||
char *recvbuf;
|
||||
unsigned short recvcnt;
|
||||
at_return ret;
|
||||
}at_response_t;
|
||||
|
||||
@ -90,23 +94,23 @@ typedef struct {
|
||||
unsigned char type : 3;
|
||||
unsigned char abort : 1;
|
||||
void *param;
|
||||
void *info;
|
||||
void *info;
|
||||
struct list_head node;
|
||||
}at_item_t;
|
||||
|
||||
/*AT<41><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ------------------------------------------------------------------*/
|
||||
typedef struct at_core{
|
||||
at_core_conf_t cfg;
|
||||
at_core_conf_t cfg;
|
||||
at_env_t env;
|
||||
at_item_t tbl[10];
|
||||
at_item_t tbl[10];
|
||||
at_item_t *cursor;
|
||||
struct list_head ls_ready, ls_idle; /*<2A><><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5>*/
|
||||
unsigned int resp_timer;
|
||||
unsigned int urc_timer;
|
||||
at_return ret;
|
||||
//urc<72><63><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>
|
||||
unsigned short urc_cnt, rcv_cnt;
|
||||
unsigned char suspend: 1;
|
||||
unsigned int resp_timer;
|
||||
unsigned int urc_timer;
|
||||
at_return ret;
|
||||
//urc<72><63><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>
|
||||
unsigned short urc_cnt, rcv_cnt;
|
||||
unsigned char suspend: 1;
|
||||
}at_core_t;
|
||||
|
||||
typedef struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user