春暖花开
雪化了,花开了,春天来了
posts - 149,comments - 125,trackbacks - 0
 

最近在工作中遇到一个比较怪异的现象,在某些省区与SP的短信交互存在问题,短信发送不出去。查了一下原因:SmsSendMessage参数设置的问题。

Windows Mobile 5.0SDKHelloSMS例子中,发送短信的代码是这样写的

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, 
00), 
                    (LPCTSTR)LoadString(ghInstance, IDS_CAPTION_ERROR, 
00),
                    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, 0sizeof(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, 
00), 
                    (LPCTSTR)LoadString(ghInstance, IDS_CAPTION_SUCCESS, 
00),
                    MB_OK);
    }

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


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


这段代码在一般情况下是运行正确的,对于手机与手机的发送是不存在问题的,但是与SP的交互在某些省区就存在短信发送不出去的情况。

为了更好的理解这段代码,我们先来熟悉一下SmsSendMessage及各个参数。

SmsSendMessage

功能Use the SmsSendMessage function to create and send an Short Message Service (SMS) message.(创建和发送短信,但短信发送后并不保存到发件箱中)

原型

HRESULT SmsSendMessage (

const SMS_HANDLE smshHandle, // 调用SmsOpen时获得的短信句柄

const SMS_ADDRESS * const psmsaSMSCAddress, //指向短信中心号码的地址

const SMS_ADDRESS * const psmsaDestinationAddress, // 发送的目的地址

const SYSTEMTIME * const pstValidityPeriod, // 发送时间的有效期

const BYTE * const pbData, // 信息的内容部分

const DWORD dwDataSize,// 信息内容的长度

const BYTE * const pbProviderSpecificData, //运营商的附加数据

const DWORD dwProviderSpecificDataSize, // 附加数据的长度

const SMS_DATA_ENCODING smsdeDataEncoding, // 短信编码

const DWORD dwOptions, // 其他选项

SMS_MESSAGE_ID * psmsmidMessageID); // 用于得到系统回执的信息

(具体介绍可查看http://msdn.microsoft.com/en-us/library/aa455068.aspx

在实际应用中短信发送不出去,但是SmsSendMessage的返回值是S_OK值。在一些文章中有人这样认为是短信编码的问题造成的。

如果编码格式不对可能造成短信中心网关把短信给吞掉的情况,程序虽然调用成功,但是就是目标号码收不到短信。函数参数中的后三个参数可以不用或设默认值都可以。

起初我也是认为这个地方造成的,很是兴奋。短信的回复内容恰为字母,我误以为短信内容此时是7-BIT的短消息,短信网关把短信给吞掉了,造成目标号码收不到短信。在练习中却也阴差阳错的成功了。很高兴的把理由归到了这个地方。并这样总结:SmsSendMessage可以支持7-bitASCII码的短消息,也支持16-bitunicode的短消息。但内容为ASCII的时候,短信编码为 SMSDE_GSMSMSDE_OPTIMAL,当内容不全是ASCII的时候,短信编码为SMSDE_GSMSMSDE_OPTIMAL。所以回复内容改为汉字即可。

但是这样对么?起初我认为我的解释很合理.但是我却发现我的一个参数与原来的程序不一样.

是我在尝试中无意修改了一个参数,

tpsd.psMessageClass = PS_MESSAGE_CLASS1;

修改为了

tpsd.psMessageClass = PS_MESSAGE_CLASSUNSPECIFIED;

这是发送短信中的运营商的指定数据TEXT_PROVIDER_SPECIFIC_DATA,它的参数psMessageClass是指

Text Short Message Service (SMS) messages with the appropriate flag can replace previously received notifications with a similar flag and originating address.

它有以下五个值:

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发送确认信息。)

PS_MESSAGE_CLASS1The message should be stored and an acknowledgement should be sent to the Service Center when it is stored.(接收后被存储,一旦存储,需要向SMSC发送确认信息。)

PS_MESSAGE_CLASS2The 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_CLASS3When the message has successfully reached the destination and can be stored, an acknowledgement is sent to the Service Center.

PS_MESSAGE_CLASSUNSPECIFIEDThe message Class is not set in the outgoing or incoming message. (对发出或收到的短信不进行设置)

 

分析以上五个值,前四个值有一个共同的特点,都需要向SMSC发送确认。而最后一个值没有设定。

这个值的改动,解决了我所遇到的问题。但究其原因,我有些想不通为什么?
    但是在实际应用中,出现了
tmail.exe的异常。不知道是这个值的变动带来的问题,还是实际模块中存在的问题。还需要继续研究一下。

如果大家有知道的,给些建议哈.

posted on 2009-03-10 14:14 Sandy 阅读(6328) 评论(13)  编辑 收藏 引用 所属分类: windows学习

FeedBack:
# re: Windows Mobile 发送短信的问题
2009-03-10 15:26 | Herb
建议看一下短信协议smpp  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-03-16 17:08 | science
建议不要直接用api,用mapi(就是操作win mobile短信的一套接口)建一条短信放在发件箱里,然后submitmessage,让手机自己去发送。  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-04-14 22:21 | 飞飘飘
你好,请问你用过wm6的SDK吗?在这种情况下,运行这个程序就会有异常,实在不知道为什么,期待你的解答!谢谢  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-04-15 10:09 | Sandy
@飞飘飘
你好,我今天还专门试了一下wm6中HelloSMS的那个例子,没有异常啊!
WM5和WM6中两个例子的代码基本上是相同的。

在这种情况下,是不是指将PS_MESSAGE_CLASS1替换成PS_MESSAGE_CLASSUNSPECIFIED。

我分别在模拟器和真机上试验过,似乎也没有什么异常,所以还请赐教。

  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-04-18 21:45 | 飞飘飘
你好!今天我刚找到原因,我之前是在classic模拟器进行模拟,而这个程序不能用classic模拟器,而要在professional模拟器上调试,因为在classic模拟器没有radio模块,只有接收功能不能进行发送,所以出现了异常.我是刚入门,想请教一下应该如何把这个程序下载到真机上进行试验呢?谢谢 !  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-04-20 09:37 | Sandy

@飞飘飘
在真机上运行需要安装同步软件,如果你是xp系统的话,安装Active Sync同步软件, 在调试的时候,选择相应平台的device; 如果是vista系统的话,安装Microsoft Windows Mobile 设备中心6.1,即drvupdate-x86.exe.

如果只是简单的试验一下这个程序的话,安装同步软件后,只需把那个exe文件拷贝到手机上,点击该文件即可.  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-04-20 21:01 | 飞飘飘
恩,谢谢指点!
  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-05-05 11:17 | qingyuzhui
@Sandy
可是我用WM6.0运行 SmsSendMessage 返回值不对啊?什么原因啊
  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-05-05 12:44 | Sandy
@qingyuzhui

这个我建议你看一下SDK。里面有一些对返回值的说明。

这里我对SmsSendMessage说明一下它的返回值,

如果SmsSendMessage执行成功的话,它会返回S_OK ,表示该方法成功执行。
如果返回的值为E_INVALIDARG, E_OUTOFMEMORY, E_UNEXPECTED, and E_FAIL,或者为其他,可以查看一下SMS Specific Errors 和 SMS General Errors。

如果你觉得不是很明白的话,可以给我发邮件:qiyanhd@163.com

  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-06-05 15:33 | beautymind
你好我现在做短信管理软件 要将已发送短信里边的特殊短信移到我自己建的一个MenuItem下边 需要做哪些判断 用哪个接口可以实现!
我做的Mobile 5  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2009-06-08 11:15 | Sandy
@beautymind
hi, 你说的是不是将发送的特殊短信移到自己建的目录下,这个我还真的没有尝试过.
不过理论上是不是可以这样去想,按照短信存储的相关信息,将其存储到数据库中,这样,我们自己就可以查看相应的短信信息,而不在系统的收件箱里面出现.
如果还原回去的话,就把记录的相关信息插入到系统的文件夹里.

这是我自己的理解.  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2011-05-17 16:15 | futetan
兄台,太感谢你了,引你的观点做了下修改,接收到的信息格式正确了。  回复  更多评论
  
# re: Windows Mobile 发送短信的问题
2011-12-19 16:01 | 受益者
很多时候[PS_MESSAGE_CLASS1替换成PS_MESSAGE_CLASSUNSPECIFIED]好像关系不大,主要是
smsaDestination.smsatAddressType = SMSAT_INTERNATIONAL;
时手机号前加[86]国家代码,或设为SMSAT_NATIONAL。
  回复  更多评论
  

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理