⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at_pdu.c

📁 一个操作系统源代码 用于嵌入式设备 在Vc++环境下仿真 成功移植到多款处理器上
💻 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 + -