📄 at_pdu.c
字号:
#include <string.h>
#include <sys\lmalloc.h>
#include <sys\at.h>
#include <service\psst\at_pdu.h>
extern WORD Uni2Gb(WORD code);
extern WORD Gb2Uni(WORD code);
#ifdef _AT_PAR_INDEPENDENT_TEST
// only valid in the case of independent test
void main()
{
/* BYTE buf[] = {0x08,0x91,
0x68,0x31,0x08,0x20,0x05,0x05,0xF0,
0x04,0x0D,0x91,
0x68,0x31,0x08,0x09,0x00,0x82,0xF2,
0x00,0x00,
0x20,0x60,0x40,0x21,0x62,0x85,0x00,
0x09,
0xE8,0x32,0x9B,0xFD,0x46,0x97,0xD9,0xEC,0x37}; */
char buf[] = {"0891"
"683108200505F0"
"040D91"
"683108090082F2"
"0000"
"20604021628500"
"05"
"E8329BFD06"};
SMS_DELIVER_PDU_CONTENT *sdc;
sdc = TranslateSDPC( buf );
DispSDC( sdc );
return;
}
#endif
// abstract SMS_DELIVER_PDU_CONTENT from the data stream
SMS_DELIVER_PDU_CONTENT *TranslateSDPC( char *str )
{
SMS_DELIVER_PDU_CONTENT *sdc;
int i, len;
BYTE *buf = NULL;
if( str == NULL )
return NULL;
len = ( strlen(str) +1 ) >> 1;
buf = (BYTE *)SysLmalloc( len );
if( buf == NULL )
return NULL;
Char2Hex( buf, &len, str );
sdc = (SMS_DELIVER_PDU_CONTENT *)SysLmalloc( sizeof(SMS_DELIVER_PDU_CONTENT) );
if( sdc == NULL )
return NULL;
sdc->sa = NULL;
sdc->oa = NULL;
sdc->ud = NULL;
sdc->tsmc = buf[1];
len = buf[0]-1;
sdc->sa = (char *)SysLmalloc( ( len <<1 )+1 );
if( sdc->sa == NULL )
goto ERROR_HANDLE;
BCD2CHAR( sdc->sa, &buf[2], len );
i = len +2;
sdc->fo = buf[i++];
len = ( buf[i++] +1 )>>1;
sdc->tn = buf[i++];
sdc->oa = (char *)SysLmalloc( len<<2 );
if( sdc->oa == NULL )
goto ERROR_HANDLE;
BCD2CHAR( sdc->oa, &buf[i], len );
i += len;
sdc->pid = buf[i++];
sdc->dcs = buf[i++];
sdc->time.year = BCD2INT( buf[i++] );
sdc->time.month = BCD2INT( buf[i++] );
sdc->time.day = BCD2INT( buf[i++] );
sdc->time.hour = BCD2INT( buf[i++] );
sdc->time.min = BCD2INT( buf[i++] );
sdc->time.sec = BCD2INT( buf[i++] );
sdc->time.zone = buf[i++];
len = buf[i++];
sdc->ud = (char *)SysLmalloc( len+1 );
if( sdc->ud == NULL )
goto ERROR_HANDLE;
switch( sdc->dcs & 0xc0 )
{
case 0x00: // General Data Coding indication
if( ( sdc->dcs & 0x20 ) != 0 ) // Text is compressed
{
}
if( ( sdc->dcs & 0x10 ) == 0x10 ) // message class
{
}
switch( sdc->dcs & 0x0c )
{
case 0x00: // Default alphabet
Septet2ASCII( sdc->ud, &len, &buf[i], len );
break;
case 0x04: // 8 bit data
memcpy( sdc->ud, &buf[i], len );
sdc->ud[len] = '\0';
break;
case 0x08: // UCS2 (16bit)
UCS22ASCII( sdc->ud, &len, &buf[i], len );
break;
case 0x0c: // Reserved
break;
}
switch( sdc->dcs & 0x03 )
{
case 0x00: // Immediate display (alert)
break;
case 0x01: // ME specific
break;
case 0x02: // SIM specific
break;
case 0x03: // TE specific
break;
}
break;
case 0x40:
break;
case 0xc0: // Message Waiting Indication Group
switch( sdc->dcs & 0x30 )
{
case 0x00: // Discard Message
sdc->ud[0] = '\0';
break;
case 0x10: // Store Message ( Default Alphabet Encode )
if( sdc->dcs & 0x04 ) // Set Indication Inactive
{
}
else // Set Indication active
{
}
switch( sdc->dcs & 0x03 )
{
case 0x00: // Voicemail Message Waiting
break;
case 0x01: // Fax Message Waiting
break;
case 0x02: // Electronic Mail Message Waiting
break;
case 0x03: // Other Message Waiting
break;
}
break;
case 0x20: // Store Message ( UCS2 Encode )
break;
case 0x30: // Data coding/message class
// Message Coding
if( sdc->dcs & 0x04 ) // 8-bit data
{
memcpy( sdc->ud, &buf[i], len );
sdc->ud[len] = '\0';
}
else // Default alphabet
{
Septet2ASCII( sdc->ud, &len, &buf[i], len );
}
// Message Class
switch( sdc->dcs & 0x03 )
{
case 0x00: // Immediate display (alert)
break;
case 0x01: // ME specific
break;
case 0x02: // SIM specific
break;
case 0x03: // TE specific
break;
}
break;
}
break;
}
// ASCII2Septet( &buf[i], &len, sdc->ud, len );
return sdc;
ERROR_HANDLE:
if( sdc->sa != NULL )
SysLfree( sdc->sa );
if( sdc->oa != NULL )
SysLfree( sdc->oa );
if( sdc->ud != NULL )
SysLfree( sdc->ud );
SysLfree( buf );
SysLfree( sdc );
return NULL;
}
// form the data stream with SMS_SUBMIT_PDU_CONTENT
char *TranslateSSPC( SMS_SUBMIT_PDU_CONTENT *ssc, int *msgLen )
{
int i = 0, oaLen, udLen;
char *buf;
BYTE *temp;
temp = (char *)SysLmalloc( MAX_AT_SMS_LEN );
if( temp == NULL )
return NULL;
// CHAR2BCD( &temp[2], &saLen, ssc->sa );
// temp[0] = (BYTE)( saLen + 1 );
// temp[1] = ssc->tsmc;
// i = saLen + 2;
temp[i++] = 0x00;
temp[i++] = ssc->fo;
temp[i++] = ssc->mr;
temp[i++] = (BYTE)strlen( ssc->oa );
temp[i++] = ssc->tn;
CHAR2BCD( &temp[i], &oaLen, ssc->oa );
i += oaLen;
temp[i++] = ssc->pid;
temp[i++] = ssc->dcs;
temp[i++] = ssc->vp;
udLen = strlen( ssc->ud );
DataCodingScheme( ssc->ud, ssc->dcs, &temp[++i], &udLen, DCS_ENCODE );
temp[i-1] = udLen;
// ASCII2Septet( &temp[i], &udLen, ssc->ud, );
i += udLen;
// *msgLen = i - saLen -2;
*msgLen = i - 1;
buf = (char *)SysLmalloc( ( i << 1 ) + 1 );
if( buf == NULL )
{
SysLfree( temp );
return NULL;
}
Hex2Char( buf, temp, i );
SysLfree( temp );
return buf;
}
// convert data from BCD format to character format with byte-swap.
// EX: 0x04 0x12 --> "4021", 0x65 0xF3 --> "563"
void BCD2CHAR( char *des, BYTE *src, int srcLen )
{
int i, j;
for( i = 0, j = 0; i < srcLen; i++ )
{
des[j++] = ( src[i] | 0x30 ) & 0x3f;
des[j++] = ( ( src[i] >> 4 ) | 0x30 ) & 0x3f;
}
if( des[j-1] == 0x3f ) // 'F' used to fill the odd
des[j-1] = '\0';
else
des[j] = '\0';
return;
}
// convert data from character format to BCD format with byte-swap.
// EX: "4021" --> 0x04 0x12, "563" --> 0x65 0xF3
void CHAR2BCD( BYTE *des, int *desLen, char *src )
{
int i = 0, j = 0;
BYTE ch;
while( src[i] != '\0' )
{
ch = src[i] & 0xf;
if( i & 0x1 )
des[j++] |= ( ch << 4 );
else
des[j] = ch;
i++;
}
if( i & 0x1 ) // length of source string is odd
{
des[j++] |= 0xF0; // fill 'F' at the end;
}
*desLen = j;
return;
}
// convert data from BCD format to integer format with byte-swap.
// EX: 0x02 --> 20 ( 0x14 )
BYTE BCD2INT( BYTE ch )
{
BYTE i;
i = ( ch >> 4 ) + ( ch & 0xf )*10;
// i = ( ch >> 4 )*10 + ( ch & 0xf );
return i;
}
// convert data from septet format to ASCII format.
// EX: 0xE8 0x32 0x9B 0xFD 0x46 0x97 0xD9 0xEC 0x37 --> "hellohello"
void Septet2ASCII( BYTE *des, int *desLen, BYTE *src, int srclen )
{
BYTE mask[7] = { 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
BYTE k = 0, pre = 0;
int i, j;
for( i = 0, j = 0; i < srclen; i++ )
{
des[j] = ( ( ~mask[k] & src[i] ) << k ) | pre;
pre = ( mask[k] & src[i] ) >> ( 7 - k );
k++;
j++;
if( k == 7 )
{
des[j] = pre;
pre = 0;
k = 0;
j++;
}
}
des[j] = '\0';
*desLen = j;
return;
}
// convert data from ASCII format to septet format.
// EX: "hellohello" --> 0xE8 0x32 0x9B 0xFD 0x46 0x97 0xD9 0xEC 0x37
void ASCII2Septet( BYTE *des, int *desLen, BYTE *src, int srclen )
{
BYTE mask[8] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f };
BYTE k = 0, pre = 0;
int i, j;
for( i = 0, j = 0; i < srclen; i++ )
{
if( k == 0 )
{
des[j] = src[i] & 0x7f;
k++;
j++;
}
else
{
des[j-1] |= ( ( src[i] & mask[k] ) << ( 8 - k ) );
if( k == 7 )
{
k = 0;
}
else
{
des[j] = src[i] >> k;
k++;
j++;
}
}
}
*desLen = j;
return;
}
// convert data from UCS2 format to ASCII format.
// EX: 0x4E 0x2D 0x56 0xFD 0x00 0x30 0x00 0x32 --> "中国02"
void UCS22ASCII( BYTE *des, int *desLen, BYTE *src, int srclen )
{
WORD codeIn, codeOut;
int i, j;
if( srclen & 0x1 )
return;
for( i = 0, j = 0; i < srclen; i++ )
{
if( src[i] == 0x00 )
{
des[j++] = src[++i];
}
else
{
codeIn = src[i++];
codeIn = ( codeIn << 8 ) | src[i];
codeOut = Uni2Gb( codeIn );
des[j++] = (BYTE)( codeOut >> 8 ) | 0x80 ;
des[j++] = (BYTE)( codeOut & 0xff ) | 0x80 ;
}
}
des[j] = '\0';
*desLen = j+1;
return;
}
// convert data from ASCII format to UCS2 format.
// EX: "中国02" --> 0x4E 0x2D 0x56 0xFD 0x00 0x30 0x00 0x32
// srclen is the character length, exclude '\0'.
void ASCII2UCS2( BYTE *des, int *desLen, BYTE *src, int srclen )
{
WORD codeIn, codeOut;
int i, j;
for( i = 0, j = 0; i < srclen; i++ )
{
if( src[i] & 0x80 ) // Wide Character
{
codeIn = src[i++] & 0x7f;
codeIn = ( codeIn << 8 ) | ( src[i] & 0x7f );
codeOut = Gb2Uni( codeIn );
des[j++] = (BYTE)( codeOut >> 8 ) ;
des[j++] = (BYTE)( codeOut & 0xff );
}
else // English Character
{
des[j++] = 0;
des[j++] = src[i];
}
}
*desLen = j;
return;
}
// convert data from ASCII format to HEX format.
// EX: "E8329BFD" --> 0xE8 0x32 0x9B 0xFD
void Char2Hex( BYTE *buf, int *len, char *str )
{
int i = 0, j = 0;
char c;
while( str[i] != '\0' )
{
c = ( str[i] & 0x10 ) ? str[i] & 0xf : ( ( str[i] & 0xf ) + 9 );
if( i & 0x1 )
{
buf[j] |= c;
j++;
}
else
buf[j] = c <<4;
i++;
}
*len = ( i + 1 ) >> 1;
return;
}
// convert data from HEX format to ASCII format.
// EX: 0xE8 0x32 0x9B 0xFD --> "E8329BFD"
void Hex2Char( char *str, BYTE *buf, int len )
{
int i, j;
BYTE c;
for( i = 0, j = 0; i < len; i++ )
{
c = buf[i] >> 4;
if( c > 0x9 )
str[j++] = c + 0x37; // 'A'~'F'
else
str[j++] = c | 0x30; // '0'~'9'
c = buf[i] & 0xf;
if( c > 0x9 )
str[j++] = c + 0x37; // 'A'~'F'
else
str[j++] = c | 0x30; // '0'~'9'
}
str[j] = '\0';
return;
}
void DataCodingScheme( char *ud, BYTE dcs, BYTE *buf, int *len, BYTE type )
{
switch( dcs & 0xc0 )
{
case 0x00: // General Data Coding indication
if( ( dcs & 0x20 ) != 0 ) // Text is compressed
{
}
if( ( dcs & 0x10 ) == 0x10 ) // message class
{
}
switch( dcs & 0x0c )
{
case 0x00: // Default alphabet
if( type == DCS_DECODE)
Septet2ASCII( ud, len, buf, *len );
else
ASCII2Septet( buf, len, ud, *len );
break;
case 0x04: // 8 bit data
if( type == DCS_DECODE)
{
memcpy( ud, buf, *len );
ud[*len] = '\0';
}
else
{
memcpy( buf, ud, *len );
}
break;
case 0x08: // UCS2 (16bit)
if( type == DCS_DECODE)
{
UCS22ASCII( ud, len, buf, *len );
}
else
{
ASCII2UCS2( buf, len, ud, *len );
}
break;
case 0x0c: // Reserved
break;
}
switch( dcs & 0x03 )
{
case 0x00: // Immediate display (alert)
break;
case 0x01: // ME specific
break;
case 0x02: // SIM specific
break;
case 0x03: // TE specific
break;
}
break;
case 0x40:
break;
case 0xc0: // Message Waiting Indication Group
switch( dcs & 0x30 )
{
case 0x00: // Discard Message
if( type == DCS_DECODE)
ud[0] = '\0';
break;
case 0x10: // Store Message ( Default Alphabet Encode )
if( dcs & 0x04 ) // Set Indication Inactive
{
}
else // Set Indication active
{
}
switch( dcs & 0x03 )
{
case 0x00: // Voicemail Message Waiting
break;
case 0x01: // Fax Message Waiting
break;
case 0x02: // Electronic Mail Message Waiting
break;
case 0x03: // Other Message Waiting
break;
}
break;
case 0x20: // Store Message ( UCS2 Encode )
break;
case 0x30: // Data coding/message class
// Message Coding
if( dcs & 0x04 ) // 8-bit data
{
if( type == DCS_DECODE)
{
memcpy( ud, buf, *len );
ud[*len] = '\0';
}
else
{
memcpy( buf, ud, *len );
}
}
else // Default alphabet
{
if( type == DCS_DECODE)
Septet2ASCII( ud, len, buf, *len );
else
ASCII2Septet( buf, len, ud, *len );
}
// Message Class
switch( dcs & 0x03 )
{
case 0x00: // Immediate display (alert)
break;
case 0x01: // ME specific
break;
case 0x02: // SIM specific
break;
case 0x03: // TE specific
break;
}
break;
}
break;
}
return;
}
void FreeSDPC( SMS_DELIVER_PDU_CONTENT *p )
{
if( p == NULL )
return;
SysLfree( p->sa );
SysLfree( p->oa );
SysLfree( p->ud );
SysLfree( p );
return;
}
void DispSDC( SMS_DELIVER_PDU_CONTENT *p )
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -