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

Diff of /smsdaemon/SmsPdu.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 59 by torben, Wed Jun 11 19:42:24 2008 UTC revision 68 by torben, Thu Jun 12 18:54:24 2008 UTC
# Line 2  Line 2 
2   */   */
3    
4    
5    #include "SmsPdu.h"
6    
7  #include <string>  #include <string>
8  #include <sstream>  #include <sstream>
9    
10    #include <time.h>
11    #include <stdlib.h>
12    
13    #include "common.h"
   
14  #include "util.h"  #include "util.h"
15    
16    
# Line 18  namespace SmsPdu Line 21  namespace SmsPdu
21  {  {
22    
23    
 vector<unsigned char> BcdEncode(string input)  
 {  
         char buf[2] = " ";  
         vector<unsigned char> result;  
24    
25          unsigned char current;  string SwitchChars(string input)
26          for (unsigned int i=0; i<input.length(); ++i)  {
27            for (unsigned int i=1; i<input.length(); i+=2)
28          {          {
29                  buf[0] = input.at(i);                  char tmp = input[i];
30                  unsigned char tmp = atoi(buf);                  input[i] = input[i-1];
31                    input[i-1] = tmp;
                 if ( (i%2) == 0)  
                 {  
                         current = tmp;  
                 }  
                 else  
                 {  
                         current |= (tmp<<4);  
                         result.push_back(current);  
                 }  
32          }          }
33            return input;
34    }
35    
36          return result;  string EncodePhonenr(string input)
37    {
38            if ( (input.length() % 2) == 1)
39                    input.append("F");
40            return SwitchChars(input);
41    }
42    
43    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  }  }
52    
53    
54    
55    
56  string HexformatVector(vector<unsigned char> vec)  string HexformatVector(vector<unsigned char> vec)
57  {  {
58          ostringstream os;          ostringstream os;
# Line 58  string HexformatVector(vector<unsigned c Line 68  string HexformatVector(vector<unsigned c
68          return os.str();          return os.str();
69  }  }
70    
71    std::string Decode8to7bit(vector<unsigned char> input)
72    {
73            string result;
74    
75            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            return result;
98    }
99    
100    
101    
102    
103  vector<unsigned char> Encode7to8bit(std::string str)  vector<unsigned char> Encode7to8bit(std::string str)
104  {  {
105          vector<unsigned char> buf;          vector<unsigned char> buf;
# Line 85  vector<unsigned char> Encode7to8bit(std: Line 127  vector<unsigned char> Encode7to8bit(std:
127          return buf;          return buf;
128  }  }
129    
130  string CreateSmsPdu(string to, string message, int& len)  vector<PduInfo> CreateSmsPdu(string to, string message, bool allowMultipart)
131  {  {
132          message = message.substr(0,160); //truncate to 160          bool multipart = allowMultipart && message.length() > 160;
133    
134          vector<unsigned char> pdu;          const unsigned char UDHI = multipart ? 0x40 : 0;
135    
136          pdu.push_back(0x00); // use SMSC from phone          srand(time(0));
137          pdu.push_back(0x01); // first octet -- no timeout          unsigned char csms_ref = rand() % 128;
         pdu.push_back(0x00); // TP-MR message reference  
         pdu.push_back(to.length() ); //length of phone nr  
         pdu.push_back(0x91); // type of address (international nr  + ISDN/telephone range) - else try 0x81  
138    
139          vector<unsigned char> phone = BcdEncode(to);          int part_count;
         pdu.insert( pdu.end(), phone.begin(), phone.end());  
140    
141          pdu.push_back(0x00); // Protocol identifier          const int PDU_LEN = 153;
         pdu.push_back(0x00); // Data coding scheme  
         pdu.push_back( message.length() ); //UserDataLength  
142    
143          vector<unsigned char> userData = Encode7to8bit(message);          if (multipart)
144          pdu.insert( pdu.end(), userData.begin(), userData.end());          {
145                    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                    part_count = message.length() / PDU_LEN;
152                    if (message.length() % PDU_LEN)
153                            part_count++;
154            }
155            else
156            {
157                    part_count = 1;
158            }
159    
160            vector<PduInfo> result;
161            for (int partnr = 0; partnr < part_count; ++partnr)
162            {
163                    vector<unsigned char> pdu;
164    
165          len = pdu.size()-1;                  pdu.push_back(0x00); // use SMSC from phone
166          return HexformatVector(pdu);                  pdu.push_back( 0x01|UDHI ); // first octet -- no timeout
167                    pdu.push_back(0x00); // TP-MR message reference
168                    pdu.push_back(to.length() ); //length of phone nr
169                    pdu.push_back(0x81); // type of address (international nr  + ISDN/telephone range) - else try 0x81
170    
171                    
172                    string phone = EncodePhonenr(to);
173                    pdu.insert( pdu.end(), phone.begin(), phone.end());
174    
175                    pdu.push_back(0x00); // Protocol identifier
176                    pdu.push_back(0x00); // Data coding scheme
177    
178                    string message_part;
179                    if (multipart)
180                    {
181                            message_part = message.substr(0, PDU_LEN);
182                            message.erase(0, PDU_LEN);
183    
184                            pdu.push_back( message_part.length()+ 7 );  //UserDataLength
185                            pdu.push_back( 0x06 ); // UDH Len
186                            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                            pdu.push_back( part_count );
190                            pdu.push_back( partnr+1 );
191                            pdu.push_back( 0x00);
192    
193                    }
194                    else
195                    {
196                            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    
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  }  }
221    
222  }  }

Legend:
Removed from v.59  
changed lines
  Added in v.68

  ViewVC Help
Powered by ViewVC 1.1.20