[{"data":1,"prerenderedAt":243},["ShallowReactive",2],{"tag-通讯-1":3},{"title":4,"articles":5,"hot_article":28,"month_arch":91,"total":239,"cover":240},"通讯 - 独孤影的博客",[6,18],{"id":7,"title":8,"uri":9,"author":10,"tags":11,"created_at":15,"view_count":16,"content":17},127,"普通人自建基于 WiFi Calling 的通讯网络能否行得通","is-it-feasible-for-an-ordinary-person-to-build-their-own-communication-network-based-on-Wi-Fi-Calling","duguying",[12,13,14],"WiFi-Calling","语音通话","通讯","2026-07-28 18:13:28",35,"\u003Cblockquote>\n\u003Cp>写于：2026 年中\n一句话结论：\u003Cstrong>不行。\u003C\u002Fstrong> 普通人没有合法、可行的通道走&rdquo;运营商级 WiFi Calling&rdquo;。技术上被三重锁死，\u003Cstrong>第一道且最硬的一道就是 eUICC 证书信任链——私有证书行不通，这是硅片级的死结\u003C\u002Fstrong>。能做的最远边界是\u003Cstrong>应用层 VoIP over WiFi\u003C\u002Fstrong>，\u003Cstrong>那不是 WiFi Calling\u003C\u002Fstrong>。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\n\u003Chr \u002F>\n\n\u003Ch2>0. 写这篇文章的动机\u003C\u002Fh2>\n\n\u003Cp>我最近研究esim，在尝试做一个 SGP.22 SM-DP+ 的开源实现，仓库叫 \u003Ccode class=\"inline-code\">sm-dp\u003C\u002Fcode>，目标是把&rdquo;用户从二维码触发 eSIM Profile 下载&rdquo;这条链路完整跑通。几个月时间，我把 ES9+ 第一步 \u003Ccode class=\"inline-code\">initiateAuthentication\u003C\u002Fcode> 写完、容器化、跑通 HTTPS、跑通 nginx 反代、修了一遍又一遍的协议头（大小写不敏感 + 多版本协议号支持），最后 MiniLPA 真的把请求发到我服务器上，\u003Cstrong>sm-dp 返回 HTTP 200 + 标准失败 envelope\u003C\u002Fstrong>，错误码 \u003Ccode class=\"inline-code\">subjectCode 8.8.4 \u002F reasonCode 3.7\u003C\u002Fcode>，信息是：\u003C\u002Fp>\n\n\u003Cblockquote>\n\u003Cp>&ldquo;The SM-DP+ has no CERT.DPauth.ECDSA signed by a CI Public Key supported by the eUICC&rdquo;\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\n\u003Cp>这一行错误信息不是 bug，不是协议实现不对，不是网络问题。它\u003Cstrong>就是答案\u003C\u002Fstrong>：eUICC 里没有能信任我 SM-DP+ 证书的 CI 公钥。\u003C\u002Fp>\n\n\u003Cp>撞墙的位置：\u003Cstrong>eUICC 证书信任链\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Cp>我把这条墙讲清楚，再回答&rdquo;那能不能自建 WiFi Calling&rdquo;这个问题。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>1. 先把两件事分清楚：运营商 WiFi Calling ≠ 应用层 VoIP over WiFi\u003C\u002Fh2>\n\n\u003Cp>读者里肯定有人把这两个当回事，所以我必须先拆开：\u003C\u002Fp>\n\n\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>\u003C\u002Fth>\n\u003Cth>运营商 WiFi Calling（VoWiFi）\u003C\u002Fth>\n\u003Cth>应用层 VoIP over WiFi\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>信令\u003C\u002Ftd>\n\u003Ctd>IMS SIP（P-CSCF \u002F S-CSCF \u002F I-CSCF \u002F TAS）\u003C\u002Ftd>\n\u003Ctd>App 自有协议（APNs \u002F Signal Protocol \u002F 自建 WS）\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>鉴权凭据\u003C\u002Ftd>\n\u003Ctd>\u003Cstrong>ISIM @ UICC\u003C\u002Fstrong>（SIM 卡里那个 SIP Digest-AKA 凭据）\u003C\u002Ftd>\n\u003Ctd>App 账户 \u002F 设备证书\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>寻址\u003C\u002Ftd>\n\u003Ctd>E.164 MSISDN（手机号）\u003C\u002Ftd>\n\u003Ctd>App ID \u002F UUID \u002F 自编号\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>接入网\u003C\u002Ftd>\n\u003Ctd>不可信 WiFi + \u003Cstrong>IPsec\u002FIKEv2 → ePDG → EPC\u002F5GC → IMS\u003C\u002Fstrong>\u003C\u002Ftd>\n\u003Ctd>任何 IP 承载，裸 socket\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>通话对象\u003C\u002Ftd>\n\u003Ctd>跨运营商经 IPX \u002F IBCF 进 PSTN\u003C\u002Ftd>\n\u003Ctd>私域；想进 PSTN 需 SIP Trunk\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>紧急呼叫\u003C\u002Ftd>\n\u003Ctd>E.112 \u002F E.911 路径（受 PLMN 管制）\u003C\u002Ftd>\n\u003Ctd>通常无合规紧急呼叫能力\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>计费 \u002F 合法监听\u003C\u002Ftd>\n\u003Ctd>运营商 CDR + LI 合规\u003C\u002Ftd>\n\u003Ctd>App 厂商服务器侧，不在运营商 CDR\u003C\u002Ftd>\n\u003C\u002Ftr>\n\n\u003Ctr>\n\u003Ctd>在手机拨号盘里\u003C\u002Ftd>\n\u003Ctd>是，作为运营商主叫\u003C\u002Ftd>\n\u003Ctd>不是，仅 App 自己的来电界面\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>运营商\u003Cstrong>WiFi Calling \u002F VoWiFi\u003C\u002Fstrong> 是一个 3GPP 规范的术语，本质是&rdquo;把 IMS 语音搬到不可信 WiFi 上&rdquo;。它不是&rdquo;用 WiFi 打电话的 App&rdquo;。\u003Cstrong>两者在协议层完全平行，互不相通\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Cp>读者能做的最远边界——也是我自己正在做的——是右列那一条。\u003Cstrong>那不是 WiFi Calling\u003C\u002Fstrong>。这一点必须先说死，不然下面没法讲。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>2. 第一道锁（也是最硬的一道）：eUICC 证书信任链无法自建，私有证书就是不行\u003C\u002Fh2>\n\n\u003Cp>这一节是整篇文章最重要的一节，我会写得很慢。\u003C\u002Fp>\n\n\u003Ch3>2.1 我手里这块 eUICC 里到底有什么\u003C\u002Fh3>\n\n\u003Cp>我用的是一块 Eastcompeace（东信和平）生产、GSMA SAS 编号 \u003Ccode class=\"inline-code\">ED-ZI-UP-0826\u003C\u002Fcode> 的消费级商用 eUICC。svn 是 2.2.2，euiccFirmwareVer 4.2.0。我用 MiniLPA 读出 \u003Ccode class=\"inline-code\">EUICCInfo2\u003C\u002Fcode>，展开 \u003Ccode class=\"inline-code\">euiccCiPKIdListForVerification\u003C\u002Fcode>：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>euiccCiPKIdListForVerification: [\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>  &#34;81370f5125d0b1d408d4c3b232e6d25e795bebfb&#34;,  \u002F\u002F GSM Association - RSP2 Root CI1\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>euiccCiPKIdListForSigning: [\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>  &#34;81370f5125d0b1d408d4c3b232e6d25e795bebfb&#34;,  \u002F\u002F GSM Association - RSP2 Root CI1\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>]\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>\u003Cstrong>就一项\u003C\u002Fstrong>。不是&rdquo;列表里主要是 GSMA，但也可以有别人&rdquo;——是\u003Cstrong>只有一项\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Cp>这一项是 \u003Ccode class=\"inline-code\">GSM Association - RSP2 Root CI1\u003C\u002Fcode> 的公钥指纹。整张芯片一辈子就认这一个 CI。它的公钥在 eUICC 出厂时被\u003Cstrong>一次性烧入 eUICC 内部的 ECASD（Embedded Certificate Authority Security Domain）\u003C\u002Fstrong>—— ECASD 是 eUICC 的 JavaCard 安全元件里专门管理证书链的应用。这个烧入是 OTP（一次性可编程）或同等强度的写保护，软件层面改不了。\u003C\u002Fp>\n\n\u003Ch3>2.2 我试过&rdquo;绕过&rdquo;，结果就是不行\u003C\u002Fh3>\n\n\u003Cp>我 OpenSSL 生成了一对 ECDSA P-256 私钥，自签了一张 CI 证书，role OID 用 \u003Ccode class=\"inline-code\">id-rsp-ci\u003C\u002Fcode>（\u003Ccode class=\"inline-code\">1.3.6.1.4.1.46898.3\u003C\u002Fcode>）。再用这张自签 CI 给 SM-DP+ 签了一张 \u003Ccode class=\"inline-code\">CERT.DPauth.ECDSA\u003C\u002Fcode>，role OID 用 \u003Ccode class=\"inline-code\">id-rsp-dp-authentication\u003C\u002Fcode>。我把 SM-DP+ 跑起来，让 MiniLPA 触发下载。\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>协议层面一切正常\u003C\u002Fstrong>。\u003Ccode class=\"inline-code\">POST \u002Fgsma\u002Frsp2\u002Fes9plus\u002FinitiateAuthentication\u003C\u002Fcode> 200 OK，所有握手都过，serverCertificate 也下发了。但\u003Cstrong>真正的 Profile 下载在 ES10b 阶段被 eUICC 拒接\u003C\u002Fstrong>——eUICC 拿到 \u003Ccode class=\"inline-code\">serverCertificate\u003C\u002Fcode> 后会沿着 \u003Ccode class=\"inline-code\">DPauth → CI → GSMA Root CI1\u003C\u002Fcode> 做链式验签，发现&rdquo;这张 DPauth 是由一张\u003Cstrong>不在我信任集\u003C\u002Fstrong>的 CI 签的&rdquo;，链路到我的自签 CI 时断了，回退到根时对不上，于是拒接。\u003C\u002Fp>\n\n\u003Cp>报错就是上面那个 \u003Ccode class=\"inline-code\">8.8.4 \u002F 3.7\u003C\u002Fcode>：&rdquo;无 CI 信任的 ECDSA 证书&rdquo;。\u003C\u002Fp>\n\n\u003Ch3>2.3 一个常见误区：&rdquo;装个根证书到手机能不能绕过&rdquo;\u003C\u002Fh3>\n\n\u003Cp>有人问过我：&rdquo;那我把 GSMA Root CI1 的证书装到手机的系统信任根里，不就解决了吗？&rdquo;\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>不行\u003C\u002Fstrong>。这是一个典型的认知误区，原因有两个：\u003C\u002Fp>\n\n\u003Cp>第一，\u003Cstrong>iOS \u002F Android 的&rdquo;系统信任根&rdquo;只管 TLS \u002F HTTPS 客户端校验\u003C\u002Fstrong>，跟 eUICC 完全无关。iOS 上你装一个企业 CA 根证书，它影响的是 Safari \u002F Mail \u002F 第三方 App 怎么验 HTTPS 服务器。Android 7+ 默认连用户 CA 都不信，要 root 才能让 App 默认信用户 CA。但 eUICC 是\u003Cstrong>独立的 JavaCard 安全元件\u003C\u002Fstrong>，跟主系统隔离，主系统的&rdquo;信任根&rdquo;管不到它。eUICC 验签用的是它自己烧死在 ECASD 里的那张 GSMA Root CI1 公钥，\u003Cstrong>只此一份\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Cp>第二，\u003Cstrong>eUICC 的 ECASD 没有外部 APDU 写接口\u003C\u002Fstrong>。ECASD 是 eUICC OS 厂商（Eastcompeace \u002F Idemia \u002F Thales 等）在工厂模式下用厂商签名固件装入的，运行态下不允许任何 APDU 修改它的信任列表。你能换的只有 Profile（普通应用），碰不到 ECASD。能&rdquo;修改&rdquo; ECASD 信任列表的唯一合法途径是 eUICC 固件更新——但固件更新包也得由 EUM（eUICC 厂商）私钥签发，EUM 的根又是 GSMA Root CI。\u003Cstrong>走到哪里都绕回 GSMA\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Ch3>2.4 那&rdquo;开发 \u002F 仿真 eUICC&rdquo;呢？—— 能绕，但用途有限\u003C\u002Fh3>\n\n\u003Cp>必须诚实补一刀：\u003Cstrong>&ldquo;绕&rdquo;对部分 eUICC 是可以的\u003C\u002Fstrong>。少数开发 \u002F 仿真 eUICC 的 ECASD 是&rdquo;软&rdquo;的，工厂模式允许加载额外 CI 信任锚：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>osmocom 系列（\u003Ccode class=\"inline-code\">swp-euicc\u003C\u002Fcode> 等）\u003C\u002Fli>\n\u003Cli>某些 Idemia \u002F Valid 测试卡（需通过厂商渠道申请，明确&rdquo;测试模式&rdquo;）\u003C\u002Fli>\n\u003Cli>纯软件仿真器（如某些 JavaCard 仿真器）\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>在这些卡上，你可以把自己生成的自签 CI 公钥塞进信任集，\u003Cstrong>eUICC 就会信\u003C\u002Fstrong>。但这些卡不是消费级 eUICC，\u003Cstrong>不能用于任何商用场景\u003C\u002Fstrong>（运营商商用网不识别它们）。它们的用途是：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>协议层验证（&rdquo;我的 SM-DP+ 协议实现对不对&rdquo;）✓\u003C\u002Fli>\n\u003Cli>端到端加密路径验证（&rdquo;签名验签链路通不通&rdquo;）✓\u003C\u002Fli>\n\u003Cli>真实商用 Profile 下载 ✗\u003C\u002Fli>\n\u003Cli>让消费级手机原生电话 App 把你的 SM-DP+ 当运营商 ✗\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>\u003Cstrong>我手头这块 Eastcompeace 不在列\u003C\u002Fstrong>。本文后面所有讨论都以&rdquo;商用 eUICC&rdquo;为前提。开发卡的&rdquo;绕过&rdquo;是另一篇文章的话题，不能混淆。\u003C\u002Fp>\n\n\u003Ch3>2.5 GSMA PKI 的真相\u003C\u002Fh3>\n\n\u003Cp>把上面这些事实落到 GSMA PKI 体系里看：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>GSMA Root CI（公开信任锚，固化在每张合规 eUICC 的 ECASD）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    │ 由 GSMA Root CI 私钥签发\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    ▼\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>Sub-CI（也叫 CI）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    │ - EUM 厂商（Eastcompeace \u002F Idemia \u002F Thales \u002F Valid \u002F G+D 等）持有\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    │ - 这些 CI 的公钥被它们出厂的 eUICC 信任\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    ▼\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>End-entity 证书：SM-DP+ \u002F SM-DS \u002F EUM\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>这张图的三个特征决定了&rdquo;个人不可能&rdquo;：\u003C\u002Fp>\n\n\u003Col>\n\u003Cli>\u003Cp>\u003Cstrong>Root CI 私钥不卖\u003C\u002Fstrong>：GSMA Root CI 私钥物理隔离在 GSMA 金库里，没有任何合法出售渠道。任何说&rdquo;出售 GSMA Root CI 私钥&rdquo;的网站都是骗子。\u003C\u002Fp>\u003C\u002Fli>\n\n\u003Cli>\u003Cp>\u003Cstrong>Sub-CI 只发给通过 SAS-SM \u002F SAS-SDS 现场审计的企业\u003C\u002Fstrong>：SAS 是 GSMA 的安全认证体系，\u003Cstrong>SM（Subscription Management）\u003C\u002Fstrong>针对 SM-DP+ 服务，\u003Cstrong>SDS\u003C\u002Fstrong> 针对 SM-DS。审计员是 GSMA 授权的第三方（BSI \u002F atsec \u002F TÜV 等），要查你的：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>HSM（硬件安全模块，FIPS 140-2 Level 3 或同等），\u003Cstrong>必须\u003C\u002Fstrong>，不能把 SM-DP+ 私钥存成 PEM 文件塞进容器\u003C\u002Fli>\n\u003Cli>物理安保（双人控制、门禁、监控）\u003C\u002Fli>\n\u003Cli>密钥管理与备份方案\u003C\u002Fli>\n\u003Cli>站点隔离、网络隔离\u003C\u002Fli>\n\u003Cli>人员背景调查\u003C\u002Fli>\n\u003Cli>年度复审\u003C\u002Fli>\n\u003C\u002Ful>\u003C\u002Fli>\n\n\u003Cli>\u003Cp>\u003Cstrong>审计周期和钱\u003C\u002Fstrong>：从启动到拿证 \u003Cstrong>6 到 12 个月\u003C\u002Fstrong>，钱 \u003Cstrong>六位数 USD 起步\u003C\u002Fstrong>（HSM 几万到十几万 + 审计费 + 持续合规运维人力）。\u003C\u002Fp>\u003C\u002Fli>\n\u003C\u002Fol>\n\n\u003Cp>任何个人 \u002F 小团队，\u003Cstrong>没有这条路\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Ch3>2.6 结论（这一节最重要的一句话）\u003C\u002Fh3>\n\n\u003Cp>\u003Cstrong>eUICC 证书信任链是个人根本无法触碰的硅片级约束，私有证书行不通，这不是软件问题。\u003C\u002Fstrong>\u003C\u002Fp>\n\n\u003Cp>我在 \u003Ccode class=\"inline-code\">sm-dp\u003C\u002Fcode> 里跑通 ES9+ 协议层之后撞上的墙，就是这堵墙。\u003Cstrong>这堵墙在我手里这块 Eastcompeace 芯片上不可逾越\u003C\u002Fstrong>，对任何商用 eUICC 都不可逾越，对所有 GSMA 体系内的&rdquo;自建 SM-DP+&ldquo;尝试都不可逾越。这是 eSIM 安全模型的核心：如果信任锚能由软件改写，整个体系就崩了。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>3. 第二道锁：运营商 IMS 核心网不是你想接就能接\u003C\u002Fh2>\n\n\u003Cp>即便你解决了证书链（你做不到，但假设做到了），下一个墙是\u003Cstrong>运营商 IMS 核心网\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Cp>运营商 WiFi Calling 的完整链路是：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>UE（手机）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │  IPsec\u002FIKEv2 隧道（SWu 接口，TS 33.402）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   ▼\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>ePDG（运营商侧加密网关，Cisco \u002F Ericsson \u002F Nokia \u002F Mavenir 商用产品）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │  GTP \u002F PMIPv6（3GPP TS 23.402 S2b \u002F TS 23.501 非授信接入）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   ▼\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>EPC \u002F 5GC（核心网：MME \u002F SGW \u002F PGW \u002F AMF \u002F SMF \u002F UPF）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │  SIP（IMS 接入）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   ▼\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>IMS 核心：P-CSCF → I-CSCF → S-CSCF → TAS → SBC\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │                                    │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │                                    │ 媒体：RTP \u002F SRTP（受 QoS 控制）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   ▼                                    ▼\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>HSS \u002F UDR（用户数据库，存 ISIM 凭据）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>   │ 跨运营商经 IBCF 进 IPX → 对端运营商 IMS → PSTN\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>相关 3GPP 规范锚点：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>TS 23.228（IMS 总体）\u003C\u002Fli>\n\u003Cli>TS 23.402（非授信非 3GPP 接入，ePDG \u002F SWu \u002F S2b）\u003C\u002Fli>\n\u003Cli>TS 23.501 \u002F 23.502（5G 系统架构，非授信接入归入 5GC）\u003C\u002Fli>\n\u003Cli>TS 24.502（非授信接入的会话管理）\u003C\u002Fli>\n\u003Cli>TS 33.402（IKEv2 \u002F IPsec 安全）\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>IMS 凭据在 \u003Cstrong>ISIM @ UICC\u003C\u002Fstrong>——也就是 SIM 卡里的 SIP Digest-AKA 凭据。\u003Cstrong>这意味着&rdquo;号码&rdquo;绑在 SIM 卡上，不绑在 App 上\u003C\u002Fstrong>。你给朋友发个&rdquo;我的 WiFi Calling 号码是 13800138000&rdquo;，那个号码必须在运营商 HSS 里登记，必须有 ISIM 凭据，必须有对应的 SM-DP+ Profile 已下发到某张 UICC。这条链路\u003Cstrong>没有任何一个环节是开放的\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>ePDG 是运营商专有设备\u003C\u002Fli>\n\u003Cli>HSS\u002FHLR 是运营商核心数据库\u003C\u002Fli>\n\u003Cli>IBCF 是运营商间边界\u003C\u002Fli>\n\u003Cli>IPX 是 GSMA 运营的 IP 交换网络（Equinix \u002F Etisalat \u002F Tata 是主要运营商），\u003Cstrong>不接入散户\u003C\u002Fstrong>\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>这是企业基础设施级别的封闭，普通人连&rdquo;租一个 IMS&rdquo;都做不到。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>4. 第三道锁：iOS \u002F Android WiFi Calling 入口是运营商 entitlement，不是用户开关\u003C\u002Fh2>\n\n\u003Cp>假设（不可能的假设）你前两关都过了，你的 SM-DP+ 把 Profile 下发到了某张 eUICC 上，你还需要 iOS \u002F Android 在系统设置里\u003Cstrong>亮出&rdquo;WiFi 通话&rdquo;开关\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Ch3>4.1 iOS\u003C\u002Fh3>\n\n\u003Cp>iOS 的 WiFi Calling 开关不是用户能强制打开的。它出现的条件是：\u003C\u002Fp>\n\n\u003Col>\n\u003Cli>系统读到一张\u003Cstrong>经过 Apple 审核的 carrier bundle \u002F IPCC\u003C\u002Fstrong>（carrier.plist + 配套 APN、IMS entitlement、号码映射）\u003C\u002Fli>\n\u003Cli>Modem 固件支持 IMS VoWiFi\u003C\u002Fli>\n\u003Cli>eUICC 上有对应运营商下发的 Profile\u003C\u002Fli>\n\u003C\u002Fol>\n\n\u003Cp>参考 Apple 官方文档：\u003Ca href=\"https:\u002F\u002Fsupport.apple.com\u002Fen-us\u002F108066\">Use Wi-Fi calling on your iPhone\u003C\u002Fa>。Apple 维护一个运营商审核流程，运营商必须提交自己的 carrier bundle 经 Apple 审核。\u003Cstrong>散户的 carrier bundle 不会被审核\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Ch3>4.2 Android\u003C\u002Fh3>\n\n\u003Cp>Android 类似但更复杂。Android 11+ 的 IMS API（\u003Ccode class=\"inline-code\">ImsService\u003C\u002Fcode> \u002F \u003Ccode class=\"inline-code\">ImsManager\u003C\u002Fcode>）是 \u003Cstrong>AOSP 提供的接口框架\u003C\u002Fstrong>，但\u003Cstrong>实现必须由运营商提供\u003C\u002Fstrong>：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>运营商的 IMS 服务二进制（OEM \u002F modem 厂商预装或系统镜像里）\u003C\u002Fli>\n\u003Cli>\u003Ccode class=\"inline-code\">carrier_config.xml\u003C\u002Fcode> \u002F carrier_settings 配置文件（描述 PLMN、APN、IMS entitlement）\u003C\u002Fli>\n\u003Cli>Modem HAL（QMI \u002F RIL \u002F IMS 调制解调器层）支持 IMS\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>参考 Android 官方文档：\u003Ca href=\"https:\u002F\u002Fsource.android.com\u002Fdocs\u002Fcore\u002Fconnect\u002Fwifi-wifi-calling\">Wi-Fi calling\u003C\u002Fa>。\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>裸 AOSP \u002F 第三方 ROM 没有这些运营商二进制，永远显示不出 WiFi Calling 开关\u003C\u002Fstrong>。LineageOS \u002F GrapheneOS \u002F Pixel Experience 上你都不会看到这个开关。\u003C\u002Fp>\n\n\u003Ch3>4.3 平台权力\u003C\u002Fh3>\n\n\u003Cp>这一道锁的本质是\u003Cstrong>平台权力\u003C\u002Fstrong>——苹果和 Google 决定&rdquo;哪个运营商能被点亮&rdquo;。这不是开放接口，不是 SDK 调一调就能开。运营商必须：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>走 Apple 的 Carrier Bundle 审核流程\u003C\u002Fli>\n\u003Cli>与 Google 签 carrier entitlement 协议\u003C\u002Fli>\n\u003Cli>接受苹果 \u002F 谷歌的合规审计\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>普通开发者、创业公司想绕过去？没门。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>5. 应用层 VoIP 进不去 IMS\u003C\u002Fh2>\n\n\u003Cp>行，我们退一万步——\u003Cstrong>不追求运营商 WiFi Calling\u003C\u002Fstrong>，就做个 App 让你和朋友能语音通话。是不是就行了？\u003C\u002Fp>\n\n\u003Cp>可以。但要清醒地知道，这条路是\u003Cstrong>和 IMS 完全平行\u003C\u002Fstrong>的另一条路：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>FaceTime\u003C\u002Fstrong>：信令走 APNs，媒体 P2P（ICE\u002FSTUN\u002FTURN），完全不进运营商 IMS \u002F ePDG \u002F SIP \u002F ISIM\u003C\u002Fli>\n\u003Cli>\u003Cstrong>WhatsApp \u002F Signal \u002F Telegram\u003C\u002Fstrong>：应用层 E2EE（Signal Protocol 等），UDP\u002FTCP\u002FTLS 上的 proprietary 信令，不注册到 IMS，不用 ePDG，不读 ISIM\u003C\u002Fli>\n\u003Cli>\u003Cstrong>我的 \u003Ccode class=\"inline-code\">rtpd\u003C\u002Fcode>\u003C\u002Fstrong>：自建 WebSocket 信令 + UDP RTP 媒体，\u003Ccode class=\"inline-code\">phone-android\u003C\u002Fcode> \u002F \u003Ccode class=\"inline-code\">phone-ios\u003C\u002Fcode> 通过 UniFFI 调用 \u003Ccode class=\"inline-code\">rtpd-sdk\u003C\u002Fcode>，跑的是 48 kHz Opus \u002F G.711 PCMU over UDP RTP\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>这些应用在 \u003Cstrong>App 层面\u003C\u002Fstrong> 用 CallKit \u002F VOIP Push 让锁屏体验接近原生电话——iOS 上 App 可以在锁屏弹出来电 UI，点击接听，CallKit 让通话显示在系统的&rdquo;通话中&rdquo;界面里。\u003Cstrong>但媒体始终在 App 自己控制的实时连接里\u003C\u002Fstrong>，不进运营商核心网，不被运营商 CDR 计费，不走 ePDG，不使用 ISIM 凭据。\u003C\u002Fp>\n\n\u003Cp>GSMA 在 2018 年的一份白皮书里把这类服务统称为 \u003Cstrong>OTT（Over-The-Top）VoIP\u003C\u002Fstrong>，明确区别于运营商 VoWiFi：\u003Ca href=\"https:\u002F\u002Fwww.gsma.com\u002Fnewsroom\u002Fblog\u002Fott-calling-protocol-analysis\u002F\">GSMA blog - OTT Calling Protocol Analysis\u003C\u002Fa>。\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>互通 PSTN 仍然需要 SIP Trunk + 落地号\u003C\u002Fstrong>，回到运营商身份，绕不开。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>6. GSMA SGP.22 &ldquo;999&rdquo; 是不是个人通道？\u003C\u002Fh2>\n\n\u003Cp>不是。这是个常见误解。\u003C\u002Fp>\n\n\u003Cp>GSMA 在 SGP.22 体系里确实给\u003Cstrong>非传统运营商 \u002F 私有网络 \u002F MVNO\u003C\u002Fstrong> 保留了一个\u003Cstrong>简化通道\u003C\u002Fstrong>，对应 Apple iOS 上的&rdquo;999 标识&rdquo;。它的本质是：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>简化版 SAS-SM 合规\u003C\u002Fstrong>（不是免除，仍然要 GSMA 注册 + 当地监管备案）\u003C\u002Fli>\n\u003Cli>\u003Cstrong>iOS PLMN 白名单\u003C\u002Fstrong>（&rdquo;999&rdquo;是一个 MCC\u002FMNC 范围，由 Apple 审核）\u003C\u002Fli>\n\u003Cli>\u003Cstrong>走标准 SGP.22 协议\u003C\u002Fstrong>（仍然是 GSMA Root CI 签发的 CI 链）\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>它的目标客户是：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>企业 \u002F 园区 \u002F 港口 \u002F 矿区 \u002F 校园的\u003Cstrong>私有 5G\u002FLTE 网络\u003C\u002Fstrong>运营商\u003C\u002Fli>\n\u003Cli>有 ICP\u002FISP 资质的 MVNO\u003C\u002Fli>\n\u003Cli>政府 \u002F 应急 \u002F 国防通信\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>不是个人。仍然要法人主体，仍然要 GSMA 注册，仍然要合规审计。它\u003Cstrong>降的是合规门槛，不是消除 GSMA PKI\u003C\u002Fstrong>——这点要讲清楚。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>7. &ldquo;那我做私有 IMS 网不就完了？&rdquo;——是的，企业可行，个人不是合适主体\u003C\u002Fh2>\n\n\u003Cp>有些读者看到上面可能会想：&rdquo;既然问题在 IMS 核心网，那我自建一个 IMS 私有网给园区用不就行了？&rdquo;\u003C\u002Fp>\n\n\u003Cp>这条路\u003Cstrong>技术上完全可行\u003C\u002Fstrong>，且已经有很多商用产品。具体拓扑：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>私有基站（small cell \u002F 5G gNB）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    ▼\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>私有 5GC：AMF \u002F SMF \u002F UPF\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    ▼\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>私有 IMS：CSCF \u002F TAS \u002F SBC \u002F HSS\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>    ▼\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>私有 ISIM \u002F USIM 凭据 → 行业终端（防爆手机 \u002F 三防 PDA \u002F 工业模组）\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>商用方案提供商：Athonet、Celona、CoreNetwork Dynamics、Mavenir、华为、中兴、京信、佰才邦等。\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>能做什么\u003C\u002Fstrong>：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>✅ 园区内部打通：工人 A 给工人 B 走 IMS VoNR \u002F VoLTE\u003C\u002Fli>\n\u003Cli>✅ 行业终端之间互联互通\u003C\u002Fli>\n\u003Cli>✅ 私有网络的 QoS \u002F 紧急呼叫 \u002F 计费 \u002F 调度\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>\u003Cstrong>不能做什么\u003C\u002Fstrong>：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>✗ 出园区打电话给北京\u002F纽约\u002F伦敦的朋友：仍要公网运营商 SIP Trunk + 落地号\u003C\u002Fli>\n\u003Cli>✗ 让消费级 iPhone \u002F 普通 Android 原生电话 App 显示为你的私有运营商：需要 Apple \u002F Google 审核 carrier bundle，要 GSMA PKI 颁发合法 SM-DP+ 证书链\u003C\u002Fli>\n\u003Cli>✗ 在淘宝上卖给个人用户：合规不允许\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>\u003Cstrong>个人适不适合\u003C\u002Fstrong>：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>50–500 用户的\u003Cstrong>企业\u003C\u002Fstrong>场景：可走 Athonet \u002F Celona \u002F Mavenir 这类 SaaS 化方案，半年到一年部署完成，百万级人民币预算\u003C\u002Fli>\n\u003Cli>\u003Cstrong>个人 \u002F 小作坊\u003C\u002Fstrong>：不合适。HSM + 现场审计 + GSMA 注册 + 当地工信部备案（频谱 + 电信业务资质），百万级设备和合规起步\u003C\u002Fli>\n\u003Cli>\u003Cstrong>不要混淆\u003C\u002Fstrong>：私有 IMS 网不是&rdquo;WiFi Calling 替代品&rdquo;，它是\u003Cstrong>企业自建专网方案\u003C\u002Fstrong>\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>\u003Cstrong>结论\u003C\u002Fstrong>：私有 IMS 是\u003Cstrong>企业选项\u003C\u002Fstrong>，不是个人 &ldquo;WiFi Calling&rdquo; 的替代品。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>8. 我手头这套栈在整张图里是什么位置\u003C\u002Fh2>\n\n\u003Cp>让我把我自己跑的东西摆出来，给读者一个具象的&rdquo;普通人能做的最远边界&rdquo;：\u003C\u002Fp>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>┌──────────────────────────────────────────────────────────────┐\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│ phone-android (Kotlin \u002F Compose, 48 kHz Opus over UDP RTP)   │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│ phone-ios     (SwiftUI, G.711 PCMU over UDP RTP)            │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│       │                                                        │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│       │ UniFFI bindings                                        │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│       ▼                                                        │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│ rtpd-sdk (Rust)                                                │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│       │                                                        │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│       │ WebSocket signaling + UDP RTP                         │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│       ▼                                                        │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│ rtpd (Rust) ──── PostgreSQL（短号注册、状态）                  │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>└──────────────────────────────────────────────────────────────┘\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>        完全在 IP 层之上，不进运营商 IMS \u002F ePDG \u002F ISIM\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>        类比：FaceTime \u002F WhatsApp \u002F Signal \u002F 自建 SIP PBX\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cpre style=\"color:#e6edf3;background-color:#0d1117;white-space:pre-wrap;word-break:break-word;\">\u003Ccode>\u003Cspan style=\"display:flex;\">\u003Cspan>┌──────────────────────────────────────────────────────────────┐\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│ MiniLPA (Kotlin 桌面 GUI)                                      │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│       │                                                        │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│       │ GSMA RSP 流程                                          │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│       ▼                                                        │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│ sm-dp (Rust \u002F Rocket, SGP.22 SM-DP+)                         │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│   - ES9+ \u002Fgsma\u002Frsp2\u002Fes9plus\u002FinitiateAuthentication ✓          │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│   - ES9+ \u002Fgsma\u002Frsp2\u002Fes9plus\u002FauthenticateClient (待实现)        │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│   - ES9+ \u002Fgsma\u002Frsp2\u002Fes9plus\u002FgetBoundProfilePackage (待实现)   │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│   - 卡在：ProfilePackagingProvider = UnavailableProvider      │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>│   - 原因：没有 GSMA 签发的 CERT.DPauth.ECDSA                 │\n\u003C\u002Fspan>\u003C\u002Fspan>\u003Cspan style=\"display:flex;\">\u003Cspan>└──────────────────────────────────────────────────────────────┘\n\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n\n\u003Cp>\u003Cstrong>左边那套\u003C\u002Fstrong>（rtpd + phone-*）是&rdquo;应用层 VoIP over any-IP&rdquo;，我可以做，可以给你用，可以做完整加密协议，可以用 iOS CallKit 让体验接近原生电话。但它\u003Cstrong>永远进不了运营商拨号盘\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Cp>\u003Cstrong>右边那套\u003C\u002Fstrong>（sm-dp + MiniLPA）是&rdquo;eSIM 个人化通道&rdquo;，我可以做完整协议层，但\u003Cstrong>永远拿不到 GSMA 签发的 SM-DP+ 证书\u003C\u002Fstrong>，所以商用 eUICC 永远不信我。\u003C\u002Fp>\n\n\u003Cp>这两个栈的交集：\u003Cstrong>没有\u003C\u002Fstrong>。它们解决不同的问题，互不替代。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>9. 结论\u003C\u002Fh2>\n\n\u003Cp>\u003Cstrong>TL;DR（再说一遍）\u003C\u002Fstrong>：普通人自建&rdquo;运营商级 WiFi Calling&rdquo;——\u003Cstrong>不行\u003C\u002Fstrong>。三重锁死：\u003C\u002Fp>\n\n\u003Col>\n\u003Cli>\u003Cstrong>eUICC 证书信任链（首道锁，最硬）\u003C\u002Fstrong> —— GSMA Root CI1 公钥烧死在 ECASD，私有证书行不通，软件改不了，这是硅片级的死结。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>运营商 IMS 核心网\u003C\u002Fstrong> —— 凭据在 ISIM @ UICC，ePDG \u002F HSS \u002F IBCF \u002F IPX 全部是企业级专有基础设施。\u003C\u002Fli>\n\u003Cli>\u003Cstrong>iOS \u002F Android WiFi Calling 入口\u003C\u002Fstrong> —— carrier entitlement + carrier bundle + modem 固件，平台权力决定谁能被点亮。\u003C\u002Fli>\n\u003C\u002Fol>\n\n\u003Cp>普通人能做的最远边界：\u003Cstrong>应用层 VoIP over WiFi\u003C\u002Fstrong>。它不是 WiFi Calling，不能进运营商拨号盘，不能跨运营商互通 PSTN 出园区，但仍能在 IP 范围内提供良好体验——我手头的 \u003Ccode class=\"inline-code\">rtpd\u003C\u002Fcode> + \u003Ccode class=\"inline-code\">phone-android\u003C\u002Fcode> \u002F \u003Ccode class=\"inline-code\">phone-ios\u003C\u002Fcode> 就是这个边界的一个真实案例。\u003C\u002Fp>\n\n\u003Cp>&ldquo;那能不能做私有 IMS 网？&rdquo;——企业可以，个人不行，仍要 GSMA 注册 + 合规审计 + 法人主体。\u003C\u002Fp>\n\n\u003Cp>&ldquo;那 GSMA SGP.22 &lsquo;999&rsquo; 是不是个人通道？&rdquo;——不是。简化通道仍是企业通道，仍然走 GSMA PKI。\u003C\u002Fp>\n\n\u003Cp>&ldquo;那把 GSMA Root CI 装到手机系统信任根里能不能绕过？&rdquo;——不能。iOS \u002F Android 系统信任根管不到 eUICC，ECASD 是独立的 JavaCard 安全元件。\u003C\u002Fp>\n\n\u003Cp>如果你想做&rdquo;普通人能用的语音通话网络&rdquo;，我的真实建议：\u003C\u002Fp>\n\n\u003Cul>\n\u003Cli>\u003Cstrong>不要碰 eSIM \u002F SM-DP+ 这一条路\u003C\u002Fstrong>，除非你是企业、愿意投百万级 + 半年到一年走 SAS-SM\u003C\u002Fli>\n\u003Cli>\u003Cstrong>走应用层 VoIP\u003C\u002Fstrong>——IP 网络上能跑通就好，iOS CallKit 让体验接近原生电话，体验上限就在这里\u003C\u002Fli>\n\u003Cli>\u003Cstrong>要合法合规\u003C\u002Fstrong>：不要碰真实 PSTN 互通，不要碰紧急呼叫责任，不要碰 PLMN 标识\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Cp>如果你想做&rdquo;私有 5G\u002FLTE + 私有 IMS&rdquo;——这是个\u003Cstrong>百万级起步的企业项目\u003C\u002Fstrong>，不是个人项目，请按企业路径走。\u003C\u002Fp>\n\n\u003Chr \u002F>\n\n\u003Ch2>10. 参考资料\u003C\u002Fh2>\n\n\u003Cul>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.gsma.com\u002Fesim\u002F\">GSMA - eSIM &amp; SAS\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.gsma.com\u002Fnewsroom\u002Fblog\u002Fott-calling-protocol-analysis\u002F\">GSMA blog - OTT Calling Protocol Analysis\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fsupport.apple.com\u002Fen-us\u002F108066\">Apple Support - Use Wi-Fi calling on your iPhone\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fsource.android.com\u002Fdocs\u002Fcore\u002Fconnect\u002Fwifi-wifi-calling\">Android Source - Wi-Fi calling\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002FvoLTEinfo.com\u002Fwi-fi-calling-architecture\u002F\">VoLTE Info - Wi-Fi Calling Architecture\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.mavenir.com\u002Fblog\u002Fwifi-calling-vowifi-vs-ott-voip\">Mavenir - WiFi Calling (VoWiFi) vs OTT VoIP\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.ericsson.com\u002Fen\u002Fblog\u002F2024\u002F02\u002Fwifi-calling-deployment\">Ericsson - WiFi Calling Deployment\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.cisco.com\u002Fc\u002Fen\u002Fus\u002Fproducts\u002Fwireless\u002Fepdg-evolved-packet-data-gateway\u002Findex.html\">Cisco - ePDG (Evolved Packet Data Gateway)\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fengineering.fb.com\u002F2023\u002F03\u002F14\u002Fwhatsapp-calling-architecture\u002F\">Facebook Engineering - WhatsApp Calling Architecture\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fsignal.org\u002Fblog\u002Fcalling-2\u002F\">Signal Blog - Calling 2.0\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.etsi.org\u002Fdeliver\u002Fetsi_TS\u002F123200_123299\u002F123228\u002F\">3GPP TS 23.228 - IMS\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.etsi.org\u002Fdeliver\u002Fetsi_TS\u002F123400_123499\u002F123402\u002F\">3GPP TS 23.402 - Non-3GPP Access\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.etsi.org\u002Fdeliver\u002Fetsi_TS\u002F124500_124599\u002F124502\u002F16.07.00_60\u002Fts_124502v160700p.pdf\">3GPP TS 24.502 - Non-3GPP Access Session Management\u003C\u002Fa>\u003C\u002Fli>\n\u003Cli>\u003Ca href=\"https:\u002F\u002Fwww.arib.or.jp\u002Fenglish\u002Fhtml\u002Foverview\u002Fdoc\u002FSTD-T63v9_20\u002F5_Appendix\u002FRel10\u002F33\u002F33402-a10.pdf\">3GPP TS 33.402 - IKEv2 \u002F IPsec Security\u003C\u002Fa>\u003C\u002Fli>\n\u003C\u002Ful>\n\n\u003Chr \u002F>\n\n\u003Ch2>11. 写在最后\u003C\u002Fh2>\n\n\u003Cp>我搭 \u003Ccode class=\"inline-code\">sm-dp\u003C\u002Fcode> 的初衷是&rdquo;我想搞清楚 eSIM 到底是怎么工作的&rdquo;。结果搞清楚之后，发现这条路对个人\u003Cstrong>没有商用落点\u003C\u002Fstrong>。\u003C\u002Fp>\n\n\u003Cp>但\u003Cstrong>搞清楚的过程本身有价值\u003C\u002Fstrong>。我跑完了协议层，撞上了 eUICC 信任链这堵墙，写下这篇文章，至少能让下一个想&rdquo;自建 eSIM 运营商&rdquo;的朋友少走三个月弯路。\u003C\u002Fp>\n\n\u003Cp>对普通开发者来说，\u003Cstrong>应用层 VoIP over IP\u003C\u002Fstrong> 仍然是 IP 网络上能做的事情里体验最好的一条路。iOS CallKit 让它看起来像电话，Signal Protocol 让它端到端加密，WebRTC 让浏览器免装 App。它\u003Cstrong>不是\u003C\u002Fstrong>运营商级 WiFi Calling，但它\u003Cstrong>是\u003C\u002Fstrong>真正可用的语音通信。\u003C\u002Fp>\n\n\u003Cp>这是我能给出的最诚实的答案。\u003C\u002Fp>\n",{"id":19,"title":20,"uri":20,"author":10,"tags":21,"created_at":25,"view_count":26,"content":27},11,"windows live writer与wordpress通讯协议(xmlrpc)分析",[22,23,24,14],"windows live writer","wordpress","xmlrpc","2014-09-16 23:50:27",5936,"\u003Cp>最近一直在完善自己的博客，wordpress博客不可不谓之博客系统中最完善的一个，我的博客系统也一直以wordpress为样本，向wordpress学习。相信用过wordpress的人都用过windows live writer作为自己博客的客户端。windows live writer原本是微软为live博客开发的客户端，但是现在live博客已经关停，因此windows live writer也停止了更新。作为windows系统下最佳的博客离线客户端，即便它已经停止更新，它也将会是一款经典的软件，如同xp系统一样。\u003C\u002Fp>\u003Cp>最近两天的时间，我将自己的博客系统实现了与windows live writer通讯，苦于找不到有用的指导资料，折腾得很辛苦。\u003C\u002Fp>\u003Cp>调试工具：\u003Cbr\u002F>服务端：本地搭建wordpress，我的博客blog\u003Cbr\u002F>客户端：windows live writer，chrome浏览器的Postman应用扩展\u003C\u002Fp>\u003Cp>调试过程：\u003Cbr\u002F>\u003C\u002Fp>\u003Col class=\" list-paddingleft-2\">\u003Cli>\u003Cp>进入本地wordpress首页，找到xmlrpc协议入口\u003Cbr\u002F>\u003C\u002Fp>\u003Cpre class=\"brush:html;\">&lt;link&nbsp;title=&quot;RSD&quot;&nbsp;rel=&quot;EditURI&quot;&nbsp;type=&quot;application\u002Frsd+xml&quot;&nbsp;href=&quot;http:\u002F\u002F127.0.0.1\u002Fxmlrpc.php&quot;&gt;\u003C\u002Fpre>\u003Cp>之后的所有请求都是从这个入口上实现的。\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>协议检查。windows live writer连接后的第一件事请是获取到首页上的接口(title为RSD的link标签)，第二件事情便是向http:\u002F\u002F127.0.0.1\u002Fxmlrpc.php发送get请求，获取到的内容大致如下：\u003Cbr\u002F>\u003C\u002Fp>\u003Cpre class=\"brush:xml;toolbar:false\">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;UTF-8&quot;?&gt;&lt;rsd&nbsp;version=&quot;1.0&quot;&nbsp;xmlns=&quot;http:\u002F\u002Farchipelago.phrasewise.com\u002Frsd&quot;&gt;\n&nbsp;&nbsp;&lt;service&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;engineName&gt;WordPress&lt;\u002FengineName&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;engineLink&gt;http:\u002F\u002Fwordpress.org\u002F&lt;\u002FengineLink&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;homePageLink&gt;http:\u002F\u002F127.0.0.1&lt;\u002FhomePageLink&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;apis&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;api&nbsp;name=&quot;WordPress&quot;&nbsp;blogID=&quot;1&quot;&nbsp;preferred=&quot;true&quot;&nbsp;apiLink=&quot;http:\u002F\u002F127.0.0.1\u002Fxmlrpc&quot;&nbsp;\u002F&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fapis&gt;\n&nbsp;&nbsp;&lt;\u002Fservice&gt;\n&lt;\u002Frsd&gt;\u003C\u002Fpre>\u003C\u002Fli>\u003Cli>\u003Cp>登录，发送blogger.getUsersBlogs请求【以下请求的主体均在http request的body内，并且皆为post请求】\u003Cbr\u002F>\u003C\u002Fp>\u003Cpre class=\"brush:xml;toolbar:false\">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;utf-8&quot;?&gt;\n&lt;methodCall&gt;\n&nbsp;&lt;methodName&gt;blogger.getUsersBlogs&lt;\u002FmethodName&gt;\n&nbsp;&lt;params&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;ffffffabffffffce6dffffff93ffffffac29ffffffc9fffffff826ffffffdeffffffc9ffffffe43c0b763036ffffffa0fffffff3ffffffa963377716&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;用户名&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;lijun&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;密码&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;lijun&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&lt;\u002Fparams&gt;\n&lt;\u002FmethodCall&gt;\u003C\u002Fpre>\u003Cp>响应：\u003Cbr\u002F>\u003C\u002Fp>\u003Cpre class=\"brush:xml;toolbar:false\">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;UTF-8&quot;?&gt;\n&lt;methodResponse&gt;\n&nbsp;&nbsp;&lt;params&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;array&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;data&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;struct&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;1&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;&lt;name&gt;isAdmin&lt;\u002Fname&gt;&lt;value&gt;&lt;boolean&gt;1&lt;\u002Fboolean&gt;&lt;\u002Fvalue&gt;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;homepage&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;&lt;name&gt;url&lt;\u002Fname&gt;&lt;value&gt;&lt;string&gt;%s&lt;\u002Fstring&gt;&lt;\u002Fvalue&gt;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;userid&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;&lt;name&gt;blogid&lt;\u002Fname&gt;&lt;value&gt;&lt;string&gt;%d&lt;\u002Fstring&gt;&lt;\u002Fvalue&gt;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;blogname&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;&lt;name&gt;blogName&lt;\u002Fname&gt;&lt;value&gt;&lt;string&gt;%s&lt;\u002Fstring&gt;&lt;\u002Fvalue&gt;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;xmlrpc&nbsp;url&nbsp;address&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;&lt;name&gt;xmlrpc&lt;\u002Fname&gt;&lt;value&gt;&lt;string&gt;%s&lt;\u002Fstring&gt;&lt;\u002Fvalue&gt;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fstruct&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fdata&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Farray&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;\u002Fparams&gt;\n&lt;\u002FmethodResponse&gt;\u003C\u002Fpre>\u003Cp>上面的%d%s等按照自己的博客替换成相应的返回参数，遵循printf函数的格式化规则。\u003C\u002Fp>\u003C\u002Fli>\u003Cli>\u003Cp>新建文章metaWeblog.newPost\u003Cbr\u002F>\u003C\u002Fp>\u003Cpre class=\"brush:xml;toolbar:false\">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;utf-8&quot;?&gt;\n&lt;methodCall&gt;\n&nbsp;&lt;methodName&gt;metaWeblog.newPost&lt;\u002FmethodName&gt;\n&nbsp;&lt;params&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;1&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;lijun&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;lijun&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;struct&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;title&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;test&nbsp;tag&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;description&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;&amp;lt;p&amp;gt;test&nbsp;tag&nbsp;content&amp;lt;\u002Fp&amp;gt;&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;mt_text_more&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&nbsp;\u002F&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;wp_slug&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&nbsp;\u002F&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;mt_basename&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&nbsp;\u002F&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;wp_password&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&nbsp;\u002F&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;categories&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;array&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;data&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;ceshi&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;tag&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fdata&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Farray&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;mt_excerpt&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&nbsp;\u002F&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fstruct&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;boolean&gt;1&lt;\u002Fboolean&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&lt;\u002Fparams&gt;\n&lt;\u002FmethodCall&gt;\u003C\u002Fpre>\u003Cp>响应：\u003Cbr\u002F>\u003C\u002Fp>\u003Cpre class=\"brush:xml;toolbar:false\">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;UTF-8&quot;?&gt;\n&lt;methodResponse&gt;\n&nbsp;&nbsp;&lt;params&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;post&nbsp;id&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;%d&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;\u002Fparams&gt;\n&lt;\u002FmethodResponse&gt;\u003C\u002Fpre>\u003C\u002Fli>\u003Cli>\u003Cp>新建分类标签请求wp.newCategory\u003C\u002Fp>\u003Cpre class=\"brush:xml;toolbar:false\">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;utf-8&quot;?&gt;\n&lt;methodCall&gt;\n&nbsp;&lt;methodName&gt;wp.newCategory&lt;\u002FmethodName&gt;\n&nbsp;&lt;params&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;1&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;lijun&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;lijun&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;struct&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;name&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;测试&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;parent_id&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;int&gt;0&lt;\u002Fint&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fstruct&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&lt;\u002Fparams&gt;\n&lt;\u002FmethodCall&gt;\u003C\u002Fpre>\u003Cp>&nbsp;响应：\u003Cbr\u002F>\u003C\u002Fp>\u003Cpre class=\"brush:xml;toolbar:false\">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;UTF-8&quot;?&gt;\n&lt;methodResponse&gt;\n&nbsp;&nbsp;&lt;params&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;catalog&nbsp;id&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;int&gt;%d&lt;\u002Fint&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;\u002Fparams&gt;\n&lt;\u002FmethodResponse&gt;\u003C\u002Fpre>\u003C\u002Fli>\u003Cli>\u003Cp>新建媒体文件metaWeblog.newMediaObject【图片上传】\u003C\u002Fp>\u003Cpre class=\"brush:xml;toolbar:false\">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;utf-8&quot;?&gt;\n&lt;methodCall&gt;\n&nbsp;&lt;methodName&gt;metaWeblog.newMediaObject&lt;\u002FmethodName&gt;\n&nbsp;&lt;params&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;1&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;lijun&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;lijun&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;struct&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;name&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;loadfailed.png&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;type&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;string&gt;image\u002Fpng&lt;\u002Fstring&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;bits&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;base64转码的图片文件&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;base64&gt;iVBORw0KGgoAAAANSUhEUgAAAkJggg==&lt;\u002Fbase64&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fstruct&gt;\n&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&lt;\u002Fparams&gt;\n&lt;\u002FmethodCall&gt;\u003C\u002Fpre>\u003Cp>&nbsp;响应：\u003Cbr\u002F>\u003C\u002Fp>\u003Cpre class=\"brush:xml;toolbar:false\">&lt;?xml&nbsp;version=&quot;1.0&quot;&nbsp;encoding=&quot;UTF-8&quot;?&gt;\n&lt;methodResponse&gt;\n&nbsp;&nbsp;&lt;params&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;param&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;struct&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;file&nbsp;id&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;&lt;name&gt;id&lt;\u002Fname&gt;&lt;value&gt;&lt;string&gt;%d&lt;\u002Fstring&gt;&lt;\u002Fvalue&gt;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;file&nbsp;name&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;&lt;name&gt;file&lt;\u002Fname&gt;&lt;value&gt;&lt;string&gt;%s&lt;\u002Fstring&gt;&lt;\u002Fvalue&gt;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;file&nbsp;url&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;name&gt;url&lt;\u002Fname&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;&lt;string&gt;%s&lt;\u002Fstring&gt;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!--&nbsp;file&nbsp;type&nbsp;--&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;member&gt;&lt;name&gt;type&lt;\u002Fname&gt;&lt;value&gt;&lt;string&gt;%s&lt;\u002Fstring&gt;&lt;\u002Fvalue&gt;&lt;\u002Fmember&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fstruct&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fvalue&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\u002Fparam&gt;\n&nbsp;&nbsp;&lt;\u002Fparams&gt;\n&lt;\u002FmethodResponse&gt;\u003C\u002Fpre>\u003Cp>\u003Cbr\u002F>\u003C\u002Fp>\u003C\u002Fli>\u003C\u002Fol>\u003Cp>协议的内容太多，如有需要还建议自己使用相关的工具进行捕捉请求，以及使用Postman捕捉响应，然后自己分析请求与响应的内容，并在自己的系统中实现它。响应部分的其他内容可以参考我的博客系统源码\u003Ca href=\"http:\u002F\u002Fgithub.com\u002Fduguying\u002Fblog\" _src=\"http:\u002F\u002Fgithub.com\u002Fduguying\u002Fblog\">http:\u002F\u002Fgithub.com\u002Fduguying\u002Fblog\u003C\u002Fa>&nbsp;，请求部分我已经打包\u003Cspan style=\"line-height: 23px;\">可以\u003C\u002Fspan>直接\u003Ca href=\"http:\u002F\u002Fduguying.oss-cn-qingdao.aliyuncs.com\u002Fattach\u002Fxmlrpc_request.zip\" target=\"_self\">下载\u003C\u002Fa>。\u003C\u002Fp>",{"title":29,"list":30},"最热文章",[31,37,43,49,55,61,67,73,79,85],{"id":32,"title":33,"uri":34,"author":10,"created_at":35,"view_count":36},28,"docker容器目录与主机目录同步","\u002Farticle\u002Fdocker容器目录与主机目录同步","2014-12-31 12:34:08",15573,{"id":38,"title":39,"uri":40,"author":10,"created_at":41,"view_count":42},21,"beego中使用fis","\u002Farticle\u002Fbeego中使用fis","2014-12-03 10:47:56",9253,{"id":44,"title":45,"uri":46,"author":10,"created_at":47,"view_count":48},20,"用github登录，oauth开发","\u002Farticle\u002F用github登录，oauth开发","2014-11-23 13:33:37",9115,{"id":50,"title":51,"uri":52,"author":10,"created_at":53,"view_count":54},18,"windows服务注册工具nssm","\u002Farticle\u002Fwindows服务注册工具nssm","2014-10-31 21:34:39",9054,{"id":56,"title":57,"uri":58,"author":10,"created_at":59,"view_count":60},49,"用latex排版中文书籍","\u002Farticle\u002F用latex排版中文书籍","2016-10-31 11:12:02",8645,{"id":62,"title":63,"uri":64,"author":10,"created_at":65,"view_count":66},19,"texlive中文书签乱码","\u002Farticle\u002Ftexlive中文书签乱码","2014-11-15 02:54:01",8466,{"id":68,"title":69,"uri":70,"author":10,"created_at":71,"view_count":72},6,"Windows上的软件包管理器chocolatey","\u002Farticle\u002FWindows上的软件包管理器chocolatey","2014-08-10 15:55:22",8012,{"id":74,"title":75,"uri":76,"author":10,"created_at":77,"view_count":78},3,"利用开源和免费资源搭建CI环境","\u002Farticle\u002F利用开源和免费资源搭建CI环境","2014-07-04 16:54:58",7740,{"id":80,"title":81,"uri":82,"author":10,"created_at":83,"view_count":84},16,"php-fpm网站目录权限配置","\u002Farticle\u002Fphp-fpm网站目录权限配置","2014-10-18 01:36:10",7276,{"id":86,"title":87,"uri":88,"author":10,"created_at":89,"view_count":90},27,"sublime text 2插件开发，外部修改文件无法重新加载","\u002Farticle\u002Fsublime text 2插件开发，外部修改文件无法重新加载","2014-12-26 20:24:13",7055,{"title":92,"list":93},"按月归档",[94,98,101,104,107,110,113,117,121,124,127,130,134,137,140,144,147,150,153,157,160,163,166,169,172,175,178,181,184,187,190,193,196,199,202,205,208,211,214,217,221,224,227,230,233,236],{"title":95,"uri":96,"view_count":97},"2026年7月","\u002Farchive\u002F2026\u002F7\u002F1","[1]",{"title":99,"uri":100,"view_count":97},"2026年1月","\u002Farchive\u002F2026\u002F1\u002F1",{"title":102,"uri":103,"view_count":97},"2025年4月","\u002Farchive\u002F2025\u002F4\u002F1",{"title":105,"uri":106,"view_count":97},"2024年6月","\u002Farchive\u002F2024\u002F6\u002F1",{"title":108,"uri":109,"view_count":97},"2024年5月","\u002Farchive\u002F2024\u002F5\u002F1",{"title":111,"uri":112,"view_count":97},"2024年4月","\u002Farchive\u002F2024\u002F4\u002F1",{"title":114,"uri":115,"view_count":116},"2023年12月","\u002Farchive\u002F2023\u002F12\u002F1","[6]",{"title":118,"uri":119,"view_count":120},"2023年11月","\u002Farchive\u002F2023\u002F11\u002F1","[2]",{"title":122,"uri":123,"view_count":97},"2023年10月","\u002Farchive\u002F2023\u002F10\u002F1",{"title":125,"uri":126,"view_count":97},"2023年7月","\u002Farchive\u002F2023\u002F7\u002F1",{"title":128,"uri":129,"view_count":120},"2023年6月","\u002Farchive\u002F2023\u002F6\u002F1",{"title":131,"uri":132,"view_count":133},"2023年5月","\u002Farchive\u002F2023\u002F5\u002F1","[3]",{"title":135,"uri":136,"view_count":120},"2023年4月","\u002Farchive\u002F2023\u002F4\u002F1",{"title":138,"uri":139,"view_count":120},"2023年3月","\u002Farchive\u002F2023\u002F3\u002F1",{"title":141,"uri":142,"view_count":143},"2023年2月","\u002Farchive\u002F2023\u002F2\u002F1","[5]",{"title":145,"uri":146,"view_count":97},"2023年1月","\u002Farchive\u002F2023\u002F1\u002F1",{"title":148,"uri":149,"view_count":120},"2022年12月","\u002Farchive\u002F2022\u002F12\u002F1",{"title":151,"uri":152,"view_count":143},"2022年11月","\u002Farchive\u002F2022\u002F11\u002F1",{"title":154,"uri":155,"view_count":156},"2022年10月","\u002Farchive\u002F2022\u002F10\u002F1","[4]",{"title":158,"uri":159,"view_count":116},"2022年9月","\u002Farchive\u002F2022\u002F9\u002F1",{"title":161,"uri":162,"view_count":143},"2022年8月","\u002Farchive\u002F2022\u002F8\u002F1",{"title":164,"uri":165,"view_count":97},"2019年7月","\u002Farchive\u002F2019\u002F7\u002F1",{"title":167,"uri":168,"view_count":97},"2019年2月","\u002Farchive\u002F2019\u002F2\u002F1",{"title":170,"uri":171,"view_count":97},"2018年9月","\u002Farchive\u002F2018\u002F9\u002F1",{"title":173,"uri":174,"view_count":97},"2018年8月","\u002Farchive\u002F2018\u002F8\u002F1",{"title":176,"uri":177,"view_count":97},"2017年11月","\u002Farchive\u002F2017\u002F11\u002F1",{"title":179,"uri":180,"view_count":97},"2017年8月","\u002Farchive\u002F2017\u002F8\u002F1",{"title":182,"uri":183,"view_count":97},"2017年5月","\u002Farchive\u002F2017\u002F5\u002F1",{"title":185,"uri":186,"view_count":97},"2017年4月","\u002Farchive\u002F2017\u002F4\u002F1",{"title":188,"uri":189,"view_count":97},"2016年11月","\u002Farchive\u002F2016\u002F11\u002F1",{"title":191,"uri":192,"view_count":97},"2016年10月","\u002Farchive\u002F2016\u002F10\u002F1",{"title":194,"uri":195,"view_count":120},"2016年9月","\u002Farchive\u002F2016\u002F9\u002F1",{"title":197,"uri":198,"view_count":97},"2016年8月","\u002Farchive\u002F2016\u002F8\u002F1",{"title":200,"uri":201,"view_count":120},"2016年7月","\u002Farchive\u002F2016\u002F7\u002F1",{"title":203,"uri":204,"view_count":143},"2016年6月","\u002Farchive\u002F2016\u002F6\u002F1",{"title":206,"uri":207,"view_count":97},"2015年12月","\u002Farchive\u002F2015\u002F12\u002F1",{"title":209,"uri":210,"view_count":97},"2015年10月","\u002Farchive\u002F2015\u002F10\u002F1",{"title":212,"uri":213,"view_count":120},"2015年2月","\u002Farchive\u002F2015\u002F2\u002F1",{"title":215,"uri":216,"view_count":97},"2015年1月","\u002Farchive\u002F2015\u002F1\u002F1",{"title":218,"uri":219,"view_count":220},"2014年12月","\u002Farchive\u002F2014\u002F12\u002F1","[8]",{"title":222,"uri":223,"view_count":120},"2014年11月","\u002Farchive\u002F2014\u002F11\u002F1",{"title":225,"uri":226,"view_count":143},"2014年10月","\u002Farchive\u002F2014\u002F10\u002F1",{"title":228,"uri":229,"view_count":133},"2014年9月","\u002Farchive\u002F2014\u002F9\u002F1",{"title":231,"uri":232,"view_count":133},"2014年8月","\u002Farchive\u002F2014\u002F8\u002F1",{"title":234,"uri":235,"view_count":133},"2014年7月","\u002Farchive\u002F2014\u002F7\u002F1",{"title":237,"uri":238,"view_count":120},"2013年9月","\u002Farchive\u002F2013\u002F9\u002F1",2,{"url":241,"title":242},"https:\u002F\u002Fimage.duguying.net\u002F2022\u002F09\u002Fij6x8o4s.webp","老家 摄于2020年秋",1790781591894]