一、背景与目标
设备信息
路由器:GL-XE 300,已刷入 OpenWrt 24.10.8
蜂窝模组:Quectel EC20
eUICC 卡:标准 GSMA 白卡
目标:通过 lpac 远程下载并写入 eSIM profile
核心链路:路由器 CPU → QMI 协议 → EC20 模组 → eUICC 卡。lpac 通过 OpenWrt 的 uqmi 工具与 EC20 通信,uqmi 再将 APDU 指令透传给卡。
二、安装 lpac
1、通过 opkg 安装
opkg update
opkg install lpac2、验证安装
lpac version返回 {"code":0,"message":"success"} 即安装成功。版本显示 v0.0.0-unknown 是 OpenWrt 打包时的正常现象,不影响功能。
三、配置 uqmi 后端
1、确认 EC20 的 QMI 设备节点
ls /dev/cdc-wdm0如果这个设备不存在,说明 EC20 没有以 QMI 模式工作,需要先检查模组的 USB 模式配置。
2、直接验证 lpac 与 eUICC 通信
路由器上插入 eUICC 卡,重启后执行:
LPAC_APDU=uqmi lpac chip info返回包含 eidValue 的 JSON,即说明 EC20 的 QMI 通道和 uqmi 后端都在正常工作。
预期成功输出(包含关键字段):
{
"eidValue": "89086030...",
"EuiccConfiguredAddresses": {
"rootDsAddress": "lpa.ds.gsma.com"
},
"EUICCInfo2": {
"freeNonVolatileMemory": 280833,
"rspCapability": ["additionalProfile", ...]
}
}关键判断:
eidValue 有值 → 卡被正确识别
rspCapability 包含 additionalProfile → 支持写入新 profile
freeNonVolatileMemory 数值充足 → 有空间存储 profile
3、踩坑:插卡后运行报 euicc_init
{"code":-1,"message":"euicc_init","data":""}原因:EC20 固件在热插拔场景下不会主动初始化 eUICC 卡。卡虽然物理上在位,但逻辑上未激活。lpac 尝试打开逻辑通道并选中 ISD-R 应用时,卡端无响应,导致初始化超时。
解决:重启路由器,让 EC20 执行完整的启动序列,强制对 eUICC 执行 UIM Power On 和 Card Reset,之后 lpac 即可正常通信。
补充说明:这个问题在 EC20 上表现为“必须重启路由器才能首次成功”。重启后 chip info 一次通过,后续只要不拔卡、不重启模组,lpac 的命令都能正常执行。因此插卡操作应在路由器关机状态下完成,或插卡后重启路由器再开始写卡。
四、下载并写入 Profile
1、下载命令
LPAC_APDU=uqmi lpac profile download -a 'LPA:1$<SM-DP+域名>$<匹配ID>'示例(红茶移动 CSL 香港卡):
LPAC_APDU=uqmi lpac profile download -a 'LPA:1$rsp-eu.redteamobile.com$47ExxxxxFBA62287'
LPAC_APDU=uqmi lpac profile download -a "LPA:1\$rsp-eu.redteamobile.com\$47ExxxxxFBA62287"注意:$ 是 shell 特殊字符,需要用反斜杠 \ 转义,或者用单引号包裹整个激活码,避免被 shell 解析。
2、成功输出(完整流程)
{"code":0,"message":"es10b_get_euicc_challenge_and_info"}
{"code":0,"message":"es9p_initiate_authentication"}
{"code":0,"message":"es10b_authenticate_server"}
{"code":0,"message":"es9p_authenticate_client"}
{"code":0,"message":"es8p_meatadata_parse","data":{"iccid":"898520...","profileName":"CSL_45400_Release"}}
{"code":0,"message":"es10b_prepare_download"}
{"code":0,"message":"es9p_get_bound_profile_package"}
{"code":0,"message":"es10b_load_bound_profile_package"}
{"code":0,"message":"success","data":null}最终 {"code":0,"message":"success"} 即写入成功。
3、解决 TLS 握手失败(核心踩坑)
(1)问题现象
执行 profile 下载时,在 es9p_initiate_authentication 阶段报错:
curl_easy_perform() failed: Error
{"code":-1,"message":"es9p_initiate_authentication","data":"HTTP transport failed"}(2)根本原因
OpenWrt 默认的 libcurl 使用 mbedTLS 作为 SSL 后端。mbedTLS 在处理部分 SM-DP+ 服务器的证书链时存在限制,无法完成 TLS 握手。OpenWrt 官方 Issue 确认了这一问题:mbedTLS 难以读取 GSMA Root CA(使用 ECDSA-SHA256 签名),且可能不支持服务器要求的部分加密套件(如 TLS 1.3 的 TLS_AES_256_GCM_SHA384)。
(3)解决办法:替换 gnutils 版 libcurl
opkg install libcurl-gnutls4安装后,将 libcurl 的符号链接指向 gnutls 版本:
cd /usr/lib
rm -f libcurl.so.4
ln -s libcurl-gnutls.so.4 libcurl.so.4验证替换生效:
ls -l /usr/lib/libcurl.so.4
# 应显示: libcurl.so.4 -> libcurl-gnutls.so.4注意:libcurl-gnutls4 会额外占用约 6MB 闪存空间。XE300 的 128MB NAND 足够容纳,无需担心。
(4)如果 opkg 找不到 libcurl-gnutls4
手动下载对应架构的 ipk 文件(mips_24kc):
https://downloads.openwrt.org/releases/24.10.8/packages/mips_24kc/packages/搜索 libcurl-gnutls4,下载后通过 SCP 传到路由器:
# 加 -O 参数强制使用旧版 SCP 协议
scp -O libcurl-gnutls4_*.ipk root@192.168.1.1:/tmp/
opkg install /tmp/libcurl-gnutls4_*.ipk五、管理 Profile
1、列出卡内所有 Profile
LPAC_APDU=uqmi lpac profile list结果示例:
{"type":"lpa","payload":{"code":0,"message":"success","data":[{"iccid":"898520002xx","isdpAid":"a0000005591010ffffffff8900001200","profileState":"enabled","profileNickname":null,"serviceProviderName":"eSIM","profileName":"CSL_45400_Release","iconType":null,"icon":null,"profileClass":"operational"}]}}输出中包含每个 profile 的 iccid、profileName、profileState(enabled / disabled)。
2、启用 Profile
LPAC_APDU=uqmi lpac profile enable <ICCID>成功返回 {"code":0,"message":"success"}。同一时间只能有一个 profile 处于 enabled 状态。
3、设置别名(可选)
LPAC_APDU=uqmi lpac profile nickname <ICCID> "我的香港卡"