--- smsdaemon/SmsPdu.cpp 2008/06/13 06:38:43 69 +++ smsdaemon/SmsPdu.cpp 2008/12/12 12:13:05 178 @@ -10,13 +10,16 @@ #include #include -#include "common.h" -#include "util.h" +#include "Logger.h" +#include "Util.h" -#include +#include "Exceptions.h" +#include +#include +#include -using namespace std; +using namespace std; namespace SmsPdu { @@ -36,6 +39,9 @@ string EncodePhonenr(string input) { + if ( input.at(0) == '+' ) + input.erase(0,1); + if ( (input.length() % 2) == 1) input.append("F"); return SwitchChars(input); @@ -78,11 +84,11 @@ return vec; } - std::string Decode8to7bit(vector input) + std::string Decode8to7bit(vector input, int shift_start) { string result; - int shift = 0; + int shift = shift_start; for (unsigned int i=0; i Encode7to8bit(std::string str) + vector Encode7to8bit(std::string str, int shift_start) { vector buf; - int shift = 0; + int shift = shift_start; for (unsigned int i=0; i 800) { - Common::instance()->logMessage("Trying to send multipart sms > 800 bytes !!!"); + Logger::logMessage("Trying to send multipart sms > 800 bytes !!!"); message = message.substr(0,800); } @@ -178,18 +183,19 @@ pdu.push_back(to.length() ); //length of phone nr pdu.push_back(0x81); // type of address (international nr + ISDN/telephone range) - else try 0x81 - - string phone = EncodePhonenr(to); + + vector phone = HexDecodeString( EncodePhonenr(to )); pdu.insert( pdu.end(), phone.begin(), phone.end()); pdu.push_back(0x00); // Protocol identifier pdu.push_back(0x00); // Data coding scheme + int shift_start = 0; string message_part; if (multipart) { message_part = message.substr(0, PDU_LEN); - message.erase(0, PDU_LEN); + message.erase(0, PDU_LEN-1); pdu.push_back( message_part.length()+ 7 ); //UserDataLength pdu.push_back( 0x06 ); // UDH Len @@ -199,14 +205,14 @@ pdu.push_back( part_count ); pdu.push_back( partnr+1 ); pdu.push_back( 0x00); - + //shift_start = 6; } else { if (message.length() > 160) { message_part = message.substr(0,160); //truncate to 160 - Common::instance()->logMessage("Truncated message"); + Logger::logMessage("Truncated message"); } else { @@ -216,7 +222,7 @@ pdu.push_back( message_part.length() ); //UserDataLength } - vector userData = Encode7to8bit(message_part); + vector userData = Encode7to8bit(message_part, shift_start); pdu.insert( pdu.end(), userData.begin(), userData.end()); @@ -273,9 +279,88 @@ } + std::list partlist; + typedef std::list::iterator iterator; + + SMS ConcatenateParts(SmsPart& part) + { + SMS sms; + if (part.group == -1) + { + sms.SetMessage(part.message); + sms.SetSender(part.sender); + } + else + { + partlist.push_back(part); + + vector vec; + for (iterator it=partlist.begin(); it!=partlist.end(); ++it) + { + SmsPart& current = *it; + if (current.sender == part.sender && current.group == part.group) + vec.push_back(current); + } + + if (vec.size() == (unsigned)part.count) //we have all parts + { + sort(vec.begin(), vec.end()); + string message; + for (unsigned i=0; i& udh, SmsPart& part) + { + if (udh.size() == 0) + { + Logger::logMessage("ParseUdh(): empty udh"); + return; + } + + if (udh[0] != 0) + { + Logger::logMessage("unknown UDH type"); + return; + } + + if (udh.size() < 5) + { + Logger::logMessage("UDH to short to be multipart"); + return; + } + + part.group = udh[2]; + part.count = udh[3]; + part.id = udh[4]; + } + + + SmsPart ParseSmsPduWorker(std::string pdu_str) + { vector pdu = HexDecodeString(pdu_str); @@ -284,30 +369,62 @@ it += (*it++); // Skip smsc info unsigned char deliver_first_octet = (*it++); + + bool UDHI = (deliver_first_octet & 0x40) > 0; + unsigned char sender_len = (*it++); if ( (sender_len % 2) == 1) sender_len++; ++it; //ignore Type-Of-Address - result.sender = DecodeRawPhonenr( it, it+(sender_len/2) ); + string sender = DecodeRawPhonenr( it, it+(sender_len/2) ); it += (sender_len/2); ++it; //protocol identifier ++it; //Data encoding - result.timestamp = DecodeTimestamp(it, it+7); + string timestamp = DecodeTimestamp(it, it+7); it += 7; + unsigned char data_len = (*it++); + + SmsPart part; + part.group = -1; + + int shift_start = 0; + + if (UDHI) + { + int udh_len = (*it++); + + vector udh; + for (int i=0; i user_data; user_data.insert(user_data.end(), it, it+data_len); - result.message = Decode8to7bit(user_data); + string message = Decode8to7bit(user_data, shift_start).substr(0,data_len); + + message = Util::str_trim(message); + + part.message = message; + part.sender = sender; - return result; + return part; } }