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

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

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

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

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

Следуйте рекомендациям Universal , чтобы убедиться, что 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 должен сначала выполнить те же задачи, что и любой клиентский драйвер 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 вызывает эту функцию обратного вызова по крайней мере один раз, поэтому всегда имеется один объект NETADPATER для основного контекста 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, он должен предоставить функцию EvtDesphereCallback в структуре атрибутов объекта при вызове NetAdapterCreate.

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

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

Обработка сеансов службы устройств

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

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

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