/[projects]/smsdaemon/SmsPdu.cpp
ViewVC logotype

Contents of /smsdaemon/SmsPdu.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 60 - (show annotations) (download)
Wed Jun 11 21:18:04 2008 UTC (15 years, 11 months ago) by torben
File size: 3054 byte(s)
First take at multi-part/concatenated SMS pdu's - doesn't work yet!

1 /* using http://sourceforge.net/projects/libserial/
2 */
3
4
5 #include "SmsPdu.h"
6
7 #include <string>
8 #include <sstream>
9
10 #include <time.h>
11 #include <stdlib.h>
12
13
14 #include "util.h"
15
16
17 using namespace std;
18
19
20 namespace SmsPdu
21 {
22
23
24 vector<unsigned char> BcdEncode(string input)
25 {
26 char buf[2] = " ";
27 vector<unsigned char> result;
28
29 unsigned char current;
30 for (unsigned int i=0; i<input.length(); ++i)
31 {
32 buf[0] = input.at(i);
33 unsigned char tmp = atoi(buf);
34
35 if ( (i%2) == 0)
36 {
37 current = tmp;
38 }
39 else
40 {
41 current |= (tmp<<4);
42 result.push_back(current);
43 }
44 }
45
46 return result;
47 }
48
49 string HexformatVector(vector<unsigned char> vec)
50 {
51 ostringstream os;
52
53 for (unsigned int i=0; i<vec.size(); ++i)
54 {
55 os.width(2);
56 os.fill('0');
57 os << hex << uppercase << static_cast<unsigned int>(vec.at(i));
58 }
59
60
61 return os.str();
62 }
63
64 vector<unsigned char> Encode7to8bit(std::string str)
65 {
66 vector<unsigned char> buf;
67
68 int shift = 0;
69 for (unsigned int i=0; i<str.size(); ++i)
70 {
71 unsigned char current = str.at(i) & 0x7F;
72 unsigned char next = ( (i+1)<str.size()) ? str.at(i+1) : 0;
73 next &= 0x7F;
74
75 current >>= shift;
76 next <<= (7-shift);
77
78 unsigned char byte = current | next;
79 buf.push_back(byte);
80
81 if (shift == 6)
82 i++;
83
84 shift = (shift+1) % 7;
85
86 }
87
88 return buf;
89 }
90
91 vector<PduInfo> CreateSmsPdu(string to, string message, bool allowMultipart)
92 {
93 bool multipart = allowMultipart && message.length() > 160;
94
95 const unsigned char UHDI = multipart ? 0x40 : 0;
96
97 srand(time(0));
98 unsigned char csms_ref = rand() % 256;
99
100 int part_count;
101 if (multipart)
102 {
103 part_count = message.length() / 153;
104 if (message.length() % 153)
105 part_count++;
106 }
107 else
108 {
109 part_count = 1;
110 }
111
112 vector<PduInfo> result;
113 for (int partnr = 0; partnr < part_count; ++partnr)
114 {
115 vector<unsigned char> pdu;
116
117 pdu.push_back(0x00); // use SMSC from phone
118 pdu.push_back( 0x01|UHDI ); // first octet -- no timeout
119 pdu.push_back(0x00); // TP-MR message reference
120 pdu.push_back(to.length() ); //length of phone nr
121 pdu.push_back(0x91); // type of address (international nr + ISDN/telephone range) - else try 0x81
122
123 vector<unsigned char> phone = BcdEncode(to);
124 pdu.insert( pdu.end(), phone.begin(), phone.end());
125
126 pdu.push_back(0x00); // Protocol identifier
127 pdu.push_back(0x00); // Data coding scheme
128
129 string message_part;
130 if (multipart)
131 {
132 message_part = message.substr(0,153);
133 message.erase(0,153);
134
135 pdu.push_back( message_part.length()+5 ); //UserDataLength
136 pdu.push_back( 0x00 ); // UDH[0]
137 pdu.push_back( 0x03 ); // UDH[1] = UDH_LEN
138 pdu.push_back( csms_ref ); //UDH[2]
139 pdu.push_back( part_count );
140 pdu.push_back( partnr );
141
142 }
143 else
144 {
145 message_part = message.substr(0,160); //truncate to 160
146
147 pdu.push_back( message_part.length() ); //UserDataLength
148 }
149
150 vector<unsigned char> userData = Encode7to8bit(message_part);
151
152 pdu.insert( pdu.end(), userData.begin(), userData.end());
153
154 PduInfo info;
155 info.len = pdu.size()-1;
156 info.pdu = HexformatVector(pdu);
157 result.push_back(info);
158
159 }
160 return result;
161 }
162
163 }

  ViewVC Help
Powered by ViewVC 1.1.20