Décortiquage du Runbo X5

Un nouveau fabricant de smartphone est arrivé sur le marché cet hiver : Runbo. Il commercialise des téléphones renforcés à la norme IP67 avec un talky-walky intégré. Deux de ces modèles tournent sous Android.
Un collègue à craqué et c’est offert le modèle X5. Après les premiers essais, j’ai eu de fort soupçons que la partie talky-walky s’articule autour du chip RDA1846, le même que l’on trouve dans les transceivers Baofeng.
L’application gérant la partie talky-walky est on ne peut plus spartiate et semble encore un peu buggée : volume trop fort même au minimum, le squelch qui ne fonctionne pas toujours correctement. Qui plus est, pour des applis OM il serait intéressant de pouvoir dialoguer directement avec le RDA1846 !
Mon collègue (merci Thomas! :)) a été assez sympa de me le prêter pour le weekend afin que je puisse faire un peu de reverse engineering.
Encore une fois, cet article est d’abord un mémo pour archiver et documenter mon travail. Mais si ça peut servir à quelqu’un ! :)

La première chose a été de récupérer le paquet de l’appli talky-walky et de le décompiler. Ceci nous apprends que la partie radio est pilotée par la classe android.hardware.intercom.

Extrait du code de l’appli (on notera que la décompilation ne produit pas un code utilisable) :

  public void manualSetIntercom(int paramInt1, int paramInt2, int paramInt3, int paramInt4)
  {
    Log.v("Property_set", "Call manualSetIntercom!");
    Log.v("Property_set", "tx = " + paramInt1);
    Log.v("Property_set", "rx = " + paramInt2);
    Log.v("Property_set", "ctcss = " + paramInt3);
    Log.v("Property_set", "sq = " + paramInt4);
    this.mIntercom.setTXFrequency(paramInt1);
    try
    {
      Thread.sleep(300L);
      this.mIntercom.setRXFrequency(paramInt2);
    }
    catch (InterruptedException localInterruptedException3)
    {
      try
      {
        Thread.sleep(300L);
        this.mIntercom.setCtcss(paramInt3);
      }
      catch (InterruptedException localInterruptedException3)
      {
        try
        {
          Thread.sleep(300L);
          this.mIntercom.setSq(this.mRow1SqValue);
        }
        catch (InterruptedException localInterruptedException3)
        {
          try
          {
            while (true)
            {
              Thread.sleep(300L);
              return;
              localInterruptedException1 = localInterruptedException1;
              localInterruptedException1.printStackTrace();
              continue;
              localInterruptedException2 = localInterruptedException2;
              localInterruptedException2.printStackTrace();
            }
            localInterruptedException3 = localInterruptedException3;
            localInterruptedException3.printStackTrace();
          }
          catch (InterruptedException localInterruptedException4)
          {
            while (true)
              localInterruptedException4.printStackTrace();
          }
        }
      }
    }
  }

La classe android.hardware.Intercom n’est pas une classe standard de l’API Android. Le constructeur l’a toutes fois ajouté dans le framework interne de sa version d’Android. Il a donc fallu la récupérer dans les entrailles de la bête. Ceci fait, cela ne nous apprend pas grand chose. Si ce n’est que c’est un classe n’est qu’un wrapper vers une librairie native. Librairie, que je n’ai pas encore réussie à localiser à l’heure ou j’écris ceci.

package android.hardware;
 
public class Intercom
{
  private static native int JNI_closeCharDev();
  private static native int JNI_intercomHeadsetMode();
  private static native int JNI_intercomPowerOff();
  private static native int JNI_intercomPowerOn();
  private static native int JNI_intercomSpeakerMode();
  private static native int JNI_openCharDev();
  private static native int JNI_resumeIntercomSetting();
  private static native int JNI_setCtcss(int paramInt);
  private static native int JNI_setRXFrequency(int paramInt);
  private static native int JNI_setRadioFrequency(int paramInt);
  private static native int JNI_setSq(int paramInt);
  private static native int JNI_setTXFrequency(int paramInt);
  private static native int JNI_setVolume(int paramInt);
 
  public void closeCharDev()
  {
    JNI_closeCharDev();
  }
 
  public void intercomHeadsetMode()
  {
    JNI_intercomHeadsetMode();
  }
 
  public void intercomPowerOff()
  {
    JNI_intercomPowerOff();
  }
 
  public void intercomPowerOn()
  {
    JNI_intercomPowerOn();
  }
 
  public void intercomSpeakerMode()
  {
    JNI_intercomSpeakerMode();
  }
 
  public void openCharDev()
  {
    JNI_openCharDev();
  }
 
  public void resumeIntercomSetting()
  {
    JNI_resumeIntercomSetting();
  }
 
  public void setCtcss(int paramInt)
  {
    JNI_setCtcss(paramInt);
  }
 
  public void setRXFrequency(int paramInt)
  {
    JNI_setRXFrequency(paramInt);
  }
 
  public void setRadioFrequency(int paramInt)
  {
    JNI_setRadioFrequency(paramInt);
  }
 
  public void setSq(int paramInt)
  {
    JNI_setSq(paramInt);
  }
 
  public void setTXFrequency(int paramInt)
  {
    JNI_setTXFrequency(paramInt);
  }
 
  public void setVolume(int paramInt)
  {
    JNI_setVolume(paramInt);
  }
}

Pour continuer je suis allé farfouiller dans le fichier init.rc

A la ligne 106 on trouve ceci :

    #chmod of the intercom devices
    chmod 0777  /dev/ttyMT1
    chmod 0777 /dev/intercom_A1840

Et à la ligne 505 cela :

    #chown of the intercom devices
    chown system system /dev/ttyMT1
    chown system system /dev/intercom_A1840

Suite au prochain épisode : à quoi correspondent ces deux périphériques ? Comment dialoguer avec ?

Bookmarquez le permalien.

27 Comments

  1. Pas mal du tout, super job.
    mais moi je suis vraiment néophyte. As-tu 1 mode d’emploi du TW?
    merci

  2. Bonjour,

    Je ne sais pas où en es-tu de tes recherches mais j’ai essayé de creuser aussi de mon coté maintenant que j’ai un X5.
    Le port /dev/MT1 est en fait un port UART qui sert à piloter le RDA1846.
    J’ai fait un essai avec l’application « Serial Port API Sample » : ouvrir le device /dev/MT1, règler la vitesse à 9600 puis aller dans la console.
    Lancer l’application Intercom…
    Et dans la fenetre réception des choses apparaissent :)

    Reste à en trouver la signification….

    Cordialement

  3. Un peu plus d’infos…

    A travers cet UART, l’application teste la présence d’un module. 3 possibilités sont prévues (lib/libandroid_runtime.so):
    Runbo: This is the INTERCOM_80BK_400M module
    Runbo: This is the INTERCOM_81BK_480M module
    Runbo: This is the INTERCOM_AUCTUS_400M module

    Le mien est un 81BK en version 1.0.
    En cherchant une référence, j’ai trouvé que le module Auctus est décrit sur ce site: http://www.auctus.cn/en/product/indexlj4.php

    Cordialement

    • Bonjour,

      Bravo pour tes trouvailles.
      Je ne suis guère plus loin car j’avais l’appareil en prêt et là je ne l’ai plus.

      Donc en fait, si je te suis bien le RDA ne serait pas directement connecté à cet UART mais monté sur ce module Auctus qui lui serait interfacé via l’UART.

      As tu pu faire des dumps de tout ce qui transit ?

      A+

  4. Non pas encore, je viens tout juste de passer à l’étape « mode adb » après avoir joué avec l’image du firmware.
    Je veux tester le /dev/intercom pour voir à quoi il correspond.

  5. Quelques éléments de plus récupérés via un strace:
    – jni_openCharDev: ouvre /dev/ttyMT1 à 9600baud (open() puis ioctl())
    – jni_intercomPowerOn: ouvre /dev/intercom_A1840 (open()) puis ioctl(FIBMAP)
    – écrit « AT+DMOVERQ\r\n » sur /dev/ttyMT1
    – lis la chaine en retour (soit « +DMOVERQ:81BKV1.0\r\n » dans mon cas)
    – Règle les paramètres (jni_setTXFrequency) Tx=401MHz, rx=433Mhz, ctcss=0, sq=0, tx_ctcss=0 (config de test) en écrivant « AT+DMOSETGROUP=0,401.0000,433.00(chaine tronquée) »
    – idem sur jni_setRXFrequency, le début de la chaine est identique
    – idem sur jni_setCtcss
    – idem sur jni_setSq, toujours le meme début de chaine (faut que je trouve comment l’afficher en entier !!!)
    – réglage du volume avec « AT+DMOSETVOLUME=2\r\n »

    Voilà pour la partie init, je regarde la suite…

    • Donc en fait ce sont de « bêtes commandes » AT ??
      Dans l’absolue on pourrait donc se passer de la lib native…

      Et donc ouvre /dev/intercom_A1840 ne sert qu’à allumer/éteindre ….

      Super boulot !

  6. L’extinction est réalisée en effectuant un ioctl sur /dev/intercom_A1840 en écrivant 0. Et donc on peut le démarrer en écrivant 1 :)

  7. Je viens de comprendre à quoi correspondent les modules 80BK/81BK/Auctus présents dans le code : il n’y a pas de chipset RDA1846 dans le Runbo, mais l’un des trois pour gérer la partie radio.
    Dans le mien c’est donc le module HKT-81BK qui gère la partie radio. Il ne fonctionne que dans la bande 400-480MHz ce qui explique pourquoi il faut préciser à la commande si l’on souhaite une version VHF ou UHF du téléphone. Le version VHF doit à mon avis etre fournie avec le module Auctus puisque celui-ci est capable de travailler sur les deux bandes.

    La doc (en chinois, faire un Google Translate) est disponible ici :
    http://www.hktelec.com/products/duijiangji/2W/2013/0326/129.html

    Points confirmés en lisant la doc:
    – la puissance maximale du chip est en effet d’1W
    – il se commande au travers de commandes ‘AT’
    – démodulation FM uniquement

    La version HKT-80BK diffère sur la bande : 400-470MHz.

    Donc pour du radioamateur, il faut commander le téléphone en demandant la version VHF. En bidouillant, il doit etre possible de la faire travailler aussi en UHF.

    • J’avais une doc du RDA (perdue dans un crash de mon DD) et il n’était pas question de commandes AT… Voilà ce qui me fait penser que le module Auctus s’articule peut être autour du RDA, non?

      Beucoup de sites (russes notamment) mentionnent le RDA….. tout le monde ferais fausse route depuis le début?

      Mon collègue n’a pas eu le choix lors de la commande, c’était UHF et c’est tout. Tu as commandé le tiens où ?

      • Chez itsto.re et d’après le vendeur, il est possible de lui demander la version VHF en lui précisant par mail sur la commande.

        Sur l’histoire du RDA, je ne sais pas d’où ça vient, sans doute que le module Auctus les a induit en erreur. Ou alors, c’est ce blog, car tu es souvent référencé ;)

        D’après le code, le module Auctus se pilote de la meme façon. Chose étrange, le code ne traite que du UHF avec ce module… Ou alors la version VHF est fournie avec le chipset RDA avec un MCU ? En tout cas, la ROM est certainement différente pour la version VHF.

        La doc du RDA est assez facile à retrouver dans Google et en effet, il n’y a aucune commande de type AT pour lui parler, suffit d’utiliser le protocole I2C et d’envoyer quelques ordres du genre .

        • J’ai trouvé la réponse : le module Auctus est bien un composant RDA. Auctus est en effet un intégrateur de cette solution.

          Par contre, vu qu’il n’y a pas de trace de commandes pour les fréquences VHF dans le code, cela signifierai bien qu’une autre version de la ROM serait nécessaire ?

          • Ouf je n’ai donc pas lancé de fausses rumeurs sur le Web ! :D

            a mon avis il faut plus qu’une autre ROM pour la VHF. L’étage de puissance en sortie du RDA ne doit pas être taillé pour la VHF.

  8. Doc en chinois du protocole de commande A1841 (d’où le nom du device intercom_A1841…) :
    http://3y.uu456.com/bp-30727e49e4sc3b3s67ec8b24-1.html

  9. J’ai enfin pu tester l’application Intercom avec un Talkie PMR446: c’est vrai qu’elle est bugguée puisque le canal 1 ne fonctionne pas… Il a fallu que je passe en manuel et règle la fréquence à la main… Du coup ça a marché ! Bon il manque des options à cette application, vivement que je trouve suffisamment d’informations pour la re-développer.

  10. J’ai téléchargé la ROM de la version VHF : c’est le module D150_136M qui est testé. Donc le module Auctus n’est pas capable de faire du VHF. Par contre, la ROM contient le test des autres modules, elle serait donc capable de gérer les deux versions du téléphone ?

  11. Bonjour,
    je possede le Runbo x5 depuis 3 mois.
    Tout fonctionne bien et je suis content.
    Comme il n’existe pas de mode d’emploi, je ne sais pas faire marcher le WT.
    Que faut il inscrire ou cocher dans les cases de l’intercom pour communiquer avec quel quin en region Parisienne Est?
    Je n’ai pas de permis, mais c’est MON risque.

  12. The Walkie Talkie is OK, but the frequencies are not set up correctly for Australia. The system can send TX but you caN NOT rx (Receive)…. Manually set up a channel and it works, so must be the app. But no way to change it…

  13. Bonjour,

    Sur un forum russe, j’ai trouvé une possible alternative.
    J’ai copier quelqes versions de leurs Intercomm (avec 2 mm en fin de mot) dans ma dropbox.

    https://www.dropbox.com/sh/xakvix8exuoc7sl/AAAAfnKA8zxWfcunpFlAXiQNa

    Qui veut essayer en premier?

Laisser un commentaire