?? smsprs.cpp
字號(hào):
}
// Parse protocol ID
if (!ParseMsgProtocolID(pbWalk, rrmMsg.msgOutCommand.dwProtocolID, cbParsed)) {
goto Error;
}
rrmMsg.dwParams |= RIL_PARAM_M_PROTOCOLID;
pbWalk += cbParsed;
if (pbWalk > pbEnd) {
goto Error;
}
// Parse command type
if (!ParseMsgCommandType(pbWalk, rrmMsg.msgOutCommand.dwCommandType, cbParsed)) {
goto Error;
}
rrmMsg.dwParams |= RIL_PARAM_M_COMMANDTYPE;
pbWalk += cbParsed;
if (pbWalk > pbEnd) {
goto Error;
}
// Parse the target message reference
rrmMsg.msgOutCommand.dwTgtMsgReference = *pbWalk++;
rrmMsg.dwParams |= RIL_PARAM_M_TGTMSGREFERENCE;
if (pbWalk > pbEnd) {
goto Error;
}
// Parse address
if (!ParseMsgAddress(pbWalk, FALSE, rrmMsg.msgOutCommand.raDestAddress, cbParsed, TRUE)) {
goto Error;
}
rrmMsg.dwParams |= RIL_PARAM_M_DESTADDRESS;
pbWalk += cbParsed;
if (pbWalk > pbEnd) {
goto Error;
}
// Parse command data length
rrmMsg.msgOutCommand.cbCmdLength = *pbWalk++;
rrmMsg.dwParams |= RIL_PARAM_M_CMDLENGTH;
if (pbWalk > pbEnd) {
goto Error;
}
// Parse command data
(void)memcpy(rrmMsg.msgOutCommand.rgbCmd, pbWalk, min(rrmMsg.msgOutCommand.cbCmdLength, MAXLENGTH_CMD));
rrmMsg.dwParams |= RIL_PARAM_M_CMD;
pbWalk += cbParsed;
if (pbWalk > pbEnd) {
goto Error;
}
fRet = TRUE;
Error:
return fRet;
}
//
// Parse an Incoming SMS message into a RILMESSAGE structure
//
HRESULT ParseSMSMessage(const LPCSTR sIn, const UINT cbIn, BOOL fIncoming, BOOL fPrependedSMSC, RILMESSAGE& rrmMsg)
{
FUNCTION_TRACE(ParseSMSMessage);
DEBUGCHK(NULL != sIn);
DEBUGCHK(0 < cbIn);
BYTE* pbGSMBytes = NULL;
UINT cbGSMBytes;
UINT cbParsed = 0;
BYTE bMsgType;
BOOL fRet = TRUE;
HRESULT hr = S_OK;
// Zero out the message structure
(void)memset(&rrmMsg, 0x00, sizeof(RILMESSAGE));
rrmMsg.cbSize = sizeof(RILMESSAGE);
// HW-SPECIFIC: some hardware don't encode the SMSC address prepended to a message
if ('+' == *sIn) {
UINT i;
LPWSTR pwchAddress;
LPCSTR pchIn;
LPCSTR sAfterSMSCAddress;
UINT cbAfterSMSCAddress;
// Assume the type and numplan
rrmMsg.raSvcCtrAddress.dwType = RIL_ADDRTYPE_INTERNATIONAL;
rrmMsg.raSvcCtrAddress.dwNumPlan = RIL_NUMPLAN_TELEPHONE;
// Copy the phone number over
pwchAddress = rrmMsg.raSvcCtrAddress.wszAddress;
pchIn = sIn + 1;
for (i = 0; i < SMSC_BOGUS_ADDR_LENGTH ; i++) {
*pwchAddress++ = *pchIn & 0x00ff;
}
*pwchAddress = L'\0';
// Set approproiate param flags
rrmMsg.raSvcCtrAddress.dwParams |= (RIL_PARAM_A_TYPE | RIL_PARAM_A_NUMPLAN | RIL_PARAM_A_ADDRESS);
rrmMsg.dwParams |= RIL_PARAM_M_SVCCTRADDRESS;
// Convert the rest of the message from GSM default HEX represention into GSM default
sAfterSMSCAddress = sIn + SMSC_BOGUS_ADDR_LENGTH;
cbAfterSMSCAddress = cbIn - SMSC_BOGUS_ADDR_LENGTH;
pbGSMBytes = new BYTE[cbAfterSMSCAddress/ 2 + 1];
if (!pbGSMBytes) {
hr = E_OUTOFMEMORY;
goto Error;
}
if (!GSMHexToGSM(sAfterSMSCAddress, cbAfterSMSCAddress, (LPSTR)pbGSMBytes, cbAfterSMSCAddress / 2 + 1, cbGSMBytes)) {
hr = E_FAIL;
goto Error;
}
} else {
// Convert the whole message from GSM default HEX represention into GSM default
pbGSMBytes = new BYTE[cbIn / 2 + 1];
if (!pbGSMBytes) {
hr = E_OUTOFMEMORY;
goto Error;
}
if (!GSMHexToGSM(sIn, cbIn, (LPSTR)pbGSMBytes, cbIn / 2 + 1, cbGSMBytes)) {
hr = E_FAIL;
goto Error;
}
if (fPrependedSMSC)
{
// Grab the prepended SMSC address
if (!ParseMsgAddress(pbGSMBytes, TRUE, rrmMsg.raSvcCtrAddress, cbParsed, FALSE)) {
hr = E_FAIL;
goto Error;
}
rrmMsg.dwParams |= RIL_PARAM_M_SVCCTRADDRESS;
}
}
// Mask the bottom two bits to get the message type (GSM 03.40 section 9.2.3.1)
bMsgType = *(pbGSMBytes + cbParsed) & 0x03;
switch (bMsgType)
{
case 0x00: // SMS-DELIVER or SMS-DELIVER-REPORT
if (!fIncoming) {
// We don't support SMS-DELIVER-REPORTs
hr = E_FAIL;
goto Error;
}
fRet = ParseDeliverMsg(pbGSMBytes + cbParsed, cbGSMBytes - cbParsed, rrmMsg);
break;
case 0x01: // SMS-SUBMIT or SMS-SUBMIT-REPORT
if (fIncoming) {
// We don't support SMS-SUBMIT-REPORTs
hr = E_FAIL;
goto Error;
}
fRet = ParseSubmitMsg(pbGSMBytes + cbParsed, cbGSMBytes - cbParsed, rrmMsg);
break;
case 0x02: // SMS-STATUS-REPORT or SMS_COMMAND
if (fIncoming) {
fRet = ParseStatusMsg(pbGSMBytes + cbParsed, cbGSMBytes - cbParsed, rrmMsg);
} else {
fRet = ParseCommandMsg(pbGSMBytes + cbParsed, cbGSMBytes - cbParsed, rrmMsg);
}
break;
default:
hr = E_FAIL;
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ParseSMSMessage : Invalid Message Type\r\n")));
goto Error;
}
if (!fRet) {
DEBUGMSG(ZONE_ERROR, (TEXT("RILDrv : E : ParseSMSMessage : Failed\r\n")));
hr = E_FAIL;
}
Error:
delete[] pbGSMBytes;
return hr;
}
//
// Helper for setting RILMSGDCS language properties
//
static void SetDCSLanguageType(RILMSGDCS& rrmdDCS, DWORD dwAlphabet, DWORD dwLanguage)
{
rrmdDCS.dwType = RIL_DCSTYPE_LANGUAGE;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_TYPE;
rrmdDCS.dwAlphabet = dwAlphabet;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
rrmdDCS.dwLanguage = dwLanguage;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_LANGUAGE;
}
//
// Set Data Coding Scheme of Incoming Cell Broadcast Message
// see GSM 03.38
//
static BOOL ParseCellBroadcastDCS(const BYTE bIn, RILMSGDCS& rrmdDCS, UINT& rcbLangInMsgBody)
{
FUNCTION_TRACE(ParseCellBroadcastDCS);
BOOL fRet = FALSE;
rcbLangInMsgBody = 0;
(void)memset(&rrmdDCS, 0x00, sizeof(RILMSGDCS));
rrmdDCS.cbSize = sizeof(RILMSGDCS);
switch (bIn & 0xf0)
{
case 0x00:
SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, g_rgdwDCSLanguagesGroup1[bIn & 0x0f]);
break;
case 0x10:
switch (bIn & 0x0f)
{
case 0x00:
// First 3 characters of message body contain language.
rcbLangInMsgBody = 3;
SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, RIL_DCSLANG_UNKNOWN);
break;
case 0x01:
// First 2 characters of message body contain language.
rcbLangInMsgBody = 2;
SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_UCS2, RIL_DCSLANG_UNKNOWN);
break;
default:
SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, RIL_DCSLANG_UNKNOWN);
break;
}
break;
case 0x20:
if (0x00 == (bIn & 0x0f))
{
SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, g_rgdwDCSLanguagesGroup2[bIn & 0x0f]);
break;
}
__fallthrough;
case 0x30:
SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, RIL_DCSLANG_UNKNOWN);
break;
case 0xf0:
rrmdDCS.dwType = RIL_DCSTYPE_GENERAL;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_TYPE;
if (bIn & 0x04)
{
rrmdDCS.dwAlphabet = RIL_DCSALPHABET_8BIT;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
}
else
{
rrmdDCS.dwAlphabet = RIL_DCSALPHABET_DEFAULT;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
}
switch (bIn & 0x03)
{
case 0x00:
// None
break;
case 0x01:
rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_1;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
break;
case 0x02:
rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_2;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
break;
case 0x03:
rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_3;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
break;
}
break;
default:
if (bIn & 0x40)
{
rrmdDCS.dwType = RIL_DCSTYPE_GENERAL;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_TYPE;
if (bIn & 0x20)
{
rrmdDCS.dwFlags |= RIL_DCSFLAG_COMPRESSED;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_FLAGS;
}
if (bIn & 0x10)
{
switch (bIn & 0x03)
{
case 0x00:
rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_0;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
break;
case 0x01:
rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_1;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
break;
case 0x02:
rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_2;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
break;
case 0x03:
rrmdDCS.dwMsgClass = RIL_DCSMSGCLASS_3;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_MSGCLASS;
break;
}
}
switch ((bIn >> 2) & 0x03)
{
case 0x00:
rrmdDCS.dwAlphabet = RIL_DCSALPHABET_DEFAULT;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
break;
case 0x01:
rrmdDCS.dwAlphabet = RIL_DCSALPHABET_8BIT;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
break;
case 0x02:
rrmdDCS.dwAlphabet = RIL_DCSALPHABET_UCS2;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
break;
case 0x03:
// Reserved... so use assume alphabet
rrmdDCS.dwAlphabet = RIL_DCSALPHABET_DEFAULT;
rrmdDCS.dwParams |= RIL_PARAM_MDCS_ALPHABET;
break;
}
}
else
{
// All other cases are reserved and assumed to use default alphabet.
SetDCSLanguageType(rrmdDCS, RIL_DCSALPHABET_DEFAULT, RIL_DCSLANG_UNKNOWN);
}
break;
}
return TRUE;
}
//
// Parses header information for
//
static BOOL ParseCellBroadcastHeader(const BYTE* const pbIn, const UINT cbIn, RILMESSAGE& rrmMsg, UINT& rcbParsed)
{
rcbParsed = 0;
if (cbIn < CELLBROADCAST_HEADER_LENGTH)
{
return FALSE;
}
// Parse values from the first 2 octets (the serial number)
WORD wSerialNumber = MAKEWORD(*(pbIn+1), *pbIn);
rrmMsg.msgBcGeneral.dwGeoScope = GEOSCOPE_FROM_SERIALNUMBER (wSerialNumber);
rrmMsg.msgBcGeneral.dwMsgCode = MESSAGECODE_FROM_SERIALNUMBER (wSerialNumber);
rrmMsg.msgBcGeneral.dwUpdateNumber = UPDATENUMBER_FROM_SERIALNUMBER(wSerialNumber);
// Parse the message ID
rrmMsg.msgBcGeneral.dwID = MAKEWORD(*(pbIn+3), *(pbIn+2));
// Parse DCS info
UINT cbLanguageInMessageBody = 0;
if (!ParseCellBroadcastDCS(*(pbIn+4), rrmMsg.msgBcGeneral.rmdDataCoding, cbLanguageInMessageBody))
{
return FALSE;
}
// Parse page info
BYTE bPageInfo = *(pbIn+5);
rrmMsg.msgBcGeneral.dwTotalPages = TOTALPAGES(bPageInfo);
rrmMsg.msgBcGeneral.dwPageNumber = PAGENUMBER(bPageInfo);
if (rrmMsg.msgBcGeneral.dwTotalPages == 0 ||
rrmMsg.msgBcGeneral.dwPageNumber == 0)
{
rrmMsg.msgBcGeneral.dwTotalPages = 1;
rrmMsg.msgBcGeneral.dwPageNumber = 1;
}
rcbParsed = CELLBROADCAST_HEADER_LENGTH + cbLanguageInMessageBody;
return TRUE;
}
HRESULT ParseCellBroadcastMessage(const LPCSTR sIn, const UINT cbIn, RILMESSAGE& rrmMsg)
{
FUNCTION_TRACE(ParseCellBroadcastMessage);
DEBUGCHK(NULL != sIn);
DEBUGCHK(0 < cbIn);
HRESULT hr = S_OK;
BYTE* pbGSMBytes = NULL;
UINT cbGSMBytes;
UINT cbParsed = 0;
// Zero out the message structure
(void)memset(&rrmMsg, 0x00, sizeof(RILMESSAGE));
rrmMsg.cbSize = sizeof(RILMESSAGE);
// Convert the whole message from GSM default HEX represention into GSM default
pbGSMBytes = new BYTE[cbIn / 2 + 1];
if (!pbGSMBytes) {
hr = E_OUTOFMEMORY;
goto Error;
}
if (!GSMHexToGSM(sIn, cbIn, (LPSTR)pbGSMBytes, cbIn / 2 + 1, cbGSMBytes)) {
hr = E_FAIL;
goto Error;
}
// Parse the header information
if (!ParseCellBroadcastHeader(pbGSMBytes, cbGSMBytes, rrmMsg, cbParsed))
{
hr = E_FAIL;
goto Error;
}
// This is a cell broadcast message.
rrmMsg.dwType = RIL_MSGTYPE_BC_GENERAL;
// Copy the message body to the output structure
rrmMsg.msgBcGeneral.cchMsgLength = min(cbGSMBytes - cbParsed, MAXLENGTH_MSG);
if ( (cbParsed + rrmMsg.msgBcGeneral.cchMsgLength >= cbIn / 2 + 1) ||
(rrmMsg.msgBcGeneral.cchMsgLength > sizeof(rrmMsg.msgBcGeneral.rgbMsg)) ) {
hr = E_FAIL;
goto Error;
}
memcpy(rrmMsg.msgBcGeneral.rgbMsg, pbGSMBytes + cbParsed, rrmMsg.msgBcGeneral.cchMsgLength);
// We always get all the parameters for cell broadcast
rrmMsg.dwParams = RIL_PARAM_M_ALL_BC_GENERAL;
Error:
delete[] pbGSMBytes;
return hr;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -