Partager via


Appairage d’un ensemble avec la propriété DeviceInformationPairing.Custom

Remarque

Certaines informations portent sur la préversion du produit, qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Utilisez les API Windows.Devices.Enumeration pour appairer des appareils en tant qu’ensemble.

Windows permet d’appairer une collection d’appareils en tant qu’ensemble. La plate-forme prend en charge deux types d’ensembles.

  • Ensemble détecté automatiquement. Cela se produit lorsqu’un protocole (tel que Bluetooth LE) détecte automatiquement d’autres points de terminaison qui appartiennent à l’ensemble pendant l’appairage d’un point de terminaison principal. Par exemple, lorsqu’un utilisateur appaire l’écouteur droit via Bluetooth LE, la pile de protocole peut détecter l’écouteur gauche ; les deux peuvent donc être appairés en tant qu’ensemble.
  • Ensemble explicite. Ces ensembles sont utiles lorsqu’un appareil est détecté par plus d’un protocole. Par exemple, les imprimantes IPP (Internet Printing Protocol) sont généralement détectées par le biais de trois protocoles : IPP, WSD et eSCL. Lorsque plusieurs points de terminaison sont détectés pour le même appareil, ils peuvent être explicitement appairés ensemble.

Exemple de code pour un ensemble à détection automatique (style Bluetooth)

Cet exemple de code met en œuvre l’appairage d’un ensemble détecté automatiquement (style Bluetooth) à l’aide d’un objet d’appairage personnalisé. Comme pour une mise en œuvre typique de l’appairage personnalisé, un gestionnaire de demande d’appairage est nécessaire pour gérer la cérémonie d’appairage. Dans ce cas, l’exemple de code implémente uniquement la cérémonie d’appairage confirmer seulement. Ce qui est nouveau et intéressant, c’est d’appairer un gestionnaire de set-member-requested.

Ce gestionnaire permet à la plateforme de tenter d’appairer l’appareil transmis en tant qu’ensemble. Sans ce gestionnaire, la pile de protocole ne tentera pas d’énumérer les membres d’un ensemble d’appairage. Le protocole Bluetooth détecte les membres de l’ensemble lors de la finalisation de l’appairage, de manière à ce que le gestionnaire de l’ensemble soit appelé quelque temps après le retour du gestionnaire de la cérémonie. Dans ce flux, le gestionnaire d’ensemble peut généralement s’attendre à être appelé une fois après avoir traité la cérémonie avec une liste fixe de membres de l’ensemble ; autrement dit, le protocole détecte tous les points de terminaison qu’il peut pendant l’appairage, et il n’en découvrira pas d’autres par la suite.

Cet exemple de code appaire de manière synchrone tous les membres de l’ensemble détectés avec la même routine BtSetPairing utilisée pour appairer l’appareil/le point de terminaison principal. L’appairage en parallèle est également supporté et peut être plus efficace pour votre scénario. Pour des raisons de simplicité, cet aspect n’est pas illustré dans l’exemple de code. Puisque nous appairons également les membres de l’ensemble avec un gestionnaire d’ensemble, ils peuvent potentiellement produire de manière récursive d’autres membres de l’ensemble à appairer. Mais typiquement, le gestionnaire d’ensemble pour les membres d’ensemble détectés ne verra probablement la détection terminée que si le vecteur de membres d’ensemble est vide.

Remarque

Cet exemple de code ne s’inscrit pas dans le contexte d’un scénario ou d’une application plus vaste, mais une application aurait probablement besoin de suivre les appareils qu’elle appaire et les résultats de l’appairage. Cela permet à l’application de savoir si l’opération d’appairage a réussi ou non.

Remarque

Ces API sont généralement asynchrones. Les opérations d’appairage ont leurs propres threads de travail, et les gestionnaires sont appelés sur différents threads. Votre code n’a pas besoin de se bloquer aussi souvent que dans cet exemple de code.

Exemple de code 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);
    }
}

Exemple de code pour un ensemble explicite (style IPP)

Cet exemple de code met en œuvre l’appairage d’un ensemble explicite à l’aide d’un objet d’appairage personnalisé. Comme pour une mise en œuvre typique de l’appairage personnalisé, un gestionnaire de demande d’appairage est nécessaire pour gérer la cérémonie d’appairage. Dans ce cas, l’exemple de code implémente uniquement la cérémonie d’appairage confirmer seulement. Comme dans l’exemple de code Bluetooth, la partie nouvelle et intéressante consiste à appairer un gestionnaire pairing-set-member. Ce gestionnaire permet à la plateforme d’appairer les appareils en tant qu’ensemble.

Par rapport au scénario d’appairage de type Bluetooth, cet exemple de code ajoute explicitement des appareils à l’ensemble. Par rapport au Bluetooth, le gestionnaire d’ensemble implique quelque chose d’un peu différent des protocoles liés à l’appairage d’imprimantes IPP. Cela implique que les clients gèrent la détection des appareils via les différents protocoles, et que l’état PnP et les files d’attente d’impression créées à la suite de l’appairage de tous les membres de l’ensemble doivent être synchronisés.

Pour que la mise en œuvre de l’exemple de code reste simple, on suppose qu’un vecteur de points de terminaison des membres de l’ensemble a été détecté au préalable et transmis en tant que paramètre avec l’appareil principal. Par exemple, dans un scénario IPP typique, les points de terminaison sont détectés dans un ordre arbitraire. Ainsi, l’appareil principal pourrait avoir été détecté par WSD, par exemple, et le vecteur contiendrait alors des appareils représentant des points de terminaison détectés par IPP et eSCL. Mais toutes les combinaisons sont possibles et valables. L’application ajoute des membres à l’objet d’appairage personnalisé de l’appareil principal sur le fil d’exécution principal de l’application, puis appelle PairAsync.

Remarque

Concrètement, les membres d’un ensemble peuvent être ajoutés à un objet d’appairage personnalisé à tout moment et dans n’importe quel fil d’exécution. Les opérations sur un protocole peuvent prendre beaucoup de temps, voire être bloquées jusqu’à ce qu’elles s’arrêtent. C’est pourquoi il est utile de les faire se chevaucher. Pensez à tirer parti du parallélisme de l’API pour ajouter et appairer des appareils simultanément. Cela est possible même si vous continuez à énumérer les appareils sur le fil. Les avantages de les appairer en tant qu’ensemble restent généralement valables.

Avec cette implémentation, le membre principal de l’ensemble sera appairé simultanément avec les membres de l’ensemble. Les membres de l’ensemble sont appairés un par un de manière synchrone dans le gestionnaire. Mais là encore, ils peuvent être appairés en parallèle pour une meilleure efficacité.

Les objets nœuds d’appareil dans PnP sont souvent créés à la suite d’un appairage. Dans le cas d’IPP, les nœuds d’appareil sont toujours créés pour chaque point de terminaison après l’appairage. Cette API d’appairage d’ensembles synchronise implicitement la création de nœuds d’appareils entre les points de terminaison de l’ensemble. Dans le flux de cet exemple de code, tous les nœuds d’appareil seront synchronisés car tous les membres de l’ensemble sont ajoutés avant que l’appairage ne commence. Pour plus de détails sur la manière dont cette API synchronise les nœuds d’appareil dans PnP, consultez la section Commentaire général de cette rubrique.

Remarque

Cet exemple de code ne s’inscrit pas dans le contexte d’un scénario ou d’une application plus vaste, mais une application aurait probablement besoin de suivre les appareils qu’elle appaire et les résultats de l’appairage. Cela permet à l’application de savoir si l’opération d’appairage a réussi ou non.

Exemple de code 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);
    }
}

Commentaire général

Appairage d’ensembles par détection automatique (style Bluetooth)

Cette API est nécessaire pour réaliser l’appairage d’ensembles de type Bluetooth, où les membres de l’ensemble sont détectés par le protocole après que le point de terminaison principal a été appairé. Un exemple simple est celui d’un ensemble d’oreillettes sans fil. Lorsque l’appairage du premier écouteur est finalisé, l’appareil informe le PC qu’il y a un deuxième appareil à appairer dans le cadre de l’ensemble. L’API d’appairage personnalisée est étendue pour permettre aux applications de gérer les opérations d’ensemble par le biais du nouveau gestionnaire d’état d’ajout de membre d’ensemble.

Appairage explicite (style IPP) d’un ensemble

De même, vous pouvez utiliser cette API pour appairer n’importe quel groupe d’appareils à point de terminaison d’association (AEP) en tant qu’ensemble. Avec un objet d’appairage personnalisé, votre application peut ajouter d’autres points de terminaison à l’ensemble d’appairage à tout moment et dans n’importe quel thread. Cela a été conçu parce que la détection et l’appairage des appareils sur un réseau peuvent prendre beaucoup de temps pour chaque appareil, de manière à éviter de sérialiser ces opérations quand cela est possible.

Il est particulièrement utile d’appairer dans des ensembles lors de la détection d’appareils sur de nombreux protocoles où les piles de protocoles et d’appareils ne sont pas facilement coordonnées. Par exemple, une imprimante réseau moderne sera probablement détectée par Windows avec trois protocoles réseau différents, chacun produisant des points de terminaison d’association. Dans ce cas, l’appairage des trois points terminaison en tant que groupe est très utile pour deux raisons : il évite une redétection inutile sur le réseau et il crée une seule file d’attente d’impression rationalisée.

Même si une imprimante réseau n’est pas appairée en tant qu’ensemble, le spouleur d’impression tente toujours de créer une seule file d’attente d’impression par utilisateur, qu’elle puisse ou non être appairée par le biais de plusieurs protocoles. Si une imprimante est initialement appairée sur un protocole, le système d’exploitation (OS) tentera de la redétecter sur les autres protocoles pris en charge et de l’associer sur chacun d’entre eux afin d’éviter les files d’attente d’impression en double. En général, le système d’exploitation y parvient rapidement et avec succès et produit une seule file d’attente d’impression rationalisée.

Toutefois, si l’application a déjà détecté tous les points de terminaison de l’imprimante, cette étape de redétection est inutile. Pire encore, elle peut entraîner de longs délais avant que l’imprimante ne soit prête à être utilisée. De plus, si les protocoles sont trop désynchronisés ou retardés, le spouleur peut être amené à créer des files d’attente supplémentaires pour la même imprimante, ce qui est source de confusion pour les utilisateurs finaux.

Appairer tous les points de terminaison en une seule fois permet d’éviter une redétection potentiellement lente. Il garantit que l’état PnP est synchronisé et produit des files d’attente d’impression optimales et rationalisées.

Synchronisation des nœuds d’appareils

Lorsque les appareils sont appairés en tant qu’ensemble avec cette API, l’état des appareils PnP qui en résulte est synchronisé de manière pratique. L’API ne limite pas le moment une application peut ajouter un membre à un ensemble, mais il y a des limites au moment où la plateforme peut synchroniser les nœuds des appareils. La synchronisation des nœuds d’appareils est bloquée jusqu’à ce que tous les points de terminaison de l’ensemble aient finalisé leur appairage. Ensuite, tous les nœuds d’appareil de tous les points de terminaison sont créés en même temps. Vous pouvez ajouter d’autres membres à l’ensemble après cela, mais la création ultérieure de nœuds de dispositif n’est pas bloquée, elle est au contraire créée immédiatement.

  • La création de nœuds d’appareils est synchronisée lorsque :
    • Les membres de l’ensemble sont ajoutés avant que l’appairage ne commence.
    • Des membres de l’ensemble sont ajoutés alors qu’au moins un des membres de l’ensemble n’est pas finalisé.
  • La création du nœud de l’appareil n’est pas synchronisée :
    • À tout moment après que tous les membres de l’ensemble ajoutés ont été finalisés.

En pratique, l’API ne permet pas à une application de contrôler le moment où la finalisation de la cérémonie se termine afin d’influencer ce comportement sur la façon dont les nœuds d’appareils sont synchronisés. L’approximation la plus proche serait le moment où l’application choisit de terminer la cérémonie. Un appairage ne peut pas être finalisé tant que le gestionnaire de cérémonie de l’application n’est pas revenu ; c’est donc la dernière chance pour l’application d’influencer le moment où tous les membres de l’ensemble sont finalisés.