NipGeihou's blog NipGeihou's blog
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档

NipGeihou

我见青山多妩媚,料青山见我应如是
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档
  • default

    • 骁龙410随身WiFi-Android
    • 骁龙410随身WiFi-Debain
    • 玩客云刷armbian
    • 基于ESP32 + Air780EPV的短信转发
      • 前言
      • 材料
      • 最佳实践
        • 硬件
        • 焊接
        • 连接
        • 软件
        • 准备与连接
        • 烧录固件
      • 优化
        • 通电开机
        • 对英文发件人的支持
      • 参考
    • 云游戏主机环境搭建(远程串流)
    • 东菱DL-KF5400改OPV
  • 黑苹果

  • 瞎折腾
  • default
NipGeihou
2024-02-14
目录

基于ESP32 + Air780EPV的短信转发

# 前言

本来是打算基于 Air780E 开发板实现的,后来发现有个新品 Air780EPV 还支持电信短信,关键这个芯片 9.9 盲订的时候我还知道这件事,但当时的说法是 9.9 盲订 + 尾款,结果是 9.9 到手(错过 1 个亿~)。秉持着买新不买旧的原则(大坑),最后选择了原价且不包邮的 Air780EPV。

# 材料

名称 数量 价格 说明
合宙 Air780EPV 开发板 1 39
合宙 ESP32C3 简约版 1 9.9
运费 - 7
1×16p 2.54MM 直插单排母 2 0.5 某宝 2.5/10 件。
飞线 2 -

笔记

  • 原本开发板是在闲鱼 29 收的,结果遇到一个不发货的 ** 卖家,最后还是去了官方淘宝店买,又刚好遇到合宙现在不包邮了,估计我的买入价是最高位,随着后面闲鱼有货,应该能 50 以内搞定。
  • 实际上排母买 1×2p 的就可以了

注意

如果只是转发移动、联通网络的短信,使用 合宙Air780E开发板 可以减少很多不必要的麻烦

# 最佳实践

# 硬件

image-20240301211555819

image.png

# 焊接

注意

实践过程中发现,esp32c3 与 air780epv 接口并不完全兼容,如没有把握能解决兼容问题,千万不要在直接把整排 16p 排母焊到 esp32c3 上,同时又把 20pin 的排针焊在 air780epv 开发板上,否则焊时有多爽,拆时就有多惨!

  • 在 esp32c3 上方的下述引脚焊接排母

    • 01
    • 13-14
    • 17-18
    • 31-32
    • 上述实际上只用到 31-32 供电引脚,其他引脚上的排母主要作用是连接时支撑开发板。
  • 在 air780epv 的下方的下述引脚焊接排针

    • 03-04
    • 25-26
    • 17-18
    • 38
    • 当然排针可以全焊上去,只要保证无关的引脚不会与 esp32c3 的引脚连通即可。

# 连接

不知道是故意的还是不小心的,air780epv 的 UART1_RXD、UART1_TXD 与 air780e 的引脚是相反的,因此不能像 air780e 一样直接用排母连接 eps32c3,需要用跳线对调。

  • 将焊接的排母和排针连接
  • 使用飞线,将 esp32c3 的 02 与 air780epv 的 36 , 03 与 37 连接。

55d311642560f6fc58abea4ca3d2ce1

# 软件

# 准备与连接

参考官方视频教程:ESP32C3 - 新版_哔哩哔哩_bilibili (opens new window)

  • LuaTools 下载 (右键另存为) (opens new window)(创建一个文件夹 luatools 存放,因为下面会在启动目录下载资源)
  • 将 esp32c3 通过 usb 连接到电脑
  • 查看设备管理器,确认串口号
  • 在 Luatools 中
    • 勾选 通用串口打印
    • 选择 esp32c3 的串口号
    • 串口日志波特率: 921600
    • 打开串口
    • 能打印日志即为成功连接

# 烧录固件

  • 下载 NipGeihou/sms_forwarder_air780ep_esp32 (opens new window) 项目到本地

  • luatools 右上角, 项目管理测试

  • 创建项目 ,名字随意

  • 选择文件, \sms_forwarder_air780_esp32-master\firmware\LuatOS-SoC_V1006_ESP32C3_lite.soc

  • 增加脚本或资源文件 ,将 \sms_forwarder_air780_esp32-master\ 下的所有 lua 文件倒入进来

  • 使用 vscode (编辑器) 编辑 config.lua

    • config.board_type = "esp32c3"
    • config.wifi :配置 WiFi 账号、密码
    • config.notification_channel :开启并配置推送方式
  • luatools 的项目管理,点击 下载底层和脚本 将固件和脚本写入 esp32c3 中

  • 长按 air780epv 的 power 按键,出现绿灯即为开机

[2024-03-02 14:42:54.502] E (598) task_wdt: esp_task_wdt_init(593): TWDT already initializI/main.lua:60	main - 初始化Air780	Air780E已连接
[2024-03-02 14:42:54.502] I/main.lua:62	main - 初始化Air780	正在检查有无SIM卡
[2024-03-02 14:42:54.608] I/main.lua:41	main - 初始化网络	无线网络连接成功,IP地址:10.10.xx.xx
[2024-03-02 14:42:54.608] I/main.lua:44	main - 初始化网络	配置第1个DNS服务器为119.29.29.29
[2024-03-02 14:42:54.608] I/main.lua:44	main - 初始化网络	配置第2个DNS服务器为223.5.5.5
[2024-03-02 14:42:54.630] I/main.lua:44	main - 初始化网络	配置第3个DNS服务器为8.8.8.8
[2024-03-02 14:42:54.630] I/main.lua:44	main - 初始化网络	配置第4个DNS服务器为1.1.1.1
[2024-03-02 14:42:54.630] I/main.lua:48	main - 初始化网络	等待时间同步
[2024-03-02 14:42:54.630] I/main.lua:75	main - 初始化Air780	正在配置短信功能
[2024-03-02 14:42:54.939] I/main.lua:82	main - 初始化Air780	短信功能配置完成
[2024-03-02 14:42:54.939] I/main.lua:85	main - 初始化Air780	正在禁用RNDIS
[2024-03-02 14:42:54.939] I/main.lua:89	main - 初始化Air780	检查GPRS附着状态
[2024-03-02 14:42:55.062] I/main.lua:96	main - 初始化Air780	GPRS未附着,将在5秒后重新检查
[2024-03-02 14:42:55.549] I/main.lua:50	main - 初始化网络	时间同步完成
[2024-03-02 14:43:00.153] I/main.lua:93	main - 初始化Air780	GPRS已附着
[2024-03-02 14:43:00.153] I/main.lua:102	main - 初始化Air780	正在关闭NET灯闪烁
[2024-03-02 14:43:00.153] I/main.lua:106	main - 初始化Air780	初始化完成,等待新短信...
[2024-03-02 16:36:26.339] I/main.lua:60	main - 初始化Air780	Air780E已连接
[2024-03-02 16:36:26.339] I/main.lua:62	main - 初始化Air780	正在检查有无SIM卡
[2024-03-02 16:36:26.446] I/main.lua:75	main - 初始化Air780	正在配置短信功能
[2024-03-02 16:36:26.767] I/main.lua:82	main - 初始化Air780	短信功能配置完成
[2024-03-02 16:36:26.767] I/main.lua:85	main - 初始化Air780	正在禁用RNDIS
[2024-03-02 16:36:26.767] I/main.lua:89	main - 初始化Air780	检查GPRS附着状态
[2024-03-02 16:36:26.888] I/main.lua:93	main - 初始化Air780	GPRS已附着
[2024-03-02 16:36:26.888] I/main.lua:102	main - 初始化Air780	正在关闭NET灯闪烁
[2024-03-02 16:36:26.888] I/main.lua:106	main - 初始化Air780	初始化完成,等待新短信...

如果顺利将会看到类似上面的日志

# 优化

# 通电开机

默认情况下 air780epv 通电后需要长按 power 按键开机。

想让开发板上电同时自动开机,这种方式也能实现,但是需要调整开发板上的电阻了。 把下图标准的电阻短接,会将 Air780EP 的 POWKEY 信号拉低,也就实现开发板上电开机。

image.png

笔记

尝试使用一坨锡短接,发现连不起来,最后是先在两个触点上锡,再找一段排针连接。

# 对英文发件人的支持

海外的一些短信是没有手机号的,只有一个英文名,如 3HK 、 Apple ,而原项目中并为对英文发件人支持,因此转发的短信这些短信的发件人会是一段 16 进制值。

在 50 元内自制短信转发器(Air780E+ESP32C3) (opens new window)一文的留言中,有人提及这个问题,并且项目作者已增加对此的支持,而我使用的是另一个项目 (opens new window)的源码,而这个项目中目前并没有,因此我打算尝试一下提交个 PR。

解码工具:Online SMS PDU Decoder/Converter | Diafaan SMS Server (opens new window)

PDU 协议

时间关系,这里只分析收短信的 PDU 格式,由 wiki 可在 SMS Center (SC) -> Mobile Station (MS) 的 message type (消息类型) 为 SMS-DELIVER ,对应的 TP-MTI 为 00

07915862337418F62410D0C3B0FC5D9F97D96C0000320113324282238CC3B0FC5D9F97D96CD0F04D2EBB40CEB2BD2C07CDD1617919947FD7E5A0F19B5C06DDD3743428ECCEBFDD65500B340CCBDFF57999CD0695DB70F63B5F2ECF41F7349B0D7297ED6539283C5F83CC6F39284D7781B2EFBA1C347E93CBA0F41C24A3C1702E50920E4ACF41F6303B4D0699DF72900CD44EBBEBF4F2DC05

# SMSC
07
91
58 62 33 74 18 F6
# 第一个字节
24
# Originating Address  始发地址
10 #(10 hex = 16 dec,16个半字节 = 8字节)
D0
C3 B0 FC 5D 9F 97 D9 6C # 8字节
#TP-PID
00
# TP-DCS
00
# TP-SCTS
32 01 13 32 42 82 23 
# TP-UDL
8C
# TP-UD
C3B0FC5D9F97D96CD0F04D2EBB40CEB2BD2C07CDD1617919947FD7E5A0F19B5C06DDD3743428ECCEBFDD65500B340CCBDFF57999CD0695DB70F63B5F2ECF41F7349B0D7297ED6539283C5F83CC6F39284D7781B2EFBA1C347E93CBA0F41C24A3C1702E50920E4ACF41F6303B4D0699DF72900CD44EBBEBF4F2DC05
SMSC

SMSC 我想应该类似于网关一样的东西

这一段在 wiki 中没有找到,但交叉佐证可以肯定是有这么一段数据。

这段数据的格式跟 Originating Address 的格式是类似的,表明由谁承运?

First Octet 第一个字节
bit(s) field Meaning 参考值
0-1 TP-MTI Message Type Indicator 消息类型指示器 00
2 TP-MMS More Messages to Send 更多要发送的消息 0
3 TP-LP Loop Prevention 环路预防 0
4 - 0
5 TP-SRI Status Report Indication 状态报告指示
是否将状态报告返回给短消息实体 1 是 0 否
0
6 TP-UDHI User Data Header Indicator 用户数据标头指示器 0
7 TP-RP Reply Path 回复路径 0
TP-OA,Originating Address 始发地址

参考:GSM_03.40#Addresses - Wikipedia (opens new window)

字节索引 含义 参考值
0 地址数字共有多少个半字节 0B
1 {EXT,1}{TON,3}{NPI,4} 国际号码 91( 1 0001 0001 )
字母数字 D0( 1 001 0000 )
2-11 地址数字 5862337418F6( 85263347816 )
  • EXT:固定为 1

  • TON:

    • 0 0 0 :未知
    • 0 0 1 :国际号码,即 1001 = 9(hex)
    • 1 0 1 :字母数字,即 1101 = D(hex)
  • NPI:Numbering plan identification

    • 0 0 0 0 :未知
    • 0 0 0 1 :ISDN / 电话编号计划(E.164/E.163),即 1(hex)

    当用户发送的收件人以 + 开头是,发送时就会将 + 删除,并地址开头设为 91 (TON=1、NPI=1);反之如果不以 + 开头,则地址开头设为 01 (TON=0、NPI=1),由运营商匹配。(所以国内使用 00?)

  • 地址数字:

    • NPI = 1 :每个数字占半个字节,同时需要将同一个字节的两个数对调,其中最后一个字节的 F 在对调之后丢弃,得到手机号
    • NPI = 0 :则可能是字母数字,需要使用 GSM 7-bit 解码
GSM7-bit编解码代码
import (
	"encoding/hex"
	"github.com/warthog618/sms/encoding/gsm7"
)

func main() {

	text := "Design@Home"

	println("编码:")

	// 转换为gsm7编码
	gsm7encode, _ := gsm7.Encode([]byte(text))
	println(hex.EncodeToString(gsm7encode)) // 44657369676e00486f6d65

	// 按7位打包成一个字节
	pack := gsm7.Pack7Bit(gsm7encode, 0)
	println(hex.EncodeToString(pack)) // c4f23c7d760390ef7619

	println("解码:")

	// 解码
	gsm7encode = gsm7.Unpack7Bit(pack, 0)
	println(hex.EncodeToString(gsm7encode)) // 44657369676e00486f6d65

	decode, _ := gsm7.Decode(gsm7encode)
	println(string(decode)) // Design@Home

}

编码思路

# Design@Home
# 根据GSM 7-bit编码表得到16进制的:
44 65 73 69 67 6E 00 48 6F 6D 65
# 将其转换为2进制:
01000100 01100101 01110011 01101001 01100111 01101110 00000000 01001000 01101111 01101101 01100101
# 由于7-bit编码最高位均为0,需要去掉:
1000100 1100101 1110011 1101001 1100111 1101110 0000000 1001000 1101111 1101101 1100101

# 组合成8位,第一个字节现在只有7位,需将下一个字节的最低位添加到第一个字节的最高位:
待处理1:110010 1110011 1101001 1100111 1101110 0000000 1001000 1101111 1101101 1100101
已处理1:11000100

# 此时待处理1第一个字节只有6位,需要将下一个字节的最低位依次添加到第一个字节的最高位:
待处理2:11100 1101001 1100111 1101110 0000000 1001000 1101111 1101101 1100101
已处理2:11000100 11110010

# 以此类推
待处理3:1101 1100111 1101110 0000000 1001000 1101111 1101101 1100101
已处理3:11000100 11110010 00111100

待处理4:110 1101110 0000000 1001000 1101111 1101101 1100101
已处理4:11000100 11110010 00111100 01111101

待处理5:11 0000000 1001000 1101111 1101101 1100101
已处理5:11000100 11110010 00111100 01111101 01110110

...

# 最后一次处理,后面没有字节了,则在前面补0,直到8位
最终得到:11000100 11110010 00111100 01111101 01110110 00000011 10010000 11101111 01110110 00011001(16进制:C4 F2 3C 7D 76 03 90 EF 76 19)
TP-PID,Parameter Indicator 参数指标

GSM_03.40#Protocol_Identifier (opens new window)

  • 00:默认存储转发短信
TP-DCS,Data Coding Scheme 数据编码方案

GSM_03.40#Data_Coding_Scheme (opens new window)

GSM 03.38 - Wikipedia (opens new window)

Data_Coding_Scheme#SMS_data_coding_scheme (opens new window)

  • GSM 7-bit : 0 ,默认,包含大多数西欧语言中最常用的符号(以及一些希腊大写字母),7 位 bit
  • UCS-2 : 08 ,即 UTF-16,中文、韩语或日语消息必须使用 UTF-16 字符编码进行编码,16 位 bit
  • 8-bit data : 04 ,8 位 bit
TP-SCTS,Service Centre Time Stamp 服务中心时间戳
octet Content 参考值
0 Last two digits of the year 年份的最后两位数字 31
1 Month 月 30
2 Day 天 52
3 Hour 小时 32
4 Minute 分钟 10
5 Second 秒 65
6 Time zone 时区 8A

2013 年 3 月 25 日 23:01:56 PST (GMT-7),同样为转位(数字 35 存储为十六进制 53)

TP-UDL,User Data Length 用户数据长度

TP-UDL * TP-DCS对应单位长度 为 TP-UD 的长度

TP-UD,User Data 用户数据

todo


  • 由于只是对发件人(手机号)部分调整,不涉及到其他内容,只需要对解析手机号部分代码修改即可。
  • 经过翻阅 wiki 可知当 TP-OA 的第二个字节为 D0 时则为 Alphanumeric(字母数字),需要使用 GSM 7-bit 解码。因此只需要在代码中添加对此类短信的判断,并复用对 TP-UD 的 GSM 7-bit 解码逻辑即可来对 TP-OA 部分进行相同的操作即可。
  • 实际操作查看:Add support for alphanumeric SMS center type · NipGeihou/sms_forwarder_air780ep_esp32@55f23a6 (opens new window)

参考:

  • GSM 03.40 - Wikipedia (opens new window)

# 参考

  • 50 元内自制短信转发器(Air780E+ESP32C3) – 晨旭的博客~ (opens new window)
  • Air780EPV 文档中心 (opens new window)
  • boris1993/sms_forwarder_air780_esp32: 使用合宙 ESP32 和 Air780E 构建的短信转发器 (opens new window)
  • 0wQ/air780e-forwarder: 合宙 Air780 系列 4G 模组,短信转发,来电通知,Air724 在这里 -> https://github.com/0wQ/air724ug-forwarder (opens new window)
  • Luat 4G LTE 模块 QAT 命令手册 V1.0.0 (opens new window)
上次更新: 2024/05/13, 16:22:17
玩客云刷armbian
云游戏主机环境搭建(远程串流)

← 玩客云刷armbian 云游戏主机环境搭建(远程串流)→

最近更新
01
iSCSI服务搭建
05-10
02
磁盘管理与文件系统
05-02
03
网络测试 - iperf3
05-02
更多文章>
Theme by Vdoing | Copyright © 2018-2025 NipGeihou | 友情链接
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式