Compartilhar via


Escrevendo um driver de cliente MBBCx

Aviso

Os diagramas de sequência neste tópico são apenas para fins ilustrativos. Eles não são contratos públicos e estão sujeitos a mudanças no futuro.

Arquivos INF para drivers de cliente MBBCx

Os arquivos INF para drivers de cliente MBBCx são os mesmos que outros drivers de cliente NetAdapterCx. Para obter mais informações, consulte arquivos INF para drivers de cliente NetAdapterCx.

Siga as diretrizes universais para garantir que os arquivos INF atendam aos requisitos universais.

Inicializar o dispositivo

Além das tarefas exigidas pelo NetAdapterCx para a inicialização do dispositivo NetAdapter, um driver de cliente MBB também deve executar as seguintes tarefas em sua função de retorno de chamada EvtDriverDeviceAdd:

  1. Chame MBB_DEVICE_CONFIG_INIT depois de chamar NetDeviceInitConfig , mas antes de chamar WdfDeviceCreate, referenciando o mesmo objeto WDFDEVICE_INIT passado pela estrutura.

  2. Chame MbbDeviceInitialize para registrar funções de retorno de chamada específicas do dispositivo MBB utilizando uma estrutura MBB_DEVICE_CONFIG inicializada e o objeto WDFDEVICE obtido de WdfDeviceCreate.

O exemplo a seguir demonstra como inicializar o dispositivo MBB. O tratamento de erros foi deixado de fora para maior clareza.

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

Ao contrário de outros tipos de drivers NetAdapterCx, os drivers de cliente do MBB não devem criar o objeto NETADAPTER de dentro da função de retorno de chamada EvtDriverDeviceAdd. Em vez disso, o MBBCx instruirá você a fazer isso mais tarde.

Em seguida, o driver do cliente deve chamar MbbDeviceSetMbimParameters, geralmente na função de retorno de chamada EvtDevicePrepareHardware que se segue.

Este diagrama de fluxo de mensagens ilustra o processo de inicialização.

Diagrama que mostra o processo de inicialização do driver de cliente MBBCx.

Este diagrama de fluxo de mensagens ilustra o processo de inicialização.

Diagrama que mostra o processo de inicialização do driver de cliente MBBCx.

Manipulando mensagens de controle MBIM

O MBBCx usa os comandos de controle MBIM padrão definidos na especificação MBIM Rev 1.0, seções 8, 9 e 10, para o plano de controle. Comandos e respostas são trocados por meio de um conjunto de funções de retorno de chamada fornecidas pelo driver do cliente e APIs fornecidas pelo MBBCx. O MBBCx imita o modelo operacional de um dispositivo MBIM, conforme definido na especificação MBIM Rev 1.0, seção 5.3, usando estas chamadas de função:

  • O MBBCx envia uma mensagem de comando MBIM para o driver cliente invocando sua função de retorno de chamada EvtMbbDeviceSendMbimFragment . O driver cliente conclui essa solicitação de envio de forma assíncrona chamando MbbRequestComplete.
  • O driver cliente sinaliza a disponibilidade do resultado chamando MbbDeviceResponseAvailable.
  • O MBBCx obtém a mensagem de resposta MBIM do driver cliente ao invocar sua função de retorno de chamada EvtMbbDeviceReceiveMbimFragment. O driver cliente conclui de forma assíncrona essa solicitação get-response chamando MbbRequestCompleteWithInformation.
  • O driver do cliente MBB pode notificar o MBBCx de um evento de dispositivo não solicitado chamando MbbDeviceResponseAvailable. Em seguida, o MBBCx recupera as informações do driver cliente de maneira semelhante à maneira como ele busca mensagens de resposta MBIM.

O diagrama a seguir ilustra o fluxo de troca de mensagens do driver MBBCx-client.

Diagrama que mostra a troca de mensagens MBIM entre MBBCx e o driver cliente.

Sincronização de mensagens de controle MBIM

A estrutura MBBCx sempre serializa chamadas nas funções de retorno de chamada EvtMbbDeviceSendMbimFragment e EvtMbbDeviceReceiveMbimFragment do driver do cliente. Nenhuma nova chamada será feita pela estrutura até que o driver cliente chame MbbRequestComplete ou MbbRequestCompleteWithInformation.

Embora seja garantido que um driver cliente não receba retornos de chamada EvtMbbDeviceSendMbimFragment ou EvtMbbDeviceReceiveMbimFragment sobrepostos, ele pode receber várias chamadas para eles sucessivamente antes que a resposta de um comando anterior esteja disponível no dispositivo.

Se o dispositivo não estiver no estado D0 , a estrutura MBBCx primeiro levará o dispositivo para D0 (em outras palavras, ele chama EvtDeviceD0Entry) antes de chamar EvtMbbDeviceSendMbimFragment ou EvtMbbDeviceReceiveMbimFragment. A estrutura MBBCx também garante que manterá o dispositivo no estado D0, o que significa que ele não chamará EvtDeviceD0Exit até que o cliente chame MbbRequestComplete ou MbbRequestCompleteWithInformation.

Criar a interface NetAdapter para o contexto PDP/portador EPS

Antes de estabelecer uma sessão de dados, o MBBCx instruirá o driver cliente a criar um objeto NETADAPTER e ele será usado pelo MBBCx para representar a interface de rede para a sessão de dados ativada. Isso é feito pelo MBBCx chamando a função de retorno de chamada EvtMbbDeviceCreateAdapter do driver de cliente.

Na implementação da função de retorno de chamada EvtMbbDeviceCreateAdapter, o driver cliente MBBCx deve inicialmente executar as mesmas tarefas necessárias que qualquer driver cliente NetAdapterCx para criar um objeto NETADAPTER. Além disso, ele também deve executar as seguintes tarefas adicionais:

  1. Chame MbbAdapterInitialize no objeto NETADAPTER criado por NetAdapterCreate.

  2. Depois de chamar MbbAdapterinitialize, chame MbbAdapterGetSessionId para recuperar a ID da sessão de dados para a qual o MBBCx pretende usar esse objeto NETADAPTER. Por exemplo, se o valor retornado for 0, significa que o MBBCx usará esta interface NETADAPTER para a sessão de dados estabelecida pelo contexto PDP primário/portador EPS padrão.

  3. Recomendamos que os drivers de cliente MBBCx mantenham um mapeamento interno entre o objeto NETADAPTER criado e o SessionId retornado. Isso ajuda a acompanhar a relação entre a sessão de dados e o objeto NETADAPTER, que é especialmente útil quando vários contextos PDP/portadores EPS foram ativados.

  4. Antes de retornar de EvtMbbDeviceCreateAdapter, os drivers cliente devem iniciar o adaptador chamando NetAdapterStart. Opcionalmente, eles também podem definir os recursos do adaptador chamando uma ou mais dessas funções antes de a chamada para NetAdapterStart:

O MBBCx invoca essa função de retorno de chamada pelo menos uma vez; portanto, sempre há um objeto NETADPATER para o contexto PDP primário/portador EPS padrão. Se vários contextos PDP/portadores EPS forem ativados, o MBBCx poderá invocar essa função de retorno de chamada mais vezes, uma vez para cada sessão de dados a ser estabelecida. Deve haver uma relação um-para-um entre o adaptador de rede representado pelo objeto NETADAPTER e uma sessão de dados, conforme mostrado no diagrama a seguir.

Diagrama que mostra vários objetos NETADAPTER para sessões de dados diferentes.

O exemplo a seguir mostra como criar um objeto NETADAPTER para uma sessão de dados. Observe que o tratamento de erros e o código necessários para configurar os recursos do adaptador são deixados de fora para fins de brevidade e clareza.

    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 obter um exemplo de código para configurar recursos de datapath, consulte Gerenciamento de buffer de dados de rede.

A MBBCx garante que ele chame EvtMbbDeviceCreateAdapter antes de solicitar MBIM_CID_CONNECT com a mesma ID de sessão. O diagrama de fluxo a seguir mostra as interações entre o driver cliente e a extensão de classe na criação do objeto NETADAPTER.

Diagrama que mostra a criação e a ativação de NETADAPTER para um driver de cliente MBB.

O fluxo para criar o objeto NETADAPTER para o contexto PDP primário/portador EPS padrão é iniciado pela MBBCx quando EvtDevicePrepareHardware é concluído com sucesso.

O fluxo para criar o objeto NETADAPTER para o contexto PDP secundário/portador de EPS dedicado é disparado pelo WwanSvc sempre que conexões sob demanda são solicitadas por aplicativos.

Tempo de vida do objeto NETADAPTER

O objeto NETADAPTER criado pelo driver cliente será destruído automaticamente pelo MBBCx quando ele não estiver mais em uso. Por exemplo, isso acontece depois que portadores de contexto PDP/EPS adicionais são desativados. Os drivers de cliente MBBCx não devem chamar WdfObjectDelete nos objetos NETADAPTER que eles criam.

Se um driver cliente precisar limpar dados de contexto vinculados a um objeto NETADAPTER, ele deverá fornecer uma função EvtDestroyCallback na estrutura de atributos de objeto ao chamar NetAdapterCreate.

Gerenciamento de energia do dispositivo MBB

Para o gerenciamento de energia, os drivers cliente devem usar o objeto NETPOWERSETTINGS como outros tipos de drivers de cliente NetAdapterCx.

Gerenciamento de sessões de serviço de dispositivo

Quando um aplicativo envia dados DSS para o dispositivo do modem, a MBBCx invoca a função de retorno de chamada EvtMbbDeviceSendServiceSessionData do driver do cliente. Em seguida, o driver cliente deve enviar os dados de forma assíncrona para o dispositivo e chamar MbbDeviceSendDeviceServiceSessionDataComplete depois que o envio for concluído, para que o MBBCx possa liberar a memória alocada para os dados.

Por outro lado, o driver cliente chama MbbDeviceReceiveDeviceServiceSessionData para passar todos os dados para o aplicativo por meio do MBBCx.

Requisitos de compatibilidade com drivers do Windows