SMS im PDU Format entschlüsseln C-Code

Gast #1609334
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
Gast #1609413
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
Gast #1609577
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
   }
Gast #1612797
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 );
Gast #1613804
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
Gast #1615967
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?
Gast #1619441
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...
#1634585
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.
#1639533
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren