最近在工作中遇到一個(gè)比較怪異的現(xiàn)象,在某些省區(qū)與SP的短信交互存在問題,短信發(fā)送不出去。查了一下原因:SmsSendMessage參數(shù)設(shè)置的問題。
在Windows Mobile 5.0SDK的HelloSMS例子中,發(fā)送短信的代碼是這樣寫的
void SendSMS(BOOL bSendConfirmation, BOOL bUseDefaultSMSC, LPCTSTR lpszSMSC, LPCTSTR lpszRecipient, LPCTSTR lpszMessage)


{
SMS_HANDLE smshHandle;
SMS_ADDRESS smsaSource;
SMS_ADDRESS smsaDestination;
TEXT_PROVIDER_SPECIFIC_DATA tpsd;
SMS_MESSAGE_ID smsmidMessageID;

// try to open an SMS Handle
if(FAILED(SmsOpen(SMS_MSGTYPE_TEXT, SMS_MODE_SEND, &smshHandle, NULL)))

{
MessageBox(NULL,
(LPCTSTR)LoadString(ghInstance, IDS_ERROR_SMSOPEN, 0, 0),
(LPCTSTR)LoadString(ghInstance, IDS_CAPTION_ERROR, 0, 0),
MB_OK | MB_ICONERROR);
return;
}

// Create the source address
if(!bUseDefaultSMSC)

{
smsaSource.smsatAddressType = SMSAT_INTERNATIONAL;
_tcsncpy(smsaSource.ptsAddress, lpszSMSC, SMS_MAX_ADDRESS_LENGTH);
}

// Create the destination address
smsaDestination.smsatAddressType = SMSAT_INTERNATIONAL;
_tcsncpy(smsaDestination.ptsAddress, lpszRecipient, SMS_MAX_ADDRESS_LENGTH);

// Set up provider specific data
memset(&tpsd, 0, sizeof(tpsd));
tpsd.dwMessageOptions = bSendConfirmation ? PS_MESSAGE_OPTION_STATUSREPORT : PS_MESSAGE_OPTION_NONE;
tpsd.psMessageClass = PS_MESSAGE_CLASS1;
tpsd.psReplaceOption = PSRO_NONE;
tpsd.dwHeaderDataSize = 0;

// Send the message, indicating success or failure
if(SUCCEEDED(SmsSendMessage(smshHandle, ((bUseDefaultSMSC) ? NULL : &smsaSource),
&smsaDestination, NULL, (PBYTE) lpszMessage,
_tcslen(lpszMessage) * sizeof(TCHAR), (PBYTE) &tpsd,
sizeof(TEXT_PROVIDER_SPECIFIC_DATA), SMSDE_OPTIMAL,
SMS_OPTION_DELIVERY_NONE, &smsmidMessageID)))

{
MessageBox(NULL,
(LPCTSTR)LoadString(ghInstance, IDS_SMSSENT, 0, 0),
(LPCTSTR)LoadString(ghInstance, IDS_CAPTION_SUCCESS, 0, 0),
MB_OK);
}
else

{
MessageBox(NULL,
(LPCTSTR)LoadString(ghInstance, IDS_ERROR_SMSSEND, 0, 0),
(LPCTSTR)LoadString(ghInstance, IDS_CAPTION_ERROR, 0, 0),
MB_OK | MB_ICONERROR);
}

// clean up
VERIFY(SUCCEEDED(SmsClose(smshHandle)));
}

這段代碼在一般情況下是運(yùn)行正確的,對于手機(jī)與手機(jī)的發(fā)送是不存在問題的,但是與SP的交互在某些省區(qū)就存在短信發(fā)送不出去的情況。
為了更好的理解這段代碼,我們先來熟悉一下SmsSendMessage及各個(gè)參數(shù)。
SmsSendMessage
功能:Use the SmsSendMessage function to create and send an Short Message Service (SMS) message.(創(chuàng)建和發(fā)送短信,但短信發(fā)送后并不保存到發(fā)件箱中)
原型:
HRESULT SmsSendMessage (
const SMS_HANDLE smshHandle, // 調(diào)用SmsOpen時(shí)獲得的短信句柄
const SMS_ADDRESS * const psmsaSMSCAddress, //指向短信中心號碼的地址
const SMS_ADDRESS * const psmsaDestinationAddress, // 發(fā)送的目的地址
const SYSTEMTIME * const pstValidityPeriod, // 發(fā)送時(shí)間的有效期
const BYTE * const pbData, // 信息的內(nèi)容部分
const DWORD dwDataSize,// 信息內(nèi)容的長度
const BYTE * const pbProviderSpecificData, //運(yùn)營商的附加數(shù)據(jù)
const DWORD dwProviderSpecificDataSize, // 附加數(shù)據(jù)的長度
const SMS_DATA_ENCODING smsdeDataEncoding, // 短信編碼
const DWORD dwOptions, // 其他選項(xiàng)
SMS_MESSAGE_ID * psmsmidMessageID); // 用于得到系統(tǒng)回執(zhí)的信息
(具體介紹可查看http://msdn.microsoft.com/en-us/library/aa455068.aspx)
在實(shí)際應(yīng)用中短信發(fā)送不出去,但是SmsSendMessage的返回值是S_OK值。在一些文章中有人這樣認(rèn)為是短信編碼的問題造成的。
如果編碼格式不對可能造成短信中心網(wǎng)關(guān)把短信給吞掉的情況,程序雖然調(diào)用成功,但是就是目標(biāo)號碼收不到短信。函數(shù)參數(shù)中的后三個(gè)參數(shù)可以不用或設(shè)默認(rèn)值都可以。
起初我也是認(rèn)為這個(gè)地方造成的,很是興奮。短信的回復(fù)內(nèi)容恰為字母,我誤以為短信內(nèi)容此時(shí)是7-BIT的短消息,短信網(wǎng)關(guān)把短信給吞掉了,造成目標(biāo)號碼收不到短信。在練習(xí)中卻也陰差陽錯(cuò)的成功了。很高興的把理由歸到了這個(gè)地方。并這樣總結(jié):SmsSendMessage可以支持7-bit的ASCII碼的短消息,也支持16-bit的unicode的短消息。但內(nèi)容為ASCII的時(shí)候,短信編碼為 SMSDE_GSM或SMSDE_OPTIMAL,當(dāng)內(nèi)容不全是ASCII的時(shí)候,短信編碼為SMSDE_GSM或SMSDE_OPTIMAL。所以回復(fù)內(nèi)容改為漢字即可。
但是這樣對么?起初我認(rèn)為我的解釋很合理.但是我卻發(fā)現(xiàn)我的一個(gè)參數(shù)與原來的程序不一樣.
是我在嘗試中無意修改了一個(gè)參數(shù),將
tpsd.psMessageClass = PS_MESSAGE_CLASS1;
修改為了
tpsd.psMessageClass = PS_MESSAGE_CLASSUNSPECIFIED;
這是發(fā)送短信中的運(yùn)營商的指定數(shù)據(jù)TEXT_PROVIDER_SPECIFIC_DATA,它的參數(shù)psMessageClass是指
Text Short Message Service (SMS) messages with the appropriate flag can replace previously received notifications with a similar flag and originating address.
它有以下五個(gè)值:
PS_MESSAGE_CLASS0: The message should be displayed immediately but not stored. The MS shall send an acknowledgement to the service center when the message has successfully reached the MS. (被接受后立即顯示但不存儲(稱為閃信)。需要向SMSC發(fā)送確認(rèn)信息。)
PS_MESSAGE_CLASS1:The message should be stored and an acknowledgement should be sent to the Service Center when it is stored.(接收后被存儲,一旦存儲,需要向SMSC發(fā)送確認(rèn)信息。)
PS_MESSAGE_CLASS2:The message should be transferred to the SMS data field in the subscriber identity module (SIM) before an acknowledgement is sent to the Service Center.
PS_MESSAGE_CLASS3:When the message has successfully reached the destination and can be stored, an acknowledgement is sent to the Service Center.
PS_MESSAGE_CLASSUNSPECIFIED:The message Class is not set in the outgoing or incoming message. (對發(fā)出或收到的短信不進(jìn)行設(shè)置)
分析以上五個(gè)值,前四個(gè)值有一個(gè)共同的特點(diǎn),都需要向SMSC發(fā)送確認(rèn)。而最后一個(gè)值沒有設(shè)定。
這個(gè)值的改動,解決了我所遇到的問題。但究其原因,我有些想不通為什么?
但是在實(shí)際應(yīng)用中,出現(xiàn)了tmail.exe的異常。不知道是這個(gè)值的變動帶來的問題,還是實(shí)際模塊中存在的問題。還需要繼續(xù)研究一下。
如果大家有知道的,給些建議哈.
posted on 2009-03-10 14:14
Sandy 閱讀(6778)
評論(13) 編輯 收藏 引用 所屬分類:
windows學(xué)習(xí)