Share via


Emparejamiento de un conjunto con la propiedad DeviceInformationPairing.Custom

Nota:

Parte de la información hace referencia al producto de versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Use las API Windows.Devices.Enumeration para emparejar dispositivos como un conjunto.

Windows admite el emparejamiento de una colección de dispositivos como un conjunto. La plataforma admite dos tipos de conjuntos.

  • Conjunto detectado automáticamente. Esto sucede cuando un protocolo (como Bluetooth LE) detecta automáticamente otros puntos de conexión que pertenecen al conjunto al emparejar un punto de conexión principal. Por ejemplo, mientras un usuario está emparejando el auricular derecho a través de Bluetooth LE, la pila de protocolos puede detectar el auricular izquierdo, de modo que ambos pueden emparejarse como un conjunto.
  • Conjunto explícito. Son útiles cuando se detecta un dispositivo en más de un protocolo. Por ejemplo, las impresoras del Protocolo de impresión en Internet (IPP) normalmente se detectan en tres protocolos: IPP, WSD y eSCL. Cuando se detectan varios puntos de conexión para el mismo dispositivo, se pueden emparejar explícitamente como un conjunto.

Ejemplo de código para un conjunto detectado automáticamente (estilo Bluetooth)

Este ejemplo de código implementa el emparejamiento de conjuntos detectados automáticamente (estilo Bluetooth) mediante un objeto de emparejamiento personalizado. Al igual que con una implementación típica del emparejamiento personalizado, se requiere un controlador solicitado por emparejamiento para controlar la ceremonia de emparejamiento. En este caso, el ejemplo de código implementa solo la ceremonia de emparejamiento de confirmación. La parte nueva e interesante es añadir un controlador pairing-set-member-requested.

El controlador set-member permite a la plataforma intentar emparejar el dispositivo transferido como un conjunto. Sin ese controlador, la pila de protocolos no intentará enumerar los miembros de un conjunto de emparejamiento. El protocolo Bluetooth detecta los miembros del conjunto como parte de la finalización del emparejamiento, por lo que se llama al controlador del conjunto en algún momento después de que su controlador de ceremonia regrese. En este flujo, el controlador de conjuntos generalmente puede esperar ser llamado una vez después de controlar la ceremonia con una lista fija de miembros del conjunto; lo que significa que el protocolo detecta todos los puntos de conexión que puede durante el emparejamiento y no detectará más después.

Este ejemplo de código empareja de forma sincrónica todos los miembros del conjunto detectados con la misma rutina BtSetPairing que se usa para emparejar el dispositivo o punto de conexión principal. También se admite el emparejamiento en paralelo y puede ser más eficaz para su escenario. Pero por motivos de simplicidad, esto no se muestra en el ejemplo de código. Dado que también estamos emparejando los miembros del conjunto con un controlador de conjuntos, pueden producir de forma recursiva más miembros del conjunto para emparejar. Pero normalmente, el controlador de conjuntos para los miembros del conjunto detectado probablemente solo verá la detección completada con el vector de miembro del conjunto que está vacío.

Nota:

Este ejemplo de código es sin el contexto de un escenario o aplicación más grande; pero es probable que una aplicación tenga que realizar un seguimiento de los dispositivos que está emparejando y los resultados del emparejamiento. De este modo, la aplicación puede saber si la operación de emparejamiento de conjuntos se ha realizado correctamente o no.

Nota:

Estas API suelen ser asincrónicas. Las operaciones de emparejamiento tienen sus propios subprocesos de trabajo y se llama a los controladores en diferentes subprocesos. El código no tiene que bloquearse con tanta frecuencia como lo hace este ejemplo de código.

Ejemplo de código en C++/WinRT

void PairingTests::BtSetPairing(DeviceInformation device)
{
    DevicePairingKinds ceremonies = DevicePairingKinds::ConfirmOnly;
    auto customPairing = device.Pairing().Custom();
    event_revoker ceremonyEventToken = customPairing.PairingRequested(
        { this, &PairingTests::PairingRequestedHandler });
    event_revoker setEventToken = customPairing.PairingSetMembersRequested(
        { this, &PairingTests::PairingSetMembersRequestedHandler });

    DevicePairingResult result = customPairing.PairAsync(ceremonies).get();

    if (DevicePairingResultStatus::Paired == result.Status()) // Pairing worked.
    else // Handle pairing failure.
}

void PairingTests::PairingRequestedHandler(DeviceInformationCustomPairing const&,
    DevicePairingRequestedEventArgs const& args)
{
    switch (args.PairingKind())
    {
    case DevicePairingKinds::ConfirmOnly:
        args.Accept();
        break;
    default:
        // This code example doesn't implement other ceremonies.
        // The handler wouldn't be called for ceremonies that the app didn't register.
    }
}

void PairingTests::PairingSetMembersRequestedHandler(DeviceInformationCustomPairing
    const&, DevicePairingSetMembersRequestedEventArgs const& args)
{
    switch (args.Status())
    {
    case DevicePairingAddPairingSetMemberStatus::SetDiscoveryCompletedByProtocol:
        // This is the expected result if we started set pairing 
        // a Bluetooth device. Note: there still might be no set members.
        break;
    case DevicePairingAddPairingSetMemberStatus::SetDiscoveryPartiallyCompletedByProtocol:
        // The protocol enumerated some but not all set members.
        break;
    case DevicePairingAddPairingSetMemberStatus::SetDiscoveryNotAttemptedByProtocol:
        // Not expected for Bluetooth.
        // This constant implies that the protocol likely doesn't support set-pairing.
    default:
        // The other constants aren't expected in an auto-discovered Bluetooth set scenario.
        // Error handling can go here.
    }

    for (auto setMember : args.PairingSetMembers())
    {
        BtSetPairing(setMember);
    }
}

Ejemplo de código para un conjunto explícito (estilo IPP)

En este ejemplo de código se implementa el emparejamiento de conjuntos explícitos mediante un objeto de emparejamiento personalizado. Al igual que con una implementación típica del emparejamiento personalizado, se requiere un controlador solicitado por emparejamiento para controlar la ceremonia de emparejamiento. En este caso, el ejemplo de código implementa solo la ceremonia de emparejamiento de confirmación. Al igual que con el ejemplo de código Bluetooth, la parte nueva e interesante es añadir un controlador pairing-set-member-requested. El controlador de miembros del conjunto permite a la plataforma intentar emparejar dispositivos como un conjunto.

En comparación con el escenario de emparejamiento de conjuntos de estilo Bluetooth, este ejemplo de código agrega explícitamente dispositivos al conjunto. En comparación con Bluetooth, el controlador de conjuntos implica algo un poco diferente de los protocolos relacionados con el emparejamiento de impresoras IPP. Implica que los clientes controlan la detección de dispositivos en los distintos protocolos y se deben sincronizar el estado PnP y las colas de impresión creadas como resultado de emparejar todos los miembros del conjunto.

Para simplificar la implementación del ejemplo de código, se supone que se detectó de antemano un vector de puntos de conexión de miembros del conjunto que se transfirió como un parámetro junto con el dispositivo principal. Por ejemplo, en un escenario típico de IPP, los puntos de conexión se detectan en orden arbitrario. Por lo tanto, el dispositivo principal podría haberse detectado a través de WSD por ejemplo; y, a continuación, el vector incluiría dispositivos que representan los puntos de conexión detectados a través de IPP y eSCL. Pero cualquier combinación es posible y válida. Agrega miembros del conjunto al objeto de emparejamiento personalizado del dispositivo principal en el subproceso principal de la aplicación y, a continuación, llama a PairAsync.

Nota:

En la práctica, los miembros del conjunto se pueden agregar a un objeto de emparejamiento personalizado en cualquier momento en cualquier subproceso. Las operaciones sobre un protocolo pueden tardar mucho tiempo o incluso pueden bloquearse hasta que agotan el tiempo de espera, por lo que es útil superponerlas. Considere la posibilidad de aprovechar el paralelismo de la API para agregar y emparejar dispositivos simultáneamente. Esto es posible incluso mientras sigue enumerando dispositivos a través de la conexión. Las ventajas de emparejarlos como un conjunto siguen aplicándose generalmente.

Con esta implementación, el miembro del conjunto principal se emparejará simultáneamente con los miembros del conjunto. Los miembros del conjunto se emparejan de una en una vez de forma sincrónica en el controlador. Pero de nuevo, se pueden emparejar en paralelo para mejorar la eficacia.

Los objetos de nodo de dispositivo en PnP se suelen crear como resultado del emparejamiento. En el caso de IPP, los nodos de dispositivo siempre se crean para cada punto de conexión después del emparejamiento. Esta API de emparejamiento de conjuntos sincroniza implícitamente la creación de nodos de dispositivo entre los puntos de conexión del conjunto. En el flujo de este ejemplo de código, todos los nodos de dispositivo se sincronizarán porque todos los miembros del conjunto se han añadido antes de que se inicie el emparejamiento. Para obtener más información sobre cómo esta API sincroniza los nodos de dispositivo en PnP, consulte la sección Comentarios generales de este tema.

Nota:

Este ejemplo de código es sin el contexto de un escenario o aplicación más grande; pero es probable que una aplicación tenga que realizar un seguimiento de los dispositivos que está emparejando y los resultados del emparejamiento. De este modo, la aplicación puede saber si la operación de emparejamiento de conjuntos se ha realizado correctamente o no.

Ejemplo de código en C++/WinRT

void PairingTests::IppSetPairing(DeviceInformation device,
    std::vector<DeviceInformation> const& setMemberDevices)
{
    DevicePairingKinds ceremonies = DevicePairingKinds::ConfirmOnly;
    auto customPairing = device.Pairing().Custom();
    event_revoker ceremonyEventToken = customPairing.PairingRequested({ this,
                     &PairingTests::PairingRequestedHandler });
    event_revoker setEventToken = customPairing.PairingSetMembersRequested({ this,
                  &PairingTests::PairingSetMembersRequestedHandler });

    if (setMemberDevices)
    {
        for (auto setDevice : setMemberDevices)
        {
            customPairing.AddPairingSetMember(setDevice);
        }
    }

    DevicePairingResult result = customPairing.PairAsync(ceremonies).get();

    if (DevicePairingResultStatus::Paired == result.Status()) // Pairing worked.
    else // Handle pairing failure.
}

void PairingTests::PairingRequestedHandler(DeviceInformationCustomPairing const&,
    DevicePairingRequestedEventArgs const& args)
{
    switch (args.PairingKind())
    {
    case DevicePairingKinds::ConfirmOnly:
        args.Accept();
        break;
    }
}

void PairingTests::PairingSetMembersRequestedHandler(DeviceInformationCustomPairing const&,
    DevicePairingSetMembersRequestedEventArgs args)
{
    switch (args.Status())
    {
    case DevicePairingAddPairingSetMemberStatus::AddedToSet:
        // This is the expected result of adding a set member(s) to
        // a Bluetooth device. Note: there still might be no set members.
        break;
    case DevicePairingAddPairingSetMemberStatus::CouldNotBeAddedToSet:
        // Means we failed to add set member(s).
        break;
    case DevicePairingAddPairingSetMemberStatus::SetDiscoveryNotAttemptedByProtocol:
    default:
        // The other constants aren't expected in an auto-discovered Bluetooth set scenario.
        // Error handling can go here.
    }

    for (auto setMember : args.PairingSetMembers())
    {
        IppSetPairing(setMember, nullptr);
    }
}

Comentarios generales

Emparejamiento de conjuntos detectados automáticamente (estilo Bluetooth)

Esta API es necesaria para lograr el emparejamiento de conjuntos de estilo Bluetooth donde el protocolo detecta los miembros del conjunto después de emparejar el punto de conexión principal. Un ejemplo sencillo podría ser un conjunto de auriculares inalámbricos. Al finalizar el emparejamiento del primer auricular, el dispositivo informa al equipo de que hay un segundo dispositivo para emparejar como parte del conjunto. La API de emparejamiento personalizado se extiende para permitir que las aplicaciones controlen las operaciones de conjunto mediante el nuevo controlador de add set member status.

Emparejamiento de conjuntos explícitos (estilo IPP)

Del mismo modo, también puede usar esta API para emparejar cualquier grupo de dispositivos de punto de conexión de asociación (AEP) como un conjunto. Con un objeto de emparejamiento personalizado, la aplicación puede agregar otros puntos de conexión al conjunto de emparejamiento en cualquier momento en cualquier subproceso. Esto es así porque la detección y el emparejamiento de dispositivos a través de una red puede llevar mucho tiempo para cada dispositivo, por lo que no queremos serializar estas operaciones cuando podemos evitarlo.

Es especialmente útil emparejar conjuntos al detectar dispositivos en muchos protocolos en los que las pilas de protocolos y dispositivos no se coordinan fácilmente. Por ejemplo, es probable que Windows detecte una impresora de red moderna con tres protocolos de red diferentes, cada uno de los cuales genera puntos de conexión de asociación. En ese caso, emparejar los tres puntos de conexión como un conjunto es muy útil por un par de razones: evita el desperdicio de una nueva detección por cable y crea una sola cola de impresión simplificada.

Incluso si una impresora de red no está emparejada como un conjunto, el administrador de trabajos de impresión sigue intentando crear una sola cola de impresión por usuario, independientemente de si se puede emparejar a través de varios protocolos. Si una impresora se empareja inicialmente a través de un protocolo, el sistema operativo (SO) intentará volver a detectarla en los demás protocolos admitidos y asociarse a través de todos ellos para evitar colas de impresión duplicadas. Normalmente, el sistema operativo puede hacerlo de forma rápida y correcta y generar una cola de impresión simplificada.

Sin embargo, si la aplicación ya ha descubierto todos los puntos de conexión de la impresora, este paso de nueva detección es inútil. Y lo que es peor, puede provocar grandes retrasos antes de que la impresora esté lista para su uso. Además, si los protocolos están demasiado desincronizados o retrasados, es posible que el administrador de trabajos de impresión tenga que crear colas de impresión adicionales para la misma impresora, lo que resulta confuso para los usuarios finales.

Emparejar todos los puntos de conexión a la vez como un conjunto evita una nueva detección que puede resultar lenta. Garantiza la sincronización del estado PnP y genera colas de impresión optimizadas.

Sincronización de nodos de dispositivos

Cuando los dispositivos se emparejan como un conjunto con esta API, el estado de dispositivo PnP resultante se sincroniza convenientemente. La API no limita el momento en que una aplicación puede añadir un miembro a un conjunto, pero sí el momento en que la plataforma puede sincronizar los nodos de los dispositivos. La sincronización de nodos de dispositivo se bloquea hasta que todos los puntos de conexión del conjunto tengan finalizado su emparejamiento. Después, todos los nodos de dispositivo para todos los puntos de conexión se crean a la vez. Puede añadir más miembros al conjunto después de ese punto, pero no se bloquea la creación de nodos de dispositivo posteriores, sino que se crean de inmediato.

  • La creación del nodo de dispositivo se sincroniza cuando:
    • Los miembros del conjunto se agregan antes de que se inicie el emparejamiento.
    • Los miembros del conjunto se agregan mientras al menos uno de los miembros del conjunto no está finalizado.
  • La creación de nodos de dispositivo no está sincronizada:
    • En cualquier momento después de que se hayan agregado todos los miembros del conjunto.

En la práctica, la API no permite que una aplicación controle cuándo se completa la finalización de la ceremonia para influir en este comportamiento sobre cómo se sincronizan los nodos del dispositivo. La aproximación más cercana sería cuando la aplicación elige completar la ceremonia. Un emparejamiento no puede finalizar hasta que el controlador de ceremonias de la aplicación regresa; así que esa es la última oportunidad de la aplicación para influir cuando todos los miembros del conjunto están finalizados.