撰寫 MBBCx 用戶端驅動程式
警告
本主題中的順序圖表僅供說明之用。 它們不是公用合約,未來可能會變更。
MBBCx 用戶端驅動程式的 INF 檔案
MBBCx 用戶端驅動程式的 INF 檔案與其他 NetAdapterCx 用戶端驅動程式相同。 如需詳細資訊,請參閱 NetAdapterCx 用戶端驅動程式的 INF 檔案。
遵循 通用指導方針 ,以確保 INF 檔案符合通用需求。
初始化裝置
除了 NetAdapterCx 針對 NetAdapter 裝置初始化所需的工作之外,MBB 用戶端驅動程式也必須在其 EvtDriverDeviceAdd 回呼函式中執行下列工作:
呼叫NetDeviceInitConfig之後呼叫MBB_DEVICE_CONFIG_INIT,但在呼叫WdfDeviceCreate之前,參考架構傳入的相同WDFDEVICE_INIT物件。
呼叫 MbbDeviceInitialize ,以使用初始化 的MBB_DEVICE_CONFIG 結構和從 WdfDeviceCreate 取得的 WDFDEVICE物件來註冊 MBB 裝置特定的回呼函式。
下列範例示範如何初始化 MBB 裝置。 為了清楚起見,錯誤處理已留下。
status = NetDeviceInitConfig(deviceInit);
status = MbbDeviceInitConfig(deviceInit);
// Set up other callbacks such as Pnp and Power policy
status = WdfDeviceCreate(&deviceInit, &deviceAttributes, &wdfDevice);
MBB_DEVICE_CONFIG mbbDeviceConfig;
MBB_DEVICE_CONFIG_INIT(&mbbDeviceConfig,
EvtMbbDeviceSendMbimFragment,
EvtMbbDeviceReceiveMbimFragment,
EvtMbbDeviceSendServiceSessionData,
EvtMbbDeviceCreateAdapter);
status = MbbDeviceInitialize(wdfDevice, &mbbDeviceConfig);
不同于其他類型的 NetAdapterCx 驅動程式,MBB 用戶端驅動程式不得從 EvtDriverDeviceAdd 回呼函式內建立 NETADAPTER 物件。 相反地,MBBCx 會指示稍後執行此動作。
接下來,用戶端驅動程式必須呼叫 MbbDeviceSetMbimParameters,通常是在後續的 EvtDevicePrepareHardware 回呼函式中。
此訊息流程圖說明初始化程式。
此訊息流程圖說明初始化程式。
處理 MBIM 控制訊息
MBBCx 會針對控制平面使用 MBIM 規格 Rev 1.0、區段 8、9 和 10 中定義的標準 MBIM 控制項命令。 命令和回應會透過用戶端驅動程式所提供的一組回呼函式和 MBBCx 提供的 API 來交換。 MBBCx 會使用下列函式呼叫,模擬 MBIM 裝置的操作模型,如 MBIM 規格 Rev 1.0 第 5.3 節所定義:
- MBBCx 藉由叫用其 EvtMbbDeviceSendMbimFragment 回 呼函式,將 MBIM 命令訊息傳送至用戶端驅動程式。 用戶端驅動程式會呼叫 MbbRequestComplete以非同步方式完成此傳送要求。
- 用戶端驅動程式會呼叫 MbbDeviceResponseAvailable來發出結果的可用性。
- MBBCx 藉由叫用其 EvtMbbDeviceReceiveMbimFragment 回 呼函式,從用戶端驅動程式擷取 MBIM 回應訊息。 用戶端驅動程式會呼叫 MbbRequestCompleteWithInformation,以非同步方式完成此 get-response 要求。
- MBB 用戶端驅動程式可能會藉由呼叫 MbbDeviceResponseAvailable 來通知 MBBCx未要求裝置事件。 接著,MBBCx 會從用戶端驅動程式擷取資訊,類似于擷取 MBIM 回應訊息的方式。
下圖說明 MBBCx-client 驅動程式訊息交換流程。
MBIM 控制訊息的同步處理
MBBCx 架構一律會將呼叫序列化為用戶端驅動程式的 EvtMbbDeviceSendMbimFragment 和 EvtMbbDeviceReceiveMbimFragment 回 呼函式。 在用戶端驅動程式呼叫 MbbRequestComplete 或 MbbRequestCompleteWithInformation之前,架構不會進行任何新的呼叫。
雖然用戶端驅動程式保證不會接收重迭的 EvtMbbDeviceSendMbimFragment 或 EvtMbbDeviceReceiveMbimFragment 回呼,但它可能會在從裝置取得先前命令的回應之前,連續收到對它們的多個呼叫。
如果裝置不是 處於 D0 狀態,MBBCx 架構會先將裝置帶入 D0 (,換句話說,它會先呼叫 EvtDeviceD0Entry) ,再呼叫 EvtMbbDeviceSendMbimFragment 或 EvtMbbDeviceReceiveMbimFragment。 MBBCx 架構也保證它會讓裝置保持 D0 狀態,這表示在用戶端呼叫MbbRequestComplete 或 MbbRequestCompleteWithInformation之前,它不會呼叫EvtDeviceD0Exit。
建立 PDP 內容/EPS 持有人的 NetAdapter 介面
建立資料會話之前,MBBCx 會指示用戶端驅動程式建立 NETADAPTER 物件,而且 MBBCx 會使用 MBBCx 來代表啟用之資料會話的網路介面。 這可透過 MBBCx 呼叫用戶端驅動程式的 EvtMbbDeviceCreateAdapter 回呼函式來完成。
在 EvtMbbDeviceCreateAdapter 回呼函式的實作中,MBBCx 用戶端驅動程式必須先執行與任何 NetAdapterCx 用戶端驅動程式建立 NETADAPTER 物件所需的相同工作。 此外,它也必須執行下列其他工作:
在NetAdapterCreate所建立的 NETADAPTER 物件上呼叫MbbAdapterInitialize。
呼叫 MbbAdapterinitialize之後,請呼叫 MbbAdapterGetSessionId 來擷取 MBBCx 想要使用此 NETADAPTER 物件的資料會話識別碼。 例如,如果傳回的值是 0,表示 MBBCx 會將這個 NETADAPTER 介面用於主要 PDP 內容/預設 EPS 持有人所建立的資料會話。
建議 MBBCx 用戶端驅動程式在建立的 NETADAPTER 物件與傳回的 SessionId之間保留內部對應。 這有助於追蹤資料會話對 NETADAPTER 物件關聯性,這在啟動多個 PDP 內容/EPS 持有人時特別有用。
從 EvtMbbDeviceCreateAdapter 傳回之前,用戶端驅動程式必須先呼叫 NetAdapterStart來啟動配接器。 或者,您也可以在呼叫NetAdapterStart之前呼叫其中一或多個函式來設定配接器的功能:
MBBCx 至少會叫用此回呼函式一次,因此主要 PDP 內容/預設 EPS 持有人一律會有一個 NETADPATER 物件。 如果啟動多個 PDP 內容/EPS 持有人,MBBCx 可能會多次叫用此回呼函式,一次讓每個資料會話建立一次。 NETADAPTER 物件所代表的網路介面與資料會話之間必須有一對一關聯性,如下圖所示。
下列範例示範如何為數據會話建立 NETADAPTER 物件。 請注意,設定配接器功能所需的錯誤處理和程式碼會保持簡潔明瞭。
NTSTATUS
EvtMbbDeviceCreateAdapter(
WDFDEVICE Device,
PNETADAPTER_INIT AdapterInit
)
{
// Get the client driver defined per-device context
PMY_DEVICE_CONTEXT deviceContext = MyGetDeviceContext(Device);
// Set up the client driver defined per-adapter context
WDF_OBJECT_ATTRIBUTES adapterAttributes;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&adapterAttributes,
MY_NETADAPTER_CONTEXT);
// Create the NETADAPTER object
NETADAPTER netAdapter;
NTSTATUS status = NetAdapterCreate(AdapterInit,
&adapterAttributes,
&netAdapter);
// Initialize the adapter for MBB
status = MbbAdapterInitialize(netAdapter);
// Retrieve the Session ID and use an array to store
// the session <-> NETADAPTER object mapping
ULONG sessionId;
PMY_NETADAPTER_CONTEXT netAdapterContext = MyGetNetAdapterContext(netAdapter);
netAdapterContext->NetAdapter = netAdapter;
sessionId = MbbAdapterGetSessionId(netAdapter);
netAdapterContext->SessionId = sessionId;
deviceContext->Sessions[sessionId].NetAdapterContext = netAdapterContext;
//
// Optional: set adapter capabilities
//
...
NetAdapterSetDatapathCapabilities(netAdapter,
&txCapabilities,
&rxCapabilities);
...
NetAdapterSetLinkLayerCapabilities(netAdapter,
&linkLayerCapabilities);
...
NetAdapterSetLinkLayerMtuSize(netAdapter,
MY_MAX_PACKET_SIZE - ETHERNET_HEADER_LENGTH);
//
// Required: start the adapter
//
status = NetAdapterStart(netAdapter);
return status;
}
如需設定資料路徑功能的程式碼範例,請參閱 網路資料緩衝區管理。
MBBCx 保證它會在要求具有相同會話識別碼的MBIM_CID_CONNECT之前呼叫EvtMbbDeviceCreateAdapter。 下列流程圖顯示建立 NETADAPTER 物件時,用戶端驅動程式與類別延伸模組之間的互動。
當 EvtDevicePrepareHardware 成功完成時,MBBCx 會起始主要 PDP 內容/預設 EPS 持有人的 NETADAPTER 物件流程。
每當應用程式要求隨選連線時, WwanSvc 就會觸發建立次要 PDP 內容/專用 EPS 持有人的 NETADAPTER 物件流程。
NETADAPTER 物件的存留期
當用戶端驅動程式不再使用時,MBBCx 會自動終結用戶端驅動程式所建立的 NETADAPTER 物件。 例如,這會在停用其他 PDP 內容/EPS 持有人之後發生。 MBBCx 用戶端驅動程式不得在所建立的 NETADAPTER 物件上呼叫 WdfObjectDelete 。
如果用戶端驅動程式需要清除系結至 NETADAPTER 物件的內容資料,它應該在呼叫NetAdapterCreate時,在物件屬性結構中提供EvtDestroyCallback函式。
MBB 裝置的電源管理
針對電源管理,用戶端驅動程式應該使用 NETPOWERSETTINGS 物件 ,就像其他類型的 NetAdapterCx 用戶端驅動程式一樣。
處理裝置服務會話
當應用程式將 DSS 資料向下傳送至數據機裝置時,MBBCx 會叫用用戶端驅動程式的 EvtMbbDeviceSendServiceSessionData 回 呼函式。 然後,用戶端驅動程式應該以非同步方式將資料傳送至裝置,並在傳送完成後呼叫 MbbDeviceSendDeviceServiceSessionDataComplete ,因此 MBBCx 可以釋放為數據配置的記憶體。
相反地,用戶端驅動程式會呼叫 MbbDeviceReceiveDeviceServiceSessionData ,以透過 MBBCx 將任何資料傳遞至應用程式。
Windows 驅動程式相容需求
- 符合 DCH 設計原則
- 遵循 驅動程式套件隔離 原則
- 遵循 API 分層需求
- 使用硬體實驗室套件向Windows 硬體相容性計畫認證程式進行認證