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

Diff of /smsdaemon/SmsPdu.cpp

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

revision 70 by torben, Fri Jun 13 07:56:57 2008 UTC revision 178 by torben, Fri Dec 12 12:13:05 2008 UTC
# Line 10  Line 10 
10  #include <time.h>  #include <time.h>
11  #include <stdlib.h>  #include <stdlib.h>
12    
13  #include "common.h"  #include "Logger.h"
14  #include "util.h"  #include "Util.h"
15    
16  #include <iostream>  #include "Exceptions.h"
17    #include <list>
18    #include <vector>
19    #include <algorithm>
20    
 using namespace std;  
21    
22    using namespace std;
23    
24  namespace SmsPdu  namespace SmsPdu
25  {  {
# Line 36  namespace SmsPdu Line 39  namespace SmsPdu
39    
40          string EncodePhonenr(string input)          string EncodePhonenr(string input)
41          {          {
42                    if ( input.at(0) == '+' )
43                            input.erase(0,1);
44    
45                  if ( (input.length() % 2) == 1)                  if ( (input.length() % 2) == 1)
46                          input.append("F");                          input.append("F");
47                  return SwitchChars(input);                  return SwitchChars(input);
# Line 78  namespace SmsPdu Line 84  namespace SmsPdu
84                  return vec;                  return vec;
85          }          }
86    
87          std::string Decode8to7bit(vector<unsigned char> input, int shift_start = 0)          std::string Decode8to7bit(vector<unsigned char> input, int shift_start)
88          {          {
89                  string result;                  string result;
90    
# Line 110  namespace SmsPdu Line 116  namespace SmsPdu
116    
117    
118    
119          vector<unsigned char> Encode7to8bit(std::string str)          vector<unsigned char> Encode7to8bit(std::string str, int shift_start)
120          {          {
121                  vector<unsigned char> buf;                  vector<unsigned char> buf;
122    
123                  int shift = 0;                  int shift = shift_start;
124                  for (unsigned int i=0; i<str.size(); ++i)                  for (unsigned int i=0; i<str.size(); ++i)
125                  {                  {
126                          unsigned char current = str.at(i) & 0x7F;                          unsigned char current = str.at(i) & 0x7F;
# Line 143  namespace SmsPdu Line 149  namespace SmsPdu
149    
150                  const unsigned char UDHI = multipart ? 0x40 : 0;                  const unsigned char UDHI = multipart ? 0x40 : 0;
151    
                 srand(time(0));  
152                  unsigned char csms_ref = rand() % 128;                  unsigned char csms_ref = rand() % 128;
153    
154                  int part_count;                  int part_count;
# Line 154  namespace SmsPdu Line 159  namespace SmsPdu
159                  {                  {
160                          if (message.length() > 800)                          if (message.length() > 800)
161                          {                          {
162                                  Common::instance()->logMessage("Trying to send multipart sms > 800 bytes !!!");                                  Logger::logMessage("Trying to send multipart sms > 800 bytes !!!");
163                                  message = message.substr(0,800);                                  message = message.substr(0,800);
164                          }                          }
165    
# Line 178  namespace SmsPdu Line 183  namespace SmsPdu
183                          pdu.push_back(to.length() ); //length of phone nr                          pdu.push_back(to.length() ); //length of phone nr
184                          pdu.push_back(0x81); // type of address (international nr  + ISDN/telephone range) - else try 0x81                          pdu.push_back(0x81); // type of address (international nr  + ISDN/telephone range) - else try 0x81
185    
186                    
187                          string phone = EncodePhonenr(to);                          vector<unsigned char> phone = HexDecodeString( EncodePhonenr(to ));
188                          pdu.insert( pdu.end(), phone.begin(), phone.end());                          pdu.insert( pdu.end(), phone.begin(), phone.end());
189    
190                          pdu.push_back(0x00); // Protocol identifier                          pdu.push_back(0x00); // Protocol identifier
191                          pdu.push_back(0x00); // Data coding scheme                          pdu.push_back(0x00); // Data coding scheme
192    
193                            int shift_start = 0;
194                          string message_part;                          string message_part;
195                          if (multipart)                          if (multipart)
196                          {                          {
197                                  message_part = message.substr(0, PDU_LEN);                                  message_part = message.substr(0, PDU_LEN);
198                                  message.erase(0, PDU_LEN);                                  message.erase(0, PDU_LEN-1);
199    
200                                  pdu.push_back( message_part.length()+ 7 );  //UserDataLength                                  pdu.push_back( message_part.length()+ 7 );  //UserDataLength
201                                  pdu.push_back( 0x06 ); // UDH Len                                  pdu.push_back( 0x06 ); // UDH Len
# Line 199  namespace SmsPdu Line 205  namespace SmsPdu
205                                  pdu.push_back( part_count );                                  pdu.push_back( part_count );
206                                  pdu.push_back( partnr+1 );                                  pdu.push_back( partnr+1 );
207                                  pdu.push_back( 0x00);                                  pdu.push_back( 0x00);
208                                    //shift_start = 6;
209                          }                          }
210                          else                          else
211                          {                          {
212                                  if (message.length() > 160)                                  if (message.length() > 160)
213                                  {                                  {
214                                          message_part = message.substr(0,160); //truncate to 160                                          message_part = message.substr(0,160); //truncate to 160
215                                          Common::instance()->logMessage("Truncated message");                                          Logger::logMessage("Truncated message");
216                                  }                                  }
217                                  else                                  else
218                                  {                                  {
# Line 216  namespace SmsPdu Line 222  namespace SmsPdu
222                                  pdu.push_back( message_part.length() ); //UserDataLength                                  pdu.push_back( message_part.length() ); //UserDataLength
223                          }                          }
224    
225                          vector<unsigned char> userData = Encode7to8bit(message_part);                          vector<unsigned char> userData = Encode7to8bit(message_part, shift_start);
226    
227                          pdu.insert( pdu.end(), userData.begin(), userData.end());                          pdu.insert( pdu.end(), userData.begin(), userData.end());
228    
# Line 273  namespace SmsPdu Line 279  namespace SmsPdu
279          }          }
280    
281    
282            std::list<SmsPart> partlist;
283            typedef std::list<SmsPart>::iterator iterator;
284            
285            SMS ConcatenateParts(SmsPart& part)
286            {
287                    SMS sms;
288                    if (part.group == -1)
289                    {
290                            sms.SetMessage(part.message);
291                            sms.SetSender(part.sender);
292                    }
293                    else
294                    {
295                            partlist.push_back(part);
296                            
297                            vector<SmsPart> vec;
298                            for (iterator it=partlist.begin(); it!=partlist.end(); ++it)
299                            {
300                                    SmsPart& current = *it;
301                                    if (current.sender == part.sender && current.group == part.group)
302                                            vec.push_back(current);
303                            }
304    
305                            if (vec.size() == (unsigned)part.count) //we have all parts
306                            {
307                                    sort(vec.begin(), vec.end());
308                                    string message;
309                                    for (unsigned i=0; i<vec.size(); i++)
310                                    {
311                                            partlist.remove( (vec[i]) );
312                                            message += vec[i].message;
313                                    }
314                                    sms.SetSender(part.sender);
315                                    sms.SetMessage(message);
316                            }
317                            else
318                            {
319                                    throw smsnotfoundexception(); // need more parts
320                            }
321    
322                    }
323    
324                    return sms;
325            }
326    
327    
328          SMS ParseSmsPdu(std::string pdu_str)          SMS ParseSmsPdu(std::string pdu_str)
329          {          {
330                  SMS result;                  SmsPart part = ParseSmsPduWorker(pdu_str);
331    
332                    return ConcatenateParts(part);
333    
334            }
335    
336            void ParseUdh(vector<unsigned char>& udh, SmsPart& part)
337            {
338                    if (udh.size() == 0)
339                    {
340                            Logger::logMessage("ParseUdh(): empty udh");
341                            return;
342                    }
343            
344                    if (udh[0] != 0)
345                    {
346                            Logger::logMessage("unknown UDH type");
347                            return;
348                    }
349    
350                    if (udh.size() < 5)
351                    {
352                            Logger::logMessage("UDH to short to be multipart");
353                            return;
354                    }
355                    
356                    part.group = udh[2];
357                    part.count = udh[3];
358                    part.id = udh[4];
359            }
360    
361    
362            SmsPart ParseSmsPduWorker(std::string pdu_str)
363            {
364    
365                  vector<unsigned char> pdu = HexDecodeString(pdu_str);                  vector<unsigned char> pdu = HexDecodeString(pdu_str);
366    
# Line 293  namespace SmsPdu Line 378  namespace SmsPdu
378    
379                  ++it; //ignore Type-Of-Address                  ++it; //ignore Type-Of-Address
380    
381                  result.sender = DecodeRawPhonenr( it, it+(sender_len/2) );                  string sender = DecodeRawPhonenr( it, it+(sender_len/2) );
382    
383                  it += (sender_len/2);                  it += (sender_len/2);
384                  ++it; //protocol identifier                  ++it; //protocol identifier
385                  ++it; //Data encoding                  ++it; //Data encoding
386    
387                  result.timestamp = DecodeTimestamp(it, it+7);                  string timestamp = DecodeTimestamp(it, it+7);
388                  it += 7;                  it += 7;
389    
390    
391                  unsigned char data_len = (*it++);                  unsigned char data_len = (*it++);
392    
393    
394                    SmsPart part;
395                    part.group = -1;
396    
397                  int shift_start = 0;                  int shift_start = 0;
398    
399                  if (UDHI)                  if (UDHI)
400                  {                  {
401                          int udh_len = (*it++);                          int udh_len = (*it++);
402                          cout << "UDH_LEN:" << udh_len << endl;  
403                          it += udh_len; //just ignore the User Data Header                          vector<unsigned char> udh;
404                            for (int i=0; i<udh_len; i++)
405                            {
406                                    udh.push_back (*it++);
407                            }
408                            ParseUdh(udh,part);
409    
410                          data_len -= udh_len;                          data_len -= udh_len;
411    
412                          shift_start = udh_len+1; //make the 8to7bit decode start with the right shift level                          shift_start = udh_len+1; //make the 8to7bit decode start with the right shift level
413                  }                  }
                 cout << hex<< (int)(*it) << endl;;  
414    
415    
416                  vector<unsigned char> user_data;                  vector<unsigned char> user_data;
417                  user_data.insert(user_data.end(), it, it+data_len);                  user_data.insert(user_data.end(), it, it+data_len);
418                                    
419                  result.message = Decode8to7bit(user_data, shift_start);                  string message = Decode8to7bit(user_data, shift_start).substr(0,data_len);
420    
421                    message = Util::str_trim(message);
422    
423                                    
424                    part.message = message;
425                    part.sender = sender;
426    
427                  return result;                  return part;
428          }          }
429    
430  }  }

Legend:
Removed from v.70  
changed lines
  Added in v.178

  ViewVC Help
Powered by ViewVC 1.1.20