使用多个 PDP 上下文开发应用

数据包数据协议 (PDP) 上下文提供数据包数据连接,设备和移动网络可通过该连接交换 IP 数据包。 根据 3GPP 标准,设备一次可以激活多个 PDP 上下文。 在 Windows 8.1 和 Windows 10 中,支持多个 PDP 上下文,并使应用能够通过特殊 PDP 上下文与移动网络以及 Windows 8 中支持的 Internet PDP 上下文进行通信。 可以使用此功能在 Windows 上创建差异化体验和创新服务。 你还可以与应用开发人员合作,为其客户开发高质量的 VOIP 和视频流式处理体验。

下图显示了多个 PDP 上下文在Windows 8.1和Windows 10中的工作原理:

显示多个 PDP 上下文如何在Windows 8.1和Windows 10中工作的关系图。

使用本主题中的以下部分详细了解多个 PDP 上下文:

关键方案

可以使用多个 PDP 上下文来启用高级服务。

  • 差异化计费 - 可以使用多个 PDP 上下文来改变数据或计费限制。 例如,Contoso 是为其客户开发数据备份应用的移动运营商。 作为移动运营商,Contoso 可以创建多个 PDP 上下文,并允许高级订阅者免费使用该应用。 所有其他订阅者单独付费才能使用它。

  • 丰富通信服务 - GSM 协会创建的一项全球计划,旨在提供丰富的通信服务,例如增强的电话簿、增强的消息传送和扩充呼叫。 丰富通信服务提供跨移动运营商的互操作性,并提供使用现有资产和功能提供高质量和创新的通信服务的新方法。

  • 赞助连接 - 这允许用户访问特定类型的内容,而不会违反其每月的数据使用情况。 内容提供商通过直接向移动运营商付款、进行收入共享交易或其他一些业务安排来安排补偿移动运营商。

  • 个人热点 - 当连接用作个人热点时,某些移动运营商收取不同的费率。 可以使用多个 PDP 上下文来区分这两者。

移动宽带应用

UWP 移动宽带应用可以利用多个 PDP 上下文来激活特殊的 PDP 上下文,并指定用于路由数据流量的规则。 这些应用可以为特定目标或所有数据流量创建规则。

当移动宽带应用需要与网络交换数据时,它会检查可用和连接的网络。 如果移动宽带应用针对这些网络中的任何一个都有特殊规则,则它使用 连接管理器 API 打开一个特殊的 PDP 上下文。 如果此连接成功,PDP 上下文会为此连接提供路由规则,并使用网络 API 传输数据。 如果移动宽带应用收到 NetworkStatusChanged 事件,则应该重复此操作,以查看是否有任何连接已更改,以及是否需要为新连接打开 PDP 上下文。

说明移动宽带应用检查可用和连接的网络的流程图。

网络 API

若要使用特殊的 PDP 上下文发送数据,Microsoft Store 应用必须基于用于传输数据的网络 API 使用不同的逻辑。

基于 HTTP 的 API

基于 HTTP 的 API(如 XMLHTTPRequestIXHR2Windows.Web.SyndicationWindows.Web.AtomPub)以及基于 Windows HTTP 协议的 API(如 JQuery 和 Windows.Web.Http)无法绑定到特定接口。 对于这些 API,Windows 使用策略处理将数据路由到特殊 PDP 上下文。 激活特殊 PDP 上下文后,应用可以根据目标和特殊 PDP 上下文指定路由规则。 目标可以是域名或 IP 地址,例如 video.fabrikam.com、.contoso.com 或 123.23.34.333。 指定路由规则后,如果应用使用上述任一 HTTP API 来传输数据,Windows 将根据路由规则将数据发送到特殊的 PDP 上下文。 应用完成数据传输后,应断开特殊 PDP 上下文的连接,并删除路由策略。

注意

后台传输 APIHTTP 客户端 (C#) API 无法使用路由策略。

演示使用基于 HTTP 的 API 通过特殊 PDP 上下文发送数据的过程的示意图。

基于套接字的 API

Windows.Networking.Sockets 命名空间中可用的基于套接字的 API(例如 TCP、UDP 和流套接字)提供了绑定到特定接口的机制。 当应用使用套接字 API 时,它应绑定到特定接口,以便将数据路由到特殊的 PDP 上下文。 激活特殊 PDP 上下文后, AcquireConnectionAsync API 会向应用提供接口信息。 它可以使用此信息绑定到特定接口并开始传输数据。

描述使用基于套接字的 API 通过特殊 PDP 上下文发送数据的过程的示意图。

多个 PDP 内容 API 信息

Windows 8.1和Windows 10添加了以下 API 以支持多个 PDP 上下文:

  • CellularApnContext 此类包含用于指定网络上的接入点的属性。 通过 AcquireConnectionAsync 调用传递 CellularApnContext 对象,以建立与特定接入点的连接。

  • ConnectivityManager::AcquireConnectionAsync 此 API 为指定的接入点名称 (接入点) 或 PDP 上下文激活新连接。 此异步方法允许应用使用适当的配置信息请求与特定 APN 或 PDP 上下文的连接。 激活特殊 APN 后,它显示为 Windows 和应用的新虚拟接口。

  • ConnectivityManager::AddHttpRoutePolicy 此方法添加 HTTP 堆栈流量用于将数据路由到特殊 PDP 上下文的策略。 应用可以根据目标指定策略,例如域名和 IP 地址,以及特殊的 PDP 上下文配置文件。 应用创建策略后,Windows HTTP 堆栈使用该策略将数据路由到特殊的 PDP 上下文。

  • ConnectivityManager::RemoveHttpRoutePolicy 此方法删除以前添加的 HTTP 路由策略。

以下代码演示如何使用这些 API 进行基于 HTTP 的数据传输:

var connectivity = Windows.Networking.Connectivity;
var currentRoutePolicy = null;
var currentConnectionSession = null;

//  Create PDP context/APN data
var apnContext                      =   new connectivity.CellularApnContext();
apnContext.accessName               =   "myAPN.com";
apnContext.userName                 =   "APNusername"
apnContext.password                 =   "[PLACEHOLDER]";
apnContext.isCompressionEnabled     =   false;
apnContext.authenticationType       =   connectivity.CellularApnAuthenticationType.none;

//  Request a connection to Windows
connectivity.ConnectivityManager.acquireConnectionAsync(apnContext).done(onConnectionSucceeded, onConnectionFailed);


//  On successful Activation of APN, Windows returns a ConnectionSession object that encapsulates the new connection profile

function onConnectionSucceeded(result
{
    // keep the connectionSession in scope
    currentConnectionSession= result;

    //  create a route policy for the new connection
    currentRoutePolicy = new connectivity.routePolicy(currentConnectionSession.ConnectionProfile, new hostName("video.mydomain.com"),Windows.Networking.DomainNameType.suffix);

    //  indicate the new route policy to the Http stack
    connectivity.connectivityManager.addHttpRoutePolicy(currentRoutePolicy);

    // Backend data interaction with appropriate HTTP APIs (IXHR, Open IFrame etc.)


    // After completing the data transfer remove the Route Policy
    connectivity.connectivityManager.removeHttpRoutePolicy(currentRoutePolicy);
    currentRoutePolicy = null;

    // Disconnect the PDP Context to free up resources
    currentConnectionSession.close();
}

以下代码演示如何使用这些 API 进行基于套接字的数据传输:

// Connect to Special PDP Context
var connectivity = Windows.Networking.Connectivity;
var currentRoutePolicy = null;
var currentConnectionSession = null;

// Create PDP Context/APN Data
var apnContext = new connectivity.CellularApnContext();

// Create PDP context/APN data
var apnContext = new connectivity.CellularApnContext();
apnContext.accessName = "myAPN.com";
apnContext.userName = "APNusername"
apnContext.password = "[PLACEHOLDER]";
apnContext.isCompressionEnabled = false;
apnContext.authenticationType = connectivity.CellularApnAuthenticationType.none;

// Request the connection to Windows
connectivity.ConnectivityManager.acquireConnectionAsync(apnContext).done(onConnectionSucceeded, onConnectionFailed);

// On successful activation of an APN, Windows returns a ConnectionSession object that encapsulates the new connection profile
                function onConnectionSucceeded(result) {

// keep the connectionSession in scope
currentConnectionSession = result;

var socket = new Windows.Networking.Sockets.StreamSocket();
var hostName = new Windows.Networking.HostName("www.contoso.com");
var portNumber = "1234";

// Bind the socket to new Special PDP Context Connection
socket.connectAsync(hostName, portNumber, SocketProtectionLevel.PlainSocket, currentConnectionSession.connectionProfile.networkAdapter).done(onSocketConnectionSucceeded, onSocketConnectionFailed);

function onSocketConnectionSucceeded(result)
{
    // Start transferring data using socket APIs

}

// Closing the sockets
socket.close();

// Disconnect the PDP Context to free up resources
currentConnectionSession.close();

应用必须处理 NetworkStatusChanged 事件才能处理特殊 PDP 上下文连接上的任何网络转换。

场景:高级移动宽带应用使用特殊接入点提供免费数据访问

在此方案中,移动宽带应用使用特殊 PDP 上下文提供免费数据访问。 如果应用是免费的,则使用连接的网络(例如 Wi-Fi 网络),或者如果连接到特定的运营商网络,则使用特殊的接入点。 以下示例代码演示在没有连接免费网络的情况下,应用如何使用多个 PDP 上下文 API 在特殊 PDP 上下文上传输数据。

// Reference the namespace
var connectivity = Windows.Networking.Connectivity;

// Current route policy
var currentRoutePolicy = null;
var currentConnectionSession = null;

function onLoad()
{
  // Register for network status change
  connectivity.networkInformation.addEventListener("networkstatuschanged", OnNetworkStatusChange);
  // Process the current status
  handleNetworkChange();
}

//  Handle newtork status changes
function onNetworkStatusChange()
{
  HandleNetworkChange();
}

// On network status change:
//  if there is no connectionPolicy, evaluate a new one
//  if there is a current connectionPolicy ==> verify it is still valid
//      evaluate a new one if the current connectionPolicy is not valid
function handleNetworkChange()
{
  if (isCurrentPolicyStillValid())
  {
    //the current policy is still valid.
    return;
  }

  //  No policy or current policy is not good anymore
  //  cleanup any previous configuration
  if (currentRoutePolicy)
  {
    connectivity.ConnectivityManager.removeHttpRoutePolicy(currentRoutePolicy);
    currentRoutePolicy = null;
  }

  //  if a different APN was connected, disconnect it to free up resources
  if (connectionConnectionSession != null)
  {
    connectionConnectionSession.close();
    connectionConnectionSession = null;
  }

  // evaluate connection policy
  startEvaluateConnectionPolicy();
}

//  evaluate if the current connectionPolicy is still valid
function isCurrentPolicyStillValid()
{
  if (null != currentRoutePolicy)
  {
    // a policy is currently in place, let's verify if it is still valid
    var currentProfile = currentRoutePolicy.connectionProfile();
    if (NetworkConnectivityLevel.none != currentProfile.GetNetworkConnectivityLevel())
    {
      // current policy is still good. bail out
      return true;
    }
  }
  return false;
}

// starts the evaluation of a new connection policy
function startEvaluateConnectionPolicy()
{
  // first try to get a free network if it is available
  var queryFilter = new connectivity.connectionProfileFilter();
  queryFilter.networkCostType = connectivity.networkCostType.unrestricted;
  queryFilter.isConnected = true;

  connectivity.networkInformation.findConnectionProfilesAsync(queryFilter).done(onSuccess, onFailure);
}

//  Succesfully retrieved at least one free connection profile
function onSuccess(results)
{
  if(results.count > 0)
  {
  //  Enfore the route to the http stack
  enforceHttpRoutePolicy(results[0]);

  // Backend data interaction with appropriate APIs(Open IFrame etc.)

  }
  else
  {
    onFailure();
  }
}

//  there are no free networks available at this time
function onFailure()
{
  //  create a request to connect a specific APN on the network
  // no free network available, connect
  var apnContext                      =   new connectivity.CellularApnContext();
  apnContext.accessPointName          =   "myAPN.com";
  apnContext.userName                 =   "APNusername"
  apnContext.password                 =   "[PLACEHOLDER]";
  apnContext.isCompressionEnabled     =   false;
  apnContext.authenticationType       =   connectivity.CellularApnAuthenticationType.none;

  //
  //  request the connection to Windows
  connectivity.connectivityManager.acquireConnectionAsync(apnContext).done(onConnectionSucceeded, onConnectionFailed);
}

//  on success Windows returns a ConnectionSession object that encapsulates the new connection profile
function onConnectionSucceeded(result)
{
  // keep the connectionSession in scope
  currentConnectionSession= result;
  //  create a route policy for the new connection
  enforceHttpRoutePolicy(currentConnectionSession.ConnectionProfile,new hostName("video.mydomain.com"),Windows.Networking.DomainNameType.suffix);

  // Backend data interaction with appropriate APIs(Open IFrame etc.)

}

//  Windows was not able to connect the specified APN
function onConnectionFailed()
{
  // display error message and just wait for Network Status Change event to try again
}

//  utility function to enforce a route policy
function enforceHttpRoutePolicy(connectionProfile,targetSuffix)
{
  //  Keep the route request global so we can close it later
  currentRoutePolicy= new connectivity.routePolicy(connectionProfile, targetSuffix);
  //  Indicate the new route policy to the Http stack
  connectivity.connectivityManager.addHttpRoutePolicy(currentRoutePolicy);
}

//  cleanup on shutdown
function onShutdown()
{
  //  Remove the route policy from HttpStack
  connectivity.connectivityManager.removeHttpRoutePolicy(currentRoutePolicy);
  currentRoutePolicy = null;

  //  If a different APN was connected, disconnect it to free up resources
  if(currentConnectionSession!= null)
  {
    currentConnectionSession.close();
  }
}

场景:移动宽带应用需要特殊的 PDP 上下文来购买和预配订阅

在此方案中,移动宽带应用需要一个特殊的 PDP 上下文来购买和预配订阅。 无论连接的网络如何,此应用都将激活特殊的 PDP 上下文。

var connectivity = Windows.Networking.Connectivity;
var currentRoutePolicy = null;
var currentConnectionSession = null;

function onLoad()
{
  // Register for network status change
  connectivity.networkInformation.addEventListener("networkstatuschanged", OnNetworkStatusChange);
  // Process the current status
  handleNetworkChange();
}

function onNetworkStatusChange()
{
  HandleNetworkChange();
}

//  Create the PDP Context/APN Data
var apnContext                      =   new connectivity.CellularApnContext();
apnContext.providerId               =   "23545";
apnContext.accessPointName          =   "myAPN.com";
apnContext.userName                 =   "APNusername"
apnContext.password                 =   "[PLACEHOLDER]";
apnContext.isCompressionEnabled     =  false;
apnContext.authenticationType       =   connectivity.CellularApnAuthenticationType.none;

//  Request the connection to Windows
connectivity.connectivityManager.acquireConnectionAsync(apnContext).done(onConnectionSucceeded, onConnectionFailed);

//  On successful connection to PDP Context,  Windows returns a ConnectionSession object that incapsulate the new connection profile
function onConnectionSucceeded(result)
{
  // keep the connectionSession in scope
  currentConnectionSession= result;

  //  create a route policy for the new connection
  currentRoutePolicy = new connectivity.routePolicy(currentConnectionSession.ConnectionProfile, new hostName("video.mydomain.com"),Windows.Networking.DomainNameType.suffix);

  //  indicate the new route policy to the Http stack
  connectivity.connectivityManager.addHttpRoutePolicy(currentRoutePolicy);

  // Backend data interaction with appropriate APIs(Open IFrame etc.)

  // After completing the data transfer remove the Route Policy
  connectivity.connectivityManager.removeHttpRoutePolicy(currentRoutePolicy);
  currentRoutePolicy = null;

  // Disconnect the PDP Context to free up resources
  currentConnectionSession.close();

}

function handleNetworkChange()
{
  // App behavior to handle network
  var currentProfile = currentRoutePolicy.connectionProfile();
  if (NetworkConnectivityLevel.none != currentProfile.GetNetworkConnectivityLevel())
  {
    // The special PDP Context is disconnected, app should handle this. It can request another connection to special PDP Context or it can show error to the user.
  }
}

移动宽带应用的注意事项

移动宽带应用可以获取每个 PDP 上下文的本地数据使用情况信息,并通过针对特殊 PDP 上下文的策略影响 Windows。

本地数据使用情况

在 Windows 8 中,可以通过移动宽带应用与用户持续建立基于订阅的关系,该应用能够显示当前数据使用情况。 用户可以查看其当前数据使用情况并了解其计费周期或会话结束日期,以做出适当的决定。 若要尽可能减少网络上的负载,应定期检查网络的数据使用情况。 Windows 提供了一个本地数据使用情况 API,你可以使用该 API 与数据使用情况相结合,向用户显示当前数据使用情况。

通过特殊的 PDP 上下文,你可以区分某些应用或服务的数据访问费用。 每个不同的 PDP 上下文被视为本地数据使用计数器的不同配置文件。 移动宽带应用可以在特定的持续时间内查询每个 PDP 上下文的本地数据使用情况,类似于 internet PDP 上下文在Windows 8中的工作方式。 可以使用此信息向用户显示适当的数据使用体验。

以下示例代码演示如何使用网络 API 读取所有 PDP 上下文的本地数据使用情况:

// Get the network account ID.
IReadOnlyList<string> networkAccIds = Windows.Networking.NetworkOperators.MobileBroadbandAccount.AvailableNetworkAccountIds;

if (networkAccIds.Count == 0)
{
  rootPage.NotifyUser("No network account ID found", NotifyType.ErrorMessage);
  return;
}

// For the sake of simplicity, assume we want to use the first account.
// Refer to the MobileBroadbandAccount API's how to select a specific account ID.
string networkAccountId = networkAccIds[0];

// Create mobile broadband object for specified network account ID
var mobileBroadbandAccount = Windows.Networking.NetworkOperators.MobileBroadbandAccount.CreateFromNetworkAccountId(networkAccountId);

// Get all connection profiles associated with this network account ID
var connectionProfiles = mobileBroadbandAccount.GetConnectionProfiles();

// Collect local usages for last one hour
DateTime endTime = DateTime.Now;
TimeSpan timeDiff = TimeSpan.FromHours(1);
DateTime startTime = endTime.Subtract(timeDiff);
string message = string.Empty;

foreach (var connectionProfile in connectionProfiles)
{
  // Display local usages for each connection profiles
  DataUsage localUsage = connectionProfile.GetLocalUsage(startTime, endTime);
  message += "Connection Profile Name:  " + connectionProfile.ProfileName + "\n\n";
  message += "Local Data Usage from " + startTime.ToString() + " to " + endTime.ToString() + ":\n";
  message += " Bytes Sent     : " + localUsage.BytesSent + "\n";
  message += " Bytes Received : " + localUsage.BytesReceived + "\n\n";
}

// Print the message string

策略

一些运算符表示特殊 PDP 上下文的带宽有限。 激活特殊 PDP 上下文但无权使用特殊 PDP 上下文的应用可能会造成拒绝服务攻击。 应将特殊 APN 的使用限制为具有业务关系的特定应用。 你可以向 Windows 提供具有特殊接入点名称的 UWP 应用列表。 Windows 将使用该信息来限制对特殊 APN 的访问。 如果未提供列表,Windows 会假定所有应用都打开了特殊的 PDP 上下文。

注意

这只是为了避免在特殊 PDP 上下文上产生额外的流量。 不能依赖此作为将应用限制为特殊 PDP 上下文的安全机制。 如果要限制对特殊 PDP 上下文的访问,则必须在网络上实现某种身份验证或安全机制。 例如,可以使用只允许特定 PDP 上下文的特定 IP 地址的筛选器。

某些移动网络不支持多个 PDP 上下文。 可以预配网络是否支持多个 PDP 上下文。 如果你的网络不支持多个 PDP 上下文,Windows 不应允许应用在特殊 APN 上创建按需连接。 默认情况下,Windows 假定你支持多个 PDP 上下文。

以下示例 XML 文件演示如何使用 Windows 预配元数据为特殊 PDP 上下文提供允许的应用列表:

<?xml version="1.0" encoding="utf-8"?>
<CarrierProvisioning xmlns="http://www.microsoft.com/networking/CarrierControl/v1">
  <Global>
    <!-- Adjust the Carrier ID to fit your own ID. Refer to the documentation about Carrier ID's. -->
    <CarrierId>{11111111-1111-1111-1111-111111111111}</CarrierId>
    <!-- Adjust the Susbscriber ID. Refer to the documentation about Subscriber ID's. -->
    <SubscriberId>1234567890</SubscriberId>
  </Global>
  <Extensions>
    <Extensions_v2 xmlns="http://www.microsoft.com/networking/CarrierControl/v2">
      <AdditionalPDPContexts>
        <MultiplePDPContextPolicies MultiplePDPContextSupport="true">
          <PDPContextPolicy>
            <!-- Adjust the profile name -->
            <Name>Contoso1</Name>
            <Context>
              <!-- Adjust the access string to your APN. -->
              <AccessString>Contoso.Contoso1</AccessString>
              <!-- Adjust the UserLogonCred to fit your UserLogonCred. Refer to the documentation about UserLogonCred's. -->
              <UserLogonCred>
                <UserName>user1</UserName>
                <Password>[PLACEHOLDER]</Password>
              </UserLogonCred>
            </Context>
            <AppIDList>
              <!-- Adjust the AppId to your AppId -->
              <AppID>Contoso.Sample1.CS_dsarewaj</AppID>
              <AppID>Contoso.Sample2.CPP_dsarewaj</AppID>
            </AppIDList>
          </PDPContextPolicy>
          <PDPContextPolicy>
            <!-- Adjust the profile name -->
            <Name>Contoso2</Name>
            <Context>
              <!-- Adjust the access string to your APN. -->
              <AccessString>Contoso.Contoso2</AccessString>
              <!-- Adjust the UserLogonCred to fit your UserLogonCred. Refer to the documentation about UserLogonCred. -->
              <UserLogonCred>
                <UserName>user2</UserName>
                <Password>[PLACEHOLDER]</Password>
              </UserLogonCred>
            </Context>
            <AppIDList>
              <!-- Adjust the AppId to your AppId -->
              <AppID>Contoso.Sample3.CS_dsarewaj</AppID>
              <AppID>Contoso.Sample4.CPP_dsarewaj</AppID>
            </AppIDList>
          </PDPContextPolicy>
        </MultiplePDPContextPolicies>
      </AdditionalPDPContexts>
    </Extensions_v2>
  </Extensions>
</CarrierProvisioning>

音频和视频流式处理

音频流式处理应用可以使用特殊的 PDP 上下文播放音频或视频流。 与 HTTP API 类似,应用可以使用以下逻辑通过 <音频或视频标记来播放音频> 或 <视频> 。

显示使用特殊 PDP 上下文的流式处理应用工作流的示意图。

可以使用基于 WinInet API 的视频框架。

InstantGo

InstantGo 提供用户在其手机上所期待的即时打开、即时关闭用户体验。 就像在手机上一样,只要有合适的网络可用,InstantGo 就能使系统保持最新、最新且可访问。 低功率电脑平台上的 InstantGo 必须满足特定的 Windows 认证要求。

InstantGo 支持以下方案:

  • 使用新内容更新动态磁贴

  • 接收电子邮件

  • 从网站下载文件或将其上传到网站

  • 共享内容,例如网站上的照片

  • 接收即时消息

  • 接收 VoIP 呼叫

  • 实时通信

  • 播放背景音频和音乐

有关 InstantGo 的详细信息,请参阅 InstantGo 简介

移动宽带应用可以使用特殊的 PDP 上下文来启用其中一些 InstantGo 方案。 如果由于范围外而断开连接,则需要使用以下逻辑重新连接到特殊 PDP 上下文。 当设备进入连接待机电源状态时,Windows 将在 10 分钟后断开与特殊 PDP 上下文的所有连接,并且你的应用必须再次请求连接。

说明在 InstantGo 方案中重新连接到特殊 PDP 上下文的过程的流程图。

后台音频流式传输

音频流式处理应用可以使用特殊的 PDP 上下文在后台和处于连接待机电源状态的音频。 有关如何在后台播放音频的详细信息,请参阅 如何在后台播放音频

实时通信应用

实时通信应用(如 VoIP 或聊天应用)可以在特殊 PDP 上下文上接收唤醒触发器。 唤醒触发器允许随时触发应用,包括系统处于连接待机电源状态时。

若要启用此方案,移动宽带设备应支持特殊 PDP 上下文上的唤醒筛选器,如 移动宽带接口模型 (MBIM) 规范中所述。

移动宽带设备

若要支持多个 PDP 上下文,移动宽带设备的固件必须支持 MBIM 规范中定义的多个 PDP 上下文。 它还必须通过特定于多个 PDP 上下文的任何 Windows 硬件认证工具包测试。

由于此功能特定于运营商,因此它对于移动宽带设备是可选的。 如果需要此功能,则必须在操作员要求中添加多个 PDP 上下文功能,并满足以下条件:

  • 设备固件应支持多个 IP 数据流,详见 MBIM 规范的第 10.5.12.1 节。 这包括支持 CID 和 IP 数据流的所有控制实现,以完全支持多个 PDP 上下文。

  • 设备固件必须支持多个双持有者 (IPv4 & IPv6) PDP 上下文供 Windows 使用。

    • 这包括 1 个用于 Internet 连接和移动宽带应用的其他 PDP 上下文(根据你的要求)。

    • 这不需要固件可用于 SMS 和其他管理上下文的设备托管 PDP 上下文。

  • 设备固件应该能够正常地利用主机操作系统请求来获取在其固件中已在内部进行设备管理的 PDP 上下文。

  • 设备固件应继续提取短信 PDP 上下文,并通过短信 CID 路由它们,而不考虑下面使用的持有者。