Showing posts with label PDU Decoder. Show all posts
Showing posts with label PDU Decoder. Show all posts

Wednesday, July 11, 2018

3G SMS PDU DECODER SOURCE CODE




int HexToInt(const char* p)
{
char temp[3];
temp[0] = p[0];
temp[1] = p[1];
temp[2] = '\0';
return strtol(temp, NULL, 16);


}

void HexToString(unsigned char* dest, unsigned char* src)
{
char temp[3];
char* p = (char*)src;
int len = strlen(p);


temp[2] = '\0';

for(int i=0; i <len; i+=2)
{
temp[0] = *p;
p++;
temp[1] = *p;
p++;

unsigned char ch = (unsigned char)strtol(temp, NULL, 16 );

dest[ i/2 ] = ch;

}

}


void cat_hex(unsigned char *dest, unsigned char val)
{
static unsigned char hex_table[]="0123456789ABCDEF";

dest[0] = hex_table[ (val >> 4) & 0x0f ];

dest[1] = hex_table[ (val ) & 0x0f ];
}


int DecodePDU(unsigned char* result, unsigned char* pDataPDU)
{
bool fUDHI;
unsigned char DataSMSDecode[255];
unsigned char *pDataSMSDecode = DataSMSDecode;
int nIndex = 0;
int nLengthUDH =0;
int nLength = 0;
unsigned char nHex=0;
unsigned char nBitMask = 0;
int nDCS;
unsigned char nShift;
unsigned char nChar1;
unsigned char nChar2;

memset( DataSMSDecode, 0, sizeof(DataSMSDecode));

// 07
nLength =  HexToInt( &pDataPDU[nIndex]);

nIndex = nIndex + 2;

//# 91280102194105
//# Type-of-address of the SMSC. (91 means international format of the phone number)
//# Service center number (+821020911450)

nIndex = nIndex + nLength * 2;

//# 44
//# Check TP-UDHI bit (40)
if (0x40 == (HexToInt( &pDataPDU[nIndex]) & 0x40))
{
fUDHI = true;
}
else
{
fUDHI = false;
nLengthUDH = 0;
}

nIndex = nIndex + 2;


//# 0BA11020903746F0
nLength = HexToInt( &pDataPDU[nIndex] );

if ( nLength % 2)
{
nLength = (nLength + 1) / 2;
}

nIndex = nIndex + (nLength + 2) * 2;

//# 00 : TP-PID
nIndex = nIndex + 2;
//# 00 : TP-DCS

nDCS = HexToInt( &pDataPDU[nIndex] );

nIndex = nIndex + 2;

//    # 21505251708263
//    # Time stamp
nIndex = nIndex + 14;

//# 0E
nIndex = nIndex + 2;

if( fUDHI )
{
//# 0A
nLengthUDH = HexToInt( &pDataPDU[nIndex] );
nIndex = nIndex + 2;

//# 22
nIndex = nIndex + 2;

//# 080B811020903746F0
nLength = HexToInt( &pDataPDU[nIndex] );
nIndex = nIndex + (nLength + 1) * 2;
}

if (0x00 == nDCS)
{
//# 8001
//# decode

pDataPDU = &pDataPDU[nIndex];
strcat( pDataPDU, "00");


if ( 0 != nLengthUDH )
{

nShift = 7 - ((nLengthUDH + 1) % 7);
nBitMask = (0xFF >> nShift) << nShift;

nLength = strlen(pDataPDU);
if(nLength > 250)
nLength = 250;



for(nIndex=0; nIndex <= nLength; nIndex+=2)
{

if (nLength - 2 == nIndex)
{
break;
}

if (7 == nShift)
{
nChar1 = HexToInt( &pDataPDU[nIndex] );
nHex = nChar1 & 0x7F;


cat_hex( pDataSMSDecode, nHex);
pDataSMSDecode++;
pDataSMSDecode++;


// szDataSMSDecode = szDataSMSDecode + hex(nHex);
}

nChar1 = HexToInt( &pDataPDU[nIndex]);
nChar2 = HexToInt( &pDataPDU[nIndex+2]);

nHex = (nChar1 & nBitMask) >> nShift;

nShift = nShift - 1;

nBitMask = (0xFF >> nShift) << nShift;

nHex = nHex | ((nChar2 & (~nBitMask)) << (7 - nShift));

cat_hex( pDataSMSDecode, nHex);
pDataSMSDecode++;
pDataSMSDecode++;

if (0 == nShift)
nShift = 7;
}

HexToString( DataSMSDecode, DataSMSDecode );
}
}
else
{
HexToString( DataSMSDecode, &pDataPDU[nIndex] );

}

strcpy( result, DataSMSDecode);
return strlen(result);
}



//  --- 아래는 테스트 예제 ---
void __fastcall TForm1::Button1Click(TObject *Sender)
{
String a ;

AnsiString t = "0791280102195140440BA11030917583F30000216051908591635D0A22080B811030917583F3088BC7E4B2F98C0E8BC7E4B2F98C0E8BC7E4B2F98C0E8BC7E4B2F98C0E8BC7E4B2F98C0E8BC7E4B2F98C0E8BC7E4B2F98C0E8BC7E4B2F98C0E8BC7E4B2F98C0E8BC7E4B2F98C06";

//t = "0791280102194189440BA11080554992F7008451805000727463110A22080B811080554992F7C7D1B1B9B8BB";

unsigned char temp[1000];

DecodePDU(temp,   t.c_str());
Memo1->Lines->Text = AnsiString((char*)temp);
}