www.pudn.com > GPRS__moder.rar > cbGSMService.cpp


/***************************************************************************** 
 *    GSM SMS Routines 
 * 
 *    Writen by Menghongwen@ 
 * 
 *   Dec., 2004 copyright YINHUA Technology, all right reserved 
\****************************************************************************/ 
#include  
#pragma hdrstop 
#include "stdio.h" 
#include "cbGSMService.h" 
 
#pragma package(smart_init) 
//--------------------------------------------------------------------------- 
__fastcall TGSMService::TGSMService(bool CreateSuspended,TSMSConfig *pcfg) 
        : TThread(CreateSuspended) 
{ 
    tpmr = 0x0; 
    pConfig = pcfg; 
    FreeOnTerminate = True; 
} 
//--------------------------------------------------------------------------- 
bool  __fastcall TGSMService::prepare4Stop() 
{ 
    return hCommand.closecomm(); 
} 
//--------------------------------------------------------------------------- 
bool  __fastcall TGSMService::prepare4Start() 
{ 
    if(!hCommand.opencomm("COM2")) return false; 
 
    if(!sms_TerminalReady()) return false; 
 
    sms_SendMode(GSMSendAsPDU); 
 
    sms_SetDefaultSC(); 
    hPDUs.sca = NULL; 
 
    return true; 
} 
//--------------------------------------------------------------------------- 
bool  TGSMService::sms_TerminalReady() 
{ 
    hCommand.atcommand("CREG?",false); 
    hCommand.appendcr(); 
    if (hCommand.send()) { 
       if (hCommand.querystring("0,1"))return true; 
    } 
    return false; 
} 
//--------------------------------------------------------------------------- 
bool  TGSMService::sms_SetDefaultSC() 
{ 
    hCommand.atcommand("CSCA"); 
    hCommand.append(0x22); 
    hCommand.append(0x2b); 
    hCommand.appendstr(pConfig->asSmscString.c_str()); 
    hCommand.append(0x22); 
    hCommand.appendcr(); 
    if(hCommand.send()) 
       if (hCommand.querystring())return true; 
    return false; 
} 
//--------------------------------------------------------------------------- 
bool  TGSMService::sms_SendMode(TSMSSendMode mode) 
{ 
    hCommand.atcommand("CMGF"); 
    if ( mode == GSMSendAsText ) hCommand.appendstr("1"); 
    else hCommand.appendstr("0"); 
    hCommand.appendcr(); 
    if(hCommand.send()) 
       if (hCommand.querystring())return true; 
    return false; 
} 
//--------------------------------------------------------------------------- 
bool  TGSMService::sms_QueryMessage() 
{ 
    hCommand.atcommand("CMGL"); 
    hCommand.appendstr("0");   
    hCommand.appendcr(); 
    hCommand.send(200); 
    if (hCommand.querystring(__GSMRESPERR)) return false; 
    if (hCommand.usRecv > 16 ) sms_ParsePDUString(); 
    return false; 
} 
//--------------------------------------------------------------------------- 
void  TGSMService::sms_DeleteMessage(short idx) 
{ 
    char  szId[8]; 
 
    hCommand.atcommand("CMGD"); 
    sprintf(szId,"%d\x0",idx); 
    hCommand.appendstr(szId); 
    hCommand.appendcr(); 
    hCommand.send(200); 
} 
//--------------------------------------------------------------------------- 
BYTE  TGSMService::sms_SendMessage(PTGSMMessage pMsg) 
{ 
    short receipt; 
    char  szAsc[32]; 
    hPDUs.tpmr = tpmr; 
//    if(tpmr >0xfe ) tpmr = 0; else tpmr++; 
 
    hPDUs.tpda = &pMsg->address; 
    hPDUs.tpudl = encode2UCS2(pMsg->asMessage,hPDUs.tpud); 
 
    // send header first 
    hCommand.atcommand("CMGS"); 
    sprintf(szAsc,"%03d\x0", hPDUs.length()); 
    hCommand.appendstr(szAsc); 
    hCommand.appendcr(); 
    if(hCommand.send()) { 
       if(!hCommand.querychar(0x3E)) { 
          receipt = __GSMSMSESNDERROR + 1; 
          goto __send_error_exit; 
       } 
    } else { 
       receipt = __GSMSMSESNDERROR + 2; 
       goto __send_error_exit; 
    } 
    // PDU content 
    hCommand.cleardata(); 
    if (hPDUs.sca) { 
       hCommand.append(hPDUs.sca->packagelen()); 
       hCommand.append(hPDUs.sca->typeOf()); 
       hCommand.append(hPDUs.sca->value,hPDUs.sca->valuelen()); 
    } else hCommand.append(0x0); 
 
    hCommand.append(hPDUs.foctet.value); 
    hCommand.append(hPDUs.tpmr); 
 
    hCommand.append(hPDUs.tpda->semioctets()); 
    hCommand.append(hPDUs.tpda->typeOf()); 
    hCommand.append(hPDUs.tpda->value,hPDUs.tpda->valuelen()); 
 
    hCommand.append(hPDUs.tppid.value); 
    hCommand.append(hPDUs.tpdcs.value); 
    hCommand.append(hPDUs.tpvp); 
 
    hCommand.append(hPDUs.tpudl); 
    hCommand.append(hPDUs.tpud,hPDUs.tpudl); 
 
    hCommand.toAscii(); 
    hCommand.appendcz(); 
 
    // send pdu string 
    hCommand.send(); 
    if (hCommand.querystring(__GSMRESPERR)) { 
       receipt = __GSMSMSESNDERROR + 3; 
       goto __send_error_exit; 
    } 
 
    // BUG ???   Wait for response 
    hCommand.cleardata(); 
    hCommand.appendstr("AT"); 
    hCommand.appendcr(); 
    Sleep(pConfig->msWaitingTime); 
    hCommand.send(); 
    if (!hCommand.querystring(__GSMRESPERR)) { 
        receipt = hCommand.queryShortValue("+CMGS:"); 
    } else receipt =  __GSMSMSNORECEIPT; 
 
    __send_error_exit: 
    return receipt; 
} 
//--------------------------------------------------------------------------- 
void  TGSMService::sms_ParsePDUString() 
{ 
    short length,index,state,alpha,pudlength,useat; 
    char *pCursor, *pHead; 
    char  szTempud[190]; 
    PTGSMMessage newMsg; 
 
    length = hCommand.usRecv; 
    pHead = hCommand.recvAsString(); 
/* 
pHead ="+CMGL: 1,1,,153 0891683108200109F02404A181160008409081718480208A6B228FCE60A862104E3A4E0A6D7779FB52A876845BA26237300260A853EF767B5F55516C53F87F517AD9007700770077002E00730068002E006300680069006E0061006D006F00620069006C0065002E0063006F006D54A88BE2529E74064E1A52A1FF0C53D19001004D004D004300585230003100380036003167E58BE24E1A52A1529E74065BC67801 \ 
+CMGL: 2,1,,49  0891683108200109F0040BA13108200103F90008409022005153201E8BF756DE7535FF1A00310033003700370034003400300033003600310035 \ 
+CMGL: 3,1,,108 0891683108200109F02405A19099F60008409042611332205C4EB27231768475286237FF0C60A8768498845B588D39752853735C0675285B8CFF0C8BF7901F52306211516C53F884254E1A70B9529E74067EED5B5862164E7051687403901A7F348D3953615145503C30028C228C22914D5408FF01 \ 
+CMGL: 4,1,,135 0891683108200109F02404A181160008409042618384207860A87684624B673A5BC67801662F003A003100320035003400310037002C8BF76CE8610F5BC6780176844FDD5BC6300260A853EF4EE5767B51657F514E0A84254E1A5385621662E86253003100380036003130010031003300380030003000320031003000310033003881EA52A94FEE65395BC678013002 \ 
+CMGL: 5,1,,137 0891683108200105F0240BA13109613103F0000840908241815420764E2D79CB56FD5E8690FD5FEB898152304E86002E624B4E0A73B091D14E0D591A4E86300253EA80FD7ED94F604E9453434E07003B53434E07898150655EB7002E53434E0789815FEB4E50003B53434E0789815E735B89003B53434E07898177E58DB3003B53434E07002E4E0D89815FD88BB062110021 \ 
+CMGL: 6,1,,77 0891683108200105F0240BA13109613103F00008409082516184203A54755475002C5E78798F002C771F5E78798F002E4E0059275BB65B5095F95FD95F974E0D5F974E86803600216CE2002C4EB24FAC4E008BB0002E \ 
+CMGL: 7,1,,127 0891683108200109F02404A18116000840904261231320700038670881F300310030670895F4FF0C60A8901A8FC777ED4FE167E58BE28BDD8D39300175338BF74E1A52A1300166F463625957991062168F6C54C1724C540EFF0C5C315DF281EA52A883B75F978D6253D6004E004F004B00490041767E4E0750CF7D20624B673A7684673A4F1A3002 \ 
+CMGL: 8,1,,126 0891683108907105F0040D91683198712247F00008409072129511006A97E956FD4E09661F96C656E253174EAC603B4EE37406002E4E3E529E624B673A53F77801644759566D3B52A8002E60A85F974E8C7B495956002E4EF7503C0039002E00384E07002E75358BDD003A0031003300330030003600390039003500380030003582CF5C0F59D0 \ 
+CMGL: 9,1,,103 0891683108200105F0240BA13109613103F00008409082518074205454755475002E002E5468672B514856DE53BB8FC74E86002E89E380015E084ECA5E745E2673ED4E3B4EFB002C4ED689818DDF4ED676845B66751F4EEC4EB270ED5C314E0D56DE53BB4E86002E4F604EEC5462003F \ 
+CMGL: 10,1,,142 0891683108200109F02405A19099F90008402141012295207E4E0A670853D15F694FE180055DF24EA7751F4E09540D5E788FD0513F83B7591A666E8FBE003500360035624B673AFF1B5F694FE17B2C4E00540D66F48D625F97591A666E8FBE003600390036FF1B6D3B52A88FD857287EE77EEDFF0C4E0D5BB995198FC7FF0C4F604E5F80FD62104E3A8FD94E2A670876845E788FD0513F \ 
+CMGL: 11,1,,53 0891683108200105F0240BA13109613103F0000840908251225420226CE55FC3002C8BA96211518D67654E008BB0002C5C318BA94F6080899EBB002154FC \ 
+CMGL: 12,1,,108 0891683108200109F02405A19099F60008409003513310205C4EB27231768475286237FF0C60A8768498845B588D39752853735C0675285B8CFF0C8BF7901F52306211516C53F884254E1A70B9529E74067EED5B5862164E7051687403901A7F348D3953615145503C30028C228C22914D5408FF01 \ 
+CMGL: 13,1,,31 0891683108200105F0240BA13109613103F00008409082513242200C54C854C854C8002E002E002E \ 
+CMGL: 14,1,,108 0891683108200109F02405A19099F60008409082615335205C4EB27231768475286237FF0C60A8768498845B588D39752853735C0675285B8CFF0C8BF7901F52306211516C53F884254E1A70B9529E74067EED5B5862164E7051687403901A7F348D3953615145503C30028C228C22914D5408FF01 \ 
+CMGL: 15,1,,49 0891683108200109F0040BA13108200103F90008409003712513201E8BF756DE7535FF1A00300032003100350034003800310032003100340034 \ 
+CMGL: 16,1,,23 0891683108200105F0240BA13107813071F00008402161325082200453EF4EE5 OK"; 
    length = strlen(pHead); 
*/ 
 
    do { 
       pCursor = strstr(pHead,"+CMGL:"); 
       if ( pCursor == NULL ) return; 
       pHead = pCursor; 
       pCursor+=6; 
       pCursor = sms_parseInteger(pCursor,index); 
       pCursor = sms_parseInteger(pCursor,state); 
       pCursor = sms_parseInteger(pCursor,alpha); 
       pCursor = sms_parseInteger(pCursor,pudlength); 
 
       // skip control alpha 
       while(*pCursor==0x0d || *pCursor==0x0a || *pCursor == 0x1a \ 
        || *pCursor==0x27 || *pCursor==0x20 ) pCursor++; 
 
       if(!isdigit(*pCursor)) return;  // Send Error Message 
       useat = hPDUr.sca.loadstring(pCursor); 
       pCursor += useat; 
       pCursor = sms_parseByte(pCursor, hPDUr.foctet.value); 
       useat = hPDUr.tpoa.loadstring(pCursor,true); 
       pCursor += useat; 
       pCursor = sms_parseByte(pCursor, hPDUr.tppid.value); 
       pCursor = sms_parseByte(pCursor, hPDUr.tpdcs.value); 
       pCursor = sms_parseSemiOctets(pCursor, (BYTE *)&hPDUr.tpscts,7); 
       pCursor = sms_parseByte(pCursor, hPDUr.tpudl); 
       pCursor = sms_parseBCDString(pCursor,szTempud,hPDUr.tpudl); 
 
       if(hPDUr.tpdcs.bitmap.alphabet==2) 
          hPDUr.tpudl = decodeUcs2(szTempud, hPDUr.tpud, hPDUr.tpudl); 
       else if(hPDUr.tpdcs.bitmap.alphabet==1) 
          hPDUr.tpudl = decode8bit(szTempud, hPDUr.tpud, hPDUr.tpudl); 
       else if(hPDUr.tpdcs.bitmap.alphabet==0) 
          hPDUr.tpudl = decode7bit(szTempud, hPDUr.tpud, hPDUr.tpudl); 
       else hPDUr.tpud[0] = 0x0; // empty 
 
       newMsg = new TGSMMessage; 
       newMsg->address = hPDUr.tpoa; 
       newMsg->asMessage = (char *)hPDUr.tpud; 
       bcd2ascb((char*)&hPDUr.tpscts, szTempud,6); 
       newMsg->traceno = szTempud; 
       putRecvMessage(newMsg); 
 
       length -=(unsigned short)(pCursor-pHead); 
       pHead = pCursor; 
       sms_DeleteMessage(index); 
    } while(length); 
} 
//--------------------------------------------------------------------------- 
char *TGSMService::sms_parseByte(char *p, BYTE &rc) 
{ 
    char szByte[4]; 
 
    szByte[0] = *p++; 
    szByte[1] = *p++; 
    asc2bcd(szByte,&szByte[2],1); 
    rc = szByte[2]; 
    return p; 
} 
//--------------------------------------------------------------------------- 
char *TGSMService::sms_parseSemiOctets(char *p,BYTE *prs, short olen) 
{ 
    asc2bcdInv(p,prs,olen); 
    p+=(olen+olen); 
    return p; 
} 
//--------------------------------------------------------------------------- 
char *TGSMService::sms_parseBCDString(char *p,BYTE *prs, short olen) 
{ 
    asc2bcd(p,prs,olen); 
    p+=(olen+olen); 
    return p; 
} 
//--------------------------------------------------------------------------- 
char *TGSMService::sms_parseInteger(char *p,short &ri) 
// 00000,,000\r 
{ 
    short  i=1; 
    char szdigits[32]; 
 
    if ( p== NULL ) return NULL; 
 
    while (*p == 0x20 ) p++; 
 
    szdigits[0] = 0x30; 
    while(*p!=',') { 
       if (isdigit(*p) ) szdigits[i++] = *p++; 
       else break; 
       //if (*p == 0x0d) break; 
    } 
 
    if (*p == ',' ) p++; 
 
    szdigits[i] = 0x0; 
    ri = atoi(szdigits); 
    return p; 
} 
//--------------------------------------------------------------------------- 
PTGSMMessage  TGSMService::querySendMessage() 
{ 
    if(pConfig->hQueueOut!=NULL) 
       if (pConfig->hQueueOut->Count()) return (PTGSMMessage)pConfig->hQueueOut->Pop(); 
    return NULL; 
} 
//--------------------------------------------------------------------------- 
void  TGSMService::putRecvMessage(PTGSMMessage pMsg) 
{ 
    if(pConfig->hQueueIn!=NULL) if (pMsg!=NULL) pConfig->hQueueIn->Push(pMsg); 
} 
//--------------------------------------------------------------------------- 
void __fastcall TGSMService::Execute() 
{ 
     ustart = GetTickCount(); 
     uscurrent = ustart; 
     while(1){ 
 
        pMessage = querySendMessage(); 
        if ( pMessage != NULL ) { 
           if(pMessage->msgtype == GSMMTMessage ) { 
               pMessage->asMessage = IntToStr(sms_SendMessage(pMessage)); 
               pMessage->msgtype = GSMMTReceipt; 
               putRecvMessage(pMessage); 
           } else delete pMessage; 
        } else { 
             uscurrent = GetTickCount(); 
             uscurrent -= ustart; 
             uscurrent /= 1000; 
             if ( uscurrent > pConfig->msPollingTime ) { 
                 sms_QueryMessage(); 
                 ustart = GetTickCount(); 
             } 
        } 
 
        if(WaitForSingleObject(pConfig->hevStopGSMService, 20) ==WAIT_OBJECT_0) { 
           prepare4Stop(); 
           SetEvent(pConfig->hevThreadStoped); 
           break; 
        } 
     } 
} 
//---------------------------------------------------------------------------