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

📄 pdumode.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 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 + -