?? msg.cpp
字號(hào):
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Module Name:
msg.cpp
Abstract:
Notes:
--*/
#include "precomp.h"
#undef assert
#include "Safeint.hxx"
//
// Broadcast message languages
//
static const BYTE g_rgbBroadcastLangs[] =
{
15, // RIL_DCSLANG_UNKNOWN
0, // RIL_DCSLANG_GERMAN
1, // RIL_DCSLANG_ENGLISH
2, // RIL_DCSLANG_ITALIAN
3, // RIL_DCSLANG_FRENSH
4, // RIL_DCSLANG_SPANISH
5, // RIL_DCSLANG_DUTCH
6, // RIL_DCSLANG_SWEDISH
7, // RIL_DCSLANG_DANISH
8, // RIL_DCSLANG_PORTUGUESE
9, // RIL_DCSLANG_FINNISH
10, // RIL_DCSLANG_NORWEGIAN
11, // RIL_DCSLANG_GREEK
12, // RIL_DCSLANG_TURKISH
13, // RIL_DCSLANG_HUNGARIAN
14, // RIL_DCSLANG_POLISH
32, // RIL_DCSLANG_CZECH
33, // RIL_DCSLANG_HEBREW
34, // RIL_DCSLANG_ARABIC
35, // RIL_DCSLANG_RUSSIAN
36, // RIL_DCSLANG_ICELANDIC
};
#define NUM_LANGUAGES (sizeof(g_rgbBroadcastLangs) / sizeof(BYTE))
//
// Message storage locations
//
static const LPCSTR g_rgszMsgLocations[] =
{
"", // RIL_MSGLOC_UNKNOWN
"BM", // RIL_MSGLOC_BROADCAST
"SM", // RIL_MSGLOC_SIM
"SR" // RIL_MSGLOC_STATUSREPORT
};
#define NUM_MSGLOCS (sizeof(g_rgszMsgLocations) / sizeof(LPCSTR))
//
// Message status values
//
static const DWORD g_rgdwMsgStats[] =
{
RIL_MSGSTATUS_RECUNREAD, // 0
RIL_MSGSTATUS_RECREAD, // 1
RIL_MSGSTATUS_STOUNSENT, // 2
RIL_MSGSTATUS_STOSENT, // 3
};
#define NUM_MSGSTATS (sizeof(g_rgdwMsgStats) / sizeof(DWORD))
//
// Appends specified GSM broadcast DCS value value to the generated DCS range
//
static void AppendLangString(const LPCSTR szAppend, LPSTR& szWalk, const UINT cbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(AppendLangString);
UINT cbAppend = strlen(szAppend);
if ((1 < rcbUsed) && (rcbUsed + 1 <= cbOut)) // Need for and room for ','
{
*szWalk = ','; // Overwrite '\0'
szWalk++;
*szWalk = '\0'; // Add '\0' back
rcbUsed++; // Caller has already counted the '\0', so just count the ',' here
}
if (rcbUsed + cbAppend <= cbOut)
{
strncpyz(szWalk, szAppend, cbOut - rcbUsed);
szWalk += cbAppend;
rcbUsed += cbAppend;
}
else
{
DEBUGCHK(FALSE);
}
}
//
// Generates a GSM broadcast DCSs range string corresponding to the specified language mask
//
static void MakeBroadcastLangRange(const DWORD dwLanguages, const LPSTR szOut, const UINT cbOut)
{
FUNCTION_TRACE(MakeBroadcastLangRange);
UINT i;
LPSTR szWalk = szOut;
UINT cbUsed = 0;
char szNumber[4];
*szWalk = '\0';
// The empty string is sufficient for RIL_DCSLANG_ALL.
if (RIL_DCSLANG_ALL != dwLanguages)
{
cbUsed = 1; // Account for the '\0'
// Iterate through all bits of the mask to see which languages to add
for (i = 0; (i < sizeof(DWORD)*8) && (i < NUM_LANGUAGES); i++)
{
if ((dwLanguages >> i) & 0x01)
{
StringCbPrintfA( szNumber, sizeof(szNumber), "%hu", g_rgbBroadcastLangs[i] );
DEBUGCHK('\0' == szNumber[1] || '\0' == szNumber[2]);
AppendLangString(szNumber, szWalk, cbOut, cbUsed);
}
}
}
}
static void MakeBroadcastMsgIDs(const RILRANGE rgrrRange[], DWORD dwNumRanges, __out_bcount( cbOut ) const LPSTR szOut, const UINT cbOut)
{
LPSTR szWalk = szOut;
LPCSTR szEnd = szOut + cbOut;
DWORD cbRange = 0;
char szRange[64];
char c_szRangeFmt[] = ",%u-%u";
char c_szSingleFmt[] = ",%u";
LPCSTR szRangeFmt = c_szRangeFmt + 1;
LPCSTR szSingleFmt = c_szSingleFmt + 1;
for (DWORD dwCurrentRange = 0; dwCurrentRange < dwNumRanges; dwCurrentRange++)
{
if (rgrrRange[dwCurrentRange].dwMinValue == rgrrRange[dwCurrentRange].dwMaxValue)
{
cbRange = _snprintfz(szRange, 64, szSingleFmt, rgrrRange[dwCurrentRange].dwMinValue);
}
else
{
cbRange = _snprintfz(szRange, 64, szRangeFmt, rgrrRange[dwCurrentRange].dwMinValue, rgrrRange[dwCurrentRange].dwMaxValue);
}
if (szWalk + cbRange < szEnd)
{
StringCchCopyExA( szWalk, szEnd - szWalk, szRange, &szWalk, NULL, STRSAFE_IGNORE_NULLS );
}
else
{
break;
}
szRangeFmt = c_szRangeFmt;
szSingleFmt = c_szSingleFmt;
}
*szWalk = '\0';
}
//
// Set a flag in the language mask correponding to the
// specified GSM broadcast DCS value
//
static BOOL AppendLanguage(const UINT nValue, DWORD& rdwLanguages)
{
FUNCTION_TRACE(AppendLanguage);
UINT i;
BOOL fRet = FALSE;
for (i = 0 ; i < NUM_LANGUAGES; i++)
{
if (nValue == g_rgbBroadcastLangs[i])
{
DEBUGCHK(i < 32);
rdwLanguages |= (0x01 << i);
break;
}
}
return fRet;
}
//
// Parses a range of GSM broadcast DCSs into a language mask
//
static BOOL ParseBroadcastLangRange(LPCSTR szRange, DWORD& rdwLanguages)
{
FUNCTION_TRACE(ParseBroadcastLangRange);
UINT nValue1;
UINT nValue2;
UINT i;
BOOL fRet = FALSE;
if (*szRange)
{
// Start off with none...
rdwLanguages = 0;
while (1)
{
if (!ParseUInt(szRange, TRUE, nValue1, szRange))
{
goto Error;
}
if (MatchStringBeginning(szRange, "-", szRange) &&
ParseUInt(szRange, TRUE, nValue2, szRange))
{
// This is a mini-range
DEBUGCHK(nValue1 < nValue2);
for (i = nValue1; i <= nValue2; i++)
{
(void)AppendLanguage(i, rdwLanguages);
}
}
else
{
(void)AppendLanguage(nValue1, rdwLanguages);
}
// If there is no trailing comma, we're done
if (!MatchStringBeginning(szRange, ",", szRange))
{
break;
}
}
}
else
{
// An empty string implies all languages.
rdwLanguages = RIL_DCSLANG_ALL;
}
fRet = TRUE;
Error:
return fRet;
}
BOOL ParseGetLocation(const LPCSTR szRspOrig, UINT& rnLocation, LPCSTR& rszPointer)
{
FUNCTION_TRACE(ParseGetLocation);
char szLocation[MAX_PATH];
UINT nLocation;
LPCSTR szRsp = szRspOrig;
// Parse "<xxx_location>"
if (!ParseString(szRsp, szLocation, MAX_PATH, szRsp))
{
return FALSE;
}
for (nLocation = NUM_MSGLOCS-1; nLocation > 0; nLocation--)
{
if (!strcmp(szLocation, g_rgszMsgLocations[nLocation]))
{
break;
}
}
rnLocation = nLocation;
rszPointer = szRsp;
return TRUE;
}
static BOOL ParseGetLocationAmount(LPCSTR szRsp, LPCSTR& rszPointer, PUINT pLocation, PUINT pUsed, PUINT pTotal)
{
FUNCTION_TRACE(ParseGetLocationAmount);
UINT nLocation;
UINT nUsed;
UINT nTotal;
// Go past initial ',' if it's there
if (*szRsp==',')
{
szRsp++;
}
// Parse "<xxx_location>"
if (!ParseGetLocation(szRsp, nLocation, szRsp))
{
return FALSE;
}
// Parse ",<xxx_used>"
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUInt(szRsp, TRUE, nUsed, szRsp))
{
return FALSE;
}
// Parse ",<xxx_total>"
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUInt(szRsp, TRUE, nTotal, szRsp))
{
return FALSE;
}
*pLocation = nLocation;
*pUsed = nUsed;
*pTotal = nTotal;
rszPointer = szRsp;
return TRUE;
}
//
//
//
static HRESULT ParseGetMsgServiceOptionsRsp(LPCSTR szRsp, void*& pBlob, UINT& cbBlob)
{
FUNCTION_TRACE(ParseGetMsgServiceOptionsRsp);
HRESULT hr = E_FAIL;
RILMSGSERVICEINFO* prmsi = NULL;
UINT nValue;
UINT nLocation;
UINT nUsed;
UINT nTotal;
pBlob = NULL;
cbBlob = 0;
prmsi = (RILMSGSERVICEINFO*)AllocBlob(sizeof(RILMSGSERVICEINFO));
if (!prmsi)
{
hr = E_OUTOFMEMORY;
goto Error;
}
memset(prmsi, 0x00, sizeof(RILMSGSERVICEINFO));
prmsi->cbSize = sizeof(RILMSGSERVICEINFO);
// Parse "<prefix>+CSMS: <svc_type>"
if (!ParseRspPrefix(szRsp, szRsp) ||
!MatchStringBeginning(szRsp, "+CSMS: ", szRsp) ||
!ParseUInt(szRsp, TRUE, nValue, szRsp))
{
goto Error;
}
if (!nValue)
{
prmsi->dwService = RIL_MSGSVCTYPE_PHASE2;
}
else if (1 == nValue)
{
prmsi->dwService = RIL_MSGSVCTYPE_PHASE2PLUS;
}
else
{
prmsi->dwService = RIL_MSGSVCTYPE_UNKNOWN;
}
prmsi->dwParams |= RIL_PARAM_MSI_SERVICE;
// Parse ",<incoming>"
prmsi->dwMsgClasses = RIL_MSGCLASS_NONE;
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUIntAndVerifyAbove(szRsp, TRUE, 2, nValue, szRsp))
{
goto Error;
}
if (1 == nValue)
{
prmsi->dwMsgClasses |= RIL_MSGCLASS_INCOMING;
}
// Parse ",<outgoing>"
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUIntAndVerifyAbove(szRsp, TRUE, 2, nValue, szRsp))
{
goto Error;
}
if (1 == nValue)
{
prmsi->dwMsgClasses |= RIL_MSGCLASS_OUTGOING;
}
// Parse ",<broadcast><postfix>"
if (!MatchStringBeginning(szRsp, ",", szRsp) ||
!ParseUIntAndVerifyAbove(szRsp, TRUE, 2, nValue, szRsp) ||
!ParseRspPostfix(szRsp, szRsp))
{
goto Error;
}
if (1 == nValue)
{
prmsi->dwMsgClasses |= RIL_MSGCLASS_BROADCAST;
}
prmsi->dwParams |= RIL_PARAM_MSI_MSGCLASSES;
// Parse "<prefix>+CPMS: "
if (!ParseRspPrefix(szRsp, szRsp) ||
!MatchStringBeginning(szRsp, "+CPMS: ", szRsp))
{
goto Error;
}
// Parse Read fields
if (!ParseGetLocationAmount(szRsp, szRsp, &nLocation, &nUsed, &nTotal))
{
goto Error;
}
prmsi->dwReadLocation = nLocation;
prmsi->dwReadUsed = nUsed;
prmsi->dwReadTotal = nTotal;
prmsi->dwParams |= RIL_PARAM_MSI_READLOCATION | RIL_PARAM_MSI_READUSED | RIL_PARAM_MSI_READTOTAL;
// Note: If write or store fields are missing, we use the values from the last set of fields.
// Therefore, we don't check the return value from the following two ParseGetLocationAmount calls.
// This works around issues with some radios where some versions of the radio firmware don't report
// all three sets of fields.
// Parse Write fields
ParseGetLocationAmount(szRsp, szRsp, &nLocation, &nUsed, &nTotal);
prmsi->dwWriteLocation = nLocation;
prmsi->dwWriteUsed = nUsed;
prmsi->dwWriteTotal = nTotal;
prmsi->dwParams |= RIL_PARAM_MSI_WRITELOCATION | RIL_PARAM_MSI_WRITEUSED | RIL_PARAM_MSI_WRITETOTAL;
// Parse Store fields
ParseGetLocationAmount(szRsp, szRsp, &nLocation, &nUsed, &nTotal);
prmsi->dwStoreLocation = nLocation;
prmsi->dwStoreUsed = nUsed;
prmsi->dwStoreTotal = nTotal;
prmsi->dwParams |= RIL_PARAM_MSI_STORELOCATION | RIL_PARAM_MSI_STOREUSED | RIL_PARAM_MSI_STORETOTAL;
ParseRspPostfix(szRsp, szRsp);
pBlob = (void*)prmsi;
cbBlob = sizeof(RILMSGSERVICEINFO);
hr = S_OK;
Error:
if (FAILED(hr))
{
FreeBlob(prmsi);
}
return hr;
}
//
//
//
HRESULT RILDrv_GetMsgServiceOptions(DWORD dwParam)
{
FUNCTION_TRACE(RILDrv_GetMsgServiceOptions);
HRESULT hr = S_OK;
CRilInstanceHandle* pHandle = ExtractHandle(dwParam);
if (!pHandle)
{
hr = E_FAIL;
goto Error;
}
if (!QueueCmd(pHandle, "AT+CSMS?;+CPMS?\r", CMDOPT_NONE, APIID_GETMSGSERVICEOPTIONS,
ParseGetMsgServiceOptionsRsp, NULL, hr))
{
hr = E_FAIL;
goto Error;
}
Error:
return hr;
}
//
//
//
HRESULT RILDrv_SetMsgServiceOptions(DWORD dwParam, const RILMSGSERVICEINFO* lpMsgServiceInfo)
{
FUNCTION_TRACE(RILDrv_SetMsgServiceOptions);
CNotificationData* pnd = NULL;
char szCmd[MAX_PATH];
LPSTR szWalk = szCmd;
UINT nValue=0;
RILMSGSTORAGEINFO rmsi; memset(&rmsi,0,sizeof(rmsi)); // zero struct
HRESULT hr = S_OK;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -