Horloge d’un mesh network

Le réseau maillé (mesh network) représente sans doute la prochaine grande vague technologique pour les mobiles. Tans un tel réseau, chaque mobile devient une « maille » au sein d’un ensemble flexible. On obtient ainsi un réseau particulièrement résistant aux accrocs qui peuvent affecter telle ou telle liaison. C’est pourquoi ce type de réseau est spécifiquement adapté en cas de catastrophe naturelle. L’absence d’un « serveur » ou d’un équipement « central » représente l’autre caractéristique fondamentale d’un mesh network : toutes les mailles sont fonctionnellement équivalentes les unes aux autres. (Cette dernière caractéristique permet d’ailleurs d’échanger des informations en évitant de les communiquer à organisme contrôlant un serveur.)

En complément de nos précédents travaux pour le traitement d’informations en environnement de transmission perturbé, nous développons de nouveaux procédés profitant des avantages d’une infrastructure de type mesh network. Avant d’exposer plus en détail ces travaux dans un autre article, nous proposons ici un moyen permettant de transmettre une information horodatée sur un tel réseau. En effet, dans un réseau avec un point central, celui-ci peut indiquer une heure commune pour tous les équipements. Or, puisque toutes les mailles d’un mesh network sont  équivalentes et que, par construction, chaque équipement présente un repère temporel différent : la notion de temps unique de référence n’existe plus sur l’ensemble du réseau. Il faut donc inventer un nouveau procédé pour indiquer l’instant commun entre deux mailles différentes.

Une référence temporelle commune peut être établie en synchronisant les horloges de chaque équipement à partir d’un événement commun. Or, l’événement commun le plus évident entre deux membres d’un mesh network est l’instant de leur association. Dans le procédé décrit ici, chaque membre conserve donc l’instant de l’association avec chaque autre membre, exprimé dans son propre repère temporel. Ainsi, dans une communication entre A et B, un instant t peut alors être partagé de manière commune en indiquant dt la différence entre t et tAB qui indique la valeur, dans le repère temporel de A, de  l’instant d’association avec B au sein du réseau.

t s’exprime par :

  • tAB+dt dans le repère temporel de A,
  • tBA+dt dans le repère temporel de B.

Remarque : une valeur temporelle ne peut pas être transmise simultanément (broadcast) à l’ensemble du réseau, puisque l’expression du temps dans un message est liée à l’instant de l’association entre l’émetteur et le récepteur.

Pour décrire plus précisément ce procédé, nous utilisons le Multipeer Connectivity Framework proposé par iOS 7. Ce service présente les avantages suivants :

  • tous les aspects délicats de la gestion du mesh network sont assurés par le système,
  • les membres du réseau peuvent communiquer aussi bien en Bluetooth qu’en WiFi.

Le repère temporel utilisé par défaut par iOS mesure le temps écoulé codé dans le type double float. Puisque le temps mesuré sera envoyé au sein de messages, et que les échanges en Bluetooth limitent la taille des messages, nous optons pour un codage du temps plus léger sous la forme de simple float lors de l’échange de messages. Afin que ce codage ne pénalise pas de manière sensible la précision, nous limitons la plage des valeurs temporelles possibles lors des échanges. Ainsi un membre du réseau mesure seulement le temps écoulé depuis sa propre instanciation. La date d’instanciation est maintenue par la variable instanciationDate.

L’instant de l’association avec chaque autre membre est maintenu par un dictionnaire nommé connectedPeerIntervals.

@property (strong, nonatomic) NSDate *instanciationDate;
@property (strong, nonatomic) NSMutableDictionary *connectedPeerIntervals;
...
- (instancetype)init
{
 self = [super init];
 if (self) {
  self.instanciationDate = [NSDate date];
  self.connectedPeerIntervals = [NSMutableDictionary dictionaryWithCapacity:4];
 }
 return self;
}

La classe MCPeerID, qui permet de désigner un autre membre du réseau, est conforme au protocole NSCopying ; ses instances peuvent être utilisées comme clé pour le dictionnaire connectedPeerIntervals.

- (NSTimeInterval)timeIntervalForPeer:(MCPeerID *)peerID
{
 NSNumber *interval = _connectedPeerIntervals[peerID];
 return [interval doubleValue];
}

Le cœur de la mise en œuvre du procédé est assuré par la méthode session:peer:didChangeState: qui est invoquée lorsqu’un  membre apparaît (MCSessionStateConnected) ou disparaît (MCSessionStateNotConnected) au sein du mesh network.

#pragma mark - MCSessionDelegate methods
- (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state
{
 if (state == MCSessionStateConnected) {
  NSDate *now = [NSDate date];
  _connectedPeerIntervals[peerID] = @([now timeIntervalSinceDate:_instanciationDate]);
 }

 if (state == MCSessionStateNotConnected) {
  [_connectedPeerIntervals removeObjectForKey:peerID];
 }
}

Il suffit ensuite d’invoquer la méthode timeIntervalForPeer: lorsque l’on souhaite envoyer une référence temporelle commune avec un autre membre du réseau.