Compartir a través de


Escritura de un controlador de cliente MBBCx

Advertencia

Los diagramas de secuencia de este tema son solo con fines ilustrativos. No son contratos públicos y están sujetos a cambios en el futuro.

Archivos INF para controladores de cliente MBBCx

Los archivos INF para los controladores de cliente MBBCx son los mismos que otros controladores de cliente netAdapterCx. Para obtener más información, vea Archivos INF para controladores de cliente netAdapterCx.

Siga las instrucciones universales para asegurarse de que los archivos INF cumplen los requisitos universales.

Inicialización del dispositivo

Además de esas tareas requeridas por NetAdapterCx para la inicialización de dispositivos NetAdapter, un controlador cliente MBB también debe realizar las siguientes tareas en su función de devolución de llamada EvtDriverDeviceAdd :

  1. Llame a MBB_DEVICE_CONFIG_INIT después de llamar a NetDeviceInitConfig , pero antes de llamar a WdfDeviceCreate, haciendo referencia al mismo objeto de WDFDEVICE_INIT pasado por el marco.

  2. Llame a MbbDeviceInitialize para registrar funciones de devolución de llamada específicas del dispositivo MBB mediante una estructura de MBB_DEVICE_CONFIG inicializada y el objeto WDFDEVICE obtenido de WdfDeviceCreate.

En el ejemplo siguiente se muestra cómo inicializar el dispositivo MBB. El control de errores se ha dejado fuera para mayor claridad.

    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);

A diferencia de otros tipos de controladores NetAdapterCx, los controladores de cliente MBB no deben crear el objeto NETADAPTER desde la función de devolución de llamada EvtDriverDeviceAdd . En su lugar, MBBCx le indicará que lo haga más adelante.

A continuación, el controlador cliente debe llamar a MbbDeviceSetMbimParameters, normalmente en la función de devolución de llamada EvtDevicePrepareHardware que sigue.

En este diagrama de flujo de mensajes se muestra el proceso de inicialización.

Diagrama que muestra el proceso de inicialización del controlador cliente MBBCx.

En este diagrama de flujo de mensajes se muestra el proceso de inicialización.

Diagrama que muestra el proceso de inicialización del controlador cliente MBBCx.

Control de mensajes de control MBIM

MBBCx usa los comandos de control MBIM estándar definidos en la especificación MBIM Rev 1.0, secciones 8, 9 y 10 para el plano de control. Los comandos y respuestas se intercambian a través de un conjunto de funciones de devolución de llamada proporcionadas por el controlador de cliente y las API proporcionadas por MBBCx. MBBCx imita el modelo operativo de un dispositivo MBIM, tal y como se define en la especificación MBIM Rev 1.0, sección 5.3, mediante estas llamadas de función:

  • MBBCx envía un mensaje de comando MBIM al controlador cliente invocando su función de devolución de llamada EvtMbbDeviceSendMbimFragment . El controlador cliente completa de forma asincrónica esta solicitud de envío llamando a MbbRequestComplete.
  • El controlador cliente señala la disponibilidad del resultado llamando a MbbDeviceResponseAvailable.
  • MBBCx captura el mensaje de respuesta MBIM del controlador cliente invocando su función de devolución de llamada EvtMbbDeviceReceiveMbimFragment . El controlador cliente completa de forma asincrónica esta solicitud get-response llamando a MbbRequestCompleteWithInformation.
  • El controlador de cliente MBB puede notificar a MBBCx un evento de dispositivo no solicitado llamando a MbbDeviceResponseAvailable. A continuación, MBBCx recupera la información del controlador de cliente de forma similar a cómo captura mensajes de respuesta MBIM.

En el diagrama siguiente se muestra el flujo de intercambio de mensajes del controlador MBBCx-client.

Diagrama que muestra el intercambio de mensajes MBIM entre MBBCx y el controlador de cliente.

Sincronización de mensajes de control MBIM

El marco MBBCx siempre serializa las llamadas a las funciones de devolución de llamada EvtMbbDeviceSendMbimFragment y EvtMbbDeviceReceiveMbimFragment del controlador cliente. El marco no realizará ninguna nueva llamada hasta que el controlador cliente llame a MbbRequestComplete o MbbRequestCompleteWithInformation.

Aunque se garantiza que un controlador de cliente no reciba devoluciones de llamada EvtMbbDeviceSendMbimFragment o EvtMbbDeviceReceiveMbimFragment superpuestas, puede recibir varias llamadas a ellas en sucesión antes de que la respuesta de un comando anterior esté disponible en el dispositivo.

Si el dispositivo no está en estado D0 , el marco MBBCx llevará primero el dispositivo a D0 (es decir, llama a EvtDeviceD0Entry) antes de llamar a EvtMbbDeviceSendMbimFragment o EvtMbbDeviceReceiveMbimFragment. El marco MBBCx también garantiza que mantendrá el dispositivo en el estado D0, lo que significa que no llamará a EvtDeviceD0Exit, hasta que el cliente llame a MbbRequestComplete o MbbRequestCompleteWithInformation.

Creación de la interfaz NetAdapter para el portador de PDP/EPS

Antes de establecer una sesión de datos, MBBCx indicará al controlador cliente que cree un objeto NETADAPTER y MBBCx lo usará para representar la interfaz de red de la sesión de datos activada. Esto se logra mediante la llamada de MBBCx a la función de devolución de llamada EvtMbbDeviceCreateAdapter del controlador cliente.

En la implementación de la función de devolución de llamada EvtMbbDeviceCreateAdapter , el controlador cliente MBBCx primero debe realizar las mismas tareas necesarias para crear un objeto NETADAPTER que cualquier controlador de cliente netAdapterCx. Además, también debe realizar las siguientes tareas adicionales:

  1. Llame a MbbAdapterInitialize en el objeto NETADAPTER creado por NetAdapterCreate.

  2. Después de llamar a MbbAdapterinitialize, llame a MbbAdapterGetSessionId para recuperar el identificador de sesión de datos para el que MBBCx pretende usar este objeto NETADAPTER. Por ejemplo, si el valor devuelto es 0, significa que MBBCx usará esta interfaz NETADAPTER para la sesión de datos establecida por el contexto PDP principal/portador EPS predeterminado.

  3. Se recomienda que los controladores de cliente MBBCx mantengan una asignación interna entre el objeto NETADAPTER creado y el SessionId devuelto. Esto ayuda a realizar un seguimiento de la relación de objeto de sesión de datos a NETADAPTER, que resulta especialmente útil cuando se han activado varios contextos de PDP o portadores EPS.

  4. Antes de volver desde EvtMbbDeviceCreateAdapter, los controladores cliente deben iniciar el adaptador llamando a NetAdapterStart. Opcionalmente, también pueden establecer las funcionalidades del adaptador llamando a una o varias de estas funciones antes de la llamada a NetAdapterStart:

MBBCx invoca esta función de devolución de llamada al menos una vez, por lo que siempre hay un objeto NETADPATER para el portador EPS predeterminado o contexto PDP principal. Si se activan varios contextos PDP o portadores EPS, MBBCx podría invocar esta función de devolución de llamada más veces, una vez para cada sesión de datos que se va a establecer. Debe haber una relación uno a uno entre la interfaz de red representada por el objeto NETADAPTER y una sesión de datos, como se muestra en el diagrama siguiente.

Diagrama que muestra varios objetos NETADAPTER para sesiones de datos diferentes.

En el ejemplo siguiente se muestra cómo crear un objeto NETADAPTER para una sesión de datos. Tenga en cuenta que el control de errores y el código necesarios para configurar las funcionalidades del adaptador se deja fuera para mayor brevedad y claridad.

    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;
    }

Para obtener un ejemplo de código de configuración de funcionalidades de ruta de datos, consulte Administración del búfer de datos de red.

MBBCx garantiza que llama a EvtMbbDeviceCreateAdapter antes de solicitar MBIM_CID_CONNECT con el mismo identificador de sesión. En el diagrama de flujo siguiente se muestran las interacciones entre el controlador de cliente y la extensión de clase para crear el objeto NETADAPTER.

Diagrama que muestra la creación y activación de NETADAPTER para un controlador de cliente MBB.

El flujo para crear el objeto NETADAPTER para el contexto PDP principal o el portador EPS predeterminado se inicia mediante MBBCx cuando EvtDevicePrepareHardware ha finalizado correctamente.

WwanSvc desencadena el flujo para crear el objeto NETADAPTER para el contexto PDP secundario o el portador EPS dedicado cuando las aplicaciones solicitan conexiones a petición.

Duración del objeto NETADAPTER

El objeto NETADAPTER creado por el controlador de cliente se destruirá automáticamente por MBBCx cuando ya no esté en uso. Por ejemplo, esto sucede después de desactivar otros portadores de PDP/EPS. Los controladores de cliente MBBCx no deben llamar a WdfObjectDelete en los objetos NETADAPTER que crean.

Si un controlador de cliente necesita limpiar los datos de contexto vinculados a un objeto NETADAPTER, debe proporcionar una función EvtDestroyCallback en la estructura de atributos de objeto al llamar a NetAdapterCreate.

Administración de energía del dispositivo MBB

Para la administración de energía, los controladores de cliente deben usar el objeto NETPOWERSETTINGS como otros tipos de controladores de cliente netAdapterCx.

Control de sesiones de servicio de dispositivos

Cuando una aplicación envía datos DSS al dispositivo módem, MBBCx invoca la función de devolución de llamada EvtMbbDeviceSendServiceSessionData del controlador cliente. A continuación, el controlador de cliente debe enviar los datos de forma asincrónica al dispositivo y llamar a MbbDeviceSendDeviceServiceSessionDataComplete una vez completado el envío, por lo que MBBCx puede liberar la memoria asignada para los datos.

Por el contrario, el controlador cliente llama a MbbDeviceReceiveDeviceServiceSessionData para pasar los datos a la aplicación a través de MBBCx.

Requisitos compatibles con los controladores de Windows