卫星短信

2 阅读6分钟

一、概述(卫星短信的特点与挑战)

Android 16 的卫星短信不使用传统 SmsDispatcher 路径,而是通过 SatelliteManagerDatagram(数据报)机制承载短信。这是一种完全独立的架构,与地面 SMS 走不同的代码路径。

核心特点:

  • Datagram 承载:短信被编码为 SatelliteDatagram(byte[]),通过 sendDatagram() 发送,而非 SmsManager.sendTextMessage()
  • 高延迟:卫星 RTT 500ms~数秒,Android 引入 SATELLITE_MODEM_STATE_DATAGRAM_RETRYING 状态处理重试
  • 受限长度SatelliteCapabilities.maxBytesPerOutgoingDatagram 限制每条数据报最大字节数
  • 需要指向isPointingRequired 标识是否需要用户对准卫星
  • 存储转发:支持 pollPendingDatagrams() 主动拉取待接收消息

二、短信发送流程

分步骤

步骤层级动作关键类/方法
1应用层短信App(如Messages)将短信编码为 SatelliteDatagram,调用 SatelliteManager.sendDatagram(DATAGRAM_TYPE_SMS, datagram, needFullScreenPointingUI, executor, resultListener)SatelliteManager.java:2289
2API层sendDatagram() 通过 ITelephony.sendDatagram() 跨进程调用到 PhoneInterfaceManagerSatelliteManager.java:2307
3Telephony层PhoneInterfaceManager.sendDatagram() 委托给 SatelliteController.sendDatagram()PhoneInterfaceManager.java:13043
4控制层SatelliteController 将 datagram 通过 ISatelliteService.sendDatagram() 下发到卫星HAL服务SatelliteController (com.android.internal.telephony.satellite)
5HAL层卫星HAL服务通过HIDL/AIDL调用Modem,Modem将数据封装到卫星信令帧发送Vendor RIL / Satellite HAL
6链路层Modem完成卫星随机接入→数据帧发送→等待ACKModem firmware
7回调Modem返回结果→HAL回调→SatelliteControllerPhoneInterfaceManagerIIntegerConsumer.accept(result)→应用 resultListener同上反向路径

时序图(Mermaid)

sequenceDiagram
    participant App as 短信App
    participant SM as SatelliteManager
    participant PIM as PhoneInterfaceManager
    participant SC as SatelliteController
    participant HAL as SatelliteService(HAL)
    participant Modem as Modem

    App->>SM: sendDatagram(SMS, datagram, pointingUI, executor, listener)
    SM->>PIM: ITelephony.sendDatagram(type, datagram, pointingUI, callback)
    PIM->>SC: sendDatagram(type, datagram, pointingUI, callback)
    SC->>SC: 检查modem状态(DATAGRAM_TRANSFERRING?)
    SC->>HAL: ISatelliteService.sendDatagram()
    HAL->>Modem: RIL/HAL命令
    Modem->>Modem: 卫星随机接入+帧发送
    
    alt 发送成功
        Modem-->>HAL: 成功回调
        HAL-->>SC: onDatagramSendResult(SUCCESS)
        SC-->>PIM: callback.accept(SATELLITE_RESULT_SUCCESS)
        PIM-->>SM: IIntegerConsumer.accept(0)
        SM-->>App: resultListener.accept(SUCCESS)
    else 发送失败需重试
        Modem-->>HAL: 失败/超时
        HAL-->>SC: onDatagramSendResult(RETRYING)
        SC->>SC: 状态→DATAGRAM_RETRYING
        SC->>HAL: 自动重试sendDatagram
    else 发送失败
        Modem-->>HAL: 错误
        HAL-->>SC: onDatagramSendResult(ERROR)
        SC-->>PIM: callback.accept(SATELLITE_RESULT_NETWORK_TIMEOUT等)
        PIM-->>SM: IIntegerConsumer.accept(错误码)
        SM-->>App: resultListener.accept(错误码)
    end

三、短信接收流程

分步骤

步骤层级动作关键类/方法
1Modem层卫星Modem收到下行数据帧,解析出datagramModem firmware
2HAL层Modem通过unsolicited event上报到SatelliteService HALISatelliteService.onSatelliteDatagramReceived()
3控制层SatelliteController 收到datagram回调,通过 ISatelliteDatagramCallback.onSatelliteDatagramReceived(datagramId, datagram, pendingCount, ack) 上报SatelliteController
4Telephony层PhoneInterfaceManager 将回调转发给注册的 ISatelliteDatagramCallbackPhoneInterfaceManager.java:12969
5API层SatelliteManager 内部回调触发 SatelliteDatagramCallback.onSatelliteDatagramReceived(datagramId, datagram, pendingCount, ack)SatelliteDatagramCallback.java
6应用层短信App解码 SatelliteDatagram 中的byte[]为短信内容并显示短信App
7ACKApp调用 ackCallback.accept(null) 确认接收,若5分钟内未确认,Telephony会重发SatelliteDatagramCallback.java:42

主动拉取模式(存储转发)

当终端重新捕获卫星信号时,App需主动拉取待接收消息:

步骤动作关键方法
1App调用 SatelliteManager.pollPendingDatagrams(executor, resultListener)SatelliteManager.java:2232
2PhoneInterfaceManagerSatelliteController.pollPendingDatagrams()PhoneInterfaceManager.java:13011
3Modem检查是否有待下发datagram,有则通过 onSatelliteDatagramReceived 回调-
4也可发送 DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS 类型datagram触发网络下发SatelliteManager.java:1523

时序图(Mermaid)

sequenceDiagram
    participant Modem as Modem
    participant HAL as SatelliteService(HAL)
    participant SC as SatelliteController
    participant PIM as PhoneInterfaceManager
    participant SM as SatelliteManager
    participant App as 短信App

    Note over Modem,App: 即时下发模式
    Modem->>HAL: 卫星数据帧→datagram
    HAL->>SC: onSatelliteDatagramReceived(datagramId, datagram, pendingCount)
    SC->>PIM: ISatelliteDatagramCallback.onSatelliteDatagramReceived()
    PIM->>SM: 回调转发
    SM->>App: SatelliteDatagramCallback.onSatelliteDatagramReceived(id, datagram, pendingCount, ack)
    App->>App: 解码datagram显示短信
    App->>SM: ack.accept(null) [5分钟内必须确认]
    SM->>PIM: IVoidConsumer.accept()
    PIM->>SC: 确认接收
    SC->>HAL: 确认接收

    Note over Modem,App: 主动拉取模式(存储转发)
    App->>SM: pollPendingDatagrams(executor, listener)
    SM->>PIM: ITelephony.pollPendingDatagrams(callback)
    PIM->>SC: pollPendingDatagrams(callback)
    SC->>HAL: 请求检查pending datagrams
    HAL->>Modem: 查询
    Modem-->>HAL: 返回pending datagrams
    HAL->>SC: onSatelliteDatagramReceived()
    SC->>PIM: 回调
    PIM->>SM: 回调
    SM->>App: onSatelliteDatagramReceived()

四、卫星短信特有机制

1. 长延迟与重试

机制说明
SATELLITE_MODEM_STATE_DATAGRAM_RETRYINGModem状态=3,表示datagram正在重试发送
SATELLITE_RESULT_NETWORK_TIMEOUT (17)网络超时错误码,卫星链路特有的超时
SATELLITE_RESULT_MODEM_TIMEOUT (24)Modem超时错误码
SATELLITE_RESULT_NOT_REACHABLE (18)卫星不可达错误码
5分钟ACK超时接收方若5分钟内未调用 ack.accept(),Telephony会重发datagram

2. 受限消息长度

机制说明
SatelliteCapabilities.getMaxBytesPerOutgoingDatagram()Modem上报的每条datagram最大字节数
DATAGRAM_TYPE_SMS (6)专门标识短信类型的datagram
客户端分段超长短信由App自行分段为多个datagram发送(非框架层分片)

3. 紧急短信优先级

Datagram类型说明
DATAGRAM_TYPE_SOS_MESSAGE1SOS紧急消息,最高优先级
DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP4最后一条SOS,仍需帮助
DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED5最后一条SOS,不再需要帮助
DATAGRAM_TYPE_SMS6普通短信
DATAGRAM_TYPE_KEEP_ALIVE3保活/检查入站消息

4. 卫星波束切换

机制说明
SatelliteAccessController监控区域变化(国家代码变更、位置设置变更),触发重新评估卫星通信允许状态
EVENT_COUNTRY_CODE_CHANGED国家代码变更事件,可能触发卫星区域切换
updateSystemSelectionChannels()向Modem更新系统选择通道(波束/频点信息)
SatelliteRegionalConfig每个区域配置包含earfcn列表,切换区域时更新

5. 卫星Modem状态机

状态说明
SATELLITE_MODEM_STATE_IDLE0空闲
SATELLITE_MODEM_STATE_LISTENING1正在监听卫星信号
SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING2正在传输datagram
SATELLITE_MODEM_STATE_DATAGRAM_RETRYING3datagram传输重试中
SATELLITE_MODEM_STATE_OFF4卫星关闭
SATELLITE_MODEM_STATE_UNAVAILABLE5卫星不可用
SATELLITE_MODEM_STATE_NOT_CONNECTED6未连接卫星
SATELLITE_MODEM_STATE_CONNECTED7已连接卫星
SATELLITE_MODEM_STATE_ENABLING_SATELLITE8正在启用卫星
SATELLITE_MODEM_STATE_DISABLING_SATELLITE9正在禁用卫星

五、与地面 SMS 的对比

对比维度地面 SMS卫星 SMS (Android 16)
API入口SmsManager.sendTextMessage()SatelliteManager.sendDatagram(DATAGRAM_TYPE_SMS)
协议栈3GPP TS 23.040/24.011, SMS over NAS/PP卫星私有协议,datagram封装(byte[])
分发器GsmSmsDispatcher / CdmaSmsDispatcherSatelliteControllerISatelliteService
RIL命令RIL_REQUEST_SEND_SMSISatelliteService.sendDatagram() (HAL)
消息格式3GPP TPDU (160字符/段)SatelliteDatagram (byte[], 长度由 maxBytesPerOutgoingDatagram 限制)
典型时延1~5秒数秒~数分钟
接收方式RIL_UNSOL_RESPONSE_NEW_SMSSMS_RECEIVED_ACTION 广播SatelliteDatagramCallback.onSatelliteDatagramReceived() 回调 + pollPendingDatagrams() 主动拉取
送达报告deliveryIntent (TP-SC-STATUS-REPORT)SATELLITE_RESULT_SUCCESS 回调,无标准送达报告
重试机制SmsDispatcher 内部重试SATELLITE_MODEM_STATE_DATAGRAM_RETRYING,Modem自动重试
长短信框架层自动分片(concat ref)App自行分段为多个datagram
存储转发SMSC存储转发,终端开机后下发pollPendingDatagrams() + DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS
ACK机制CP-ACK + RP-ACK (层2/层3)Consumer<Void> ack 回调(5分钟超时)
用户感知即时发送/接收需对准卫星、高延迟、可能需等待卫星过境
权限SEND_SMS / RECEIVE_SMSSATELLITE_COMMUNICATION (SystemApi)

六、Android 关键代码与配置位置

类/文件路径说明
SatelliteManagerframeworks/base/telephony/java/android/telephony/satellite/SatelliteManager.java卫星通信公共API,含 sendDatagram()pollPendingDatagrams()registerForIncomingDatagram()
SatelliteDatagramframeworks/base/telephony/java/android/telephony/satellite/SatelliteDatagram.javadatagram数据结构(byte[]封装)
SatelliteDatagramCallbackframeworks/base/telephony/java/android/telephony/satellite/SatelliteDatagramCallback.java接收datagram回调接口
SatelliteCapabilitiesframeworks/base/telephony/java/android/telephony/satellite/SatelliteCapabilities.java卫星能力(含 maxBytesPerOutgoingDatagram
SatelliteAccessControllerpackages/services/Telephony/src/com/android/phone/satellite/accesscontrol/SatelliteAccessController.java区域访问控制
PhoneInterfaceManagerpackages/services/Telephony/src/com/android/phone/PhoneInterfaceManager.javaITelephony实现,桥接 SatelliteManagerSatelliteController
SatelliteControllercom.android.internal.telephony.satellite.SatelliteController卫星核心控制器(本代码库中未包含源码)
ISatelliteServiceHIDL/AIDL HAL接口卫星HAL服务接口,与Modem交互

七、调试与测试建议

logcat 标签

Tag说明
SatelliteManagerAPI层日志
SatelliteController控制层日志
SatelliteAccessController区域访问控制日志
SatelliteServiceHAL层日志
PhoneInterfaceManagerITelephony桥接层日志

关键调试命令

# 查看卫星modem状态
adb shell dumpsys phone | grep -A 50 "SatelliteController"

# 查看卫星访问控制状态
adb shell dumpsys phone | grep -A 30 "SatelliteAccessController"

# 查看卫星能力(含maxBytesPerOutgoingDatagram)
adb shell dumpsys phone | grep -i "SatelliteCapabilities"

CTS 测试

测试类说明
CtsSatelliteTest卫星通信CTS测试
setIsSatelliteCommunicationAllowedForCurrentLocationCache()CTS设置允许状态缓存
allow_mock_modempersist.radio.allow_mock_modem 属性控制是否允许mock modem测试

toolName: todo_write

status: success

Todos updated: 5 items

关键发现总结:Android 16 的卫星短信架构与传统 SMS 完全解耦,不经过 SmsDispatcher,而是通过 SatelliteManager.sendDatagram(DATAGRAM_TYPE_SMS) 走独立的 Datagram 通道。SatelliteController(源码不在本代码库中)是核心枢纽,连接 PhoneInterfaceManager 与卫星 HAL 服务。接收侧采用回调 + 主动拉取双模式,并有5分钟ACK超时保障可靠性。