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

Annotation of /smsdaemon/SmsPdu.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 68 - (hide annotations) (download)
Thu Jun 12 18:54:24 2008 UTC (15 years, 11 months ago) by torben
File size: 4074 byte(s)
Added pdu decode helper functions.

1 torben 59 /* using http://sourceforge.net/projects/libserial/
2     */
3    
4    
5 torben 60 #include "SmsPdu.h"
6    
7 torben 59 #include <string>
8     #include <sstream>
9    
10 torben 60 #include <time.h>
11     #include <stdlib.h>
12 torben 59
13 torben 63 #include "common.h"
14 torben 59 #include "util.h"
15    
16    
17     using namespace std;
18    
19    
20     namespace SmsPdu
21     {
22    
23    
24 torben 68
25     string SwitchChars(string input)
26 torben 59 {
27 torben 68 for (unsigned int i=1; i<input.length(); i+=2)
28 torben 59 {
29 torben 68 char tmp = input[i];
30     input[i] = input[i-1];
31     input[i-1] = tmp;
32 torben 59 }
33 torben 68 return input;
34     }
35 torben 59
36 torben 68 string EncodePhonenr(string input)
37     {
38     if ( (input.length() % 2) == 1)
39     input.append("F");
40     return SwitchChars(input);
41     }
42 torben 61
43 torben 68 string DecodePhonenr(string input)
44     {
45     input = SwitchChars(input);
46     int last = input.length() -1;
47    
48     if (input.at(last) == 'F')
49     input.erase(last,1);
50     return input;
51 torben 59 }
52    
53 torben 68
54    
55    
56 torben 59 string HexformatVector(vector<unsigned char> vec)
57     {
58     ostringstream os;
59    
60     for (unsigned int i=0; i<vec.size(); ++i)
61     {
62     os.width(2);
63     os.fill('0');
64     os << hex << uppercase << static_cast<unsigned int>(vec.at(i));
65     }
66    
67    
68     return os.str();
69     }
70    
71 torben 68 std::string Decode8to7bit(vector<unsigned char> input)
72 torben 61 {
73     string result;
74    
75 torben 68 int shift = 0;
76     for (unsigned int i=0; i<input.size(); ++i)
77     {
78     unsigned char current = input.at(i);
79     unsigned char prev = (i>0) ? input.at(i-1) : 0;
80    
81     current <<= shift;
82    
83     prev >>= (8-shift);
84    
85     unsigned char byte = current | prev;
86     byte &= 0x7F;
87    
88     result.append(1, byte);
89    
90     if (shift == 6)
91     result.append(1, input.at(i) >> 1);
92    
93     shift = (shift+1) % 7;
94    
95     }
96    
97 torben 61 return result;
98     }
99    
100 torben 68
101    
102    
103 torben 59 vector<unsigned char> Encode7to8bit(std::string str)
104     {
105     vector<unsigned char> buf;
106    
107     int shift = 0;
108     for (unsigned int i=0; i<str.size(); ++i)
109     {
110     unsigned char current = str.at(i) & 0x7F;
111     unsigned char next = ( (i+1)<str.size()) ? str.at(i+1) : 0;
112     next &= 0x7F;
113    
114     current >>= shift;
115     next <<= (7-shift);
116    
117     unsigned char byte = current | next;
118     buf.push_back(byte);
119    
120     if (shift == 6)
121     i++;
122    
123     shift = (shift+1) % 7;
124    
125     }
126    
127     return buf;
128     }
129    
130 torben 60 vector<PduInfo> CreateSmsPdu(string to, string message, bool allowMultipart)
131 torben 59 {
132 torben 60 bool multipart = allowMultipart && message.length() > 160;
133 torben 59
134 torben 61 const unsigned char UDHI = multipart ? 0x40 : 0;
135 torben 59
136 torben 60 srand(time(0));
137 torben 61 unsigned char csms_ref = rand() % 128;
138 torben 59
139 torben 60 int part_count;
140 torben 61
141     const int PDU_LEN = 153;
142    
143 torben 60 if (multipart)
144     {
145 torben 65 if (message.length() > 800)
146     {
147     Common::instance()->logMessage("Trying to send multipart sms > 800 bytes !!!");
148     message = message.substr(0,800);
149     }
150    
151 torben 61 part_count = message.length() / PDU_LEN;
152     if (message.length() % PDU_LEN)
153 torben 60 part_count++;
154     }
155     else
156     {
157     part_count = 1;
158     }
159 torben 59
160 torben 60 vector<PduInfo> result;
161     for (int partnr = 0; partnr < part_count; ++partnr)
162     {
163     vector<unsigned char> pdu;
164 torben 59
165 torben 60 pdu.push_back(0x00); // use SMSC from phone
166 torben 61 pdu.push_back( 0x01|UDHI ); // first octet -- no timeout
167 torben 60 pdu.push_back(0x00); // TP-MR message reference
168     pdu.push_back(to.length() ); //length of phone nr
169 torben 66 pdu.push_back(0x81); // type of address (international nr + ISDN/telephone range) - else try 0x81
170 torben 59
171 torben 68
172     string phone = EncodePhonenr(to);
173 torben 60 pdu.insert( pdu.end(), phone.begin(), phone.end());
174    
175     pdu.push_back(0x00); // Protocol identifier
176 torben 61 pdu.push_back(0x00); // Data coding scheme
177 torben 60
178     string message_part;
179     if (multipart)
180     {
181 torben 61 message_part = message.substr(0, PDU_LEN);
182     message.erase(0, PDU_LEN);
183 torben 60
184 torben 62 pdu.push_back( message_part.length()+ 7 ); //UserDataLength
185     pdu.push_back( 0x06 ); // UDH Len
186 torben 61 pdu.push_back( 0x00 ); // UDH Element Identifier
187     pdu.push_back( 0x03 ); // UDH element length
188     pdu.push_back( csms_ref ); // csms_ref reference
189 torben 60 pdu.push_back( part_count );
190 torben 61 pdu.push_back( partnr+1 );
191 torben 62 pdu.push_back( 0x00);
192 torben 60
193     }
194     else
195     {
196 torben 63 if (message.length() > 160)
197     {
198     message_part = message.substr(0,160); //truncate to 160
199     Common::instance()->logMessage("Truncated message");
200     }
201     else
202     {
203     message_part = message;
204     }
205 torben 60
206     pdu.push_back( message_part.length() ); //UserDataLength
207     }
208    
209     vector<unsigned char> userData = Encode7to8bit(message_part);
210    
211     pdu.insert( pdu.end(), userData.begin(), userData.end());
212    
213     PduInfo info;
214     info.len = pdu.size()-1;
215     info.pdu = HexformatVector(pdu);
216     result.push_back(info);
217    
218     }
219     return result;
220 torben 59 }
221    
222     }

  ViewVC Help
Powered by ViewVC 1.1.20