中国移动飞信通信协议分析

  • 四月 13th, 2010

作者:刘华栋 2010.4.13
本文目的在于探讨学习,请勿用于非学习外的任何用途,否则后果自负。

出于某些需求,要用到手机短信提醒功能,自然还是免费的好。网上流传了很多版本关于飞信的通信协议,大同小异(基本都是基于2.0的,飞信现在2010协议版本为4.0),当飞信更新了一部分协议内容时,这些流行的协议似乎有些问题出现,最典型的就是:

旧版本飞信协议支持输入任何手机号码,只要是发送者好友,即可发送手机短信。
新版本飞信协议支持输入任何飞信号码,只要是发送者好友,即可发送手机短信。
新旧版本都支持发送登陆者自身手机号码为接收手机的短信。

如果我有100个飞信好友,莫非我要记住100个飞信号码?如果我要提供一个飞信接口给大伙,莫非大伙要记住他们好友的飞信号码?
当然,写本文的目的就在于从根本上解决上述两个问题(其实是一回事)。

通过对飞信协议多个版本进行了抓包分析,发现数据包格式没什么大的变化。唯一重要的变化是第五行:

M fetion.com.cn SIP-C/4.0
F:88888888
I: 10
Q: 2 M
T: sip:99999999@fetion.com.cn;p=640
//上面一行旧版本协议这里是:
//T: tel:13599999999
C: text/plain
K: SaveHistory
L: 4

这里就出现一个问题,要想发送手机短信,提交过来手机号不行,需要提交手机号对应的飞信号码才能识别,如何才能把手机号码转换为飞信号码就是解决问题的关键。经对新协议抓包分析,发现并不能直接从手机号码转换成飞信号码,但是中间有一个很不错的变量叫做”user-id”,每个手机号对应一个飞信号码,同样对应每个user-id(至于为什么会多出来一个user-id,我想可能是飞信公司准备把飞信号码当做一种商业资源来使用吧)。其实我们用户的真正的飞信号码是这个user-id,所谓飞信号码,无非是一个数字昵称(another nickname)而已。明白这些,问题就好办了:

1.发送接收者手机号码,抓包获取该号码的user-id
2.发送请求好友列表信息(登陆后自动完成);
3.匹配1user-id,对应的飞信号码(注意格式:fetion_num@fetion.com.cn)
4.发送飞信号码、短信内容,Done

具体代码省略,关键正则函数:

//获取飞信号码
function get_fetion_id($userid, $rst) {
    
preg_match("/ri=\"sip:(\d{6,10}+)@fetion.com.cn;p=(\d{0,6}+)\"
        user-id=
\"$userid/i",$rst, $matches);
    
//同理重构函数获取user-id
    
//preg_match("/user-id=\"([0-9]+)\"/i", $rst, $matches);
    
return $matches[1];
}

这样同样还会存在一个问题:给自己手机号码发送的时候转换不到自己的自己的user-id。解决办法也很简单,只需要在手机号码提交过来最初判断一下是否为登陆号码即可,如果是,取消所有转换,直接进行第4步骤即可发送。

纸上谈兵无用,演示:
Demo1:http://www.liuhuadong.com/phoneme
Demo2:http://labs.liuhuadong.com/cmcc/index.php(暂无,睡醒后继续)
QQREADERC927A243851272DC

4 引用 to “中国移动飞信通信协议分析”

  1. Gravatar Icon wei2005yh 回复说:

    如何把飞信号转换为可以直接发送的userid?就是已知飞信号码,发送短信的问题?老的2.0的协议还可以使用tel:这样的方式给手机发短信……有源码为证,不过我不太熟悉php,也可能是没看懂,源码已经发到您邮箱,希望百忙之中看一下……多谢!

  2. Gravatar Icon xhat 回复说:

    如果是已知飞信号码,直接发就可以,不用转换

  3. Gravatar Icon wei2005yh 回复说:

    不行,需要p值,我下载了contactlist.xml来获得了

  4. Gravatar Icon wei2005yh 回复说:

    sipc2.0的协议已经被飞信抛弃了,想做sipc4.0的php的飞信,做出来登陆,发短信的功能就可以了,不知道您这里有没有关于这个v4版本的详细情况?恳请老兄赐教!

给我回复