众所周知,现在大部分的好手机都是GSM/WCDMA制式的,CDMA/EVDO在国内基本上没有什么好看兼好用的机器。偶尔有些好一点的WCDMA机型,让电信的大爷们一“定制”,立刻变得歪瓜裂枣巨丑无比,让我深深怀疑自己的审美观价值观人生观是否正确并代表先进的生产力方向。
众里寻他千google,终于找到了一款外形和配置还算说得过去的机型。三星的i500。但很遗憾的是,这款机型国内并没有引进,某宝上买到的,都是美版的机子。写号倒不是很麻烦,作为一名程序猿来说都是手到擒来的活儿。可水货机始终不能接收彩信,却是一直困扰很多水货机用户的大问题。
虽然彩信是上个世纪的东西了,但日常生活中还是用得比较多的。比如我,虽然一般是不发彩信的,但经常会收到电信或其它商家发送的彩信,有些网上的信息比如优惠券,也是以彩信的形式发送的。作为一项手机功能,用不着的时候无所谓,但一旦用着了却不能用,就很让人郁闷了。
我一直坚持的生活原则就是,宁可千日不用,但不能一日没有。。。。。。
于是,经过N天和N元的努力和尝试,终于解决了i500 CDMA水货机的彩信接收问题。目前测试的结果,有很多朋友已经可以完美接收彩信。相关补丁已发布在diypda的i500版块。有使用i500的iteyer可前去围观。
本机环境:三星i500 showcase,美版MIUI.us 1.12.9 for i500 fascinate。
注:虽然只是针对i500定制,但从理论上来说,这个解决方案对所有的水货机均应适用。
1、不能接收彩信的原因
在大量搜索网上资料的基础上,经过几天的测试和分析,找到了不能接收彩信的初步原因。
彩信,按照电信规范,是分两步发送的:
第一步,发送WAP-PUSH格式的短信通知,该短信通知含有一个url,该url指向彩信内容的存储地址。
第二步,手机解析出这个url,向url发送获取请求,下载彩信内容到本地,完成彩信的接收。
向手机发送彩信之后,手机上没有任何的反映,说明第一步的彩信通知都没有接收到。
写了一个receiver,拦截系统中广播的android.provider.Telephony.WAP_PUSH_RECEIVED消息,结果没有收到这个广播。证明彩信通知并没有上传到app应用层,那么有可能在framework框架层,彩信通知就被拒绝了。
在receiver中添加android.provider.Telephony.SMS_REJECTED,收到了系统广播的消息。说明彩信通知确实是被framework层给reject了。
取出/system/framework/framework.jar,解压出classes.dex,对dex文件进行baksmali,再对照android系统源码进行流程分析(虽然只是简单的一句话,但确实够我忙活了一段时间。。。。。。),最终确定,问题在com.android.internal.telephony.cdma.CdmaSMSDispatcher.smali中。
对照android源码,找出问题的关键代码段:
if (SmsEnvelope.TELESERVICE_WAP == teleService) {
return processCdmaWapPdu(sms.getUserData(), sms.messageRef, sms.getOriginatingAddress());
}
查找smali中对应的TELESERVICE_WAP,发现其设定的值是0x1004,换算成10进制就是4100。
修改CdmaSMSDispatcher.smali,使之在返回sms rejected的原因时,填入彩信通知的TeleServiceId,发现电信的TeleServiceId确实是65002,中国电信CDMA终端规范也证实了这个判断。
那么原因找到了,由于TeleServiceId的不同,导致手机自带的美版ROM无法识别65002的电信Id,所以拒绝接收彩信通知。
2、彩信接收解决方案
找出原因来了,当时我就想,这应该就比较简单了吧。。。。。。
2.1 修改TeleServiceId
定位CdmaSMSDispatcher.smali中判断TeleServiceId的语句:
const/16 v10, 0x1004
把const/16 0x1004(4100)修改成const 0xfdea(65002),使之识别出这是一个WAP-PUSH,进而转入processCdmaWapPdu流程,处理彩信通知的pdu。
编译所有的smali文件,更新classes.dex,替换本机中的framework.jar,重启手机。
怀着激动的心情发送彩信,鸡动等待。。。。。。终于等来了。。。。。。“您的手机终端不支持接收彩信,请到mmbox.vnet.cn中提取”。。。。。。
2.2 修改pdu处理流程
问题一定出在processCdmaWapPdu这个方法里。又经过了一段时间的调试和分析(又是简单的一句话,背后是N个小时的连续奋战和N元钱的彩信发送费用。。。。。。),终于发现,pdu解析有问题。
processCdmaWapPdu传入的第一个参数,sms.getUserData(),获取的是pdu中的包括msg identifier在内的完整userData,而processCdmaWapPdu中的代码,对传入的参数是按照CHARi来进行处理的,所以导致获取的totalSegments和segment完全是错的,系统认为收到的彩信通知只是一个片断,所以把这个片断存入数据库,等待后面的片断。可后面永远都不会再有任何相关的片断了。。。。。。
wdp数据规范,请自行围观wap-259-wdp-20010614-a section 6.5。
解决方案用java写出来是这样的:
byte[] userData = sms.getUserData();
BitwiseInputStream bis = BitwiseInputStream.new(userData);
bis.skip(69);
userData = bis.readByteArray(userData.length * 8 - 72);
processCdmaWapPdu(userData,......)
把byte[]数组的userData转化成bit流,跳过最前面的69个bit(头部数据),取bit流(CHARi数据),扔掉最后的3个bit的000填充位,把取到的bit流再转化成byte[]数组。
然后,把这段java代码人肉翻译成dalvik虚拟机的字节码。。。。。。。
move-object/from16 v11, v10 # v10: userData
array-length v11, v11 # v11: userData.length
new-instance v12, Lcom/android/internal/util/BitwiseInputStream;
invoke-direct {v12, v10}, Lcom/android/internal/util/BitwiseInputStream;-><init>([B)V # v12: bis
const/16 v8, 0x45
invoke-virtual {v12, v8}, Lcom/android/internal/util/BitwiseInputStream;->skip(I)V
mul-int/lit8 v11, v11, 0x8
add-int/lit8 v11, v11, -0x48 # userData.length*8 - 72
invoke-virtual {v12, v11}, Lcom/android/internal/util/BitwiseInputStream;->readByteArray(I)[B
move-result-object v10
编译,替换,重启,搞定。
事后,我有一点点小纳闷,这套原始代码是美版ROM用的,难道美帝国主义CDMA运营商的彩信,传过来的userData,直接就是CHARi吗,不包括头部的数据?否则按照ROM中的代码,他们也肯定是无法接收彩信的。这个问题看来还要美帝自己来回答了。我们自己的好用就行,不去解放水深火热受剥削受压迫中的美国人民了。。。。。。
3、自动接收和发送彩信
搞定了彩信的接收,现在发送和接收都没有问题了。但还有一个小小的缺憾,就是发送和接收彩信时,需要先手动连接3G,不能做到自动收发。
3.1 不能自动收发的原因
经过一段时间的研究(这个研究时间倒不是很长,比上面研究彩信接收的时间短多了),发现在收发彩信时,系统会自动进行3G网络连接,然后另起一个线程收发彩信。
但关键问题是,3G网络连接是需要时间的,在ppp拨号的客户端还在和服务端卿卿我我互传数据包确认关系的时候,收发彩信的线程就已经开始工作了,所以,在连接10.0.0.200的MMSC时,当然是会被refuse的,然后程序抛出ioexception异常,收发事务被标记失败,最后系统断开3G连接。彩信的收发企图就这样被扼杀了。
3.2 解决方案
解决方案有很多种,我采用的是:
在getPdu和sendPdu这两个方法的最前部,加入ensureRouteToHost方法(android 2.3.3源码里是调用这个方法的,但MIUI.us的源码里却没有调用,原因未知),同时修改ensureRouteToHost,加入一个带有超时退出的循环,判断requestRouteToHost的值。
如果3G尚未连接,就sleep(1000)之后再试,直到从route上判断3G建立连接成功,退出ensureRouteToHost,进入收发彩信的流程。
如果60秒内3G仍未成功建立连接(要么信号不好,要不就是你欠费了。。。。。。),抛出ioexception异常,通知系统收发彩信失败,系统自动进入内置的重试排期计划。
由于这种循环写起来比较麻烦,所以没有写java。。。。。。直接写dalvik字节码:
const/16 v10, 0xa
:cond_4
add-int/lit8 v10, v10, -0x1
if-eqz v10, :cond_5
invoke-virtual {v0, v7, v1}, Landroid/net/ConnectivityManager;->requestRouteToHost(II)Z
move-result v4
if-nez v4, :cond_3
const-wide v11, 0xea60
invoke-static {v11, v12}, Ljava/lang/Thread;->sleep(J)V
goto :cond_4
:cond_5
目前在我本机测试的情况,可以完美收发彩信。在3G关闭的情况下,发送和接收彩信,系统可自动连接3G,收发成功后自动断开,极大地满足了本人的完美主义倾向和老清新风格。。。。。。
分享到:
相关推荐
"cdma水货手机写号软件"是指针对非原装或非运营商定制的CDMA手机,用于将电信运营商的网络识别信息写入手机硬件中的软件工具。这种写号过程也被称为“烧号”,因为它是将数据永久性地写入手机的某个特定存储区域。...
在droidx经过写号能够上网以后,通过以下步骤可以实现彩信的发送: 1、拨##7764726+拨号键,输入6个0的spc密码,进入收编模式 2、选“10 HTTP proxy settings”,设置“HTTP proxy"为10.0.0.200,"HTTP port"为80,...
水货CDMA手机上EVDO用的PRL文件
这个软件是水货CDMA手机用户的重要资源,因为它允许用户在不经过官方渠道的情况下,对手机进行个性化设置和功能调整。 CDMA Workshop 3.3 的主要功能包括: 1. **写号(Programming)**:这是软件的核心功能,可以...
《CDMA Universal Unpacked 3.1.4:解锁水货CDMA手机的必备利器》 在移动通信领域,CDMA(Code Division Multiple Access,码分多址)是一种广泛使用的无线通信技术,尤其在北美和亚洲的部分地区。然而,对于购买了...
对于使用非原装或者水货CDMA手机的用户来说,“烧号”或“写号”是必不可少的操作步骤,以确保手机能够接入网络。本文将详细解析“UniCDMA”的最新版本3.1.4,这个强大的烧号工具及其在EVDO设备中的应用。 首先,...
水货投影机指的是未通过正常海关渠道进入中国市场的投影设备,这些产品可能避开了关税,或是因为不符合国内标准而无法正规进口。水货投影机可能存在品质隐患,因为它们可能缺乏针对中国市场定制的功能,并且通常不...
对于消费者来说,购买水货手机需谨慎,因为市场中充斥着翻新机和克隆机。即使购买水货,也需要辨别真伪,确保交易的诚信。尽管商家会在门口挂出“诚信经营”等标语,但市场中的欺诈行为仍需消费者自行防范。 总的来...
然而,由于部分不诚信的经销商可能会销售翻新机或非原装手机,导致水货手机的声誉受损,被误认为质量较差。 购买水货手机时,消费者需要注意保修问题。一般来说,水货手机的保修通常由销售商负责,而非厂家。某些...
水货手机之所以受欢迎,主要是因为价格相对较低,原因包括中国较高的关税和不同地区的销售策略差异,如保修政策和地域经济发展水平。 【水货手机市场结构】 中国水货手机市场的壮大,除了价格优势外,还因为大陆...
三星手机水货和行货验证及编码检测方法学习 一、水货的定义和特点 水货不是一个专业词语,没有一个标准定义。一般认为,走私进来的没有缴纳关税的就是水货。但是,这个定义也不准确。我们认为,水货是指本不应该在...
不法商家可能会通过虚假标称容量、使用次品芯片等方式来降低成本,出售“水货”(即非正规渠道或质量不达标的产品)。 【描述】提到的“辨别水货行货 机芯查看”是测试工具的关键功能之一。机芯是U盘内部的核心部件...
在华强北,购买水货手机需要谨慎,因为市场上充斥着价格竞争、翻新机和克隆机。消费者购买时需辨别真伪。商家们虽然标榜诚信经营,但市场环境复杂,假货问题难以避免。在远望数码商城二楼,有3000多个档口,每天上午...
1. 港行:源于香港,不能在大陆保修,外观与行货相似,可能由天津或深圳生产,也可能为原产韩国。 2. 欧水(水改):来自欧洲的手机经过软件汉化,硬件质量通常不逊于行货。 3. 马来行:源自马来西亚的行货。 4. ...
3. **验证硬件信息**:确保手机背面白色标签上的机壳串号与待机状态下输入#06#看到的主板串号一致,这能防止购买到翻新机。同时,检查包装盒上的串号也应该与两者相符。 4. **检查电池细节**:原装BL-5C电池在触点...
购买水货手机时,消费者应留意一些特征,如水改机通常不带anycall标识,而是显示SAMSUNG;电池和配件标签为外文,说明书印刷质量粗糙,甚至与手机功能不符。此外,水改机通常只有线充,而非坐充,但商家可能会附带...