File: gsm_sms_codec.h

package info (click to toggle)
gsmlib 1.10+20120414.gita5e5ae9a-0.3
  • links: PTS
  • area: main
  • in suites: bullseye, buster, sid, stretch
  • size: 3,468 kB
  • ctags: 1,907
  • sloc: cpp: 12,315; sh: 11,376; ansic: 2,366; makefile: 263; sed: 93
file content (335 lines) | stat: -rw-r--r-- 9,782 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
// *************************************************************************
// * GSM TA/ME library
// *
// * File:    gsm_sms_codec.h
// *
// * Purpose: Coder and Encoder for SMS TPDUs
// *
// * Author:  Peter Hofmann (software@pxh.de)
// *
// * Created: 16.5.1999
// *************************************************************************

#ifndef GSM_SMS_CODEC_H
#define GSM_SMS_CODEC_H

#include <string>
#include <assert.h>

namespace gsmlib
{
  // this struct represents a telephone number
  // usually _type == Unknown or International
  // and _number == ISDN_Telephone
  struct Address
  {
    enum Type {Unknown = 0, International = 1, National = 2,
               NetworkSpecific = 3, Subscriber = 4,
               Alphanumeric = 5, Abbreviated = 6, Reserved = 7};
    enum NumberingPlan {UnknownPlan = 0, ISDN_Telephone = 1,
                        Data = 3, Telex = 4, NationalPlan = 8,
                        PrivatePlan = 9, Ermes = 10, ReservedPlan = 15};
    Type _type;
    NumberingPlan _plan;
    std::string _number;

  Address() : _type(Unknown), _plan(UnknownPlan) {}
    // the constructor sets _type and _plan to defaults
    // _plan == ISDN_Telephone
    // _type == International if number starts with "+"
    // _type == unknown otherwise
    // number must be of the form "+123456" or "123456"
    Address(std::string number);

    // return std::string representation
    std::string toString() const;

    friend bool operator<(const Address &x, const Address &y);
    friend bool operator==(const Address &x, const Address &y);
  };

  // compare two addresses
  extern bool operator<(const Address &x, const Address &y);
  extern bool operator==(const Address &x, const Address &y);

  // representation of a SMS timestamp
  struct Timestamp
  {
    short _year, _month, _day, _hour, _minute, _seconds, _timeZoneMinutes;
    bool _negativeTimeZone;

  Timestamp() : _year(0), _month(0), _day(0), _hour(0),
      _minute(0), _seconds(0), _timeZoneMinutes(0), _negativeTimeZone(false) {}

    // return true if the time stamp is empty (ie. contains only zeroes)
    bool empty() const;

    // return std::string representation
    std::string toString(bool appendTimeZone = true) const;

    friend bool operator<(const Timestamp &x, const Timestamp &y);
    friend bool operator==(const Timestamp &x, const Timestamp &y);
  };

  // compare two timestamps
  extern bool operator<(const Timestamp &x, const Timestamp &y);
  extern bool operator==(const Timestamp &x, const Timestamp &y);

  // representation of time period
  struct TimePeriod
  {
    // possible values for validity period format
    enum Format {NotPresent = 0, Relative = 2, Absolute = 3};
    Format _format;
    Timestamp _absoluteTime;
    unsigned char _relativeTime;

  TimePeriod() : _format(NotPresent), _relativeTime(0) {}

    // return std::string representation (already translated)
    std::string toString() const;
  };

  // representation of DataCodingScheme
  // the data coding scheme is described in detail in ETSI GSM 03.38, section 4
  const unsigned char DCS_COMPRESSED = 0x20; // bit 5

  const unsigned char DCS_DEFAULT_ALPHABET = 0 << 2; // bit 2..3 == 0
  const unsigned char DCS_EIGHT_BIT_ALPHABET = 1 << 2; // bit 2..3 == 01
  const unsigned char DCS_SIXTEEN_BIT_ALPHABET = 2 << 2; // bit 2..3 == 10
  const unsigned char DCS_RESERVED_ALPHABET = 3 << 2; // bit 2..3 == 11

  const unsigned char DCS_MESSAGE_WAITING_INDICATION = 0xc0; // bit 7..6 == 11
  const unsigned char DCS_VOICEMAIL_MESSAGE_WAITING = 0;
  const unsigned char DCS_FAX_MESSAGE_WAITING = 1;
  const unsigned char DCS_ELECTRONIC_MAIL_MESSAGE_WAITING = 2;
  const unsigned char DCS_OTHER_MESSAGE_WAITING = 3;

  class DataCodingScheme
  {
  private:
    unsigned char _dcs;

  public:
    // initialize with data coding scheme octet
  DataCodingScheme(unsigned char dcs) : _dcs(dcs) {}

    // set to default values (no message waiting, no message class indication,
    // default 7-bit alphabet)
  DataCodingScheme() : _dcs(DCS_DEFAULT_ALPHABET) {}

    // return type of alphabet used (if messageWaitingIndication == false)
    unsigned char getAlphabet() const
    {
      return _dcs & (3 << 2);
    }

    // return true if message compressed
    // (if messageWaitingIndication == false)
    bool compressed() const
    {
      return (_dcs & DCS_COMPRESSED) == DCS_COMPRESSED;
    }

    // return true if message waiting indication
    bool messageWaitingIndication() const
    {
      return (_dcs & DCS_MESSAGE_WAITING_INDICATION) ==
	DCS_MESSAGE_WAITING_INDICATION;
    }

    // return type of waiting message (if messageWaitingIndication == true)
    unsigned char getMessageWaitingType() const {return _dcs & 3;}

    // return std::string representation (already translated)
    std::string toString() const;

    operator unsigned char() const {return _dcs;}
  };

  // utility class facilitate SMS TPDU decoding
  class SMSDecoder
  {
  private:
    unsigned char *_p;          // buffer to hold pdu
    short _bi;                  // bit index (0..7)
    unsigned char *_op;         // current octet pointer
    unsigned char *_septetStart; // start of septet string

    unsigned char *_maxop;      // pointer to last byte after _p

  public:
    // initialize with a hexadecimal octet std::string containing SMS TPDU
    SMSDecoder(std::string pdu);

    // align to octet border
    void alignOctet();

    // remember starting point of septets (important for alignSeptet())
    void markSeptet() {alignOctet(); _septetStart = _op;}

    // align to septet border
    void alignSeptet();

    // get single bit
    bool getBit()
    {
      assert(_op < _maxop);
      bool result = ((*_op >> _bi) & 1);
      if (_bi == 7)
	{
	  _bi = 0;
	  ++_op;
	}
      else
        ++_bi;
      return result;
    }

    // get two bits
    unsigned char get2Bits();

    // get one octet
    unsigned char getOctet();

    // get std::string of octets of specified length
    void getOctets(unsigned char* octets, unsigned short length);

    // get length semi-octets (bcd-coded number) as ASCII std::string of numbers
    std::string getSemiOctets(unsigned short length);

    // get length semi-octets (bcd-coded number) as integer
    unsigned long getSemiOctetsInteger(unsigned short length);

    // get time zone (in minutes) and time zone sign
    unsigned long getTimeZone(bool &negativeTimeZone);

    // get integer with length number of bits
    unsigned long getInteger(unsigned short length);

    // get length number of alphanumeric 7-bit characters
    // markSeptet() must be called before this function
    std::string getString(unsigned short length);

    // get address/telephone number
    // service centre address has special format
    Address getAddress(bool scAddressFormat = false);

    // get Timestamp
    Timestamp getTimestamp();

    // get TimePeriod of given format
    TimePeriod getTimePeriod(TimePeriod::Format format);

    // destructor
    ~SMSDecoder();
  };

  // utility class for SMS TPDU encoding
  class SMSEncoder
  {
  private:
    unsigned char _p[2000];     // buffer to hold pdu (2000 should be enough)
    short _bi;                  // bit index (0..7)
    unsigned char *_op;         // current octet pointer
    unsigned char *_septetStart; // start of septet string

  public:
    // constructor
    SMSEncoder();

    // align to octet border
    void alignOctet();

    // remember starting point of septets (important for alignSeptet())
    void markSeptet() {alignOctet(); _septetStart = _op;}

    // align to septet border
    void alignSeptet();

    // set single bit
    void setBit(bool bit = false)
    {
      if (bit)
        *_op |= (1 << _bi);
      if (_bi == 7)
	{
	  _bi = 0;
	  ++_op;
	}
      else
        ++_bi;
    }

    // set two bits
    void set2Bits(unsigned char twoBits);

    // set one octet
    void setOctet(unsigned char octet);

    // set std::string of octets of specified length
    void setOctets(const unsigned char* octets, unsigned short length);

    // set semi-octets semiOctets (given as ASCII std::string of numbers)
    void setSemiOctets(std::string semiOctets);

    // set semi-octets (given as integer)
    void setSemiOctetsInteger(unsigned long intValue, unsigned short length);

    // set time zone (in minutes) and time zone sign
    void setTimeZone(bool negativeTimeZone, unsigned long timeZone);

    // set integer with length number of bits
    void setInteger(unsigned long intvalue, unsigned short length);

    // set alphanumeric 7-bit characters
    void setString(std::string stringValue);

    // set address/telephone number
    // service centre address has special format
    void setAddress(Address &address, bool scAddressFormat = false);

    // set Timestamp
    void setTimestamp(Timestamp timestamp);

    // set TimePeriod
    void setTimePeriod(TimePeriod period);

    // return constructed TPDU as hex-encoded string
    std::string getHexString();

    // return current length of TPDU
    unsigned int getLength();
  };

  // class to handle user data header
  class UserDataHeader
  {
  private:
    std::string _udh;

  public:
    // empty user data header
    UserDataHeader() {}

    // initialize with user data header
    UserDataHeader (std::string udh) : _udh(udh) {}

    // encode header
    void encode(SMSEncoder &e);

    // decode header
    void decode(SMSDecoder &d);

    // return a given information element, if present, or an empty string
    std::string getIE(unsigned char id);

    // return the size of the header
    unsigned int length() const {return _udh.length();}

    // return user data header as octet string
    operator std::string() const {return _udh;}
  };
};

#endif // GSM_SMS_CODEC_H