MB 操作のセマンティクス

非同期トランザクション

MB ドライバー モデルでは、NDIS 6.x で提供される非同期通知メカニズムを使用して、MB サービスとミニポート ドライバー間の非ブロッキング操作セマンティクスを想定しています。 このメカニズムにより、MB サービスは、現在の操作が完了するのを待たずに、ミニポート ドライバーに処理のための OID 要求を継続送信できます。

非同期トランザクションは、最初の要求で始まり、要求の状態応答がそれに続き、最後のトランザクション表示で完了する 3 方向ハンドシェイクです。 要求の状態応答は、ミニポート ドライバーが要求を受信したことを確認するだけの暫定的なものです。 フォローアップの非同期表示は、トランザクションの完了を通知するトランザクションに関するものです。 ミニポート ドライバーは、状態コードと結果として得られるデータをトランザクション表示で返します。

非同期のセット要求とクエリ要求

MB サービスで使用される setquery の OID 要求の多くは、非同期で処理されます。 setquery の OID 要求の詳細については、NDIS_OID_REQUEST を参照してください。 「MB データ モデル」トピックの "WWAN 固有の OID" 表で、非同期で処理される OID を確認できます。

次の図は、MB サービスとミニポート ドライバー間の非同期の query トランザクションに関する相互作用シーケンスを表しています。 太字のラベルは OID 識別子またはトランザクション フロー制御を表し、標準テキストのラベルは OID 構造体内の重要なフラグを表します。

Diagram showing the interaction sequence for an asynchronous query transaction between the MB Service and the miniport driver.

query 要求と set 要求のどちらも、3 方向のハンドシェイクは同じです。

OID_WWAN_DRIVER_CAPS を除く他のすべての MB 固有の OID 要求は、ミニポート ドライバーと MB サービス間の情報交換に関わる非同期トランザクション メカニズムに従います。ただし、次の追加の注意事項があります。

  • ミニポート ドライバは、無効な OID 要求など、何らかのエラー状態が生じた場合、直ちに OID 要求を失敗させる必要があります。

  • ミニポート ドライバーは、イベント通知構造体の uStatus メンバーで指定された正しいエラー コード (WWAN_STATUS_XXX など) で WWAN 固有のエラー条件を返す必要があります。 ミニポート ドライバーは、必要に応じて、uStatus メンバーの後に続くメンバーを適切に入力する必要があります。 たとえば、ミニポート ドライバーは、使用可能な場合、NDIS_WWAN_CONTEXT_STATE 構造体の ContextState.uNwError メンバーを入力する必要があります。 ただし、PIN に関連する OID の処理中にエラーが発生した場合、ミニポート ドライバーは、NDIS_WWAN_PIN_INFOPinInfo.PinState メンバーで指定する現在の PIN の状態情報を必ずしも持っているとは限りません。

  • ミニポート ドライバーは、すべての非同期 OID 要求に対する暫定的な応答として NDIS_STATUS_INDICATION_REQUIRED を返す必要があります。

  • ミニポート ドライバーは、OID 要求によって引き起こされるデバイスの状態の変更と他の原因とを区別できる必要があります。 ミニポート ドライバーは、OID 要求に起因する状態の変更についてトランザクション通知を送信する必要があり、他の原因による状態の変更については要求されていないイベント通知を送信する必要があります。

  • ミニポート ドライバーは、カーネルモード メモリを管理する役割を担いますが、MB サービスは要求のメモリを最初に割り当てます。 MB サービスは、ミニポート ドライバーから応答を受け取った後、OID 要求に割り当てられたユーザーモード メモリを解放する場合があります。

次の図は、MB サービスとミニポート ドライバー間の非同期の set トランザクションに関する相互作用シーケンスを表しています。 太字のラベルは OID 識別子またはトランザクション フロー制御を表し、標準テキストのラベルは OID 構造体内の重要なフラグを表します。

Diagram showing the interaction sequence for an asynchronous set transaction between the MB Service and the miniport driver.

非同期応答

NDIS 6.0 仕様 (Windows Vista でリリース) では、ミニポート ドライバーの OID 要求に対する暫定的な応答で、ミニポート ドライバーが MB サービスに対してトランザクションの非同期の性質を伝えられるように、新しい状態コードである NDIS_STATUS_INDICATION_REQUIRED が導入されました。

MB インターフェイスの概要で説明されているように、MB サービスは、MB ミニポート ドライバーによって割り当てられたカーネルモード メモリに直接アクセスできません。 カーネルモード メモリに格納されている実行結果は、WMI や NDIS フィルター ドライバーなどの仲介役によってコピーされ、MB サービスで使用できるようになると想定されています。 そのため、ミニポート ドライバーは、NdisMIndicateStatusEx 関数呼び出しがトランザクション表示で返された後に割り当てられたカーネルモード メモリを解放できます。

ミニポート ドライバーとMB サービスで従う必要があるハンドシェイク手順については、次の手順で説明します。

MB ミニポート ドライバーの手順

ミニポート ドライバーでは OID 要求を受信後、次の手順を実行する必要があります。

  1. カーネル モードでメモリを割り当てて、OID 要求に関連付けられている NDIS_OID_REQUEST データ構造の内容をコピーします。

  2. 要求のパラメーターのうち、OID 要求構造体の RequestId メンバーと RequestHandle メンバーもコピーされていることを確認します。 これらのメンバーは、トランザクション表示で後ほど使用されます。

  3. ミニポート ドライバーが要求を非同期で完了することを MB サービスに通知するために、暫定的な NDIS_STATUS_INDICATION_REQUIRED の状態応答を返します。

  4. 操作が完了したら、必要に応じて、ローカル メモリまたはドライバーが割り当てたメモリに結果を格納します。

  5. NdisMIndicateStatusEx 関数を呼び出して、未処理の操作が完了したことを MB サービスに通知します。 ミニポート ドライバーは、次のように、NDIS_STATUS_INDICATION 構造体のメンバーを入力する必要があります。

    1. StatusCode メンバーを状態通知の種類に設定します。 たとえば、NDIS_STATUS_WWAN_XXX。
    2. DestinationHandle メンバーを、ミニポート ドライバーが対応する OID 要求を受信したときに NDIS_OID_REQUEST データ構造で受信した RequestHandle メンバーに設定します。
    3. ミニポート ドライバーが対応する OID 要求を受信したときに、NDIS_OID_REQUEST の状態構造体の RequestId メンバーと一致するように RequestId メンバーを設定します。
    4. ミニポート ドライバーが割り当てたメモリとメモリ バッファーのサイズをそれぞれ指定するように、StatusBuffer メンバーと StatusBufferSize メンバーを設定します。 このメモリ バッファーには、完了した操作の結果が含まれます。
    5. 操作が正常に完了した場合は、uStatus メンバーを WWAN_STATUS_SUCCESS に設定します。 それ以外の場合は、エラーの種類を示す適切な WWAN_STATUS_XXX 値に uStatus メンバーを設定します。
  6. 関数呼び出しが返されると、ミニポート ドライバーは、OID 要求に割り当てたメモリを解放する必要があります。

MB サービスの手順

MB サービスは、次の手順を使用して非同期トランザクションを処理します。

  1. OID データ構造に基づいて、要求のバッファー メモリを割り当てます。 データ構造のメンバーに適切な値を入力します。

  2. OID 要求の OID データ構造を指定する InformationBuffer メンバーを使用して NdisOidRequest 関数を呼び出し、ミニポート ドライバーが応答するのを待ちます。

  3. ミニポート ドライバーから NDIS_STATUS_INDICATION_REQUIRED という暫定的な応答を受信すると、MB サービスは RequestId を保存し、割り当てられたメモリを解放して、トランザクションにオープンのマークを付けます。 この時点で、MB サービスは後続の OID 要求と通知を自由に処理できます。

  4. StatusCode 値として NDIS_STATUS_WWAN_XXX を持つ通知を受け取ると、その RequestId が、オープンのマークが付いたトランザクションのものと一致するかどうかを確認します。 一致するものがある場合、サービスはトランザクションを閉じます。 一致するものが見つからない場合は、通知を要求されていないイベント通知として扱います。

  5. StatusBuffer メンバーで返されたデータを処理し、必要に応じて、MB サービスに状態を変更します。

表示

ミニポート ドライバーが生成できる WWAN 固有の表示には、次の 2 種類があります。

  • MB デバイスのオブジェクト状態の変化に起因するイベント通知。

  • 非同期操作の完了を通知するトランザクション通知。

どちらの場合も、ミニポート ドライバーは NdisMIndicateStatusEx 関数を呼び出す必要があります。

イベント通知

イベント通知は、ミニポート ドライバーが状態変更イベントとして MB サービスに事前に通知を送信するという意味で、一方的なものです。 状態の変更は、MB サービス以外のエンティティからのアクションによって発生します。 MB サービスは、ミニポート ドライバーが変更の原因を検出できることを前提としています。

WWAN 固有のイベント通知の場合、ミニポート ドライバーは、NDIS_STATUS_INDICATION 構造体の RequestId メンバーを 0 に設定する必要があります。 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 値を 0 に設定するという要件の対象になるとは限りません。

トランザクション通知

ミニポート ドライバーでは、トランザクション通知を使用して、非同期トランザクションが完了したことを MB サービスに通知し、MB サービスはトランザクション通知を使用して、開いているトランザクションを閉じて状態機械を更新します。

MB サービスでは、開いているトランザクションを閉じることができるように、トランザクション通知が必要です。 これは、非同期トランザクションにおける MB サービスと非同期トランザクション間の 3 方向ハンドシェイクの最終交換です。 トランザクション通知の NDIS_STATUS_INDICATION の RequestId メンバーの値は 0 以外である必要があります。この値は、同じトランザクション内の対応する要求からコピーされます。

非同期メカニズムが適切に機能するためには、NDIS_STATUS_INDICATION 構造体の RequestId メンバーを正しく設定する必要があります。 MB サービスでは、すべての未処理の要求で RequestId 値が一意であり、0 以外であることが保証されます。 ミニポート ドライバーは、MB サービスが開いているトランザクションと表示を関連付けるために、対応する表示で同じ RequestId 値を返す必要があります。

状態表示の構造体

指定された 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 メンバーの値が 0 の場合、それは要求されていないイベント通知であり、いつでも発生する可能性があります。

set または query の OID 要求について返された表示の uStatus メンバーが WWAN_STATUS_SUCCESS に等しくない場合は、関連付けられている NDIS_WWAN_XXX 構造体のメンバーは有効である必要はありません。

ネットワーク イベントに基づく、要求されていないイベント通知の場合、ミニポート ドライバーは、必要に応じて、uNwError メンバーを入力する必要があります (該当する場合)。

次の表は、GSM ベースのネットワークの 3GPP TS 24.008 仕様で定義されている登録、パケットアタッチ、パケットデタッチの原因コードのエラー値を示しています。

3GPP 24.008 原因コード 原因コードの説明

2 - HLR で国際モバイル サブスクライバー ID (IMSI) が不明

SIM またはデバイスがアクティブ化されていないか、サブスクリプションの有効期限が切れているため、ネットワークが非アクティブ化されました。

4 - VLR で IMSI が不明

ローミング機能がサブスクライブされていません。

6 - 違法な ME

窃取されたレポートのため、ネットワークによってブロックされた MS。

7 - GPRS サービスは許可されない

ユーザーに GPRS サブスクリプションがありません。 ユーザーは音声接続サブスクリプションのみを持っています。

8 - GPRS および GPRS 以外のサービスは許可されない

GPRS および GPRS 以外のサービスは許可されません。

11 - PLMN は許可されない

サブスクリプションの有効期限が切れているか、別の原因により、サービスがネットワークによってブロックされています。

12 - 位置エリアは許可されない

ユーザー サブスクリプションでは、現在の位置エリアでのアクセスは許可されません。

13 - この位置エリアでのローミングは許可されない

サブスクリプションではローミングは許可されていますが、現在の位置エリアでのローミングは許可されていません。

14 - この PLMN では GPRS サービスは許可されない

選択したネットワーク プロバイダーは、GPRS サービスを MS に提供しません。

15 - 位置エリアに適切なセルがない

サービスのサブスクリプションがありません。

17 - ネットワーク エラー

登録に失敗しました。

22 - 輻輳

ネットワークの輻輳が原因で登録に失敗しました。

たとえば、位置エリアでローミングが許可されていないために、ネットワークが非アクティブ化コンテキスト イベントを開始する場合、ミニポート ドライバーは、GSM ベースのネットワークの 3GPP TS 24.008 原因コードに従って、uNwError メンバーを 13 に設定する必要があります。

CDMA ベースのネットワークにも同様の論理を適用する必要があります。 ただし、CDMA ベースのネットワークのエラー コードには標準はありません。 CDMA ベースのデバイスでは、ネットワーク固有またはデバイス固有のエラー コードを使用する必要があります。

OID 要求に対するミニポート ドライバーの非同期応答の場合、NDIS_STATUS_INDICATION 構造体の RequestId メンバーは、set または query の要求の一部としてミニポート ドライバーに渡された 0 以外の数値になります。 ミニポート ドライバーは、必要に応じて、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

書き込みエラーのため、操作は失敗しました。

次の表に、SMS 固有の状態の値を示します。

意味

WWAN_STATUS_SMS_OPERATION_NOT_ALLOWED

操作が許可されていないため、SMS 操作は失敗しました。

WWAN_STATUS_SMS_MEMORY_FAILURE

メモリエラーのため、SMS 操作は失敗しました。

WWAN_STATUS_SMS_INVALID_MEMORY_INDEX

無効なメモリ インデックス (OID_WWAN_SMS_READ の WwanSmsFlagIndex) により、SMS 操作は失敗しました。

WWAN_STATUS_SMS_UNKNOWN_SMSC_ADDRESS

サービス センター番号が無効であるか不明であるため、SMS 操作は失敗しました。

WWAN_STATUS_SMS_NETWORK_TIMEOUT

ネットワーク タイムアウトのため、SMS 操作は失敗しました。

WWAN_STATUS_SMS_MEMORY_FULL

SMS メッセージ ストアがいっぱいのため、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 メンバー内の非同期トランザクションにのみ使用されます。

ミニポート ドライバーはイベント通知を使用して、最初に OID 要求を受け取ることなく、MB デバイスのオブジェクトの状態変化について MB サービスに通知します。 MB サービスではイベント通知を使用して、状態機械のみを更新します。

NDIS はミニポート ドライバーに送信されるすべての要求をシリアル化しますが、ミニポート ドライバーは同じ順序で応答を返さない可能性があることにご注意ください。 これは、ミニポート ドライバーのキューに登録されている要求が並列で処理される可能性があるためです。 そのため MB サービスでは、2 つの要求が相互依存している場合、ミニポート ドライバーが最初の要求を完了するまで 2 番目の要求を送信しないようにします。

状態変化の通知

一般に、ミニポート ドライバーは常に、トランザクション通知または要求されていないイベント通知を通じて、MB デバイスの更新された状態について MBサービスに通知する必要があります。 次のシナリオは、ミニポート ドライバーが更新された状態情報を使用して応答することが想定されていない例外の一部です。 MB サービスは、他の操作の完了状態から更新された状態を判断できます。

  1. ミニポート ドライバーは、MB サービスが PIN の有効化または無効化を要求したために、PIN の状態変化が発生した場合、NDIS_STATUS_WWAN_PIN_LIST イベント表示を送信する必要はありません。

  2. ミニポート ドライバーは、OID_WWAN_PROVISIONED_CONTEXT の set 操作に対するトランザクション応答で、プロビジョニングされたコンテキストの更新された一覧を返す必要はありません。

  3. ミニポート ドライバーは、OID_WWAN_PREFERRED_PROVIDERS の set 操作に対するトランザクション応答で、優先プロバイダーの更新された一覧を使用して応答する必要はありません。 MB サービスは、set 操作の初期の一覧と成功状態に基づいて、この情報を確認できます。

  4. ミニポート ドライバーは、OID_WWAN_SMS_CONFIGURATION の set 操作に対する現在の WWAN_SMS_CONFIGURATION 値で応答する必要はありません。