📄 smsenc.cpp
字号:
return hr;
}
//
// Fill out a BYTE array for a Command message
//
static HRESULT EncodeCmdMsg(const RILMESSAGE& rmMsg, __out_bcount( cbOut ) BYTE* const pbOut, const UINT cbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeCmdMsg);
BYTE* pbWalk = pbOut;
const BYTE* pbEnd = pbOut + cbOut;
UINT cbAdvancedBy;
HRESULT hr = S_OK;
rcbUsed = 0;
if ( !pbOut || !cbOut ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto Error;
}
(void)memset(pbOut, 0, cbOut);
// These parameters are mandatory, and if not present, we error out.
if (!(rmMsg.dwParams & RIL_PARAM_M_TYPE) || !(rmMsg.dwParams & RIL_PARAM_M_DESTADDRESS) ||
!(rmMsg.dwParams & RIL_PARAM_M_PROTOCOLID) || !(rmMsg.dwParams & RIL_PARAM_M_COMMANDTYPE) ||
!(rmMsg.dwParams & RIL_PARAM_M_TGTMSGREFERENCE) || !(rmMsg.dwParams & RIL_PARAM_M_CMDLENGTH) ||
!(rmMsg.dwParams & RIL_PARAM_M_FLAGS)) {
hr = E_INVALIDARG;
goto Error;
}
// Set Type, per GSM 03.40 section 9.2.3.1
*pbWalk |= 0x02;
// See GSM 03.40 section 9.2.3.5
if (rmMsg.dwFlags & RIL_MSGFLAG_STATUSREPORTREQUESTED) {
*pbWalk |= 0x20;
}
// See GSM 03.40 section 9.2.3.23
if (rmMsg.dwFlags & RIL_MSGFLAG_HEADER) {
*pbWalk |= 0x40;
}
pbWalk++;
DEBUGCHK(pbWalk <= pbEnd);
// Add a zero for the message reference (see GSM 03.40 section 9.2.3.6)
// NOTE: it appears that we can put anything into this field -- the module generates correct msg reference for us
pbWalk++;
DEBUGCHK(pbWalk <= pbEnd);
// See GSM 03.40 section 9.2.3.9
hr = EncodeMsgProtocolID(rmMsg.msgOutCommand.dwProtocolID, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if (FAILED(hr)) {
goto Error;
}
pbWalk += cbAdvancedBy;
if ( pbWalk >= pbEnd ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto Error;
}
// See GSM 03.40 section 9.2.3.19
switch (rmMsg.msgOutCommand.dwCommandType)
{
case RIL_MSGCMDTYPE_STATUSREQ:
*pbWalk++ = 0x00;
break;
case RIL_MSGCMDTYPE_CANCELSTATUSREQ:
*pbWalk++ = 0x01;
break;
case RIL_MSGCMDTYPE_DELETEMESSAGE:
*pbWalk++ = 0x02;
break;
case RIL_MSGCMDTYPE_ENABLESTATUSREQ:
*pbWalk++ = 0x03;
break;
default:
hr = E_INVALIDARG;
goto Error;
}
DEBUGCHK(pbWalk <= pbEnd);
// See GSM 03.40 section 9.2.3.18
if ( 0xff < rmMsg.msgOutCommand.dwTgtMsgReference || pbWalk >= pbEnd ) {
hr = E_INVALIDARG;
goto Error;
}
*pbWalk++ = (BYTE)rmMsg.msgOutCommand.dwTgtMsgReference;
DEBUGCHK(pbWalk <= pbEnd);
// Encode the destination address. pbMsg should be set properly by the function
hr = EncodeMsgAddress(rmMsg.msgOutCommand.raDestAddress, FALSE, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if (FAILED(hr)) {
goto Error;
}
pbWalk += cbAdvancedBy;
if ( pbWalk >= pbEnd ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto Error;
}
// Encode command data length
*pbWalk++ = (BYTE)rmMsg.msgOutCommand.cbCmdLength;
DEBUGCHK(pbWalk <= pbEnd);
// Encode command data
if (rmMsg.dwParams & RIL_PARAM_M_CMD) {
cbAdvancedBy = min(rmMsg.msgOutCommand.cbCmdLength, MAXLENGTH_CMD);
if ( pbWalk + cbAdvancedBy > pbEnd ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto Error;
}
memcpy(pbWalk, rmMsg.msgOutCommand.rgbCmd, cbAdvancedBy);
pbWalk += cbAdvancedBy;
}
rcbUsed = pbWalk - pbOut;
Error:
return hr;
}
//
// Encode a Deliver message for SIM storage
//
static HRESULT EncodeDeliverMsg(const RILMESSAGE& rmMsg, __out_bcount( cbOut ) BYTE* const pbOut, const UINT cbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeDeliverMsg);
BYTE* pbWalk = pbOut;
const BYTE* pbEnd = pbOut + cbOut;
UINT cbAdvancedBy;
HRESULT hr = S_OK;
rcbUsed = 0;
if ( !pbOut || !cbOut ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto Error;
}
(void)memset(pbOut, 0, cbOut);
// These parameters are mandatory, and if not present, we error out.
if (!(rmMsg.dwParams & RIL_PARAM_M_TYPE) || !(rmMsg.dwParams & RIL_PARAM_M_FLAGS) ||
!(rmMsg.dwParams & RIL_PARAM_M_ORIGADDRESS) || !(rmMsg.dwParams & RIL_PARAM_M_PROTOCOLID) ||
!(rmMsg.dwParams & RIL_PARAM_M_MSGLENGTH) || !(rmMsg.dwParams & RIL_PARAM_M_SCRECEIVETIME) ||
!(rmMsg.dwParams & RIL_PARAM_M_DATACODING)) {
hr = E_INVALIDARG;
goto Error;
}
// Set Type, per GSM 03.40 section 9.2.3.1
*pbWalk |= 0x00;
// RIL_MSGFLAGS_MORETOSEND, GSM 03.40 section 9.2.3.2
if (!(rmMsg.dwFlags & RIL_MSGFLAG_MORETOSEND)) {
*pbWalk |= 0x04;
}
// RIL_MSGFLAG_STATUSREPORTRETURNED, GSM 03.40 section 9.2.3.4
if (rmMsg.dwFlags & RIL_MSGFLAG_STATUSREPORTRETURNED) {
*pbWalk |= 0x20;
}
// RIL_MSGFLAG_HEADER, GSM 03.40 section 9.2.3.23
if (rmMsg.dwFlags & RIL_MSGFLAG_HEADER) {
*pbWalk |= 0x40;
}
// RIL_MSGFLAG_REPLYPATH, GSM 03.40 section 9.2.3.17
if (rmMsg.dwFlags & RIL_MSGFLAG_REPLYPATH) {
*pbWalk |= 0x80;
}
pbWalk++;
DEBUGCHK(pbWalk <= pbEnd);
// Encode the origination address
hr = EncodeMsgAddress(rmMsg.msgInDeliver.raOrigAddress, FALSE, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if (FAILED(hr)) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
// Set ProtocolID, see GSM 03.40 section 9.2.3.9
hr = EncodeMsgProtocolID(rmMsg.msgInDeliver.dwProtocolID, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if (FAILED(hr)) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
// Reconstruct DCS, see GSM 03.40 section 9.2.3.10
hr = EncodeMsgDCS(rmMsg.msgInDeliver.rmdDataCoding, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if (FAILED(hr)) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
// Encode receive timestamp
if (rmMsg.dwParams & RIL_PARAM_M_SCRECEIVETIME) {
hr = EncodeMsgTimeStamp(rmMsg.msgInDeliver.stSCReceiveTime, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if ( FAILED( hr ) ) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
}
// Encode header and body
hr = EncodeMsgHeaderAndBody(rmMsg.dwParams, rmMsg.dwFlags, rmMsg.msgInDeliver.cchMsgLength,
rmMsg.msgInDeliver.cbHdrLength, rmMsg.msgInDeliver.rgbHdr, rmMsg.msgInDeliver.rgbMsg,
&rmMsg.msgInDeliver.rmdDataCoding, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if ( FAILED( hr ) ) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
rcbUsed = pbWalk - pbOut;
Error:
return hr;
}
//
// Encode a Status message for SIM storage
//
static HRESULT EncodeStatusMsg(const RILMESSAGE& rmMsg, __out_bcount( cbOut ) BYTE* const pbOut, const UINT cbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeStatusMsg);
BYTE* pbWalk = pbOut;
const BYTE* pbEnd = pbOut + cbOut;
UINT cbAdvancedBy;
HRESULT hr = S_OK;
rcbUsed = 0;
if ( !pbOut || !cbOut ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto Error;
}
(void)memset(pbOut, 0, cbOut);
// These parameters are mandatory, and if not present, we error out.
if (!(rmMsg.dwParams & RIL_PARAM_M_TYPE) || !(rmMsg.dwParams & RIL_PARAM_M_FLAGS) ||
!(rmMsg.dwParams & RIL_PARAM_M_TGTRECIPADDRESS) || !(rmMsg.dwParams & RIL_PARAM_M_TGTSCRECEIVETIME) ||
!(rmMsg.dwParams & RIL_PARAM_M_TGTDISCHARGETIME) || !(rmMsg.dwParams & RIL_PARAM_M_TGTDLVSTATUS)) {
hr = E_INVALIDARG;
goto Error;
}
// Set Type, per GSM 03.40 section 9.2.3.1
*pbWalk |= 0x02;
// RIL_MSGFLAGS_MORETOSEND, GSM 03.40 section 9.2.3.2
if (!(rmMsg.dwFlags & RIL_MSGFLAG_MORETOSEND)) {
*pbWalk |= 0x04;
}
// RIL_MSGFLAG_CAUSEDBYCOMMAND, GSM 03.40 section 9.2.3.26
if (rmMsg.dwFlags & RIL_MSGFLAG_CAUSEDBYCOMMAND) {
*pbWalk |= 0x20;
}
// RIL_MSGFLAG_HEADER, GSM 03.40 section 9.2.3.23
if (rmMsg.dwFlags & RIL_MSGFLAG_HEADER) {
*pbWalk |= 0x40;
}
pbWalk++;
DEBUGCHK(pbWalk <= pbEnd);
// Encode the Message Reference number
if (0xff < rmMsg.msgInStatus.dwTgtMsgReference) {
hr = E_INVALIDARG;
goto Error;
}
*pbWalk++ = (BYTE)rmMsg.msgInStatus.dwTgtMsgReference;
DEBUGCHK(pbWalk <= pbEnd);
// Encode the destination address. pbMsg should be set properly by the function
hr = EncodeMsgAddress(rmMsg.msgInStatus.raTgtRecipAddress, FALSE, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if (FAILED(hr)) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
// Encode receive timestamp
hr = EncodeMsgTimeStamp(rmMsg.msgInStatus.stTgtSCReceiveTime, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if ( FAILED( hr ) ) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
// Encode discharge timestamp
hr = EncodeMsgTimeStamp(rmMsg.msgInStatus.stTgtDischargeTime, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if ( FAILED( hr ) ) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
// Encode devivery status
hr = EncodeMsgDlvStatus(rmMsg.msgInStatus.dwTgtDlvStatus, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if (FAILED(hr)) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
// Set the Parameter Indicator and encode the indicated fields
// See GSM 03.40 section 9.2.3.27
if (rmMsg.dwParams & RIL_PARAM_M_PROTOCOLID ||
rmMsg.dwParams & RIL_PARAM_M_DATACODING ||
rmMsg.dwParams & RIL_PARAM_M_MSGLENGTH) {
if ( pbWalk >= pbEnd ) {
hr = E_INVALIDARG;
ASSERT( FALSE );
goto Error;
}
*pbWalk = 0;
if (rmMsg.dwParams & RIL_PARAM_M_PROTOCOLID) {
*pbWalk |= 0x01;
}
if (rmMsg.dwParams & RIL_PARAM_M_DATACODING) {
*pbWalk |= 0x20;
}
if (rmMsg.dwParams & RIL_PARAM_M_MSGLENGTH) {
*pbWalk |= 0x40;
}
pbWalk++;
DEBUGCHK(pbWalk <= pbEnd);
// Set ProtocolID if it exists. see GSM 03.40 section 9.2.3.9
if (rmMsg.dwParams & RIL_PARAM_M_PROTOCOLID) {
hr = EncodeMsgProtocolID(rmMsg.msgInStatus.dwProtocolID, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if (FAILED(hr)) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
}
// Set DCS if it it exists. see GSM 03.40 section 9.2.3.10
if (rmMsg.dwParams & RIL_PARAM_M_DATACODING) {
hr = EncodeMsgDCS(rmMsg.msgInStatus.rmdDataCoding, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if (FAILED(hr)) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
}
// Set Msg Data
if (rmMsg.dwParams & RIL_PARAM_M_MSGLENGTH) {
// Encode header and body
hr = EncodeMsgHeaderAndBody(rmMsg.dwParams, rmMsg.dwFlags, rmMsg.msgInStatus.cchMsgLength,
rmMsg.msgInStatus.cbHdrLength, rmMsg.msgInStatus.rgbHdr, rmMsg.msgInStatus.rgbMsg,
&rmMsg.msgInStatus.rmdDataCoding, pbWalk, pbEnd > pbWalk ? pbEnd - pbWalk : 0, cbAdvancedBy);
if ( FAILED( hr ) ) {
goto Error;
}
pbWalk += cbAdvancedBy;
DEBUGCHK(pbWalk <= pbEnd);
}
}
rcbUsed = pbWalk - pbOut;
Error:
return hr;
}
//
// Fill out a BYTE array for a Raw message
//
static HRESULT EncodeRawMsg(const RILMESSAGE& rmMsg, __out_bcount( cbOut ) BYTE* const pbOut, const UINT cbOut, UINT& rcbUsed)
{
FUNCTION_TRACE(EncodeRawMsg);
HRESULT hr = S_OK;
// These parameters are mandatory, and if not present, we error out.
if (!(rmMsg.dwParams & RIL_PARAM_M_TYPE) || !(rmMsg.dwParams & RIL_PARAM_M_MSGLENGTH)) {
hr = E_INVALIDARG;
goto Error;
}
if (rmMsg.msgOutRaw.cchMsgLength > cbOut) {
hr = E_FAIL;
goto Error;
}
rcbUsed = min(cbOut, rmMsg.msgOutRaw.cchMsgLength);
memcpy(pbOut, rmMsg.msgOutRaw.rgbMsg, rcbUsed);
Error:
return hr;
}
//
// Encode an outgoing message from an RILMESSAGE to a BYTE array
//
HRESULT EncodeSMSMessage(const RILMESSAGE& rmMsg, __out_bcount( cbOut ) const LPSTR sOut, const UINT cbOut, UINT& rcbUsed,
UINT& rnGSMLength)
{
FUNCTION_TRACE(EncodeSMSMessage);
HRESULT hr = S_OK;
BYTE rgbData[MAX_MSGBUFFER];
UINT cbDataUsed;
UINT cbAddress;
// Encode the SMSC address
if (rmMsg.dwParams & RIL_PARAM_M_SVCCTRADDRESS) {
hr = EncodeMsgAddress(rmMsg.raSvcCtrAddress, TRUE, rgbData, sizeof(rgbData), cbAddress);
if (FAILED(hr)) {
goto Error;
}
DEBUGCHK(MAX_MSGBUFFER >= cbAddress);
} else {
// SMSC address isn't specified -- indicate that by a 0 length byte
*rgbData = 0;
cbAddress = 1;
}
if ( MAX_MSGBUFFER <= cbAddress )
{
hr = E_ABORT;
goto Error;
}
// Encode the rest of the
switch (rmMsg.dwType)
{
case RIL_MSGTYPE_OUT_SUBMIT:
hr = EncodeSubmitMsg(rmMsg, &rgbData[cbAddress], MAX_MSGBUFFER - cbAddress, cbDataUsed);
break;
case RIL_MSGTYPE_OUT_COMMAND:
hr = EncodeCmdMsg(rmMsg, &rgbData[cbAddress], MAX_MSGBUFFER - cbAddress, cbDataUsed);
break;
case RIL_MSGTYPE_IN_DELIVER:
hr = EncodeDeliverMsg(rmMsg, &rgbData[cbAddress], MAX_MSGBUFFER - cbAddress, cbDataUsed);
break;
case RIL_MSGTYPE_IN_STATUS:
hr = EncodeStatusMsg(rmMsg, &rgbData[cbAddress], MAX_MSGBUFFER - cbAddress, cbDataUsed);
break;
case RIL_MSGTYPE_OUT_RAW:
hr = EncodeRawMsg(rmMsg, &rgbData[cbAddress], MAX_MSGBUFFER - cbAddress, cbDataUsed);
break;
default:
hr = E_FAIL;
goto Error;
}
// GSM length is the number of characters used for the message itself (not including the SMSC address upfront)
rnGSMLength = cbDataUsed;
// Convert the byte array into the GSMHex representation (2 chars per byte)
if (!GSMToGSMHex((LPCSTR)rgbData, cbDataUsed + cbAddress, sOut, cbOut, rcbUsed)) {
hr = E_FAIL;
goto Error;
}
Error:
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -