总结&备忘:smslib&长短信
来源:互联网 发布:斐波那契java 编辑:程序博客网 时间:2024/06/05 10:32
背景:
项目中使用了开源库smslib-3.5.4与GSM-Modem通信实现短信收发(包括使用长短信)。使用中发现该开源库对长短信的处理存在BUG,如:
1、当长短信的REF值为0时,会当作是普通单条短信,不作拼接;
2、当收到多个手机端过来的长短信时,拼接内容会乱,或接收不到部分短信,或手机卡短信塞满;
原因:
1、org.smslib.modem.ModemGateway.readMessagesPDU()中判断是否为长短信息使用了如下逻辑:
if (msg.getMpRefNo() == 0){ // single message msgList.add(msg); incInboundMessageCount();}else{ // multi-part message ...}
因为在标准(《GSM 03.40 V7.2.0》 “9.2.3.24.1 Concatenated Short Messages”)里REF的值的取值范围为[0,255],故此处按REF值为0来判断是单条短信是错误的;
2、org.smslib.modem.ModemGateway.readMessagesPDU()中判断长短信分块是否属于同一长短信时使用了如下逻辑:
// check if current message list is for this messageif (listMsg.getMpRefNo() == msg.getMpRefNo())
这逻辑只根据短信的REF值相同就认为是属于同一长短信,这是不合理的,因为这个REF值是发送方自己选择的,当多个发送端时,很有可能存在某些发送端同时选择了同一个REF值作为它们所发长短信的REF值,服务端此时接收到这些长短信时,若按上述原逻辑,则会认为这些不同发送端过来的长短信分块都是同一长短信的分块,最后导致同分块号的分块拼接到其他发送者,或不被处理(进而产生孤儿短信)
解决:
1、修改该逻辑源码为:
if (msg.getMpMaxNo() == 0){ // single message msgList.add(msg); incInboundMessageCount();}else{ // multi-part message ...}
2、修改该逻辑源码为:
// check if current message list is for this messageif (listMsg.getMpRefNo() == msg.getMpRefNo() && listMsg.getMpMaxNo() == msg.getMpMaxNo() && listMsg.getOriginator().equals(msg.getOriginator()) && (distanceOfDate(listMsg.getDate(), msg.getDate()) < 1000*60*30))
该逻辑加入了分块必须满足以下条件才认为是属于同一长短信:
1) 标识值相等;
2) 总分块数相等;
3) 发送者相同;
4) 发送时间间隔不超过30秒(这个可以根据自己的场景定义分块间最大间隔时间)
- 总结&备忘:smslib&长短信
- 长短信
- 长短信格式
- 长短信格式
- 长短信格式
- 长短信格式
- 长短信格式
- 移动长短信
- 长短信协议头
- SGIP长短信
- 长短信格式
- 长短信格式
- 长短信拆分
- 长短信格式
- CDMA长短信问题
- CDMA长短信问题
- Android发送长短信
- 长短信发送
- 算法总结:最短路
- 转牛逼公司小头目的炫富生活
- hdoj 2566 一个人的旅行
- iOS label 加下横线
- WIFI ioctl调用(从应用程序到内核再到WIFI网卡驱动)
- 总结&备忘:smslib&长短信
- 技术人员如何提升自己的价值
- Android常用代码之普通及系统权限静默安装APK
- HDU 2602Bone Collector (01背包问题)
- Dungeon Game
- Hibernate中两种获取Session的方式
- ImportError at /polls cannot import name patterns
- C++中的static关键字的总结
- Buffer创始人谈开发:先验证,后开发!