Il y a longtemps, quand un téléphone portable coûtait environ 2000 $ et qu'une minute d'appel vocal coûtait 50 cents, les téléavertisseurs étaient vraiment populaires. Plus tard, les téléphones portables sont devenus moins chers, les prix des appels et des SMS sont devenus plus bas, et les téléavertisseurs ont finalement disparu.
Pour les personnes qui possédaient un téléavertisseur auparavant et qui veulent savoir comment cela fonctionne, cet article sera utile.
Infos principales
Pour les personnes qui ont oublié les principes ou qui sont nées après 2000x, je rappellerai brièvement les principales idées.
Le réseau de communication de radiomessagerie présente certains avantages, qui sont parfois encore importants aujourd'hui:
- Il s'agit d'une communication à sens unique, sans aucune sorte de confirmation, de sorte que le réseau ne peut pas être surchargé - cela ne dépend tout simplement pas d'un certain nombre d'utilisateurs. Les messages sont transmis en continu "tels quels", l'un après l'autre, et le pager reçoit le message si son numéro (appelé Capcode) est égal au numéro interne de l'appareil.
- Le récepteur est très léger (à la fois littéralement et électroniquement), et peut fonctionner jusqu'à un mois à partir de 2 piles AA.
Il existe deux normes de base pour la transmission des messages -
POCSAG (Post Office Code Standardization Advisory Group) et
FLEX . Les deux normes sont assez anciennes, POCSAG a été fabriqué en 1982, il peut supporter des vitesses de 512, 1200 et 2400 bit / s. Pour la transmission, la méthode FSK (fréquence shift keying) est utilisée avec une séparation de fréquence de 4,5 KHz. FLEX est un peu plus récent (a été fabriqué par Motorola au 90e), il peut fonctionner avec une vitesse allant jusqu'à 6400 bit / s et peut utiliser à la fois FSK2 et FSK4.
Les deux protocoles sont en général très faciles, et il y a environ 20 ans, des décodeurs PC ont été créés, qui peuvent décoder les messages à partir d'un port série de la carte son (aucun cryptage n'est pris en charge, donc tous les messages peuvent être lus par n'importe qui).
Regardons comment cela fonctionne.
Recevoir un signal
Tout d'abord, nous avons besoin d'un signal pour le décodage. Permet de prendre un ordinateur portable, un récepteur rtl-sdr et de l'obtenir.

La touche de décalage de fréquence est utilisée, nous allons donc définir FM. Avec HDSDR, nous enregistrerons un signal au format WAV.
Vérifions ce que nous obtenons. Chargement du fichier wav en tant que tableau de données Python:
from scipy.io import wavfile import matplotlib.pyplot as plt fs, data = wavfile.read("pocsag.wav") plt.plot(data) plt.show()
Sortie (bits ajoutés manuellement):

Comme nous pouvons le voir, c'est facile, et même "à l'œil nu", nous pouvons dessiner des bits dans Paint, il est facile de distinguer où est "0" et où est "1". Mais il sera trop long de le faire manuellement, il est temps d'automatiser le processus.
Après avoir agrandi le graphique, nous pouvons voir que chaque bit a une largeur de 20 échantillons. Nous avons 24000 échantillons par seconde de fichier wav de débit binaire, donc la vitesse de saisie est de 1200bit / s. Permet de trouver une position de passage à zéro - c'est le début de la séquence de bits. Permet également d'ajouter des marqueurs pour vérifier que tous les bits sont aux bons endroits.
speed = 1200 fs = 24000 cnt = int(fs/speed) start = 0 for p in range(2*cnt): if data[p] < - 50 and data[p+1] > 50: start = p break
Comme nous pouvons le voir, son ne correspond pas parfaitement (l'émetteur et le récepteur ont des fréquences légèrement différentes), mais c'est certainement suffisant pour le décodage.

Pour les signaux longs, nous aurons probablement besoin d'un algorithme de correction de fréquence automatique, mais pour ce type de signaux, ce n'est pas critique.
La dernière étape - nous devons traduire le fichier wav dans la séquence de bits. C'est aussi facile, nous connaissons la longueur de chaque bit, si la somme des données est positive, nous ajouterons «1», sinon «0» (enfin, il a été constaté qu'un signal doit être inversé, donc 0 et 1 ont été remplacés) .
bits_str = "" for p in range(0, data.size - cnt, cnt): s = 0 for p1 in range(p, p+cnt): s += data[p] bits_str += "1" if s < 0 else "0" print("Bits") print(bits_str)
Sortie - séquence de bits appropriée (sous forme de chaîne), qui contient notre message.
101010101010101010101010101010101010101010101010101010101010101010101010101
010101010101010101010101010101010101010101010100111110011010010000101001101
100001111010100010011100000110010111011110101000100111000001100101110111101
010001001110000011001011101111010100010011100000110010111011110101000100111
000001100101110111101010001001110000011001011101111010100010011100000110010
011011110101000100111000001100101110111101010001001110000011001011101111010
100010011100000110010111011110101000100111000001100101110111101010001001110
...
111101111
Décodage des messages numériques uniquement
Une séquence de bits est beaucoup plus pratique qu'un fichier wav, nous pouvons en extraire des données. Tout d'abord, permet de diviser les données en blocs de 4 octets.
10101010101010101010101010101010
10101010101010101010101010101010
10101010101010101010101010101010
10101010101010101010101010101010
01111100110100100001010011011000
01111010100010011100000110010111
01111010100010011100000110010111
01111010100010011100000110010111
01111010100010011100000110010111
00001000011011110100010001101000
10000011010000010101010011010100
01111100110100100001010111011000
11110101010001000001000000111000
01111010100010011100000110010111
01111010100010011100000110010111
01111010100010011100000110010111
00100101101001011010010100101111
Nous pouvons certainement voir un modèle. Maintenant, nous devons trouver ce que signifie chaque partie. Le manuel POCSAG est disponible
au format PDF , permet de vérifier la description des structures de données.

C'est maintenant beaucoup plus clair. L'en-tête contient un long bloc "10101010101", il est utilisé pour "réveiller" le pager d'un mode veille. Le message lui-même contient les blocs Batch-1 ... Batch-N, chaque bloc part de la séquence unique FSC. Ensuite, comme nous pouvons le voir dans le manuel, si la chaîne commence à "0", elle contient l'adresse du destinataire. L'adresse elle-même (capcode) est stockée est le pager, et si elle ne correspond pas, le pager ignorera le message. Si une chaîne commence à "1", elle contient le corps du message. Dans notre exemple, nous avons 2 chaînes de ce type.
Permet de ne pas vérifier chaque bloc. Nous pouvons également voir les codes inactifs - blocs vides 01111 ... 0111, ils ne contiennent aucune information utile. Après les avoir supprimés, nous obtenons seulement ceci:
01111100110100100001010011011000 - Frame Sync
00001000011011110100010001101000 - Address
10000011010000010101010011010100 - Message
01111100110100100001010111011000 - Frame Sync
11110101010001000001000000111000 - Message
00100101101001011010010100101111 - Address
Nous devons trouver ce qui se trouve à l'intérieur.
Après avoir vérifié le manuel, il est clair qu'il existe deux types de messages -
uniquement numériques et
alphanumériques . Les messages numériques sont enregistrés sous forme de codes BCD 4 bits, donc 20 bits peuvent contenir 5 symboles (il y a aussi des bits CRC, nous ne les utilisons pas pour l'instant). Si le message est alphanumérique, le codage ASCII 7 bits est utilisé. Ce message est trop court, il ne peut donc s'agir que d'un message uniquement numérique.
À partir des chaînes 10000011010000010101010011010100 et 11110101010001000001000000111000, nous pouvons obtenir ces séquences de 4 bits:
1 0000 0110 1000 0010 10101 0011010100 - 0h 6h 8h 2h Ah
1 1110 1010 1000 1000 00100 0000111000 - Eh Ah 8h 8h 2h
L'étape suivante consiste à obtenir la table de décodage du manuel:

Il est évident qu'un message uniquement numérique peut contenir des chiffres de 0 à 9, la lettre U ("ugrent"), un espace et deux parenthèses. Permet d'écrire une petite méthode pour le décoder:
def parse_msg(block):
Enfin, nous obtenons un message "0682 *) * 882".
Il est difficile de dire ce que cela signifie, mais si les messages uniquement numériques sont utilisés, quelqu'un en a probablement besoin.
Décodage des messages alphanumériques
L'étape suivante, et plus intéressante, consiste à décoder les messages alphanumériques. C'est plus intéressant, car en sortie, nous devrions obtenir le texte lisible par l'homme.
Tout d'abord, nous devons enregistrer à nouveau un message, nous utiliserons HDSDR. Nous ne connaissons pas un type de message avant le décodage, nous allons donc simplement enregistrer un message le plus long, nous pouvons l'obtenir, et espérons qu'il contiendra du texte.

Après la conversion de wav en une séquence de bits (voir un code Python ci-dessus), nous obtenons ceci:

Certaines choses intéressantes que nous pouvons voir immédiatement, à l'œil nu - par exemple, la séquence de démarrage 01010101010101 se répète deux fois. Ainsi, ce message n'est pas seulement plus long, il contient littéralement deux messages, fusionnés ensemble (une norme ne le nie pas, btw).
Comme nous l'avons constaté précédemment, chaque bloc de données commence à partir d'une séquence, appelée Frame Sync Code (01111100 ...), après son envoi de blocs 32 bits. Chaque bloc peut stocker l'adresse ou le corps du message.
Auparavant, nous recevions les messages numériques uniquement, maintenant nous voulons lire les messages ASCII. Tout d'abord, nous devons les distinguer. Ces données sont enregistrées dans un champ "Function Bits" (bits 20-21) - si les deux bits sont 00, c'est un message uniquement numérique, si les bits sont 11, c'est un message texte.
Il est intéressant de mentionner que ce champ de message est de 20 bits, il est donc idéal d'y placer cinq blocs de 4 bits dans le cas d'un message numérique uniquement. Mais si nous avons un message ASCII 7 bits, nous ne pouvons pas diviser 20 à 7. Il est possible de prédire que la première version du protocole ne supportait que les messages numériques (n'oubliez pas qu'il a été créé en 1982
et probablement les premiers pagers à tube nixie n'ont pas pu afficher plus ), et seule la prise en charge des messages ASCII ultérieurs a été ajoutée. Pour des raisons héritées, la norme de cadrage n'a pas été modifiée et les développeurs ont utilisé l'approche simple - ils ont simplement combiné les bits "tels quels", l'un après l'autre. De chaque message, nous devons prendre 20 bits et le fusionner au suivant, enfin nous pouvons décoder le corps du message.
Permet de voir un bloc de notre message (les espaces ont été ajoutés pour faciliter la lecture):
0 0001010011100010111111110010010
1 00010100000110110011 11100111001
1 01011010011001110100 01111011100
1 11010001110110100100 11011000100
1 11000001101000110100 10011110111
1 11100000010100011011 11101110000
1 00110010111011001101 10011011010
1 00011001011100010110 10011000010
1 10101100000010010101 10110000101
1 00010110111011001101 00000011011
1 10100101000000101000 11001010100
1 00111101010101101100 11011111010
Bit "0" Dans la première chaîne nous montre que c'est le champ d'adresse, et "11" dans 20-21 bits nous montre que le message est vraiment alphanumérique. Ensuite, nous prenons simplement 20 bits de chaque chaîne et les fusionnons ensemble.
Voici notre séquence de bits:
00010100000110110011010110100110011101001101000111011010010011000001101000
11010011100000010100011011001100101110110011010001100101110001011010101100
000010010101000101101110110011011010010100000010100000111101010101101
Dans POCSAG, le code ASCII 7 bits est utilisé, nous allons donc diviser une chaîne en 7 blocs de caractères:
0001010 0000110 1100110 1011010 0110011 1010011 ...
Après avoir essayé de le décoder (la table ASCII peut être facilement trouvée sur Internet), nous obtenons ... juste rien. En vérifiant à nouveau le manuel, voici la petite phrase "Les caractères ASCII sont placés de gauche à droite (MSB à LSB). Le LSB transmet en premier. ". Ainsi, le bit bas transmet en premier - pour un décodage correct, nous devons inverser toutes les chaînes.
C'est trop ennuyeux pour le faire manuellement, alors écrivons un code Python:
def parse_msg(block): msgs = "" for cw in range(16): cws = block[32 * cw:32 * (cw + 1)]
Enfin, nous obtenons cette séquence (bits, codes de symboles et symboles ASCII):
0101000 40 ( 0110000 48 0 0110011 51 3 0101101 45 - 1100110 102 f 1100101 101 e 1100010 98 b 0101101 45 - 0110010 50 2 0110000 48 0 0110001 49 1 0111001 57 9 0100000 32 0110001 49 1 0110011 51 3 0111010 58 : 0110011 51 3 0110001 49 1 0111010 58 : 0110100 52 4 0110101 53 5 0100000 32 0101010 42 * 0110100 52 4 0110111 55 7 0110110 54 6 0101001 41 ) 0100000 32 1000001 65 A 1010111 87 W 1011010 90 Z
Après la fusion, nous obtenons la chaîne: "(03-feb-2019 13:31:45 * 476) AWZ". Comme promis, c'est assez lisible par l'homme.
Soit dit en passant, il est intéressant de mentionner que les codes ASCII 7 bits sont utilisés. Les symboles de certains alphabets (allemand, cyrillique, etc.) ne peuvent pas être correctement codés en 7 bits. Pourquoi 7 bits? Probablement les ingénieurs avaient décidé que "7 bits suffiront à tous", qui sait ...
Conclusion
C'était vraiment intéressant de voir comment fonctionne POCSAG. C'est l'un des rares protocoles, en usage jusqu'à présent, qui peut littéralement être décodé sur la feuille de papier (et je ne vais certainement pas essayer cela avec TETRA ou GSM).
Bien sûr, le protocole POCSAG n'est pas entièrement décrit ici. La partie la plus importante et la plus intéressante est terminée, d'autres choses ne sont pas si excitantes. Au moins, il n'y a pas de décodage de codes à barres et il n'y a pas de code de correction d'erreur (BCH Check Bits) - il peut permettre de corriger jusqu'à 2 bits incorrects dans le message. Mais il n'y avait aucun objectif d'écrire un autre décodeur POCSAG ici, il y en a déjà assez.
Pour ceux qui veulent tester le vrai décodage avec rtl-sdr, une
application PDW freeware peut être utilisée. Il ne nécessite pas d'installation, il suffit de transmettre le son du HDSDR au PDW via l'application Virtual Audio Cable.
Le résultat ressemble à ceci:

(veuillez garder à l'esprit que le décodage des messages de service public peut être illégal dans certains pays, et de toute façon respecter la vie privée des destinataires)
Si quelqu'un veut obtenir plus d'informations sur ce sujet, les sources du décodeur
multimon-ng sont disponibles, il peut décoder de nombreux protocoles, également POCSAG et FLEX.
Merci d'avoir lu.