📄 pdumode.c
字号:
/****************************************************************
** *
** FILE : PDUMode.C *
** COPYRIGHT : (c) 2001 .Xiamen Yaxon NetWork CO.LTD *
** *
** *
** By : CCH 2002.1.15 *
****************************************************************/
#include "includes.h"
#include "tools.h"
#include "flash.h"
#include "stream.h"
#include "PDUMode.h"
/*
********************************************************************************
* DEFINE MODULE VARIANT
********************************************************************************
*/
static STREAM wstrm;
static INT16U Convert(INT16U data)
{
return ((data << 8) + (data >> 8));
}
static INT16U GetGBCode(INT16U unicode)
{
INT16U begaddr, endaddr, curaddr, curcode, *ptr;
begaddr = 0;
endaddr = UNITOGB_ENDADDR;
for (;;) {
curaddr = (begaddr + endaddr) / 2;
ptr = (INT16U *)FLASH_UNITOGB_ADDR + curaddr * 2;
curcode = Convert(*ptr++);
if (curcode == unicode) return Convert(*ptr);
if (begaddr == endaddr) return 0x3030;
if (curcode > unicode) endaddr = curaddr;
else begaddr = curaddr + 1;
}
}
static INT16U GetUNICode(INT16U gbcode)
{
HWORD_UNION temp;
INT16U addr, *ptr;
temp.hword = gbcode;
if (temp.bytes.high >= 0xa1 && temp.bytes.high <= 0xa9) {
addr = (temp.bytes.high - 0xa1) * 94 + (temp.bytes.low - 0xa1);
} else if (temp.bytes.high >= 0xb0 && temp.bytes.high <= 0xf7) {
addr = (temp.bytes.high - 0xa1 - 6) * 94 + (temp.bytes.low - 0xa1);
} else {
return 0x0030;
}
ptr = (INT16U *)FLASH_GBTOUNI_ADDR + addr;
return Convert(*ptr);
}
INT16U GBToUni(INT8U *dptr, INT8U *sptr, INT16U len, INT16U limitlen)
{
INT16U rlen, unicode;
rlen = 0;
for (;;) {
if (len == 0) break;
if (*sptr < 0x80) {
unicode = *sptr++;
len--;
} else {
unicode = *sptr++ << 8;
unicode += *sptr++;
unicode = GetUNICode(unicode);
if (len < 2) return 0;
len -= 2;
}
rlen += 2;
if (rlen > limitlen) return 0;
*dptr++ = unicode >> 8;
*dptr++ = unicode;
}
return rlen;
}
INT16U UniToGB(INT8U *dptr, INT8U *sptr, INT16U len)
{
INT16U rlen, gbcode;
if (len % 2) return 0;
for (len /= 2, rlen = 0; len > 0; len--) {
gbcode = *sptr++ << 8;
gbcode += *sptr++;
if (gbcode < 0x0080) {
*dptr++ = gbcode;
rlen++;
} else {
gbcode = GetGBCode(gbcode);
*dptr++ = gbcode >> 8;
*dptr++ = gbcode;
rlen += 2;
}
}
return rlen;
}
BOOLEAN SearchGBCode(INT8U *ptr, INT16U len)
{
for (; len > 0; len--) {
if (*ptr++ >= 0x80) return TRUE;
}
return FALSE;
}
INT16U TestGBLen(INT8U *ptr, INT16U len)
{
INT16U rlen;
if (!SearchGBCode(ptr, len)) return len;
rlen = 0;
for (;;) {
if (len == 0) break;
rlen += 2;
len--;
if (len == 0) break;
if (*ptr++ >= 0x80) {
ptr++;
len--;
}
}
return rlen;
}
static BOOLEAN ParseUserData(SM_STRUCT *desSM, INT8U *orgdata)
{
INT16U temp;
INT8U len, udhl, udhl_7, fillbit, leftbit;
if (desSM->PDUtype & 0x40) udhl = orgdata[1] + 1;
else udhl = 0;
len = orgdata[0];
if (udhl > len) return FALSE;
switch (desSM->DCS & 0x0C)
{
case SM_DCS_BIT7:
if (len > 160) return FALSE;
temp = len * 7;
if (temp % 8) {
temp /= 8;
temp++;
} else {
temp /= 8;
}
fillbit = 7 - (udhl * 8) % 7;
if (fillbit != 7)
leftbit = 8 - fillbit;
else
leftbit = 8;
udhl_7 = (udhl * 8) / 7;
if (leftbit != 8) udhl_7++;
desSM->UDL = len - udhl_7;
OctetToBit7(desSM->UD, &orgdata[udhl + 1], temp - udhl, leftbit);
return TRUE;
case SM_DCS_UCS2:
if (len > 140) return FALSE;
desSM->UDL = UniToGB(desSM->UD, &orgdata[udhl + 1], len - udhl);
return TRUE;
default:
if (len > 140) return FALSE;
desSM->UDL = len - udhl;
memcpy(desSM->UD, &orgdata[udhl + 1], len - udhl);
return TRUE;
}
}
BOOLEAN ParsePDUData(SM_STRUCT *desSM, INT8U *orgdata, INT16U orglen, INT16U pdulen)
{
INT8U templen;
INT16U temp, curpos;
orglen = AsciiToHex(orgdata, orgdata, orglen - 2); /* 2 = LF, CR */
if (orglen == 0) return FALSE;
if ((pdulen + orgdata[0] + 1) != orglen) return FALSE;
if (orgdata[0] >= 11) return FALSE;
if (orgdata[0] == 0) {
desSM->SCAL = 0;
} else {
if (orgdata[1] == 0x91) {
templen = 1;
desSM->SCA[0] = '+';
} else {
templen = 0;
}
desSM->SCAL = templen + SemiOctetToAscii(&desSM->SCA[templen], &orgdata[2], orgdata[0] - 1);
}
curpos = orgdata[0] + 1;
desSM->PDUtype = orgdata[curpos++];
temp = orgdata[curpos];
if (temp >= 22) return FALSE;
if (temp % 2) temp++;
temp /= 2;
if (temp == 0) {
desSM->OAL = 0;
} else {
if (orgdata[curpos + 1] == 0x91) {
templen = 1;
desSM->OA[0] = '+';
} else {
templen = 0;
}
desSM->OAL = templen + SemiOctetToAscii(&desSM->OA[templen], &orgdata[curpos + 2], temp);
}
curpos += (temp + 2);
desSM->PID = orgdata[curpos++];
desSM->DCS = orgdata[curpos++];
SemiOctetToAscii(desSM->SCTS, &orgdata[curpos], 6);
SemiOctetToHex(&desSM->timezone, &orgdata[curpos + 6], 1);
curpos += 7;
return ParseUserData(desSM, &orgdata[curpos]);
}
INT16U AssemblePDUData(INT8U DCS, INT8U *telptr, INT8U tellen, INT8U *dataptr, INT8U datalen, INT8U *dptr, INT8U *tmpptr)
{
INT16U len;
INT8U *tmp;
InitStrm(&wstrm, tmpptr, 1024); /* initialize stream */
WriteBYTE_Strm(&wstrm, 0x0); /* write SCA */
WriteBYTE_Strm(&wstrm, 0x11); /* write PDU-type */
WriteBYTE_Strm(&wstrm, 0x0); /* write MR */
if (tellen > 22) return 0; /* write DA */
if (tellen == 0) {
WriteBYTE_Strm(&wstrm, 0x0);
WriteBYTE_Strm(&wstrm, 0x81); /* national number */
} else {
if (*telptr != '+') {
WriteBYTE_Strm(&wstrm, tellen);
WriteBYTE_Strm(&wstrm, 0x81); /* national number */
len = AsciiToSemiOctet(GetStrmPtr(&wstrm), telptr, tellen);
MovStrmPtr(&wstrm, len);
} else {
WriteBYTE_Strm(&wstrm, tellen - 1);
WriteBYTE_Strm(&wstrm, 0x91); /* international number */
len = AsciiToSemiOctet(GetStrmPtr(&wstrm), telptr + 1, tellen - 1);
MovStrmPtr(&wstrm, len);
}
}
WriteBYTE_Strm(&wstrm, 0x0); /* write PID */
WriteBYTE_Strm(&wstrm, DCS); /* write DCS */
WriteBYTE_Strm(&wstrm, 143); /* write VP = 12 hours */
tmp = GetStrmPtr(&wstrm); /* record current position */
WriteBYTE_Strm(&wstrm, datalen); /* write UDL */
switch (DCS)
{
/* default alphabet (7 bit data coding in the user data) */
case SM_DCS_BIT7:
if (datalen > 160) return 0;
len = Bit7ToOctet(GetStrmPtr(&wstrm), dataptr, datalen);
MovStrmPtr(&wstrm, len);
break;
case SM_DCS_UCS2:
if ((*tmp = len = GBToUni(GetStrmPtr(&wstrm), dataptr, datalen, 140)) == 0) return 0;
MovStrmPtr(&wstrm, len);
break;
default:
if (datalen > 140) return 0;
WriteDATA_Strm(&wstrm, dataptr, datalen);
break;
}
len = HexToAscii(dptr, tmpptr, GetStrmLen(&wstrm));
dptr[len++] = CTRL_Z; /* write CTRL+Z */
return len;
}
static INT8U GSMCODE[] = { '@', ' ', '$', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 0x0A,' ', ' ', 0x0D,' ', ' ',
'_', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', '!', '"', '#', ' ', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', ' ', ' ', ' ', ' ',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ' ', ' ', ' ', ' ', ' '
};
INT8U GsmCodeToASCII(INT8U incode)
{
return GSMCODE[incode & 0x7f];
}
INT8U ASCIIToGsmCode(INT8U incode)
{
INT8U i;
if (incode == ' ') return ' ';
for (i = 0; i < sizeof(GSMCODE); i++) {
if (incode == GSMCODE[i]) return i;
}
return ' ';
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -