pdu.cpp

Go to the documentation of this file.
00001 
00002 #include <iostream>
00003 #include <string>
00004 #include <sstream>
00005 #include <stdlib.h>
00006 #include "pdu.h"
00007 
00008 
00009 using namespace std;
00010 using std::string;
00011 
00012 
00013 
00028 string pdu::semiOctetToString (string semiOctet) {
00029         unsigned int i;
00030         string OctetString;
00031         
00032         for (i = 0; i < ( semiOctet.length() / 2 ); i++) {
00033                 OctetString += semiOctet.substr(i*2 + 1, 1);
00034                 OctetString += semiOctet.substr(i*2, 1);
00035         }
00036         return OctetString;
00037 }
00038 
00039 
00040 
00055 string pdu::stringToSemiOctet (string StringData) {
00056         if ( StringData.length() % 2 != 0 ) {
00057                 StringData += "F";
00058         }       
00059         return semiOctetToString(StringData);
00060 }
00061 
00062 
00063 
00078 int pdu::hexStringToInt (string hexString) {
00079         unsigned int i;
00080         int charvalue;
00081         int returnvalue = 0;
00082         
00083         for (i = 0; i < hexString.length(); i++) {
00084                 if ( hexString[i] >= 'a' && hexString[i] <= 'f' ) {
00085                         charvalue = (int) hexString[i] - 87;
00086                 }
00087                 if ( hexString[i] >= 'A' && hexString[i] <= 'F' ) {
00088                         charvalue = (int) hexString[i] - 55;
00089                 }
00090                 if ( hexString[i] >= '0' && hexString[i] <= '9' ) {
00091                         charvalue = (int) hexString[i] - 48;
00092                 }
00093                 returnvalue += charvalue * ( pow(16, (int)(hexString.length() - (i + 1)) ));
00094         }
00095         return returnvalue;
00096 }
00097 
00098 
00099 
00115 string pdu::intToHexString (int integer) {
00116         string hexString = "";
00117         /*
00118         for (int i=2*sizeof(int) - 1; i>=0; i--) {
00119                 if ( ( (integer >> i*4) & 0xF ) != 0 )  {
00120                         hexString += "0123456789ABCDEF"[((integer >> i*4) & 0xF)];
00121                         
00122                 }
00123         }
00124         if ( hexString.length() % 2 != 0 ){
00125                 hexString = "0" + hexString;
00126         }
00127         */
00128         //Changed Conversion from intToHex from above to below...
00129         char buf[3];
00130         sprintf(buf,"%X",integer);
00131         hexString = (string)buf;
00132         //Prepend a 0 when not even
00133         if ( hexString.length() % 2 != 0 ){
00134                 hexString = "0" + hexString;
00135         }
00136         
00137         return hexString;
00138 }
00139 
00140 
00141 
00156 int pdu::binStringToInt (string binString) {
00157         
00158         unsigned int pos;
00159         int integerReturn = 0;
00160         int base = 2;
00161         
00162         for (pos = 0; pos < binString.length(); pos++) {
00163                 if ( binString.substr(pos, 1) == "1" ) {
00164                         integerReturn += pow(base, (binString.length() - (pos + 1)) );
00165                 }
00166         }
00167         return integerReturn;
00168 }
00169 
00170 
00171 
00186 string pdu::intToBinString (int integer) {
00187         string stringReturn;
00188         
00189         if (integer <= 0) {
00190                 return "0";
00191         }
00192         
00193         while ( integer > 0 ) {
00194                 if ( integer % 2 == 1 ) {
00195                         stringReturn = "1" + stringReturn;
00196                         --integer;
00197                 } else {
00198                         stringReturn = "0" + stringReturn;
00199                 }
00200                 integer = integer / 2;
00201         }
00202         //Changed 8 to 7 because the characters are in septets
00203         while ( stringReturn.length() % 7 != 0 ) {
00204                 stringReturn = "0" + stringReturn;
00205         }
00206         return stringReturn;
00207 }
00208 
00209 
00210 
00225 int pdu::pow(int n, int i)
00226 {
00227    if (i == 0)
00228       return 1;
00229    else if (i == 1)
00230       return n;
00231    else {
00232       int partial = pow(n, i / 2);
00233       if (i % 2 == 0)
00234          return partial * partial;
00235       else
00236          return partial * partial * n;
00237    }
00238 }
00239 
00240 
00241 
00255 void pdu::parsePDU(string pduString) {
00256 
00257         int stringLocation = 0;
00258                 
00259         
00260         this->smsc_length = hexStringToInt(pduString.substr(stringLocation, 2));
00261         stringLocation += 2;
00262         
00263         if ( this->smsc_length != 0 ) {
00264         
00265                 
00266                 this->smsc_type_of_address = hexStringToInt(pduString.substr(stringLocation, 2));
00267                 stringLocation += 2;
00268 
00269                 
00270                 this->smsc_number = semiOctetToString( pduString.substr(stringLocation, ( this->smsc_length -1 ) * 2 ) );
00271                 if ( this->smsc_number[this->smsc_number.length() - 1 ] == 'F' ) {
00272                         this->smsc_number = this->smsc_number.substr(0, this->smsc_number.length() - 1);
00273                 }
00274                 stringLocation += ( this->smsc_length -1 ) * 2;
00275         } else {
00276                 
00277                 this->smsc_type_of_address = 0;
00278                 this->smsc_number = "0";
00279         }
00280 
00281         
00282         this->sms_deliver = hexStringToInt(pduString.substr(stringLocation, 2));
00283         stringLocation += 2;
00284         
00285         if (this->sms_deliver & 0x03) {
00286                 
00287                 parsePDU_send(pduString.substr(stringLocation, (pduString.length() - stringLocation  )));
00288         } else {
00289                 parsePDU_receive(pduString.substr(stringLocation, (pduString.length() - stringLocation )));
00290         }
00291 }
00292 
00293 
00307 void pdu::parsePDU_receive(string pduString) {
00308 
00309         int stringLocation = 0;
00310                 
00311 
00312         // SENDER Lenght
00313         this->sender_length = hexStringToInt(pduString.substr(stringLocation, 2));
00314         stringLocation += 2;
00315 
00316         if ( this->sender_length != 0 ) {
00317                 // SENDER Type of address
00318                 this->sender_type_of_address = hexStringToInt(pduString.substr(stringLocation, 2));
00319                 stringLocation += 2;
00320                 
00321                 // SENDER Number
00322                 int evenSenderLength = this->sender_length + ( this->sender_length % 2 );
00323                 this->sender_number = semiOctetToString( pduString.substr(stringLocation, evenSenderLength ));
00324                 this->sender_number = this->sender_number.substr(0, this->sender_length);
00325                 stringLocation += evenSenderLength;
00326         }
00327 
00328         // PROTOCOL Identifier
00329         this->tp_pid = hexStringToInt(pduString.substr(stringLocation, 2));
00330         stringLocation += 2;
00331 
00332         //DATA Coding scheme tp_dcs
00333         this->tp_dcs = hexStringToInt(pduString.substr(stringLocation, 2));
00334         stringLocation += 2;
00335 
00336         //TIMESTAMP
00337         this->tp_scts = pduString.substr(stringLocation, 14);
00338         stringLocation += 14;
00339 
00340         //DATA Lenght
00341         this->tp_length = hexStringToInt(pduString.substr(stringLocation, 2));
00342         stringLocation += 2;
00343 
00344         //DATA raw unencoded
00345         this->tp_data = pduString.substr(stringLocation, pduString.length() - stringLocation);
00346         stringLocation += pduString.length() - stringLocation;
00347 
00348         
00349 }
00350 
00364 void pdu::parsePDU_send(string pduString) {
00365         int stringLocation = 0;
00366         
00367         
00368         this->tp_msgref = hexStringToInt(pduString.substr(stringLocation, 2));
00369         stringLocation += 2;
00370         
00371         this->sender_length = hexStringToInt(pduString.substr(stringLocation, 2));
00372         
00373         stringLocation += 2;
00374         cout << stringLocation << endl;
00375         
00376         int evenSenderLength = this->sender_length + ( this->sender_length % 2 );
00377         
00378         
00379         this->sender_type_of_address = hexStringToInt(pduString.substr(stringLocation, 2));
00380         stringLocation += 2;
00381         cout << stringLocation << endl;
00382         this->sender_number = semiOctetToString( pduString.substr(stringLocation, evenSenderLength ));
00383         this->sender_number = this->sender_number.substr(0, this->sender_length);
00384         stringLocation += evenSenderLength;
00385         
00386         this->tp_pid = hexStringToInt(pduString.substr(stringLocation, 2));
00387         stringLocation += 2;
00388 
00389         
00390         //DATA Coding scheme tp_dcs
00391         this->tp_dcs = hexStringToInt(pduString.substr(stringLocation, 2));
00392         stringLocation += 2;
00393 
00394         
00395         this->tp_validity = hexStringToInt(pduString.substr(stringLocation, 2));
00396         stringLocation += 2;
00397         
00398         
00399         this->tp_length = hexStringToInt(pduString.substr(stringLocation, 2));
00400         stringLocation += 2;
00401 
00402         //DATA raw unencoded
00403         
00404         this->tp_data = pduString.substr(stringLocation, (pduString.length() - stringLocation) + 2);
00405         stringLocation += pduString.length() - stringLocation;
00406         cout<< "tp_data " << this->tp_data << endl;
00407 
00408 }
00409 
00425 string pdu::userData7_to_8() {
00426 
00427         
00428         unsigned int pos;
00429         int septetCnt = 1;
00430         string byteString = "";
00431         string messageAscii;
00432         
00433         if ( this->tp_data.length() == 0 || this->tp_data.length() % 2 != 0 ) {
00434                 return "";
00435         }
00436         
00437         for (pos = 0; pos < this->tp_data.length(); pos += 2) {
00438                 byteString += intToBinString(hexStringToInt(this->tp_data.substr(pos, 2)));
00439         }
00440         
00441 
00442         string * octetArray = new string[(byteString.length() / 8) + 1];
00443         string * restArray = new string[(byteString.length() / 8) + 1];
00444         string * septetsArray = new string[(byteString.length() / 8) + 1];
00445         
00446         for (pos = 0; pos < byteString.length(); pos += 8) {
00447                 octetArray[pos/8] = byteString.substr(pos, 8);
00448                 restArray[pos/8] = octetArray[pos/8].substr(0, septetCnt % 8);
00449                 septetsArray[pos/8] = octetArray[pos/8].substr(septetCnt % 8, 8);
00450                                 
00451                 septetCnt++;
00452                 if (septetCnt == 8){
00453                         septetCnt = 1;
00454                 }
00455         }
00456         
00457         for (pos = 0; pos < (byteString.length() / 8); pos++) {
00458                 if (pos % 7 == 0){
00459                         if (pos != 0) {
00460                                 messageAscii = messageAscii + lookup_ascii7to8[binStringToInt(restArray[pos - 1])];
00461                         }
00462                         messageAscii = messageAscii + lookup_ascii7to8[binStringToInt(septetsArray[pos])];
00463                 } else {
00464                         messageAscii = messageAscii + lookup_ascii7to8[binStringToInt(septetsArray[pos] + restArray[pos - 1])];
00465                 }
00466         }
00467                 
00468         return messageAscii;
00469         
00470 }
00471 
00472 
00473 
00489 string pdu::userData8_to_8() {
00490         unsigned int pos;
00491         string messageAscii = "";
00492         
00493         for (pos = 0; pos < this->tp_data.length(); pos+=2) {
00494                 messageAscii += (char) hexStringToInt(this->tp_data.substr(pos, 2));
00495         }
00496         cout << "userdata8_to_8" << endl;
00497         return messageAscii;
00498 }
00499 
00500 
00501 
00517 string pdu::userData16_to_8() {
00518         unsigned int pos;
00519         string messageAscii = "";
00520         
00521         for (pos = 0; pos < this->tp_data.length(); pos+=4) {
00522                 messageAscii += (char) ( hexStringToInt(this->tp_data.substr(pos, 2)) * 256 )
00523                                                 + hexStringToInt(this->tp_data.substr(pos+2, 2));
00524         }
00525         return messageAscii;
00526 }
00527 
00528 
00529 
00530 string pdu::userData() {
00531 
00532 
00533         switch ( getDCSAlphabet() ) {
00534                 case 0:
00535                         return userData7_to_8();
00536                         break;
00537                 case 4:
00538                         return userData8_to_8();
00539                         break;
00540                 case 8:
00541                         return userData16_to_8();
00542                         break;
00543         }
00544         return "";
00545         
00546 }
00547 
00548 int pdu::getDCSAlphabet() {
00549         switch (this->tp_dcs & 192) {
00550                 case 0:
00551                         return this->tp_dcs & 12;
00552                         break;
00553                 case 192:
00554                         switch (this->tp_dcs & 0x30) {
00555                                 case 0x20:
00556                                         return 8;
00557                                         break;
00558                                 case 0x30:
00559                                         if ( this->tp_dcs & 0x4 ) {
00560                                                 return 0;
00561                                         } else {
00562                                                 return 4;
00563                                         }
00564                                         break;
00565                                 default:
00566                                         return 0;
00567                                         break;
00568                         }
00569                 default:
00570                         return 0;
00571                         break;
00572         }
00573 }
00574 
00575 
00576 string pdu::getText() {
00577         return userData();
00578 }
00579 
00580 string pdu::getSender() {
00581         
00582         if ( this->sender_type_of_address == 145 ){
00583                 return "+" + this->sender_number;
00584         }
00585         return this->sender_number;
00586 }
00587 
00588 int pdu::setText( string smstext ) {
00589         if ( smstext.length() > 160 ) {
00590                 return 0;
00591         }
00592         this->tp_text = smstext;
00593         return 1;
00594 }
00595 
00596 int pdu::setSender( string number ) {
00597         
00598         this->sender_type_of_address = 146;
00599         if ( number.substr(0,1) == "+" ) {
00600                 this->sender_type_of_address = 145;
00601                 this->sender_number = number.substr(1, number.length() - 1);
00602         } else {
00603                 this->sender_number = number;
00604         }
00605         
00606         this->sender_length = this->sender_number.length();
00607         if ( this->sender_number.length() % 2 == 1 ) {
00608                 this->sender_number + "F";
00609         }
00610         
00611         return 1;
00612 }
00613 
00614 string pdu::userTextTo7(void) {
00615 
00616         unsigned int pos;
00617         string current, octetFirst, octetSecond, currentOctet;
00618         string output;
00619         
00620         for (pos = 0; pos < this->tp_text.length(); pos++) {
00621 
00622                 current = intToBinString(lookup_ascii8to7[ this->tp_text[pos] ]);
00623                 
00624                 
00625                 if ( ( pos != 0 ) && ( pos % 8 != 0 ) ) {
00626                         octetFirst = current.substr(7 - ( pos % 8 ), current.length() );
00627                         currentOctet = octetFirst + octetSecond;
00628                         
00629                         output += intToHexString(binStringToInt(currentOctet));
00630                         
00631                         octetSecond = current.substr(0, 7 - (pos % 8));
00632                 } 
00633                 else {
00634                         octetSecond = current.substr(0, 7 - (pos % 8));
00635                 }
00636                 
00637                 if ( ( pos + 1 == this->tp_text.length() ) && ( octetSecond != "" ) ) {
00638                         
00639                         output += intToHexString(binStringToInt(octetSecond));
00640                         
00641                         
00642                 }
00643                 
00644         }
00645         return output;
00646 }
00647 
00648 string pdu::encodePDU() {
00649         string pduString;
00650         
00651         pduString = "00";                                                                                       // SMSC_LENGHT
00652         pduString += "1100";                                                                            // FIRST OCTET ( message submit & tp reference)
00653         pduString += intToHexString(this->sender_length);                       // SENDER_LENGHT
00654         pduString += intToHexString(this->sender_type_of_address);  // SENDER_TYPE
00655         pduString += stringToSemiOctet(this->sender_number);            // SENDER_NUMBER
00656         pduString += "0000";                                                                            // TP-PID TP-DCS ( 7-bit default encoding )
00657         pduString += "AA";                                                                                      // VALIDITY ( 4 days )
00658         pduString += intToHexString(this->tp_text.length());
00659         pduString += userTextTo7();
00660         cout << "end of encodePdu" << endl;
00661         return pduString;
00662 }

Generated on Tue May 31 20:21:08 2005 for sendsms by  doxygen 1.4.2