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; } } } //---------------------------------------------------------------------------