总结&备忘:smslib&长短信

背景:

       项目中使用了开源库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 message
if (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 message
if (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秒(这个可以根据自己的场景定义分块间最大间隔时间)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值