Bluetooth LE n'est pas si effrayant, ou comment améliorer l'expérience utilisateur sans trop d'effort

Récemment, notre équipe a conçu et mis en œuvre la fonction de transfert d'argent par voie aérienne à l'aide de la technologie Bluetooth LE. Je veux vous dire comment nous l'avons fait et ce que Apple nous offre à partir des outils. De nombreux développeurs pensent que Bluetooth est difficile, car il s'agit d'un protocole de bas niveau, et il n'y a pas beaucoup d'experts à ce sujet. Mais tout n'est pas si effrayant, et en fait, utiliser cette fonction est très simple! Et ces fonctions qui peuvent être implémentées à l'aide de Bluetooth LE sont certainement intéressantes et mettront par la suite en valeur votre application parmi les concurrents.



Commençons par comprendre de quel type de technologie il s'agit et quelle est sa différence par rapport au Bluetooth classique.

Qu'est-ce que Bluetooth LE?


Pourquoi les développeurs Bluetooth ont-ils nommé cette technologie à savoir Low Energy? Après tout, avec chaque nouvelle version de Bluetooth, la consommation d'énergie était déjà beaucoup plus faible. La réponse réside dans cette batterie.


Son diamètre n'est que de 2 cm et sa capacité est d'environ 220 mA * h. Lorsque les ingénieurs ont développé Bluetooth LE, ils voulaient que l'appareil avec une telle batterie fonctionne pendant plusieurs années. Et ils l'ont fait! Les appareils Bluetooth LE dotés d'une telle batterie peuvent fonctionner pendant un an. Combien d'entre vous désactivent toujours le Bluetooth sur votre téléphone à l'ancienne pour économiser de l'énergie, comme vous l'avez fait en 2000? En vain, vous faites cela - les économies seront inférieures à 10 secondes du téléphone par jour. Et vous désactivez de très grandes fonctionnalités, telles que Handoff, AirDrop et autres.

Qu'ont réalisé les ingénieurs en développant Bluetooth LE? Ont-ils affiné le protocole classique? Le rend plus économe en énergie? Vous venez d'optimiser tous les processus? Non. Ils ont complètement repensé l'architecture de la pile Bluetooth et ont réalisé que maintenant, pour être visible par tous les autres appareils, vous avez besoin de moins de temps pour être en ondes et occuper le canal. À son tour, cela a permis une bonne économie sur la consommation d'énergie. Et avec la nouvelle architecture, tout nouvel appareil peut désormais être standardisé, grâce auquel les développeurs du monde entier peuvent communiquer avec l'appareil et, par conséquent, écrire facilement de nouvelles applications pour le gérer. De plus, le principe de la découverte de soi est intégré dans l'architecture: lors de la connexion à un appareil, vous n'avez pas besoin de saisir de code PIN, et si votre application peut communiquer avec cet appareil, la connexion prend quelques millisecondes.

  • Moins de temps sur l'air.
  • Moins de consommation d'énergie.
  • Nouvelle architecture.
  • Temps de connexion réduit.

Comment les ingénieurs ont-ils réussi à faire un si grand bond en matière d'efficacité énergétique?

La fréquence est restée la même: 2,4 GHz, non certifiée et gratuite pour une utilisation dans de nombreux pays. Mais le délai de connexion est devenu moindre: 15-30 ms au lieu de 100 ms avec le Bluetooth classique. La distance de travail est restée la même - 100 m. L'intervalle de transmission n'était pas fort, mais a changé - au lieu de 0,625 ms, il est devenu 3 ms.

Mais pour cette raison, la consommation d'énergie n'a pas pu être décuplée. Bien sûr, quelque chose devait souffrir. Et c'est la vitesse: au lieu de 24 Mbps, c'est devenu 0,27 Mbps. Vous direz probablement que c'est une vitesse ridicule pour 2018.

Où Bluetooth LE est-il utilisé?




Cette technologie n'est pas jeune, elle est apparue pour la première fois sur l'iPhone 4s. Et déjà réussi à conquérir de nombreux domaines. Bluetooth LE est utilisé dans tous les appareils domestiques intelligents et l'électronique portable. Maintenant, il y a même des chips de la taille des grains de café.



Et comment cette technologie est-elle appliquée aux logiciels?

Depuis qu'Apple a été le premier à intégrer Bluetooth dans leur appareil et à commencer à l'utiliser, ils ont désormais bien progressé et intégré la technologie dans leur écosystème. Et maintenant, vous pouvez rencontrer cette technologie dans des services tels que AirDrop, démarrage rapide des appareils, partage des mots de passe, transfert. Et même les notifications de la montre sont effectuées via Bluetooth LE. En outre, Apple a mis à la disposition du public une documentation sur la façon de s'assurer que les notifications de toutes les applications parviennent à vos propres appareils. Quels sont les rôles des appareils dans Bluetooth LE?



Brodcaster. Envoie des messages à tous ceux qui se trouvent à proximité, vous ne pouvez pas vous connecter à cet appareil. Par ce principe, les iBeacons et la navigation intérieure fonctionnent.

Observateur. Écoute ce qui se passe et ne reçoit des données que des messages publics. Ne crée pas de connexions.

Mais avec Central et périphérique plus intéressant. Pourquoi ne s'appelaient-ils pas simplement serveur-client? Logiquement, à en juger par le nom. Mais non.

Parce que Peripheral agit en fait comme un serveur. Il s'agit d'un périphérique qui consomme moins d'énergie et se connecte à la centrale plus puissante. Le périphérique peut vous informer de sa proximité et de ses services. Un seul appareil peut s'y connecter et le périphérique possède des données. Et Central peut analyser l'air à la recherche d'appareils, envoyer des demandes de connexion, se connecter à n'importe quel nombre d'appareils, lire, écrire et s'abonner aux données de Peripheral.

À quoi avons-nous accès en tant que développeurs dans l'écosystème Apple?

Qu'est-ce qui est à notre disposition?


iOS / Mac OS:

  • Périphérique et Central.
  • Mode fond.
  • Récupération de l'état.
  • Intervalle de connexion 15 ms.

watchOS / tvOS:

  • watchOS 4+ / tvOS 9+.
  • Central seulement.
  • Maximum deux connexions.
  • Apple Watch série 2+ / AppleTv 4+.
  • Arrêt lors de l'entrée en arrière-plan.
  • Intervalle de connexion 30 ms.

La différence la plus importante est l'intervalle de connexion. Qu'est-ce que cela affecte? Pour répondre à cette question, vous devez d'abord comprendre comment fonctionne le protocole Bluetooth LE et pourquoi une si petite différence en valeurs absolues est très importante.

Fonctionnement du protocole


Comment se déroule le processus de recherche et de connexion?

Peripheral annonce sa présence à la fréquence de l'intervalle de publicité, son package est très petit et ne contient que quelques identifiants de service fournis par l'appareil, ainsi que le nom de l'appareil. L'intervalle peut être assez long et peut varier en fonction de l'état actuel de l'appareil, du mode d'économie d'énergie et d'autres paramètres. Apple conseille aux développeurs d'appareils externes de lier la longueur de l'intervalle à l'accéléromètre: augmentez l'intervalle si l'appareil n'est pas utilisé, et lorsqu'il est actif, diminuez pour trouver rapidement l'appareil. L'intervalle de publication ne correspond pas à l'intervalle de connexion et est déterminé par le périphérique lui-même, en fonction de la consommation d'énergie et de ses paramètres. Il est inaccessible et inconnu de nous dans l'écosystème Apple, il est entièrement contrôlé par le système.



Après avoir trouvé l'appareil, nous envoyons une demande de connexion, et ici l'intervalle de connexion entre en scène - le temps après lequel le deuxième appareil peut répondre à la demande. Mais c'est lors de la connexion, mais que se passe-t-il lors de la lecture / écriture?



L'intervalle de connexion apparaît également lors de la lecture des données - une réduction de 2 fois augmente le taux de transfert de données. Mais vous devez comprendre que si les deux appareils ne prennent pas en charge le même intervalle, le maximum d'entre eux sera sélectionné.

Voyons en quoi consiste un paquet d'informations que le périphérique transmet.

La MTU (unité de transmission maximale) d'un tel package est déterminée au cours du processus de connexion et varie d'un appareil à l'autre et en fonction du système d'exploitation. Dans la version de protocole 4.0, le MTU était d'environ 30 et la taille de la charge utile ne dépassait pas 20 octets. Dans la version 4.2, tout a changé, vous pouvez désormais transférer environ 520 octets. Mais, malheureusement, seuls les appareils plus jeunes que l'iPhone 5 prennent en charge cette version du protocole. La taille de la surcharge, quelle que soit la taille du MTU, est de 7 octets: cela inclut les en-têtes ATT et L2CAP. Avec le dossier, en général, une situation similaire.



Il n'y a que deux modes: avec réponse et sans. Le mode sans réponse accélère considérablement le transfert de données, car il n'y a pas d'intervalle d'attente avant le prochain enregistrement. Mais ce mode n'est pas toujours disponible, pas sur tous les appareils et pas sur tous les systèmes. L'accès à ce mode d'enregistrement peut être limité par le système lui-même, car il est considéré comme moins économe en énergie. Dans iOS, il existe une méthode dans laquelle vous pouvez vérifier avant d'enregistrer si ce mode est disponible.

Voyons maintenant en quoi consiste le protocole.



Le protocole comprend 5 niveaux. La couche application est votre logique, décrite au-dessus de CoreBluetooth. GATT (Generic Attributes Layer) est utilisé pour échanger les services et les caractéristiques qui se trouvent sur les appareils. ATT (Attributes Layer) est utilisé pour gérer vos caractéristiques et transférer vos données. L2CAP est un protocole d'échange de données de bas niveau. Le contrôleur est la puce BT elle-même.

Vous vous demandez probablement ce qu'est le GATT et comment nous pouvons travailler avec lui?

Le GATT comprend des fonctionnalités et des services. Une caractéristique est un objet dans lequel vos données sont stockées, comme une variable. Et un service est un groupe dans lequel se trouvent vos caractéristiques, comme un espace de noms. Le service a un nom - UUID, vous le choisissez vous-même. Un service peut contenir un service subsidiaire.



La caractéristique a également son propre UUID - en fait, un nom. La valeur de la caractéristique est NSData, ici vous pouvez enregistrer et stocker des données. Les descripteurs sont une description de votre caractéristique, vous pouvez décrire les données que vous attendez de cette caractéristique, ou ce qu'elles signifient. Il existe de nombreux descripteurs dans le protocole Bluetooth, mais jusqu'à présent, seuls deux sont disponibles sur les systèmes Apple: la description humaine et le format des données. Il existe également des autorisations pour votre fonctionnalité:



Essayons vous-même


Nous avons eu l'idée de permettre le transfert d'argent par avion sans rien demander au destinataire. Imaginez, vous êtes perplexe sur une tâche très intéressante, écrivant le code parfait, et ici un collègue suggère d'aller prendre un café. Et vous êtes tellement passionné par la tâche que vous ne pouvez pas partir, et demandez-lui de vous acheter une tasse de délicieux cappuccino. Il vous apporte du café et vous devez lui rendre l'argent. Vous pouvez traduire par numéro de téléphone, cela fonctionne très bien. Mais voici une situation délicate - vous ne connaissez pas son numéro. Eh bien, comme ça, vous travaillez depuis trois ans, mais vous n'avez pas échangé de numéros :)

Par conséquent, nous avons décidé de permettre de transférer de l'argent à ceux qui se trouvent à proximité, sans entrer de données utilisateur. Comme dans AirDrop. Sélectionnez simplement un utilisateur et envoyez le montant dont il a besoin. Voyons voir ce dont nous avons besoin pour cela.



Cartographie PUSH


Nous avons besoin de l'expéditeur:

  1. J'ai pu trouver tous les appareils à proximité et prendre en charge notre service.
  2. J'ai pu lire les détails.
  3. Et il pourrait envoyer un message au destinataire qu'il lui avait bien envoyé l'argent.

Le destinataire, à son tour, doit être en mesure d'informer les expéditeurs environnants qu'il dispose d'un service avec les données nécessaires et de pouvoir recevoir des messages de l'expéditeur. Je pense que cela ne vaut pas la peine de décrire comment se déroule le processus de transfert d'argent par des détails dans notre banque. Essayons maintenant de l'implémenter.

Vous devez d'abord trouver les noms de nos services et caractéristiques. Comme je l'ai dit, c'est l'UUID. Nous les générons simplement et les enregistrons sur Périphérique et Central afin qu'ils soient les mêmes sur les deux appareils.



Vous êtes libre d'utiliser tous les UUID, à l'exception de ceux se terminant comme ceci: XXXXXXXX- 0000-1000-8000-00805F9B34FB - ils sont réservés à différentes sociétés. Vous pouvez vous-même acheter un tel numéro et personne ne l'utilisera. Cela coûtera 2500 $.

Ensuite, nous devrons créer des gestionnaires: l'un pour transférer des fonds, l'autre pour recevoir. Il vous suffit de spécifier les délégués. Nous transmettrons Central, recevrons Périphérique. Nous créons les deux, car l'expéditeur et le destinataire peuvent être une seule personne à des moments différents.



Maintenant, nous devons permettre de détecter le destinataire et d'écrire les détails du destinataire dans notre caractéristique.



Créez d'abord un service. Nous enregistrerons l'UUID et indiquerons qu'il est principal - c'est-à-dire que le service est le principal pour cet appareil. Un bon exemple: un moniteur de fréquence cardiaque, pour lequel la fréquence cardiaque actuelle sera le service principal, et l'état de la batterie est une information secondaire.

Ensuite, nous créons deux caractéristiques: l'une pour lire les détails du destinataire, la seconde pour écrire afin que le destinataire puisse s'informer sur l'envoi d'argent. Nous les enregistrons dans notre service, puis les ajoutons au gestionnaire, commençons la découverte et indiquons l'UUID du service afin que tous les appareils à proximité puissent découvrir notre service avant de s'y connecter. Ces données sont placées dans le paquet que Central envoie pendant la diffusion.

Le destinataire est prêt, passez à l'expéditeur. Exécutez la recherche et connectez-vous.



Lorsque vous activez le gestionnaire, nous démarrons la recherche d'appareils avec notre service. Lorsque nous les trouvons, nous les obtenons dans la méthode déléguée et nous nous connectons immédiatement. Important: vous devez maintenir un lien solide avec tous les périphériques avec lesquels vous travaillez, sinon ils fuiront.



Après une connexion réussie, nous configurons le délégué qui travaillera avec cet appareil et nous obtenons le service dont nous avons besoin de l'appareil.



Nous avons réussi à nous connecter au destinataire, vous devez maintenant lire ses détails.

Après la connexion, nous avons déjà demandé tous les services de l'appareil. Et après les avoir reçues, la méthode déléguée sera appelée, qui répertoriera tous les services disponibles sur cet appareil. Nous trouvons la bonne et demandons ses caractéristiques. Le résultat peut être trouvé par l'UUID dans la méthode déléguée, qui stocke les données à traduire. Nous essayons de les lire, et nous obtenons à nouveau le désiré dans la méthode déléguée. Tous les services, caractéristiques et leurs valeurs sont mis en cache par le système, il n'est donc pas nécessaire de les demander plus tard à chaque fois.



C'est tout, nous avons envoyé de l'argent pour le café, il est temps de montrer au destinataire un bel avis pour qu'il attende des roubles sur son compte. Pour ce faire, vous devez implémenter le processus d'envoi d'un message.

Nous obtenons la caractéristique dont nous avons besoin de l'expéditeur, dans ce cas, nous l'avons prise de la valeur stockée. Mais avant cela, vous devez l'obtenir de l'appareil, comme nous l'avons fait auparavant. Et puis il suffit d'écrire les données dans la caractéristique souhaitée.

Après cela, sur l'autre appareil, nous obtenons une demande d'écriture dans la méthode déléguée. Ici, vous pouvez lire les données qui vous sont envoyées, répondre à toute erreur, par exemple, il n'y a pas d'accès ou cette caractéristique n'existe pas. Tout fonctionnera, mais uniquement si les deux appareils sont allumés et que les applications sont actives. Et nous devons travailler en arrière-plan!



Apple vous permet d'utiliser Bluetooth en arrière-plan. Pour ce faire, vous devez indiquer dans info.plist la clé dans quel mode nous voulons utiliser, en périphérique ou central.



Ensuite, dans le gestionnaire, vous devez spécifier la clé de récupération et créer une méthode déléguée. Maintenant, le mode d'arrière-plan est disponible pour nous. Si l'application s'endort ou est déchargée de la mémoire, lorsque vous trouvez le périphérique souhaité ou lorsque Central est connecté, il se réveille et le gestionnaire rétablit avec votre clé.



Tout va bien, prêt à être publié. Mais ici, les concepteurs viennent en courant vers nous et disent: "Nous voulons insérer des photos d'utilisateurs afin qu'il soit plus facile pour eux de se retrouver." Que faire? Dans notre caractéristique, vous pouvez écrire seulement quelque 500 octets, mais sur certains appareils en général 20 :(



Allez plus loin


Pour résoudre ce problème, nous avons dû aller plus loin.



Nous avons maintenant parlé des appareils au niveau du GATT / ATT. Mais dans iOS 11, nous avons accès au protocole L2CAP. Cependant, dans ce cas, vous devrez vous occuper vous-même du transfert de données. Les paquets sont envoyés avec 2 Ko de MTU, pas besoin de ré-encoder quoi que ce soit, NSStream normal est appliqué. Des débits de données allant jusqu'à 394 Kbps, selon Apple.

Supposons que vous transfériez toutes les données de votre service du périphérique au central sous la forme de caractéristiques normales. Et il m'a fallu ouvrir la chaîne. Vous l'ouvrez sur Peripheral, en retour vous obtenez PSM - c'est le numéro du canal auquel vous pouvez vous connecter, et vous devez le transférer vers Central en utilisant les mêmes caractéristiques. Le nombre est dynamique, le système lui-même choisit quel PSM ouvrir pour le moment. Après le transfert, vous pouvez déjà vous connecter à Peripheral sur le Central et échanger des données dans un format qui vous convient. Voyons comment procéder.

Tout d'abord, ouvrez le port crypté sur le périphérique. Vous pouvez le faire sans cryptage, ce qui accélérera un peu le transfert.



Ensuite, dans la méthode déléguée, nous obtenons le PSM et l'envoyons à un autre appareil.



Après avoir connecté un autre appareil, nous serons appelés une méthode dans laquelle nous pouvons obtenir le NSStream dont nous avons besoin pour la transmission à partir du canal.



Le central est encore plus simple, on se connecte juste au canal avec le numéro souhaité ...



... et après cela, nous obtenons les flux dont nous avons besoin. En eux, vous pouvez transférer absolument toutes les données de n'importe quelle taille et construire votre protocole sur L2CAP. Nous avons donc réalisé le transfert des photos des destinataires.



Mais il y a des pièges, où s'en passer.

Pièges


Regardons les pièges lorsque vous travaillez en arrière-plan. Étant donné que les rôles de périphérique et central sont à votre disposition, vous pourriez penser. qu'en arrière-plan, vous pouvez déterminer quels appareils se trouvent à proximité en arrière-plan et lesquels sont actifs. En théorie, cela aurait dû l'être, mais Apple a introduit une restriction: les téléphones en arrière-plan, qu'ils soient centraux ou périphériques, ne sont pas disponibles pour d'autres téléphones qui sont également en arrière-plan. De plus, les téléphones en arrière-plan ne sont pas visibles depuis les appareils non iOS. Voyons pourquoi cela se produit.

Lorsque votre appareil est actif, il envoie un paquet de diffusion normal, qui peut contenir le nom de l'appareil et une liste de services. que cet appareil fournit. Et les données de débordement sont tout ce qui ne convenait pas.



Lorsque l'appareil passe en arrière-plan, il ne transmet pas le nom et transfère la liste des services pris en charge pour déborder les données. Si l'application est active, lors de la numérisation à partir d'un appareil iOS, elle lit ces données et lors du passage en arrière-plan, elle les ignore. Par conséquent, lorsque vous passez en arrière-plan, vous ne pourrez pas voir les applications qui sont également en arrière-plan.Les autres systèmes d'exploitation Apple ignorent toujours les données de débordement, donc si vous recherchez des appareils qui prennent en charge votre service, vous obtiendrez un tableau vide. Et si vous vous connectez à chaque appareil à proximité et demandez des services pris en charge, la liste peut contenir votre service et vous pouvez l'utiliser.



De plus, nous nous préparions déjà à soumettre à des tests, corrigions des défauts mineurs et étions engagés dans l'optimisation. Et soudain, à un moment donné, nous avons commencé à obtenir cette erreur dans la console:

CoreBluetooth[WARNING] Unknown error: 124 

Le pire était qu'aucune méthode déléguée n'était appelée, nous ne pouvions même pas battre cette erreur pour l'utilisateur. Juste un message dans le journal - et le silence, tout a gelé. Aucun changement majeur n'a été apporté, nous avons donc commencé à revenir sur les commits. Et ils ont constaté qu'ils avaient une fois optimisé le code et refait la façon d'écrire des données. Le problème était que tous les clients n'étaient pas mis à jour, cette erreur s'est donc produite.

 .write != .writeWithoutResponse 

Heureux d'avoir tout réparé, nous avons couru plutôt pour le tester, et ils nous sont presque immédiatement revenus: «Vos photos de mode ne fonctionnent pas. Ils sont tous sous-chargés. » Nous avons commencé à essayer, et il est vrai que parfois, sur différents appareils, les photos cassées arrivent à des moments différents. Ils ont commencé à chercher une raison.

Et là encore, ils ont vu l'erreur précédente. Immédiatement pensé qu'il était dans différentes versions. Mais après la suppression complète de l'ancienne version de tous les appareils de test, l'erreur s'est reproduite. Nous étions tristes ...

 CoreBluetooth[WARNING] Unknown error: 722 CoreBluetooth[WARNING] Unknown error: 249 CoreBluetooth[WARNING] Unknown error: 312 

Nous avons commencé à chercher un outil de débogage. La première chose que nous avons rencontrée était l'Apple Bluetooth Explorer. Un programme puissant, il peut faire beaucoup de choses, mais pour déboguer le protocole Bluetooth LE, il y a un petit onglet avec la recherche de périphériques et l'obtention de caractéristiques. Et nous devions analyser L2CAP.

Ensuite, ils ont trouvé LightBlue Explorer. Il s'est avéré être un programme assez décent, mais avec un design iOS 7. Il peut faire la même chose que Bluetooth Explorer, et sait également comment s'abonner aux spécifications. Et cela fonctionne plus stable. Tout va bien, mais encore une fois sans L2CAP.

Et puis nous nous sommes souvenus du renifleur WireShark bien connu.

Il s'est avéré qu'il connaissait Bluetooth LE: il peut lire L2CAP, mais uniquement sous Windows. Bien que ce ne soit pas effrayant que nous ne trouvions pas Windows ou quelque chose. Le plus gros inconvénient - le programme ne fonctionne qu'avec un appareil spécifique. Autrement dit, vous deviez trouver l'appareil quelque part dans la boutique officielle. Et vous comprenez vous-même qu'il est peu probable qu'une grande entreprise approuve l'achat d'un appareil incompréhensible sur un marché aux puces. Nous avons même commencé à parcourir les magasins en ligne à l'étranger.

Mais ici, ils ont trouvé le programme PacketLogger dans les outils Xcode supplémentaires. Il vous permet de surveiller le trafic qui circule sur l'appareil OS X. Pourquoi ne pas réécrire notre MoneyDrop sous OS X? Nous avions déjà une bibliothèque séparée. Nous venons de remplacer UIImage par NSImage, tout a commencé après 10 minutes.



Enfin, nous avons pu lire les paquets échangés entre les appareils. Il est immédiatement devenu évident qu'au moment de la transmission des données via L2CAP, l'une des caractéristiques était enregistrée. Et en raison du fait que la chaîne était complètement occupée par le transfert de photos, iOS a ignoré l'enregistrement et l'expéditeur après l'ignorer a cassé la chaîne. Après avoir résolu les problèmes avec le transfert de la photo n'était pas.



C'est tout, merci d'avoir lu :)

Liens utiles


WWDC / CoreBluetooth:


Bluetooth


YouTube

  • Arrow Electronics → Série Bluetooth Low Energy

Source: https://habr.com/ru/post/fr452278/


All Articles