MB 操作语义

异步事务

MB 驱动程序模型使用 NDIS 6.x 中提供的异步通知机制,假定 MB 服务和微型端口驱动程序之间存在非阻塞操作语义。 此机制允许 MB 服务继续将 OID 请求发送到微型端口驱动程序进行处理,而无需等待当前操作完成。

异步事务是一种三向握手,从初始请求开始,然后是请求状态响应,然后由最终事务指示完成。 请求状态响应是临时的,因为它仅确认微型端口驱动程序已收到请求。 后续异步指示是事务性的,因为它向事务完成发出信号。 微型端口驱动程序返回事务指示中的状态代码以及生成的数据。

异步 查询 请求

MB 服务使用的许多 查询 OID 请求都是异步处理的。 有关 设置查询 OID 请求的详细信息,请参阅 NDIS_OID_REQUESTMB 数据模型主题中的“特定于 WWAN 的 OID”表标识了异步处理哪些 OID。

下图表示 MB 服务和微型端口驱动程序之间的异步 查询 事务的交互序列。 粗体标签表示 OID 标识符或事务流控制,常规文本中的标签表示 OID 结构中的重要标志。

显示 MB 服务和微型端口驱动程序之间的异步查询事务交互序列的关系图。

查询设置请求的三向握手是相同的。

OID_WWAN_DRIVER_CAPS外,所有其他特定于 MB 的 OID 请求都遵循微型端口驱动程序和 MB 服务之间信息交换的异步事务机制,并附带以下附加说明:

  • 微型端口驱动程序应在出现任何错误条件(例如无效的 OID 请求)时立即使 OID 请求失败。

  • 微型端口驱动程序必须返回任何 WWAN 特定的错误条件, (正确的错误代码,例如,WWAN_STATUS_XXX) 事件通知结构的 uStatus 成员中指定的。 微型端口驱动程序还应根据需要适当填写 uStatus 成员后面的成员。 例如,微型端口驱动程序应填充NDIS_WWAN_CONTEXT_STATE结构的 ContextState.uNwError 成员(如果可用)。 但是,如果处理与 PIN 相关的 OID 失败,微型端口驱动程序不一定具有当前 PIN 状态信息,可以在 NDIS_WWAN_PIN_INFOPinInfo.PinState 成员中指定。

  • 微型端口驱动程序应返回NDIS_STATUS_INDICATION_REQUIRED作为所有异步 OID 请求的临时响应。

  • 微型端口驱动程序应能够区分 OID 请求引起的设备状态更改和其他原因。 微型端口驱动程序应针对 OID 请求导致的状态更改发送事务性通知,并且应发送来自其他原因的状态更改的未经请求的事件通知。

  • 微型端口驱动程序负责管理内核模式内存,尽管 MB 服务最初为请求分配内存。 MB 服务收到微型端口驱动程序的响应后,该服务可能会释放它为 OID 请求分配的用户模式内存。

下图表示 MB 服务和微型端口驱动程序之间的异步 事务的交互序列。 粗体标签表示 OID 标识符或事务流控制,常规文本中的标签表示 OID 结构中的重要标志。

显示 MB 服务和微型端口驱动程序之间的异步集事务交互序列的关系图。

异步响应

随 Windows Vista) 一起发布的 NDIS 6.0 规范 (引入了一个新的状态代码(NDIS_STATUS_INDICATION_REQUIRED),用于微型端口驱动程序在微型端口驱动程序对 OID 请求的临时响应中向 MB 服务传达事务的异步性质。

MB 接口概述中所述,MB 服务不能直接访问由 MB 微型端口驱动程序分配的内核模式内存。 假设某些中介(如 WMI 或 NDIS 筛选器驱动程序)复制并提供给 MB 服务存储在内核模式内存中的执行结果。 因此,微型端口驱动程序可以在事务指示中 NdisMIndicateStatusEx 函数调用返回后释放分配的内核模式内存。

以下过程中介绍了微型端口驱动程序和 MB 服务必须遵循的握手过程。

MB 微型端口驱动程序过程

收到 OID 请求后,微型端口驱动程序应执行以下步骤:

  1. 在内核模式下分配内存以复制与 OID 请求关联的 NDIS_OID_REQUEST 数据结构的内容。

  2. 在请求的参数中,确保也复制了 OID 请求结构的 RequestIdRequestHandle 成员。 稍后将在事务 指示中使用这些成员。

  3. 返回临时NDIS_STATUS_INDICATION_REQUIRED状态响应,通知 MB 服务微型端口驱动程序将以异步方式完成请求。

  4. 操作完成后,根据需要将结果存储在本地或驱动程序分配的内存中。

  5. 调用 NdisMIndicateStatusEx 函数以通知 MB 服务已完成未完成的操作。 微型端口驱动程序应填充NDIS_STATUS_INDICATION结构的成员,如下所示:

    1. StatusCode 成员设置为状态通知的类型。 例如,NDIS_STATUS_WWAN_XXX。
    2. DestinationHandle 成员设置为在微型端口驱动程序收到相应的 OID 请求时在 NDIS_OID_REQUEST 数据结构中收到的 RequestHandle 成员。
    3. 设置 RequestId 成员以在微型端口驱动程序收到相应的 OID 请求时匹配NDIS_OID_REQUEST状态结构的 RequestId 成员。
    4. StatusBufferStatusBufferSize 成员分别设置为指向微型端口驱动程序分配的内存和内存缓冲区的大小。 此内存缓冲区包含已完成操作的结果。
    5. 如果操作成功完成,请将 uStatus 成员设置为 WWAN_STATUS_SUCCESS。 否则,请将 uStatus 成员设置为相应的WWAN_STATUS_XXX值以指示失败的类型。
  6. 函数调用返回时,微型端口驱动程序应释放它为 OID 请求分配的内存。

MB 服务过程

MB 服务使用以下过程处理异步事务:

  1. 根据 OID 数据结构为请求分配缓冲区内存。 使用适当的值填充数据结构成员。

  2. 使用指向 OID 请求的 OID 数据结构的 InformationBuffer 成员调用 NdisOidRequest 函数,并等待微型端口驱动程序响应。

  3. 从微型端口驱动程序收到NDIS_STATUS_INDICATION_REQUIRED临时响应后,MB 服务将保存 RequestId,释放分配的内存,并将事务标记为打开。 此时,MB 服务可以免费处理后续 OID 请求和通知。

  4. 收到状态代码值NDIS_STATUS_WWAN_XXX的通知后,检查 RequestId 是否与标记为打开的任何事务的 RequestId 匹配。 如果存在匹配项,则服务将关闭事务。 如果未找到匹配项,请将通知视为未经请求的事件通知。

  5. 处理 StatusBuffer 成员中返回的数据,并根据需要对 MB 服务进行状态更改。

迹象

微型端口驱动程序可以生成两种类型的特定于 WWAN 的指示

  • MB 设备中对象状态更改导致的事件通知。

  • 表示异步操作完成的事务通知。

在这两种情况下,微型端口驱动程序都应调用 NdisMIndicateStatusEx 函数。

事件通知

事件通知是未经请求的,因为微型端口驱动程序主动将指示作为状态更改事件发送到 MB 服务。 状态更改是由来自 MB 服务以外的某个实体的操作引起的。 MB 服务假定微型端口驱动程序能够检测更改原因。

对于任何特定于 WWAN 的事件通知,微型端口驱动程序必须将 NDIS_STATUS_INDICATION 结构的 RequestId 成员设置为零。 StatusCode 成员指定 MB 设备中的哪个对象已更改。 微型端口驱动程序可以将此对象设置为以下任何值:

NDIS_STATUS_WWAN_DEVICE_CAPS

NDIS_STATUS_WWAN_READY_INFO

NDIS_STATUS_WWAN_RADIO_STATE

NDIS_STATUS_WWAN_PIN_INFO

NDIS_STATUS_WWAN_PIN_LIST

NDIS_STATUS_WWAN_HOME_PROVIDER

NDIS_STATUS_WWAN_PREFERRED_PROVIDERS

NDIS_STATUS_WWAN_VISIBLE_PROVIDERS

NDIS_STATUS_WWAN_REGISTER_STATE

NDIS_STATUS_WWAN_PACKET_SERVICE

NDIS_STATUS_WWAN_SIGNAL_STATE

NDIS_STATUS_WWAN_CONTEXT_STATE

NDIS_STATUS_WWAN_PROVISIONED_CONTEXTS

NDIS_STATUS_WWAN_SERVICE_ACTIVATION

NDIS_STATUS_WWAN_SMS_CONFIGURATION

NDIS_STATUS_WWAN_SMS_RECEIVE

NDIS_STATUS_WWAN_SMS_SEND

NDIS_STATUS_WWAN_SMS_DELETE

NDIS_STATUS_WWAN_SMS_STATUS

NDIS_STATUS_WWAN_VENDOR_SPECIFIC

MB 服务还可以处理来自 NDIS 的其他事件通知。 这些非 MB 事件通知不一定受其 RequestId 值设置为零的要求的约束。

事务通知

微型端口驱动程序使用事务通知通知 MB 服务异步事务已完成,MB 服务使用事务通知关闭打开的事务并更新其状态机。

MB 服务需要事务通知,以便它可以关闭打开的事务。 它是 MB 服务与微型端口驱动程序在异步事务中的三向握手的最终交换。 任何事务通知中NDIS_STATUS_INDICATION的 RequestId 成员的值必须是非零值,该值是从同一事务中的相应请求复制的。

必须正确设置 NDIS_STATUS_INDICATION 结构的 RequestId 成员,异步机制才能正常工作。 MB 服务可确保 RequestId 值在所有未完成的请求中是唯一且不为零的。 微型端口驱动程序必须在相应的指示中返回相同的 RequestId 值,以便 MB 服务将指示与打开的事务相关联。

状态指示结构

给定 OID 请求的异步响应和未经请求的事件通知结构共享由 StatusIndication 参数的 StatusBuffer 成员指向 NdisMIndicateStatusEx 的以下结构成员:

typedef struct _NDIS_WWAN_XXX {
  NDIS_OBJECT_HEADER Header;
  WWAN_STATUS uStatus;
  ULONG uNwError;//Optional. Only used for network operations.
  WWAN_XXX XxxStruct;
} NDIS_WWAN_XXX, *PNDIS_WWAN_XXX;

NDIS_STATUS_INDICATION 结构的 RequestId 成员中的值零表示它是未经请求的事件通知,并且可以随时发生。

如果任何查询请求的返回指示中的 uStatus 成员不等于WWAN_STATUS_SUCCESS则关联的 NDIS_WWAN_XXX 结构的成员不需要有效。

对于基于网络事件的未经请求的事件通知,微型端口驱动程序必须根据需要填写 uNwError 成员(如果适用)。

下表显示了针对基于 GSM 的网络的 3GPP TS 24.008 规范 中定义的注册、数据包附加和数据包分离原因代码失败值:

3GPP 24.008 原因代码 原因代码的解释

2 - HLR 中的国际移动用户标识 (IMSI) 未知

SIM 卡或设备未激活,或者订阅已过期,导致网络停用。

4 - VLR 中的 IMSI 未知

漫游功能未订阅。

6 - 非法 ME

由于报告被盗,网络阻止了 MS。

7 - 不允许使用 GPRS 服务

用户没有 GPRS 订阅。 用户只有语音连接订阅。

8 - 不允许使用 GPRS 和非 GPRS 服务

不允许使用 GPRS 和非 GPRS 服务。

11 - 不允许 PLMN

由于订阅过期或其他原因,网络阻止了服务。

12 - 不允许位置区域

用户订阅不允许在当前位置区域中进行访问。

13 - 此位置区域不允许漫游

订阅允许漫游,但不允许在当前位置区域中漫游。

14 - 此 PLMN 中不允许使用 GPRS 服务

所选网络提供商不会向 MS 提供 GPRS 服务。

15 - 位置区域中没有合适的单元格

没有该服务的订阅。

17 - 网络故障

注册失败。

22 - 拥塞

由于网络拥塞,注册失败。

例如,如果网络由于位置区域中不允许漫游而启动停用上下文事件,则微型端口驱动程序应根据 3GPP TS 24.008 基于 GSM 的网络的原因代码将 uNwError 成员设置为 13。

类似的逻辑也应应用于基于 CDMA 的网络。 但是,基于 CDMA 的网络错误代码没有标准。 基于 CDMA 的设备应使用特定于网络的错误代码或特定于设备的错误代码。

对于微型端口驱动程序对 OID 请求的异步响应,NDIS_STATUS_INDICATION结构的 RequestId 成员是作为 查询 请求的一部分传递给微型端口驱动程序的非零数字。 微型端口驱动程序必须根据需要填充 uStatus 成员。 例如,WWAN_STATUS_SUCCESS或下一节中列出的任何适当的错误值。 除此之外,微型端口驱动程序必须在适当且可用的情况下填写 uNwError 成员。

事件通知状态

下表列出了 MB 微型端口驱动程序可以在NDIS_WWAN_XXX事件通知结构的 uStatus 成员中指定的WWAN_STATUS代码。

含义

WWAN_STATUS_SUCCESS

操作成功。

WWAN_STATUS_FAILURE

操作在泛型故障) (失败。

WWAN_STATUS_BUSY

操作失败,因为设备正忙。

WWAN_STATUS_SIM_NOT_INSERTED

操作失败,因为 SIM 卡未完全插入设备。

WWAN_STATUS_BAD_SIM

操作失败,因为 SIM 卡卡错误,无法再使用。

WWAN_STATUS_PIN_REQUIRED

操作失败,因为必须输入 PIN 才能继续。

WWAN_STATUS_PIN_DISABLED

操作失败,因为 PIN 已禁用。

WWAN_STATUS_NOT_REGISTERED

操作失败,因为设备未在任何网络中注册。

WWAN_STATUS_PROVIDERS_NOT_FOUND

操作失败,因为找不到任何网络提供程序。

WWAN_STATUS_NO_DEVICE_SUPPORT

操作失败,因为设备不支持该操作。

WWAN_STATUS_PROVIDER_NOT_VISIBLE

操作失败,因为服务提供程序当前不可见。

WWAN_STATUS_DATA_CLASS_NOT_AVAILABLE

操作失败,因为请求的数据类不可用。

WWAN_STATUS_PACKET_SVC_DETACHED

操作失败,因为已分离数据包服务。

WWAN_STATUS_MAX_ACTIVATED_CONTEXTS

操作失败,因为已达到已激活上下文的最大数目。

WWAN_STATUS_NOT_INITIALIZED

操作失败,因为设备正在初始化。 在设备的就绪状态更改为 WwanReadyStateInitialized 后重试该操作。

WWAN_STATUS_VOICE_CALL_IN_PROGRESS

操作失败,因为语音呼叫正在进行。

WWAN_STATUS_CONTEXT_NOT_ACTIVATED

操作失败,因为上下文未激活。

WWAN_STATUS_SERVICE_NOT_ACTIVATED

操作失败,因为服务未激活。

WWAN_STATUS_INVALID_ACCESS_STRING

操作失败,因为访问字符串无效。

WWAN_STATUS_INVALID_USER_NAME_PWD

操作失败,因为提供的用户名和/或密码无效。

WWAN_STATUS_RADIO_POWER_OFF

操作失败,因为无线电当前已关闭。

WWAN_STATUS_INVALID_PARAMETERS

由于参数无效,操作失败。

WWAN_STATUS_READ_FAILURE

由于读取失败,操作失败。

WWAN_STATUS_WRITE_FAILURE

由于写入失败,操作失败。

下表显示了特定于短信的状态值。

含义

WWAN_STATUS_SMS_OPERATION_NOT_ALLOWED

SMS 操作失败,因为不允许该操作。

WWAN_STATUS_SMS_MEMORY_FAILURE

由于内存故障,SMS 操作失败。

WWAN_STATUS_SMS_INVALID_MEMORY_INDEX

SMS 操作失败,因为无效的内存索引 - WwanSmsFlagIndex for OID_WWAN_SMS_READ。

WWAN_STATUS_SMS_UNKNOWN_SMSC_ADDRESS

SMS 操作失败,因为服务中心号码无效或未知。

WWAN_STATUS_SMS_NETWORK_TIMEOUT

由于网络超时,SMS 操作失败。

WWAN_STATUS_SMS_MEMORY_FULL

SMS 操作失败,因为短信存储已满。

WWAN_STATUS_SMS_UNKNOWN_ERROR

由于未知错误 (泛型错误) ,SMS 操作失败。

WWAN_STATUS_SMS_FILTER_NOT_SUPPORTED

SMS 操作失败,因为请求的筛选器类型不受支持。

WWAN_STATUS_SMS_MORE_DATA

此事务尚未完成。 已返回一些数据,并且需要返回更多数据。

WWAN_STATUS_SMS_LANG_NOT_SUPPORTED

SMS 操作失败,因为不支持 SMS 语言。 这仅适用于基于 CDMA 的设备。

WWAN_STATUS_SMS_ENCODING_NOT_SUPPORTED

SMS 操作失败,因为不支持 SMS 编码。 这仅适用于基于 CDMA 的设备。

WWAN_STATUS_SMS_FORMAT_NOT_SUPPORTED

SMS 操作失败,因为不支持 SMS 格式。

注意 这些特定于 WWAN 的状态代码仅用于NDIS_WWAN_XXX结构的 uStatus 成员中的异步事务。

微型端口驱动程序使用事件通知来通知 MB 服务其 MB 设备中的对象状态更改,而无需先收到 OID 请求。 MB 服务仅使用事件通知更新其状态机。

请注意,虽然 NDIS 序列化发送到微型端口驱动程序的所有请求,但微型端口驱动程序可能不会按相同顺序返回响应。 这是因为微型端口驱动程序中的排队请求可能会并行处理。 因此,MB 服务可确保如果两个请求相互依赖,则在微型端口驱动程序完成第一个请求之前,它不会发送第二个请求。

状态更改通知

通常,微型端口驱动程序应始终通过事务通知或未经请求的事件通知通知 MB 服务其 MB 设备的更新状态。 以下方案是微型端口驱动程序不应使用更新的状态信息做出响应的一些例外情况。 MB 服务可以根据其他操作的完成状态确定更新状态:

  1. 微型端口驱动程序不需要在 PIN 状态发生更改时发送NDIS_STATUS_WWAN_PIN_LIST事件指示,因为 MB 服务请求启用或禁用 PIN。

  2. 微型端口驱动程序不需要在事务响应中返回预配上下文的更新列表,以OID_WWAN_PROVISIONED_CONTEXT 操作。

  3. 微型端口驱动程序不需要在事务性响应中响应OID_WWAN_PREFERRED_PROVIDERS 操作的首选提供程序的更新列表进行响应。 MB 服务可以根据 设置 操作的初始列表和成功状态来确定此信息。

  4. 微型端口驱动程序不需要使用当前WWAN_SMS_CONFIGURATION值响应OID_WWAN_SMS_CONFIGURATION 操作。