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
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 char buf[3];
00130 sprintf(buf,"%X",integer);
00131 hexString = (string)buf;
00132
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
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
00313 this->sender_length = hexStringToInt(pduString.substr(stringLocation, 2));
00314 stringLocation += 2;
00315
00316 if ( this->sender_length != 0 ) {
00317
00318 this->sender_type_of_address = hexStringToInt(pduString.substr(stringLocation, 2));
00319 stringLocation += 2;
00320
00321
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
00329 this->tp_pid = hexStringToInt(pduString.substr(stringLocation, 2));
00330 stringLocation += 2;
00331
00332
00333 this->tp_dcs = hexStringToInt(pduString.substr(stringLocation, 2));
00334 stringLocation += 2;
00335
00336
00337 this->tp_scts = pduString.substr(stringLocation, 14);
00338 stringLocation += 14;
00339
00340
00341 this->tp_length = hexStringToInt(pduString.substr(stringLocation, 2));
00342 stringLocation += 2;
00343
00344
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
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
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";
00652 pduString += "1100";
00653 pduString += intToHexString(this->sender_length);
00654 pduString += intToHexString(this->sender_type_of_address);
00655 pduString += stringToSemiOctet(this->sender_number);
00656 pduString += "0000";
00657 pduString += "AA";
00658 pduString += intToHexString(this->tp_text.length());
00659 pduString += userTextTo7();
00660 cout << "end of encodePdu" << endl;
00661 return pduString;
00662 }