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


von Phil (Gast)


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

von Klaus2 (Gast)


Lesenswert?

schau mal bei ulrich radig, der hat da glaube ich was...

Klaus.

von Phil (Gast)


Lesenswert?

der hat leider nur das Senden eingebaut...

von Kai (Gast)


Lesenswert?

Hallo,

ich habe hier mal meinen alten C-Code ausgegraben, der den Text einer 
SMS vom PDU-Format ins Textformat umwandelt.
1
unsigned char mirror(unsigned char original) {
2
  unsigned char i;
3
  unsigned char gespiegelt = 0;
4
5
  for (i = 0; i < 8; i++) {
6
    gespiegelt >>= 1;
7
    gespiegelt |= original & 0x80;
8
    original <<= 1;
9
  }
10
  return gespiegelt;
11
}
12
13
unsigned char mirror7bit(unsigned char original) {
14
  unsigned char i;
15
  unsigned char gespiegelt = 0;
16
17
  for (i = 0; i < 8; i++) {
18
    gespiegelt >>= 1;
19
    gespiegelt |= original & 0x80;
20
    original <<= 1;
21
  }
22
  gespiegelt = gespiegelt >> 1;
23
  return gespiegelt;
24
}
25
26
27
28
void SMS_sortieren() {
29
30
  char SMS_7bit[350];
31
  //SMS-Text wird in eigenes SMS-Array gespeichert
32
  int lv1 = 0;
33
  int lv2 = 0;
34
35
  char zwischen1 = 0;
36
  char zwischen2 = 0;
37
  unsigned char status = 1;
38
39
  //Die 8-Bit-Ketten werden gespiegelt
40
  while (SMS_Text_sortiert[lv1] != '\0') {
41
    SMS_Text_sortiert[lv1] = mirror(SMS_Text_sortiert[lv1]);
42
    lv1++;
43
  }
44
45
  //8Bit-->7Bit konverter
46
  lv1 = 0;
47
  lv2 = 0;
48
  while (SMS_Text_sortiert[lv1] != '\0') {
49
50
    switch (status) {
51
52
    case 1:
53
54
      //original des zeichen 1 wird gesichert
55
      zwischen1 = SMS_Text_sortiert[lv1];
56
      //7-Bit des Zeichen 1 wird erzeugt
57
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 1;
58
59
      //Übertrag wird erzeugt
60
      zwischen1 = zwischen1 << 7;
61
      zwischen1 = zwischen1 >> 1;
62
63
      status = 2;
64
      break;
65
66
    case 2:
67
68
      //original des Zeichen 2 wird gesichert
69
      zwischen2 = SMS_Text_sortiert[lv1];
70
71
      //7-Bit des Zeichen 2 wird erzeugt
72
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 2;
73
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen1;
74
75
      //Übertrag wird erzeugt
76
      zwischen2 = zwischen2 << 6;
77
      zwischen2 = zwischen2 >> 1;
78
79
      status = 3;
80
      break;
81
82
    case 3:
83
      //original des Zeichen 3 wird gesichert
84
      zwischen1 = SMS_Text_sortiert[lv1];
85
86
      //7-Bit des Zeichen 3 wird erzeugt
87
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 3;
88
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen2;
89
90
      //Übertrag wird erzeugt
91
      zwischen1 = zwischen1 << 5;
92
      zwischen1 = zwischen1 >> 1;
93
94
      status = 4;
95
96
      break;
97
98
    case 4:
99
      //original des Zeichen 4 wird gesichert
100
      zwischen2 = SMS_Text_sortiert[lv1];
101
102
      //7-Bit des Zeichen 4 wird erzeugt
103
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 4;
104
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen1;
105
106
      //Übertrag wird erzeugt
107
      zwischen2 = zwischen2 << 4;
108
      zwischen2 = zwischen2 >> 1;
109
110
      status = 5;
111
112
      break;
113
114
    case 5:
115
      //original des Zeichen 5 wird gesichert
116
      zwischen1 = SMS_Text_sortiert[lv1];
117
118
      //7-Bit des Zeichen 5 wird erzeugt
119
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 5;
120
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen2;
121
122
      //Übertrag wird erzeugt
123
      zwischen1 = zwischen1 << 3;
124
      zwischen1 = zwischen1 >> 1;
125
126
      status = 6;
127
128
      break;
129
130
    case 6:
131
      //original des Zeichen 6 wird gesichert
132
      zwischen2 = SMS_Text_sortiert[lv1];
133
134
      //7-Bit des Zeichen 6 wird erzeugt
135
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 6;
136
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen1;
137
138
      //Übertrag wird erzeugt
139
      zwischen2 = zwischen2 << 2;
140
      zwischen2 = zwischen2 >> 1;
141
142
      status = 7;
143
144
      break;
145
146
    case 7:
147
      //original des Zeichen 7 wird gesichert
148
      zwischen1 = SMS_Text_sortiert[lv1];
149
150
      //7-Bit des Zeichen 7 wird erzeugt
151
      SMS_7bit[lv2] = SMS_Text_sortiert[lv1] >> 7;
152
      SMS_7bit[lv2] = SMS_7bit[lv2] + zwischen2;
153
154
      ////Übertrag wird erzeugt
155
      zwischen1 = zwischen1 << 1;
156
      zwischen1 = zwischen1 >> 1;
157
158
      status = 8;
159
      break;
160
161
    case 8:
162
163
      //    zwischen2 = SMS_Text_sortiert[lv1];
164
      SMS_7bit[lv2] = zwischen1;
165
166
      status = 1;
167
      lv1--;
168
      break;
169
170
    }
171
    lv1++;
172
    lv2++;
173
  }
174
  SMS_Text_sortiert[lv1] = '\0';
175
  SMS_7bit[lv2] = '\0';
176
177
  //umkopieren in globales Array
178
179
  lv1 = 0;
180
  while (SMS_7bit[lv1] != '\0') {
181
    SMS_Text_sortiert[lv1] = SMS_7bit[lv1];
182
    lv1++;
183
  }
184
  SMS_Text_sortiert[lv1] = '\0';
185
186
  //spiegeln zur endgültigen Form!
187
  lv1 = 0;
188
  while (SMS_Text_sortiert[lv1] != '\0') {
189
    SMS_Text_sortiert[lv1] = mirror7bit(SMS_Text_sortiert[lv1]);
190
    lv1++;
191
  }
192
193
}

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

Gruß Kai

von Phil (Gast)


Lesenswert?

perfekt, vielen dank

von Andreas M. (elektronenbremser)


Lesenswert?


von Mike (Gast)


Lesenswert?

Hier eine speicherschonende Variante (ohne Zwischenspeicher)

Mike
1
// pducodec.cpp : Wandelt zwischen ASCII und PDU
2
//  
3
// asci2pdu (Initialisierung mit PDU_START als Argument, dann bei jedem Aufruf Ablage des
4
//           Arguments im PDU-Format im SMSBuffer, Argumente > 127 werden ignoriert)
5
//
6
// pdu2asci (Initialisierung mit PDU_START als Argument, Rückgabewert 0,
7
             dann bei jedem Aufruf mit Argument != PDU_START auslesen eines ASCII-Zeichens)
8
9
10
#define PDU_START 0xFF
11
12
void asci2pdu(unsigned char c);
13
unsigned char pdu2asci(unsigned char flag);
14
15
unsigned char SMSBuffer[180];
16
17
void asci2pdu(unsigned char c)
18
   {
19
   static unsigned char bitPos;
20
   static unsigned char *bufPtr;
21
   unsigned short sreg;
22
   if (c == PDU_START)
23
      {
24
      bitPos = 0;
25
      bufPtr = SMSBuffer;
26
      *bufPtr = 0;
27
      return;
28
      }
29
   else
30
      {
31
      if (c > 128)
32
         {
33
         return;
34
         //do nothing
35
         }
36
      }
37
   sreg = (unsigned short)c << 8;
38
   sreg >>= bitPos;
39
   if (bitPos > 0)
40
      {
41
      *bufPtr++ |= (sreg & 0xFF);
42
      }
43
   *bufPtr = sreg >> 8;
44
   if (++bitPos > 7)
45
      {
46
      bitPos = 0;
47
      }
48
   }
49
50
unsigned char pdu2asci(unsigned char flag)
51
   {
52
   static unsigned char bitPos;
53
   static unsigned char *bufPtr;
54
   static unsigned char sreg;
55
   unsigned char c;
56
   if (flag == PDU_START)
57
      {
58
      bitPos = 0;
59
      bufPtr = SMSBuffer;
60
      return 0;
61
      }
62
   if (bitPos >0)
63
      {
64
      c = *bufPtr++ >> (8-bitPos);
65
      }
66
   else
67
      {
68
      c = 0;
69
      }
70
   c |= *bufPtr << bitPos;
71
   c &= 0x7F;
72
   if (++bitPos > 7)
73
      {
74
      bitPos = 0;
75
      }
76
   return c;
77
   }

von Klaus2 (Gast)


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.

von Phil (Gast)


Lesenswert?

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

danke

von usb (Gast)


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 );

von usb (Gast)


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 ..

von Phil (Gast)


Lesenswert?

Hi!

Habe das ganze jetzt so aufgerufen:
1
strcpy(SMSBuffer,"0791947107160000040D91945187328511F10000909090122535800441E19008");
2
3
char klartext[128];
4
5
pdu2asci(PDU_START) ;
6
for( uint8_t i=0 ; i<=128 ; i++)
7
  klartext[i] = pdu2asci(0x00);
8
9
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

von Phil (Gast)


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?

von Phil (Gast)


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...

von Christof C. (tinybastler)


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.

von Niels K. (niels-k)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.