Android 蜂窝数据连接管理系统完整架构

6 阅读8分钟

1. 核心架构层次

┌─────────────────────────────────────────────────────────────────┐
│                     应用层 (Application)                         │
│   - ConnectivityManager.requestNetwork()                        │
│   - NetworkRequest (capability: INTERNET, MMS 等)              │
└────────────────────────┬────────────────────────────────────────┘
                         │ NetworkRequest
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│          ConnectivityService (Framework)                         │
│   - 网络评分和请求匹配                                           │
│   - 选择最优网络提供者                                           │
└────────────────────────┬────────────────────────────────────────┘
                         │ 选定 Telephony
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│      TelephonyNetworkFactory (NetworkFactory)                    │
│   - 处理 Telephony 的网络请求                                   │
│   - 与 DataNetworkController 通信                               │
└────────────────────────┬────────────────────────────────────────┘
                         │ addNetworkRequest()
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│   DataNetworkController (Per-SIM)                               │
│   - 核心数据连接管理器                                           │
│   - 选择合适的 APN/DataProfile                                  │
│   - 管理 DataNetwork 实例                                       │
└────────────────────────┬────────────────────────────────────────┘
                         │ setupDataCall()
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│        DataServiceManager (Modem Interface)                     │
│   - 通过 AIDL 与 DataService 通信                              │
│   - 向 Modem 发送 PDP 建立命令                                  │
└────────────────────────┬────────────────────────────────────────┘
                         │ IDataService.setupDataCall()
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│      CellularDataService (RIL 实现)                             │
│   - DataService 的具体实现                                      │
│   - 调用 RIL 命令                                               │
└────────────────────────┬────────────────────────────────────────┘
                         │ RIL.setupDataCall()
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│      RadioDataProxy (HAL Interface)                             │
│   - 发送 RIL 命令到 Modem HAL                                   │
│   - 1.4/1.5/1.6 版本支持                                        │
└────────────────────────┬────────────────────────────────────────┘
                         │ IRadioData.setupDataCall_1_6()
                         ▼
┌─────────────────────────────────────────────────────────────────┐
│                    Modem 硬件                                   │
│   - PDP 上下文激活                                              │
│   - 链路层连接                                                   │
└─────────────────────────────────────────────────────────────────┘

2. 蜂窝数据连接的完整生命周期

2.1 状态机模型

DataNetwork 的 5 个主要状态:

┌──────────────────────────────────────────────────────────────┐
│                                                              │
│   ┌─────────┐      ┌──────────┐                             │
│   │Connecting├─────►Connected ├─────┐                      │
│   └────┬────┘      └────┬─────┘     │                      │
│        │                │           │                      │
│   ┌────▼─────────┐      │      ┌────▼──────────┐           │
│   │Disconnected ◄┼──────┼──────► Disconnecting │           │
│   └──────────────┘      │      └─────────────────┘          │
│                         │                                    │
│              ┌──────────▼────────────┐                      │
│              │   Handover            │                      │
│              │ (IWLAN ◄─► Cellular) │                      │
│              └───────────────────────┘                      │
│                                                              │
└──────────────────────────────────────────────────────────────┘

状态转移:
- Connecting ➜ Connected: 数据连接成功
- Connecting ➜ Disconnected: 连接失败或被拒绝
- Connected ➜ Handover: IWLAN/Cellular 切换
- Handover ➜ Connected: Handover 成功
- Connected ➜ Disconnecting: 接收到断开请求
- Disconnecting ➜ Disconnected: 实际断开完成
- Any state ➜ Disconnected: 紧急断开(失败、超时等)

2.2 完整流程

┌─────────────────────────────────────────────────────────┐
│ 1️⃣  应用请求                                            │
├─────────────────────────────────────────────────────────┤
│ 应用通过 ConnectivityManager.requestNetwork() 请求网络  │
│                                                         │
│ NetworkRequest request = new NetworkRequest.Builder()  │
│     .addCapability(NET_CAPABILITY_INTERNET)            │
│     .addTransportType(TRANSPORT_CELLULAR)              │
│     .build();                                           │
│ ConnectivityManager.requestNetwork(request, callback)  │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ 2️⃣  ConnectivityService 评分                            │
├─────────────────────────────────────────────────────────┤
│ - 对所有可用网络提供者评分                              │
│ - Telephony score vs WiFi score vs VPN score           │
│ - 选择得分最高的网络                                    │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ 3️⃣  TelephonyNetworkFactory 处理                        │
├─────────────────────────────────────────────────────────┤
│ - 接收到 NetworkRequest                                │
│ - 转发给 DataNetworkController                         │
│ - addNetworkRequest(request)                           │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ 4️⃣  DataNetworkController 分析                         │
├─────────────────────────────────────────────────────────┤
│ - 检查请求的 Capability 类型                           │
│   ├─ NET_CAPABILITY_INTERNET? 需要 Internet APN      │
│   ├─ NET_CAPABILITY_MMS? 需要 MMS APN                │
│   ├─ NET_CAPABILITY_IMS? 需要 IMS APN                │
│   └─ NET_CAPABILITY_XCAP? 需要 XCAP APN             │
│                                                         │
│ - 查询数据库获取所有可用 APN 列表                      │
│   ├─ Carriers 表 (来自 Telephony Provider)          │
│   ├─ 过滤: 合适的网络类型                             │
│   └─ 排序: 优先级、最近使用等                         │
│                                                         │
│ - 找到满足条件的 DataProfile                          │
│   ├─ ApnSetting: 旧式 (2G/3G/4G)                    │
│   └─ TrafficDescriptor: 新式 (5G SA URSP)           │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ 5️⃣  创建 DataNetwork 实例                              │
├─────────────────────────────────────────────────────────┤
│ new DataNetwork(                                         │
│     phone,                    // Phone 对象            │
│     looper,                   // 事件循环               │
│     dataServiceManagers,      // Modem 接口            │
│     dataProfile,              // APN/TrafficDescriptor │
│     networkRequestList,       // 已附加的请求列表      │
│     transport,                // TRANSPORT_WWAN/WLAN   │
│     dataAllowedReason,        // 为什么允许建立        │
│     callback                  // 状态通知回调          │
│ );                                                      │
│                                                         │
│ 进入 Connecting 状态                                   │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ 6️⃣  准备数据参数                                       │
├─────────────────────────────────────────────────────────┤
│ - 确定网络类型 (LTE, 5G NR, IWLAN)                    │
│ - 获取漫游状态                                          │
│ - 是否允许数据漫游                                      │
│ - 获取 PDU Session ID (5G)                            │
│ - 获取 Slice 信息 (5G)                               │
│ - 获取 Traffic Descriptor (5G URSP)                  │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ 7️⃣  DataServiceManager.setupDataCall()                 │
├─────────────────────────────────────────────────────────┤
│ setupDataCall(                                           │
│     accessNetworkType=LTE/NR/IWLAN,                    │
│     dataProfile={apn, protocol, auth, ...},           │
│     isRoaming=true/false,                              │
│     allowRoaming=true/false,                           │
│     reason=NORMAL/HANDOVER,                            │
│     linkProperties=null (or handover data),           │
│     pduSessionId=1-15 (5G) or -1,                     │
│     sliceInfo=null (or 5G slice),                     │
│     trafficDescriptor=null (or URSP info),           │
│     matchAllRuleAllowed=true/false                    │
│ );                                                      │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ 8️⃣  CellularDataService.setupDataCall()                │
├─────────────────────────────────────────────────────────┤
│ - 从 DataService 转调到 RIL                           │
│ - mPhone.mCi.setupDataCall(                           │
│     accessNetworkType,                                 │
│     dataProfile,                                       │
│     allowRoaming,                                      │
│     reason,                                            │
│     linkProperties,                                    │
│     pduSessionId,                                      │
│     sliceInfo,                                         │
│     trafficDescriptor,                                 │
│     matchAllRuleAllowed                               │
│   );                                                    │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ 9️⃣  RadioDataProxy.setupDataCall()                     │
├─────────────────────────────────────────────────────────┤
│ 选择 HAL 版本并调用:                                   │
│ - HAL 1.6+: setupDataCall_1_6()                       │
│   ├─ TrafficDescriptor 支持 (5G URSP)                │
│   └─ Optional<SliceInfo> 支持                         │
│                                                         │
│ - HAL 1.5: setupDataCall_1_5()                        │
│   ├─ PDU Session ID 支持                              │
│   └─ Link Properties 支持                             │
│                                                         │
│ - HAL 1.4: setupDataCall_1_4()                        │
│   └─ 基础 PDP 建立                                    │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ 🔟  Modem 硬件处理                                     │
├─────────────────────────────────────────────────────────┤
│ Modem 执行:                                             │
│ 1. 检查 Access Point (APN, TrafficDescriptor)         │
│ 2. 选择合适的 QoS (Quality of Service)                │
│ 3. 发送 NAS 信息给网络                                │
│ 4. 等待 NAS Accept (包含 PDP Context, IP, DNS 等)    │
│ 5. 分配 CID (Context ID) 标识此连接                   │
│ 6. 激活无线链路层                                      │
└──────────────┬──────────────────────────────────────────┘
               │
┌──────────────▼──────────────────────────────────────────┐
│ ⑪  数据响应处理                                       │
├─────────────────────────────────────────────────────────┤
│ DataCallResponse 包含:                                 │
│ - resultCode: 成功/失败                               │
│ - cid: Context ID                                      │
│ - failCause: 失败原因 (if failed)                     │
│ - addresses: 分配的 IP 地址 (IPv4 或 IPv6)          │
│ - dnses: DNS 服务器列表                               │
│ - gateways: 网关地址                                  │
│ - pcscfAddresses: P-CSCF (IMS)                       │
│ - mtu: 最大传输单元                                   │
│ - defaultQos: 默认 QoS 参数                          │
│ - sliceInfo: 分配的网络切片 (5G)                     │
│ - pduSessionId: PDU 会话 ID (5G)                     │
│ - handoverFailureMode: Handover 失败模式             │
│ - trafficDescriptors: 流量描述符列表 (5G)           │
└──────────────┬──────────────────────────────────────────┘
               │ 成功?
        ┌──────┴──────┐
        │ YES   │ NO  │
        ▼       ▼     ▼

3. DataProfile (数据配置文件)

3.1 DataProfile 的构成

// DataProfile 包含:

public class DataProfile {
    // 1. APN 配置 (ApnSetting) - 针对 4G/LTE 及以下
    private ApnSetting mApnSetting;
        ├─ apnName: "internet.xyz.com"
        ├─ apnTypeBitmask: TYPE_DEFAULT (for Internet)
        ├─ protocol: PROTOCOL_IPV4V6
        ├─ roamingProtocol: PROTOCOL_IP
        ├─ authType: AUTH_TYPE_PAP/CHAP
        ├─ user: "username" (if needed)
        ├─ password: "password" (if needed)
        ├─ mtuV4: 1500
        ├─ mtuV6: 1500
        ├─ maxConns: 10
        ├─ maxConnsTime: 0
        ├─ waitTime: 0
        └─ enabled: true
    
    // 2. Traffic Descriptor - 针对 5G SA (URSP)
    private TrafficDescriptor mTrafficDescriptor;
        ├─ dataNetworkName: "ims" / "internet" (DNN)
        └─ osAppId: byte[] (Operating System App ID)
    
    // 3. 元数据
    private int mType; // TYPE_COMMON, TYPE_3GPP, TYPE_3GPP2
    private boolean mPreferred; // 最近使用过
}

3.2 APN 类型与用途

TYPE_DEFAULT (0x1)
├─ 用途: 普通 Internet 数据
├─ APN: "internet" / "4gnet" / "wap" 等
└─ 优先级: 最高 (用于一般数据)

TYPE_MMS (0x2)
├─ 用途: 彩信 (Multimedia Message Service)
├─ APN: "mms" / "mms.xyz.com"
└─ 特点: 需要临时激活 (DSDS 设备)

TYPE_SUPL (0x4)
├─ 用途: 定位辅助 (SUPL - Secure User Plane Location)
├─ APN: "supl" / "sprintpcs"
└─ 用于: GPS 辅助定位 (A-GPS)

TYPE_DUN (0x8)
├─ 用途: 数据拨号 (Dial-Up Network)
├─ 说明: 旧式功能,现在很少用

TYPE_IMS (0x10)
├─ 用途: IP Multimedia Subsystem (VoLTE/VoWiFi)
├─ APN: "ims" / "ims.xyz.com"
└─ 优先级: 高 (语音通话通过 IMS)

TYPE_CBS (0x20)
├─ 用途: Cell Broadcast Service (公共警报)
├─ 说明: 系统级功能

TYPE_IA (0x40)
├─ 用途: 初始附着 (Initial Attach)
├─ 说明: 设备开机时首次附着

TYPE_XCAP (0x200)
├─ 用途: XML Configuration Access Protocol
├─ 用于: 增强型通话功能配置

TYPE_FOTA (0x100)
├─ 用途: Firmware Over The Air 更新
├─ 说明: 设备固件更新

4. 数据连接状态通知

// 应用层监听数据连接状态

public interface TelephonyCallback {
    public interface DataConnectionStateListener {
        void onDataConnectionStateChanged(
            @DataState int state,    // DISCONNECTED/CONNECTING/CONNECTED/SUSPENDED/HANDOVER
            @NetworkType int networkType  // NETWORK_TYPE_LTE/NR/...
        );
    }
}

// 状态常量
@DataState int state:
├─ DATA_DISCONNECTED = 0
├─ DATA_CONNECTING = 1
├─ DATA_CONNECTED = 2
├─ DATA_SUSPENDED = 3
├─ DATA_HANDOVER_IN_PROGRESS = 4
└─ DATA_UNKNOWN = -1

// 网络类型
@NetworkType int:
├─ NETWORK_TYPE_GPRS = 1
├─ NETWORK_TYPE_EDGE = 2
├─ NETWORK_TYPE_UMTS = 3
├─ NETWORK_TYPE_CDMA = 4
├─ NETWORK_TYPE_EVDO_0 = 5
├─ NETWORK_TYPE_LTE = 13
├─ NETWORK_TYPE_NR = 20 (5G SA)
├─ NETWORK_TYPE_IWLAN = 18
└─ ... 更多类型

5. PDP 上下文和 CID

PDP (Packet Data Protocol) 上下文 = 一个数据连接会话

PDP 上下文的关键参数:

┌──────────────────────────────┐
│  CID (Context ID)            │ 标识符 (1-11 通常)
│  Access Point (APN)          │ internet/mms/imsPDN Type (PDP Type)         │ IPv4/IPv6/IPv4v6QoS (Quality of Service)    │ 优先级、速率限制
│  PDU Session ID5G 特定 (1-15)
│  UE IP Address               │ 设备 IP (v4 或 v6)
│  GGSN/PGW Address            │ 网关地址
│  DNS ServersDNS1, DNS2MTU (Maximum Transmission)  │ 最大包大小 (通常 1500)
│  P-CSCF AddressIMS 相关
│  Slice Info (S-NSSAI)        │ 5G 网络切片
└──────────────────────────────┘

实际建立过程:

LTE 网络:
User Equipment          Network
    │                      │
    ├─ ATTACH REQUEST ──────►│
    │                       │
    │◄─ ATTACH ACCEPT ──────┤ (包含 PDP Context)
    │                       │
    ├─ ACTIVATE PDP CONTEXT ┤
    │   REQUEST ───────────►│
    │                       │
    │◄─ ACTIVATE PDP CONTEXT┤ (CID=1, IP: 10.0.0.1, DNS)
    │   ACCEPT ─────────────┤
    │                       │
    └ Data Bearer 建立 ────►│

5G NR:
User Equipment          Network (5GC)
    │                      │
    ├─ REGISTRATION REQUEST┤
    │ ────────────────────►│
    │                       │
    │◄─ REGISTRATION ACCEPT┤ (包含 GUTI)
    │ ────────────────────┤
    │                       │
    ├─ PDU SESSION ESTABLISHREQUEST (DNN: internet)
    │ ────────────────────►│
    │                       │
    │◄─ PDU SESSION ESTABLISHACCEPT ─────────────┤ (PSI=1, IP: 10.0.0.2)
    │                       │
    └ Data Bearer 建立 ────►│

6. 数据连接失败和重试

// 失败原因 (DataFailCause)

public enum DataFailCause {
    // 成功状态
    NONE,
    
    // 网络拒绝
    OPERATOR_BARRED,              // 运营商禁止
    INSUFFICIENT_RESOURCES,       // 资源不足
    MISSING_UNKNOWN_APN,         // APN 不存在
    UNKNOWN_PDP_ADDRESS_TYPE,    // 地址类型错误
    USER_AUTHENTICATION_FAILED,  // 用户认证失败
    ACTIVATION_REJECT_GGSN,      // 网关拒绝
    SERVICE_OPTION_NOT_SUPPORTED,// 服务不支持
    
    // 本地错误
    NO_RETRY_FAILURE,            // 不重试的失败
    RADIO_OFF,                   // 飞行模式
    ROAMING_NOT_ALLOWED,         // 漫游禁用
    HANDOVER_FAILURE,            // Handover 失败
    PERM_FAILURE,                // 永久失败
    
    // 网络问题
    SIGNAL_LOST,                 // 信号丢失
    PREEEMPTED,                  // 被抢占
    CONGESTION,                  // 网络拥塞
    
    // 超时
    TIMED_OUT,                   // 超时
    
    // 5G 特定
    SLICE_REJECTED,              // 网络切片被拒
    MATCH_ALL_RULE_NOT_ALLOWED,  // URSP 规则不匹配
}

// 重试策略

dataSetupRetryEntry = new DataRetryEntry() {
    int failCause;           // 失败原因
    int state;               // FAILED, SUCCEEDED, CANCELLED
    long retryDelayMillis;   // 重试延迟
    int retryCount;          // 已重试次数
}

// 重试逻辑
if (failCause == RADIO_OFF || failCause == ROAMING_NOT_ALLOWED) {
    // 不重试,等待用户操作
    return NO_RETRY;
} else if (failCause == INSUFFICIENT_RESOURCES) {
    // 指数退避重试: 3s, 6s, 12s, ...
    retryDelayMillis = calculateBackoffDelay(retryCount);
} else if (failCause == TIMED_OUT) {
    // 立即重试 (最多 N 次)
    retryDelayMillis = 0;
} else {
    // 根据 CarrierConfig 规则
    retryDelayMillis = getRetryDelayFromConfig(failCause);
}

7. 多卡(DSDS)下的数据连接

DSDS 设备上的复杂性:

┌─ SIM1 (DDS - Default Data Subscription)
  ├─ DataNetworkController1
  ├─ Modem1 允许 PS 附着
  ├─ 可以建立:
    ├─ Internet APN (DDS 优先)
    ├─ IMS APN
    └─ SUPL APN
  └─ 其他请求: 允许建立

└─ SIM2 (NIDS - Non-Default Data Subscription)
   ├─ DataNetworkController2
   ├─ Modem2 PS 附着受限 (DSDS)
     └─ 仅当 Modem1  PS 时才激活
   ├─ 可以建立:
     ├─ MMS (临时激活 Modem2)
     └─ 其他 (需检查是否需要激活)
   └─ Internet 数据: 通常不允许 (除非 DDS 切换)

MMS  DSDS 上的特殊处理:

MMS 请求来到:
    
ConnectivityService 选择最佳网络
    
如果是 SIM2  MMS:
    ├─ PhoneSwitcher 激活 Modem2: setDataAllowed(1)
    ├─ MMS APN  Modem2 上建立
    ├─ MMS 发送完成
    └─ PhoneSwitcher 停用 Modem2: setDataAllowed(0)

8. 数据连接的关键 API 和事件

// Framework 级别的关键接口

// 1. DataNetworkController 回调
public interface DataNetworkCallback {
    void onConnected(DataNetwork dataNetwork);
    void onAttachFailed(DataNetwork dataNetwork, NetworkRequestList requestList);
    void onDisconnected(DataNetwork dataNetwork, int cause, int tearDownReason);
    void onValidationStatusChanged(DataNetwork dataNetwork, int status, Uri redirectUri);
    void onSuspendedStateChanged(DataNetwork dataNetwork, boolean suspended);
    void onHandoverSucceeded(DataNetwork dataNetwork);
}

// 2. DataServiceCallback (来自 Modem)
public interface DataServiceCallback {
    void onSetupDataCallComplete(int resultCode, DataCallResponse response);
    void onDeactivateDataCallComplete(int resultCode);
    void onDataCallListChanged(List<DataCallResponse> dataCallList);
    void onStartHandoverComplete(int resultCode);
}

// 3. 应用级别的监听
TelephonyManager.registerTelephonyCallback(executor, callback);
    ├─ callback.onDataConnectionStateChanged(state, networkType)
    ├─ callback.onPreciseDataConnectionStateChanged(pdcs)
    └─ callback.onDataActivity(dataActivity)  // 数据流量活动

// 4. 应用级别的控制
// 启用/禁用移动数据
TelephonyManager.setDataEnabled(true);

// 设置漫游数据
TelephonyManager.setDataRoamingEnabled(true);

// 启用/禁用特定 APN
setCarrierDataEnabled(true); // 所有 APN

9. 数据连接的性能指标

关键性能指标:

1. 连接建立时间
   ├─ Framework -> Modem: 50-100ms
   ├─ Modem -> Network: 200-1000ms (4G)
   ├─ 总计: 250-1100ms (通常)
   └─ 优化: 预连接 (Pre-attach)

2. 断开延迟
   ├─ 优雅关闭: 100-300ms
   ├─ 强制关闭: 50-100ms
   └─ Handover 时: 尽可能快 (< 200ms)

3. 数据速率
   ├─ 4G (LTE): 50-300 Mbps
   ├─ 5G (NSA): 200-500 Mbps
   ├─ 5G (SA): 300-1000+ Mbps
   └─ WiFi: 50-600 Mbps

4. 功耗
   ├─ RRC Connected: ~100-200 mA (传输中)
   ├─ RRC Idle: ~5-20 mA (待机)
   └─ 5G: 相对更高 (Modem 功耗)

总结:蜂窝数据连接管理的核心要点

┌────────────────────────────────────────────────────────┐
 1. 分层架构                                            
    - 应用  Framework  Telephony  Modem             
    - 每层有明确的职责和接口                            
                                                        
 2. 状态机驱动                                          
    - DataNetwork: Connecting  Connected  ...        
    - 明确的状态转移和事件处理                          
                                                        
 3. 多重匹配                                            
    - NetworkRequest  DataProfile 匹配              
    - 根据 Capability 选择合适 APN                    
                                                        
 4. 异步处理                                            
    - 所有操作都是异步的(Callback)                   
    - Handler 消息队列驱动                             
                                                        
 5. 错误处理与重试                                      
    - 24 种以上失败原因分类                            
    - 智能重试策略(指数退避、延迟等)                
                                                        
 6. 多维度支持                                          
    - 4G/LTE  PDP Context                           
    - 5G  PDU Session                               
    - IWLAN Handover 支持                             
    - DSDS 多卡管理                                    
                                                        
 7. QoS  SLA                                        
    - 优先级队列                                        
    - 带宽管理                                          
    - 网络切片(5G)                                   
└────────────────────────────────────────────────────────┘

这就是 Android 蜂窝数据连接管理的完整系统!它是一个复杂但设计精良的系统,确保了在各种场景下的稳定数据连接。