Поделиться через


Написание драйвера клиента MBBCx

Предупреждение

Схемы последовательностей в этом разделе предназначены только для иллюстраций. Они не являются публичными контрактами и подлежат изменению в будущем.

INF-файлы для драйверов клиентов MBBCx

INF-файлы для драйверов клиентов MBBCx совпадают с другими драйверами клиентов NetAdapterCx. Дополнительные сведения см. в INF-файлах для драйверов клиентов NetAdapterCx.

Следуйте универсальному руководству, чтобы убедиться, что INF-файлы соответствуют универсальным требованиям.

Инициализация устройства

Помимо этих задач, необходимых NetAdapterCx для инициализации устройства NetAdapter, драйвер клиента MBB также должен выполнять следующие задачи в своей функции обратного вызова EvtDriverDeviceAdd:

  1. Вызов MBB_DEVICE_CONFIG_INIT после вызова NetDeviceInitConfig, но перед вызовом WdfDeviceCreate, ссылаясь на тот же объект WDFDEVICE_INIT, переданный платформой.

  2. Вызовите MbbDeviceInitialize для регистрации функций обратного вызова для конкретного устройства MBB с помощью инициализированной структуры MBB_DEVICE_CONFIG и объекта WDFDEVICE, полученного из WdfDeviceCreate.

В следующем примере показано, как инициализировать устройство 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 не должны создавать объект NETADAPTER из функции обратного вызова EvtDriverDeviceAdd . Вместо этого MBBCx его проинструктирует сделать это позже.

Затем драйвер клиента должен вызывать MbbDeviceSetMbimParameters, как правило, в функции обратного вызова EvtDevicePrepareHardware.

Эта схема потока сообщений иллюстрирует процесс инициализации.

схема, показывающая процесс инициализации драйвера клиента MBBCx.

Эта схема потока сообщений иллюстрирует процесс инициализации.

схема, показывающая процесс инициализации драйвера клиента MBBCx.

Обработка сообщений управления MBIM

MBBCx использует стандартные команды управления MBIM, определенные в спецификации MBIM версия 1.0, в разделах 8, 9 и 10, для управляющей плоскости. Команды и ответы обмениваются набором функций обратного вызова, предоставляемых клиентским драйвером и API, предоставляемыми MBBCx. MBBCx имитирует операционную модель устройства MBIM, как определено в спецификации MBIM ред 1.0, раздел 5.3, с помощью этих вызовов функций:

  • MBBCx отправляет командное сообщение MBIM драйверу клиента, вызвав функцию обратного вызова EvtMbbDeviceSendMbimFragment. Драйвер клиента асинхронно завершает этот запрос отправки путем вызова MbbRequestComplete.
  • Драйвер клиента сигнализирует о доступности результата путем вызова MbbDeviceResponseAvailable.
  • MBBCx извлекает сообщение ответа MBIM от драйвера клиента, вызывая функцию обратного вызова EvtMbbDeviceReceiveMbimFragment. Драйвер клиента асинхронно завершает этот запрос Get-Response через вызов MbbRequestCompleteWithInformation.
  • Драйвер клиента MBB может уведомить MBBCx о непрошенном событии устройства, вызвав MbbDeviceResponseAvailable. Затем MBBCx извлекает сведения из драйвера клиента аналогично тому, как он извлекает сообщения ответа MBIM.

На следующей схеме показан поток обмена сообщениями драйвера MBBCx-client.

схема, показывающая обмен сообщениями MBIM между MBBCx и драйвером клиента.

Синхронизация сообщений управления MBIM

Платформа MBBCx всегда сериализует вызовы драйвера клиента в функции обратного вызова EvtMbbDeviceSendMbimFragment и EvtMbbDeviceReceiveMbimFragment. Новые вызовы не будут выполняться платформой, пока драйвер клиента не вызывает MbbRequestComplete или MbbRequestCompleteWithInformation.

Хотя драйвер клиента гарантированно не получает перекрывающиеся обратные вызовы EvtMbbDeviceSendMbimFragment или EvtMbbDeviceReceiveMbimFragment, он может получать несколько последовательных вызовов до того, как ответ на предыдущую команду будет доступен на устройстве.

Если устройство не находится в состоянии D0, платформа MBBCx сначала принесет устройство в D0 (иными словами, вызывает EvtDeviceD0Entry) перед вызовом EvtMbbDeviceSendMbimFragment или EvtMbbDeviceReceiveMbimFragment. Платформа MBBCx также гарантирует, что устройство будет храниться в состоянии D0, то есть он не будет вызывать EvtDeviceD0Exit, пока клиент не вызовет MbbRequestComplete или MbbRequestCompleteWithInformation.

Создание интерфейса NetAdapter для контекста PDP/носителя EPS

Перед установкой сеанса данных MBBCx будет указать драйверу клиента создать объект NETADAPTER, и он будет использоваться MBBCx для представления сетевого интерфейса для активированного сеанса данных. Это достигается тем, что MBBCx вызывает функцию обратного вызова драйвера клиента EvtMbbDeviceCreateAdapter.

В реализации функции обратного вызова EvtMbbDeviceCreateAdapter драйвер клиента MBBCx должен сначала выполнять те же задачи, необходимые для создания объекта NETADAPTER, что и любой драйвер клиента NetAdapterCx. Кроме того, он также должен выполнять следующие дополнительные задачи:

  1. Вызовите MbbAdapterInitialize для объекта NETADAPTER, созданного NetAdapterCreate.

  2. После вызова MbbAdapterinitializeвызовите MbbAdapterGetSessionId, чтобы получить идентификатор сеанса данных, который MBBCx использует для этого объекта NETADAPTER. Например, если возвращаемое значение равно 0, это означает, что MBBCx будет использовать этот интерфейс NETADAPTER для сеанса данных, установленного основным контекстом PDP/носителем EPS по умолчанию.

  3. Рекомендуется, чтобы клиентские драйверы MBBCx сохраняли внутреннее сопоставление между созданным объектом NETADAPTER и возвращенным SessionId. Это помогает отслеживать связь объекта сеанса с NETADAPTER, что особенно полезно при активации нескольких контекстов PDP/носителя EPS.

  4. Перед возвратом из EvtMbbDeviceCreateAdapterклиентские драйверы должны сначала запустить адаптер, вызвав NetAdapterStart. При необходимости они также могут задать возможности адаптера, вызвав одну или несколько этих функций перед вызовом NetAdapterStart:

MBBCx вызывает эту функцию обратного вызова по крайней мере один раз, поэтому всегда существует как минимум один объект NETADAPTER для основного контекста PDP/умолчального носителя EPS. Если активируется несколько контекстов PDP/несколько носителей EPS, MBBCx может несколько раз вызывать эту функцию обратного вызова, по одному разу для каждого сеанса данных, который необходимо установить. Между сетевым интерфейсом, представленным объектом NETADAPTER, и сеансом данных должно быть отношение один к одному, как показано на следующей схеме.

Диаграмма, показывающая несколько объектов 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 гарантирует, что он вызывает EvtMbbDeviceCreateAdapter перед запросом MBIM_CID_CONNECT с тем же идентификатором сеанса. На следующей схеме потока показаны взаимодействия между драйвером клиента и расширением класса при создании объекта NETADAPTER.

схема, показывающая создание и активацию NETADAPTER для драйвера клиента MBB.

Процесс создания объекта NETADAPTER для основного контекста PDP/носителя EPS по умолчанию инициируется MBBCx после успешного завершения EvtDevicePrepareHardware.

Поток создания объекта NETADAPTER для дополнительного контекста PDP/выделенного EPS-носителя активируется WwanSvc всякий раз, когда подключения по требованию запрашиваются приложениями.

Время существования объекта NETADAPTER

Объект NETADAPTER, созданный драйвером клиента, автоматически уничтожается MBBCx, когда он больше не используется. Например, это происходит после отключения дополнительных носителей PDP или носителя EPS. драйверы клиента MBBCx не должны вызывать WdfObjectDelete на создаваемых объектах NETADAPTER.

Если драйвер клиента должен очистить данные контекста, привязанные к объекту NETADAPTER, он должен предоставить функцию EvtDestroyCallback в структуре атрибутов объекта при вызове NetAdapterCreate.

Управление питанием устройства MBB

Для управления питанием клиентские драйверы должны использовать объект NETPOWERSETTINGS , как и другие типы клиентских драйверов NetAdapterCx.

Управление сеансами обслуживания устройств

Когда приложение отправляет данные DSS на модемное устройство, MBBCx вызывает функцию обратного вызова EvtMbbDeviceSendServiceSessionData драйвера клиента. Затем драйвер клиента должен асинхронно отправлять данные на устройство и вызывать MbbDeviceSendDeviceServiceSessionDataComplete после завершения отправки, поэтому MBBCx может освободить память, выделенную для данных.

И наоборот, драйвер клиента вызывает MbbDeviceReceiveDeviceServiceSessionData, чтобы передать любые данные в приложение через MBBCx.

Требования совместимости драйверов Windows