Files
sms_forwarding/AT_COMMANDS.md
T
wuxu 3ab7a19874 feat: 初始化Node.js 4G短信网关项目
- 实现AT指令通信和4G模组管理
- 支持PDU模式短信接收和发送
- 长短信自动合并功能
- 多通道推送支持(钉钉/飞书/Telegram等)
- 管理员短信远程控制
- RESTful API接口
- 完整的日志系统
2026-06-23 17:46:56 +08:00

311 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 4G模块AT指令交互文档
## 串口配置
- **波特率**: 115200
- **数据位**: 8
- **停止位**: 1
- **校验**: None
- **流控**: None
## 初始化流程
### 1. 基础握手
```
AT
响应: OK
作用: 测试模组是否响应
```
### 2. 查询模组信息
```
ATI
响应:
厂商名称
型号
固件版本
OK
作用: 获取模组厂商、型号、固件版本
```
### 3. 禁用数据连接(防止流量消耗)
```
AT+CGACT=0,1
响应: OK
作用: 关闭4G数据连接,防止自动联网消耗流量
注意: ML307Y型号此命令有bug,需跳过
```
### 4. 配置短信URC上报
```
AT+CNMI=2,2,0,0,0
响应: OK
作用: 配置短信到达时主动上报(URC模式)
参数说明:
- 第1参数=2: 缓冲URC到TE
- 第2参数=2: 短信直接上报+CMT URC(PDU模式)
- 其余参数=0: 禁用状态报告、广播消息等
```
### 5. 设置PDU模式
```
AT+CMGF=0
响应: OK
作用: 设置短信为PDU模式(支持中文、长短信)
```
### 6. 等待网络注册
```
AT+CEREG?
响应: +CEREG: <n>,<stat>
OK
作用: 查询LTE网络注册状态
<stat>值:
- 0: 未注册,未搜索
- 1: 已注册,本地网络
- 2: 未注册,正在搜索
- 3: 注册被拒绝
- 4: 未知状态
- 5: 已注册,漫游网络
成功条件: <stat>=1 或 5
```
## 短信接收(URC自动上报)
当收到短信时,模组会主动发送:
```
+CMT: ,<length>
<PDU_HEX_STRING>
```
**示例**:
```
+CMT: ,26
0891683108200005F0040D91683158148764F30000222151114270802C4F60597D
```
### PDU解析
PDU是十六进制字符串,需要使用PDU解析库(如 `node-pdu`)解析:
- **发送者号码**
- **时间戳**(YYMMDDHHMMSS格式,带时区)
- **短信内容**(支持中文UCS2编码)
- **长短信信息**(参考号、当前段号、总段数)
### 长短信处理
长短信PDU包含额外头部(UDH):
- **参考号** (Reference Number): 用于标识同一条长短信的不同分段
- **总段数** (Total Parts): 该长短信分为几段
- **当前段号** (Part Number): 当前是第几段(从1开始)
**合并逻辑**:
1. 检测到长短信(总段数 > 1)时,创建缓存槽位
2. 使用 `(参考号 + 发送者号码)` 作为唯一标识
3. 收到每一段后,存入对应位置
4. 收齐所有分段后,按段号顺序拼接内容
5. 30秒超时保护:未收齐也强制转发已收到的部分
## 短信发送(PDU模式)
### 1. 编码PDU
使用PDU编码库将目标号码和短信内容编码为PDU十六进制字符串。
### 2. 发送AT+CMGS命令
```
AT+CMGS=<length>
响应: > (提示符)
作用: 准备发送短信,<length>为PDU数据长度(字节数,不含SMSC)
```
### 3. 发送PDU数据
```
<PDU_HEX_STRING><Ctrl+Z>
响应: +CMGS: <mr>
OK
作用: 发送PDU数据,以Ctrl+Z(0x1A)结束
<mr>: 消息参考号
```
**完整流程示例**:
```
-> AT+CMGS=23
<- >
-> 0011000D91683158148764F30000AA05E4BDA0E5A5BD1A
<- +CMGS: 123
OK
```
## 其他常用命令
### 查询信号强度
```
AT+CSQ
响应: +CSQ: <rssi>,<ber>
OK
<rssi>: 信号强度 (0-31, 99=未知)
- 0-9: 弱
- 10-14: 一般
- 15-19: 好
- 20-31: 很好
- 99: 未知或不可检测
```
### 查询SIM卡状态
```
AT+CPIN?
响应: +CPIN: READY (或其他状态)
OK
状态:
- READY: SIM卡已就绪
- SIM PIN: 需要PIN码
- SIM PUK: 需要PUK码
```
### 查询ICCID
```
AT+CCID
响应: +CCID: <iccid>
OK
作用: 获取SIM卡ICCID(集成电路卡识别码)
```
### 查询IMEI
```
AT+GSN
响应: <imei>
OK
作用: 获取模组IMEI号
```
### 查询运营商
```
AT+COPS?
响应: +COPS: <mode>,<format>,<oper>
OK
示例: +COPS: 0,0,"CHINA MOBILE"
```
### 临时激活数据连接(用于Ping)
```
AT+CGACT=1,1
响应: OK
作用: 激活数据连接(用于网络测试后需关闭)
```
### Ping测试
```
AT+CPING="www.baidu.com",1,4,64,1000,10000,0
响应: +CPING: 1,<ip>,<time>,<ttl>
+CPING: 2,0,0,0,0
OK
参数: 域名,回显次数,数据包大小,超时,间隔,最大等待,保留
注意: 需要先激活数据连接(AT+CGACT=1,1)
```
### 删除所有短信(清理存储空间)
```
AT+CMGD=1,4
响应: OK
作用: 删除所有短信(参数4=删除所有)
```
## URC(主动上报)消息
### 短信到达
```
+CMT: ,<length>
<PDU_HEX_STRING>
```
### 网络注册状态变化
```
+CEREG: <stat>
```
## 错误处理
### 常见ERROR原因
- **命令格式错误**: 检查AT命令语法
- **参数错误**: 检查参数范围和类型
- **模组未就绪**: 确保模组已完成初始化
- **网络未注册**: 等待CEREG状态变为1或5
- **SIM卡未就绪**: 检查SIM卡是否插好
### 超时处理
- **AT命令超时**: 一般1-2秒,网络相关命令5-10秒
- **发送短信超时**: 30秒
- **网络注册超时**: 30次重试(约30-60秒)
### 重试策略
- 初始化命令失败:立即重试
- 网络注册失败:等待后重试
- 发送短信失败:记录日志,不重试
## Node.js实现要点
### 串口读取
- 使用 `serialport` 库
- 设置行解析器 (`@serialport/parser-readline`)
- 监听数据事件,逐行处理
### AT命令发送
```javascript
async function sendATCommand(cmd, timeout = 2000) {
return new Promise((resolve, reject) => {
let buffer = '';
port.write(cmd + '\r\n');
const timer = setTimeout(() => {
reject(new Error('Timeout'));
}, timeout);
const handler = (data) => {
buffer += data;
if (buffer.includes('OK') || buffer.includes('ERROR')) {
clearTimeout(timer);
port.removeListener('data', handler);
resolve(buffer);
}
};
port.on('data', handler);
});
}
```
### PDU解析
使用 `node-pdu` 库:
```javascript
const PDU = require('node-pdu');
const parsed = PDU.parse(pduHexString);
// parsed.sender: 发送者号码
// parsed.text: 短信内容
// parsed.time: 时间戳
```
### URC监听
```javascript
parser.on('data', (line) => {
if (line.startsWith('+CMT:')) {
// 下一行是PDU数据
isWaitingPDU = true;
} else if (isWaitingPDU && /^[0-9A-Fa-f]+$/.test(line)) {
// 收到PDU数据
handleSMS(line);
isWaitingPDU = false;
}
});
```
## 状态机设计
```
IDLE状态
└─ 收到 +CMT: → WAIT_PDU状态
└─ 收到十六进制行 → 解析PDU → 处理短信 → IDLE状态
└─ 收到非十六进制行 → IDLE状态
```