www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SMS im PDU Format entschlüsseln C-Code


Autor: Phil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich experimentirere gerade mit einem Siemens C55 und Atmega8!

Ich eine SMS des Handys auslesen und je nach Text Aktionen setzen.
Habt Ihr vielleicht einen C-Code, der mir das dumme PDU Format
umwandelt und den Text der Nachricht ausgibt??

So wie dieser Code:
Beitrag "SMS im PDU.Format in Text umwandeln"

nur eben in C ?!?

wäre euch dankbar,
philip

Autor: Klaus2 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schau mal bei ulrich radig, der hat da glaube ich was...

Klaus.

Autor: Phil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der hat leider nur das Senden eingebaut...

Autor: Kai (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe hier mal meinen alten C-Code ausgegraben, der den Text einer 
SMS vom PDU-Format ins Textformat umwandelt.

unsigned char mirror(unsigned char original) {
  unsigned char i;
  unsigned char gespiegelt = 0;

  for (i = 0; i < 8; i++) {
    gespiegelt >>= 1;
    gespiegelt |= original & 0x80;
    original <<= 1;
  }
  return gespiegelt;
}

unsigned char mirror7bit(unsigned char original) {
  unsigned char i;
  unsigned char gespiegelt = 0;

  for (i = 0; i < 8; i++) {
    gespiegelt >>= 1;
    gespiegelt |= original & 0x80;
    original <<= 1;
  }
  gespiegelt = gespiegelt >> 1;
  return gespiegelt;
}



void SMS_sortieren() {

  char SMS_7bit[350];
  //SMS-Text wird in eigenes SMS-Array gespeichert
  int lv1 = 0;
  int lv2 = 0;

  char zwischen1 = 0;
  char zwischen2 = 0;
  unsigned char status = 1;

  //Die 8-Bit-Ketten werden gespiegelt
  while (SMS_Text_sortiert[lv1] != '\0') {
    SMS_Text_sortiert[lv1] = mirror(SMS_Text_sortiert[lv1]);
    lv1++;
  }

  //8Bit-->7Bit konverter
  lv1 = 0;
  lv2 = 0;
  while (SMS_Text_sortiert[lv1] != '\0') {

    switch (status) {

    case 1:

      //original des zeichen 1 wird gesichert
      zwischen1 = SMS_Text_sortiert[lv1];
      //7-Bit des Zeichen 1 wird erzeugt
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 1;

      //Übertrag wird erzeugt
      zwischen1 = zwischen1 << 7;
      zwischen1 = zwischen1 >> 1;

      status = 2;
      break;

    case 2:

      //original des Zeichen 2 wird gesichert
      zwischen2 = SMS_Text_sortiert[lv1];

      //7-Bit des Zeichen 2 wird erzeugt
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 2;
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen1;

      //Übertrag wird erzeugt
      zwischen2 = zwischen2 << 6;
      zwischen2 = zwischen2 >> 1;

      status = 3;
      break;

    case 3:
      //original des Zeichen 3 wird gesichert
      zwischen1 = SMS_Text_sortiert[lv1];

      //7-Bit des Zeichen 3 wird erzeugt
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 3;
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen2;

      //Übertrag wird erzeugt
      zwischen1 = zwischen1 << 5;
      zwischen1 = zwischen1 >> 1;

      status = 4;

      break;

    case 4:
      //original des Zeichen 4 wird gesichert
      zwischen2 = SMS_Text_sortiert[lv1];

      //7-Bit des Zeichen 4 wird erzeugt
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 4;
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen1;

      //Übertrag wird erzeugt
      zwischen2 = zwischen2 << 4;
      zwischen2 = zwischen2 >> 1;

      status = 5;

      break;

    case 5:
      //original des Zeichen 5 wird gesichert
      zwischen1 = SMS_Text_sortiert[lv1];

      //7-Bit des Zeichen 5 wird erzeugt
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 5;
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen2;

      //Übertrag wird erzeugt
      zwischen1 = zwischen1 << 3;
      zwischen1 = zwischen1 >> 1;

      status = 6;

      break;

    case 6:
      //original des Zeichen 6 wird gesichert
      zwischen2 = SMS_Text_sortiert[lv1];

      //7-Bit des Zeichen 6 wird erzeugt
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 6;
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen1;

      //Übertrag wird erzeugt
      zwischen2 = zwischen2 << 2;
      zwischen2 = zwischen2 >> 1;

      status = 7;

      break;

    case 7:
      //original des Zeichen 7 wird gesichert
      zwischen1 = SMS_Text_sortiert[lv1];

      //7-Bit des Zeichen 7 wird erzeugt
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 7;
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen2;

      ////Übertrag wird erzeugt
      zwischen1 = zwischen1 << 1;
      zwischen1 = zwischen1 >> 1;

      status = 8;
      break;

    case 8:

      //    zwischen2 = SMS_Text_sortiert[lv1];
      SMS_7bit[lv2] = zwischen1;

      status = 1;
      lv1--;
      break;

    }
    lv1++;
    lv2++;
  }
  SMS_Text_sortiert[lv1] = '\0';
  SMS_7bit[lv2] = '\0';

  //umkopieren in globales Array

  lv1 = 0;
  while (SMS_7bit[lv1] != '\0') {
    SMS_Text_sortiert[lv1] = SMS_7bit[lv1];
    lv1++;
  }
  SMS_Text_sortiert[lv1] = '\0';

  //spiegeln zur endgültigen Form!
  lv1 = 0;
  while (SMS_Text_sortiert[lv1] != '\0') {
    SMS_Text_sortiert[lv1] = mirror7bit(SMS_Text_sortiert[lv1]);
    lv1++;
  }

}

Ich hoffe dieser zugegeben auf die schnelle entstandener 
unübersichtliche Code hilft dir weiter... :)

Gruß Kai

Autor: Phil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
perfekt, vielen dank

Autor: Andreas M. (elektronenbremser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier eine speicherschonende Variante (ohne Zwischenspeicher)

Mike
// pducodec.cpp : Wandelt zwischen ASCII und PDU
//  
// asci2pdu (Initialisierung mit PDU_START als Argument, dann bei jedem Aufruf Ablage des
//           Arguments im PDU-Format im SMSBuffer, Argumente > 127 werden ignoriert)
//
// pdu2asci (Initialisierung mit PDU_START als Argument, Rückgabewert 0,
             dann bei jedem Aufruf mit Argument != PDU_START auslesen eines ASCII-Zeichens)


#define PDU_START 0xFF

void asci2pdu(unsigned char c);
unsigned char pdu2asci(unsigned char flag);

unsigned char SMSBuffer[180];

void asci2pdu(unsigned char c)
   {
   static unsigned char bitPos;
   static unsigned char *bufPtr;
   unsigned short sreg;
   if (c == PDU_START)
      {
      bitPos = 0;
      bufPtr = SMSBuffer;
      *bufPtr = 0;
      return;
      }
   else
      {
      if (c > 128)
         {
         return;
         //do nothing
         }
      }
   sreg = (unsigned short)c << 8;
   sreg >>= bitPos;
   if (bitPos > 0)
      {
      *bufPtr++ |= (sreg & 0xFF);
      }
   *bufPtr = sreg >> 8;
   if (++bitPos > 7)
      {
      bitPos = 0;
      }
   }

unsigned char pdu2asci(unsigned char flag)
   {
   static unsigned char bitPos;
   static unsigned char *bufPtr;
   static unsigned char sreg;
   unsigned char c;
   if (flag == PDU_START)
      {
      bitPos = 0;
      bufPtr = SMSBuffer;
      return 0;
      }
   if (bitPos >0)
      {
      c = *bufPtr++ >> (8-bitPos);
      }
   else
      {
      c = 0;
      }
   c |= *bufPtr << bitPos;
   c &= 0x7F;
   if (++bitPos > 7)
      {
      bitPos = 0;
      }
   return c;
   }

Autor: Klaus2 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitte in die lib oder Codeschnipsel Ecke damit - wird hier immer wieder 
gefragt und ist ziemlich "cool" für Automatisierungsbrimborium!

Danke auch von mir! Klaus.

Autor: Phil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnt Ihr mir vielleicht noch sagen wie ich die Funktion pdu2ascii 
aufrufe?
Ich komm da einfach nicht klar...

danke

Autor: usb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich vermute :

empfangene SMS  in den SMSBuffer  legen
dann



char klartext[128];

pdu2asci(PDU_START) ;
for( uint8_t i=0 ; i<=128 ; i++)
  klartext[i] = pdu2asci(0x00);

print( klartext);



zum versenden einer SMS :


for( uint8_t i=0 ; i<=128 ; i++)
  asci2pdu( klartext[i] );

send_sms( SMSBuffer , nummer );

Autor: usb (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zum versenden einer SMS :

asci2pdu( PDU_START);
for( uint8_t i=0 ; i<=128 ; i++)
  asci2pdu( klartext[i] );

send_sms( SMSBuffer , nummer );

so rum ... der start hatte gefehl ..

Autor: Phil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!

Habe das ganze jetzt so aufgerufen:
strcpy(SMSBuffer,"0791947107160000040D91945187328511F10000909090122535800441E19008");

char klartext[128];

pdu2asci(PDU_START) ;
for( uint8_t i=0 ; i<=128 ; i++)
  klartext[i] = pdu2asci(0x00);

uart_puts(klartext);

Ich bekomme aber leider nur eine "8" auf den UART, der Text sollte 
"ABCD" sein.
Wisst Ihr vielleicht wo der Fehler begraben ist?

danke

Autor: Phil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, bekomme nicht nur eine "8" sondern folgende Zeichen.

0nd     M`\     c
                 0`@!Q1rP)Nd`)&
                               #1`@&9`dF
                                        5fTA
                                            4b

                                              80nd      M`\     c
                                                                 0`@!Q1rP)Nd`)&
                                                                               #
1`@&9`dF
        5fTA
            4b

              8

Habt ihr vielleicht eine Lösung für mich? Habe ich den String am Anfang 
richtig beschrieben?

Autor: Phil (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weiß vielleicht wer was fer Grund sein könnte, dass ich da nur mist 
rausbekomme??

Ich wäre euch wirklich dankbar!

SMS senden funktioniert, Aktionen auf Anrufe starten funktioniert auch.
Wie gesagt, der letzte Schritt die SMS auswerten hat leider noch nicht 
hin...

Autor: Christof C. (tinybastler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code von Mike funktioniert wunderbar, er geht aber davon aus, dass 
im SMSBuffer die PDU-Zeichen als Hex abgelegt sind. Der Code von Phil 
kann also so als ASCII nicht funktionieren. Vorher in Hex umwandeln, 
dann gehts. Wie das allerdings bei der Kommunikation mit dem Handy 
abläuft ist mir noch ein Rätsel. Soweit ich weiß, gibt das Handy die 
Zeichen auch als ASCII aus.

Autor: Niels Keller (niels-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christof C. schrieb:
>Soweit ich weiß, gibt das Handy die Zeichen auch als ASCII aus.

Da schalte ich mich auch gerade mal ein - hier geht es ja nicht um C 
;-). Das Handy gibt die Nachricht im ASCII-Code aus, nutzt davon aber 
nur den Bereich der HEX-Werte, also von "A" bis "H". Man erhält die SMS, 
wenn man an das Handy "at +cmgr=" gefolgt von der Nachrichtennummer 
sendet. Das Handy verwaltet intern Nachrichten im Speicher, entweder auf 
der SIM oder im Telefon. Zum SIM-Speicher wechselt man mit folgender 
Zeile:
"at+cpms="SM". Hoffe ich konnte helfen. Ansonsten den Bascom-Code des 
GPS-Trackers http://www.mikrocontroller.net/attachment/58438/Anhang.zip 
nutzen und dort das BAS-File ansehen. Dort ist der Funktionsaufruf 
sichtbar.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.