最近一段时间工作状态很是不好,感觉脑子里的事情太多了,精力也不集中,容易烦躁。。。。
去年12月份去日本出差的时候说是去一个月,结果一下去了三个月。。。
再那边还好一些,开始的工作安排还比较满,也有一些问题需要解决,慢慢的找回了一些工作的节奏,但是过年之前去了另一个项目,我们组的一些工作一直被Block,没有什么实际性的工作需要做,渐渐的又没有工作的节奏了,在客户现场onsite的同事里面我是最闲的,领导遇到需要调查的问题居然不是第一反应让我协助调查,而是直接找offsite的同事开始调查分析,好多次都是我自己主动要一些工作进行,这个我完全理解不了,我人在现场,有丰富的资源,但是却没有分配到任何的实质性的工作。。。 这个严重的影响就是,现场的领导会觉得非常的不舒服,其他人都很忙,只有自己清闲,虽然也可以装做很忙,看文档,看代码,但是不忙就是不忙,这个怎么样也隐藏不来的,onsite成本很高,领导肯定希望把钱都用到刀刃上,但是这个工作安排的方式。。。。
说到这了顺便吐槽一下组内的工作安排。。。
我就感觉我的任务分工非常的不明确,以前还比较清楚就是主要关注Wms短信的模块。。但是后来这部分分给了别的组,一下子似乎失去了工作重心,本来以为要跟项目,但是从日本回来之后安排我不用继续跟进我之前onsite的项目了,也暂时没有什么其他的项目让我跟进,后来又调查了几天App层的方案,然后跟进了一下另一个项目的前期准备,取消后现在是运营商相关的功能实现调查。。。
这么转一圈下来,我不知道我应该关注哪个部分,没有明确的任务分工,从上倒下转了一圈,哪部分也都没看明白,哪部分也都不深入。
其实最让我接受不了的倒不是说任务安排的混乱,不利于我深入了解,而是说工作负荷太低,人都懒了,之前学习的内容,没有对应的工作实践,也都忘的差不多了,例如昨天拿到的一个新Bug,对应的都是之前看过的内容,虽然昨天晚上就已经得出结论了,但是明显感觉到对知识生疏了很多。。。
非常怀念去年上半年的工作时光,每天虽然都是解Bug,但是有稳定的项目,有很明确负责的部分,再解决问题的过程中也有汲取知识的动力,进步也是非常快的。
但是这个情况现在来看是很难有所改善了,只能是想办法从自己开始提高了,但是现在对于自己不感兴趣的部分,没有压力的情况下真的很难投入高效的学习,尤其是不知道什么时候才能够用得上的知识,更没有动力去深入总结,分析。
From: http://heikezhi.com/2011/08/04/understanding-the-git-workflow/
如果你不了解Git背后的设计初衷,那么你正处在危险境地,当然有很多参数可以强迫Git按照你的意愿行事,但这并不是Git被设计的工作方式,这就好比你可以把改锥当锤子使用,并且它也可以完成工作,但这对改锥没什么好处。
下面就让我们来看一个最常见的Git工作流是如何变得没法收拾的。
首先从Master创建一个新分支,在这个分支上完成你的工作,然后将它合并回Master分支。
大多数情况下这不会有什么问题,你都会得到你预期的结果,这是因为在你创建新分支之后,Master的代码已经发生了变化。但是有一天,你合并了一个新特性到Master,不过这次Master的代码并没有发生变化,所以同以往不同,这次Git直接将Master指向了你的特性分支上的最后一个Commit,也就是“fast forwards”(见图),而不是创建一个合并commit。
不幸的是,你的新特性分支可能会包含一些checkpoint commits,这些小的commit保证了你的工作不会意外丢失,但是也让你的代码进入了相对不稳定的状态,现在你已经无法从Master的稳定commit中区分这些不稳定的commit了,一旦需要回滚,你很容易就会陷入灾难之中。
当然你可以添加一条规则:“只要是合并新特性时,都必须使用-no-ff来强制生成一个新的commit。”这样问题就解决了,于是你继续往下走。
直到有一天你在Production发现了一个严重的bug,你需要追踪这个bug是何时被引入的,于是你试图通过bisect来找出答案,但却总是找到那些checkpoint commit,于是你放弃了,并开始手动检查。
最终你将Bug定位到了某个单独的文件上,你想通过blame来查看过去48小时这个文件发生的变化,但是你发现这是不可能的,因为blame报告这个文件已经有几个星期没人碰过了,事实证明blame报告的是你最初的commit,而不是合并时的,你的第一个checkpoint commit在几周之前改变了这个文件,但是这个改变直到今天才被合并进来。
-no-ff标识就这样神奇的破坏了bisect和blame,就像你将改锥当做锤子一样。
重新考虑版本控制
版本控制系统的出现是为了解决2个问题
第一个问题就是帮助你更好的编写代码,你需要同你的团队成员同步代码,并且备份你的工作,通过Email发送压缩文件明显不是个靠谱的办法。
第二个问题就是配置管理,这主要是针对并行开发的管理,比如你需要在开发下一个大版本的同时,继续修复当前production版本存在的bug,配置管理也可以用来查找变更,但是这对于诊断Bug用处不是很大。
通常来说,这两个目的是矛盾的。
当你为一个新特性开发原型时,你应该不断的添加checkpoint commit,尽管如此,这些commit通常会破坏测试。
在一个理想的世界中,你的版本历史中的每次变更都应该是简明并且稳定的,不应该有checkpoint commit这种东西来制造噪音,也不应该有巨无霸,比如10,000行代码的commit,干净的提交历史让你可以很容易的撤销变更,或是在分支之间使用cherry-pick,干净的提交历史也让后期的代码检查和分析变得更简单。尽管如此,维护一个干净的提交历史记录却意味着你需要等待一切都变得完美之后再进行提交。
那么我们应该选择哪种策略呢?经常性的提交,还是保证提交历史干净整洁?
如果你是在一个产品还未发布的2人创业公司工作,干净的提交历史对你带来的好处非常有限,你可以把所有的commit都扔到Master,并在任何你需要的时候进行部署。
然后随着变更的增加,以及团队规模或是你的用户基数的增长,你需要工具和技术来确保所有事情都是经过检查的,这通常包括自动化测试,代码检查,以及干净的提交历史。
特性分支看起来是个不错的选择,它们解决了最基本的并行开发问题,但是在你写代码的时候,你迟早会开始考虑最后的集成问题。
当你的项目变得足够大时,简单的分支/提交/合并策略就变得不再奏效了,作坊式的开发时代已经结束了,你需要一个干净的提交历史。
Git的革命性就在于它很好的同时解决了这2个问题,让你在分支上开发新特性时,可以随时提交你的任何变更,并且在随后合并时,你依然可以得到一个干净的提交历史,如果这是你想要的,那么你就应该遵从Git的默认设置。
Git工作流
考虑下这两种类型的分支:公共和私有
公共分支保存着这个项目的权威历史,在公共分支上,每个提交都应该是简明,原子的,并且提交信息应该准确表达变更,同事应该尽可能的保证提交是线性的,并且是永久的,公开的分支包含Master以及Release分支。
而私有分支是属于你自己的,它就相当于你解决问题时候用到的草纸。
将私有分支存在本地是最安全的,如果你需要在你的工作电话和家庭电脑之间同步,最好告诉你的同事你推送的是一个私有分支,以防止他们在这个分支上进行开发。
永远不要把你的私有分支直接合并到任何公共分支上,而应该先使用reset,rebase,squash merges或者commit amending这样的工具清理你的分支。
你可以把自己想象成一个作家,并且将每个commit看做是一本书的章节,作家不会发布第一版手稿,Michael Crichton说过,“好书不是写出来的——而是改出来的”。
如果你使用的是其它系统,你可能会觉得修改历史是不可能的,所有提交就像刻在了石头上一样,是不可改变的,按照这个逻辑,那我们就应该在文本编辑器中禁用撤销功能。
实用主义者一般会直到事情变得不可收拾之时才会注意到问题的存在,对于配置管理来说,我们关心的是全局的变更,checkpoint commit仅仅只是为了方便撤销而保存的缓冲而已。
如果你认为你的公共历史是干净的,那么fast-forward合并不仅很安全,而且很可取,他们保证版本历史是线性的并且非常容易追踪。
而-no-ff参数唯一的作用就是“文档”,有人或许会使用merge commit的消息来表示最后一次合并到production代码中的版本信息,但是这是不对的,你应该使用tag。
根据我修改的代码量,以及修改的时间跨度,还有这个分支偏离Master的程度,我设定了3中基本的工作流。
短期开发
大多数情况都是这样,我通过squash merge来完成清理工作。
假设我创建了一个特性分支,并在接下来的一个小时做了许多checkpoint 提交。
git checkout -b private_feature_branch
touch file1.txt
git add file1.txt
git commit -am “WIP”
在我完成我的工作之后,我会运行下面的命令来完成合并:
git checkout master
git merge –squash private_feature_branch
git commit -v
然后花上一分钟详细的写上这次变更的注释。
大改动
有时一个特性可能需要几天才能够完成,并且包含许多小的提交。
这时我认为我的改动将会被打碎成许多更小的改动,所以squash在这种情况下就拍不上用场了(作为我的一条经验法则,我会问自己”这样有利于代码检查吗?“)
如果我的checkpoint commit包含逻辑上的递增,我可以使用rebase的互动模式。
互动模式非常强大,你可以使用它来编辑老的commit,分割它们,重新排序,在某些情况下,你还可以压缩(squash)它们。
我会在特性分支上执行:
git rebase –interactive master
它会打开一个编辑器,每一行包含一个commit,有SHA1以及commit的message,并且每个commit后面还会跟随一个可以执行的命令列表。
默认情况,每个commit都使用‘pick’,这不会改变commit。
pick ccd6e62 Work on back button
pick 1c83feb Bug fixes
pick f9d0c33 Start work on toolbar
我将这个操作改成了squash,这就会将第二个commit压缩到第一个commit中。
pick ccd6e62 Work on back button
squash 1c83feb Bug fixes
pick f9d0c33 Start work on toolbar
当我保存并关闭之后,会出现一个新的文本编辑器提示我为这些合并后的commit填写一个commit message,然后一切就绪。
废弃旧分支
如果我的特性分支已经存在了太久时间,并且我需要合并几个分支到我的特性分支以保证它是最新的,这样事情就变得错综复杂了,这时你可以很容易的获取原始的diff并创建一个干净的新分支。
git checkout master
git checkout -b cleaned_up_branch
git merge –squash private_feature_branch
git reset
现在我就有了一个新的分支,既有最近的Master上的commit,又有我上一个分支上的工作,现在我可以手动添加并提交我的变更了。
总结
如果你没有遵从Git的默认设置,那么你应该问问自己为什么?
你应该保证公共历史是永久的,原子的,并且易于追踪,而将私有分支看做是临时的,可丢弃的。
因此,理想的工作流应该是:
- 从一个公开分支创建一个似有分支。
- 经常新的在似有分支上提交你的工作
- 一旦你的代码已经完美了,那么清除它的历史
- 合并干净的分支到你的公共分支
特别感谢@joshaber以及@jbarnette提供反馈。
————–
本文翻译自”Understanding the Git Workflow”,作者:Benjamin Sandofsky,翻译:@yuanyiz
SCCP CALLED ADDRESS GT OF SMSC(SERVICE CENTRE ADDRESS)
转自:http://whytelecom.com/content/sms-call-flow-between-gsm-and-cdma-network
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
刚才随便乱看看到的 看起来很有趣 就转来记录一下
转自:http://iammr.7.blog.163.com/blog/static/4910269920093914452407/
C没有类 这让人很疲惫 对象的说法很时髦 不就是继承封装组合人人会 右走是C++,这个大众都熟悉它 左走就是objective-c,躲在僻静僻静的麦金塔 本是同根生的C 如何高举面向对象的大旗 求同存异标新立异且听一一细分清
对象的C
是不同的C
类的处理与众不同重点要区分
不重复是我的口头禅
任何时候我只说一次告诉你我的地盘
[@begincommand] | @end就是我的指示
@interface classname 声明类
@implementation classname 实现类
@protocol interfacename 声明接口
就是这么简单,你的一定要明白
我先声明对成员变量和方法的关系有远近
成员变量大大括在我的怀
关系远近 public / protected / private 来区分
若不声明全默默受着保护
静态成员变量请不要放在此
成员方法我不太爱
前面拴着绳子置于类的变量列表外
减号就是普通函数
加号就是静态函数莫怪
函数的声明有点怪
我要一眼叫出名,包括函数名和参数名
其余的类型括起来,我有空再来慢慢看
函数名和参数名之间用:分隔开
多个参数的函数那就是更怪
逗号其实不是我的爱
后续的每个参数分隔用空白
每个参数形式如 标签:(参数类型)参数名
其实只要把函数名看作是第一个参数标签
你就能领悟其中的奥妙并在调用时喜爱
成员方法太多我才懒得区分亲疏远近
它们一律都是公之于众要好好的干活
谁若不服胆敢出头犯上
就踢出头文件打入冷宫永世不能露面试试看
所有的成员方法都是虚函数
改则重载,不改就继承
不用任何标记请放心大胆随便使用
对象的类,在继承层次上考虑才显得重要
所有的类最终都继承于NSObject
因为它给你创建自己生命的方法
不继承于NSObject的只能是接口protocol
它没有成员变量只有方法
它只有声明不用实现
这点和java很相似
当然类还有一些绝活可以让你开开眼
可以动态的扩充一个类 而不总是用继承
@interface CClassA(Category)|@end
@implementation CClassA (Category)|@end
源代码外包含该 类的头文件
就可以使用该Category中的方法
也可以动态的替换一个类
但是只限于用继承类来替换基类功能
[CInheritClass poseAsClass: [CBaseClass class]];
声明之后用基类创建的对象实际上行为都是继承类
所以一个类的完整声明如下:
@interface CClassA(Category): CBaseClass<IA,IB…>
类别,基类,接口一一具全
加上静态 虚函数
所有特性和C++均可对应
再加上所独有的特性
这一特性编译类语言很少有
设计得当完全可以实现动态调用dll切换功能
类的定义和使用,也有点怪
想想看一个对象的生命周期,该是如何办
创建很是别扭
这样就定义了一个类对象,
CClassName* pA = [[CClassName alloc] init];
能且只能返回对象指针
释放分为两种
自动释放声明后 [pA autorelease]; 以后可以不管
否则就必须配对 [pA release];
注意类的构造函数init可以捕获
但是析构函数却没有这点很让人意外
使用类也有多种情况
调用成员方法用中括号 int nRtn = [pA method:param1];
而静态成员方法不需要对象 int nRtn = [CClassName method];
调用成员变量还是C格式 pA->m_nCount = 1;
所有的类,都可以对应一个id类型
用来引用一个对象 id cur = sq;
或者用来引用一个对象指定的接口 id<IA> cur = sq;
然后就可以调用该对象的方法和指定接口方法
转自:http://blog.lytsing.org/archives/180.html
收到两条短信,现在用AT把它们读取出来。
at+cmgr=5
+CMGR:5,”REC UNREAD”,”15338896020″,”UNKNOWN NUMBER”,”N/A”,176
“0000021002020702c54ce225a8a80601c0089d00031001e801
8e2230018801780193108b09fb087b317b012b6a080162e38c8e6
3b422e07b65980162b942e872e4b3b4246f7a70500162e54bbf9a7
053f67c7e3801729f544c0b108bb423918a75d00163317a70033b0
ae07ce3e00162b943108bb4236b54158a71680162ff5a7283b423
71c33b2b71c29dd80173108b09fb087b317c1a933cb80162b943659
b6a0bb4227122e5c00306081229192611″
at+cmgr=21
+CMGR:21,”REC UNREAD”,”15338896020″,”UNKNOWN NUMBER”,”N/A”,96
“0000021002020702c54ce225a8a806014c084d00031001f8013
e20f00190017801900162dfca7004b1acb1abb4239614c67001629
63b2b12b9827ae310c001729f544c0b108bb423918a75d00163317
a70029f52e07cf0f80306081229192616″
[deli@deli example]$ ./test_pdu_decode
0000021002020702c54ce225a8a80601c0089d00031001e8018e22
30018801780193108b09fb087b317b012b6a080162e38c8e63b422
e07b65980162b942e872e4b3b4246f7a70500162e54bbf9a7053f67
c7e3801729f544c0b108bb423918a75d00163317a70033b0ae07ce3
e00162b943108bb4236b54158a71680162ff5a7283b42371c33b2b7
1c29dd80173108b09fb087b317c1a933cb80162b943659b6a0bb422
7122e5c00306081229192611
sms context == 1/2我愿意是急流,山里的小河,在崎岖的路上,岩石上经过.只要我的爱人,是一条小鱼,在我的浪花中,快乐的游来游去.我愿意是荒林,在河流的两岸
SM_ENCODING == 4
TPA == 15338896020
SCTS == 19:26:11 12/29/08
[deli@deli example]$ ./test_pdu_decode
0000021002020702c54ce225a8a806014c084d00031001f8013e20f
00190017801900162dfca7004b1acb1abb4239614c6700162963b2
b12b9827ae310c001729f544c0b108bb423918a75d00163317a700
29f52e07cf0f80306081229192616
sms context == 2/2,对一阵阵的狂风,勇敢地作战.只要我的爱人,是一只小鸟
SM_ENCODING == 4
TPA == 15338896020
SCTS == 19:26:16 12/29/08
PDU串解析
CDMA的pdu格式与GSM的相差很多,不能直接用肉眼看出来。第一条内容比较长,就拿第二条pdu串来分析吧。
1.首先将PDU串打成PDU包
将PDU串相邻的两个ascii字符拼凑成一个8bit数据
如下:
00 00 02 10 02 02 07 02 c5 4c e2 25 a8 a8 06 01 4c 08 4d 00 03 10 01 f8 01 3e 20 f0 01 90 01 78 01 90 01 62 df ca 70 04 b1 ac b1 ab b4 23 96 14 c6 70 01 62 96 3b 2b 12 b9 82 7a e3 10 c0 01 72 9f 54 4c 0b 10 8b b4 23 91 8a 75 d0 01 63 31 7a 70 02 9f 52 e0 7c f0 f8 03 06 08 12 29 19 26 16
消息传送类型: 0×00 point to point message(表示点对点消息)
下面的内容为短消息的各个字段 每个字段分为三个部分: 字段类型(ID)(8bit)、字段长度(Length)(8bit)和字段内容.
第一个字段: 00 02 10 02
0×00, 表示uTeleserviceID字段
0×02, 字段长度,该长度必须为2,否则为错误的pdu信息
字段内容为:0×1002,十进制是4098,
第二个字段:02 07 02 c5 4c e2 25 a8 a8
0×02, SMS_TL_ORIG_ADDR 表示 (短信发送地址)
0×07, 字段长度为7
字段内容: 02 c5 4c e2 25 a8 a8
只看前面几个 02 c5 4c e2的:
0000 0010 1100 0101 0100 1100 1110 0010 0010
取第一个bit 0 表示 RIL_CDMA_SMS_DIGIT_MODE_4_BIT 是4bit压缩
第二个bit 0 表示 RIL_CDMA_SMS_NUMBER_MODE_NOT_DATA_NETWORK
下来8个bit 是 00 0010 11 = 11,表示号码长度 为11
由于是4bit压缩 ,后面44个bit(4*11)表示号码,解析出来是15338896020
第三个字段: 06 01 4c
表示SMS_TL_BEARER_RPLY_OPT
第四个字段:08 4d 00 03 10 01 f8 01 3e 20 f0 01 90 01 78 01 90 01 62 df ca 70 04 b1 ac b1 ab b4 23 96 14 c6 70 01 62 96 3b 2b 12 b9 82 7a e3 10 c0 01 72 9f 54 4c 0b 10 8b b4 23 91 8a 75 d0 01 63 31 7a 70 02 9f 52 e0 7c f0 f8 03 06 08 12 29 19 26 16
0×08, 表示SMS_TL_BEARER_DATA字段(短信内容)
0x4d,字段长度为77
这个字段也分成各个子字段:
第一子字段: 00 03 10 01 f8
0×00 Mesage Id
0×03 内容长度
10 01 f8 === 0001 0000 0000 0001 1111 1000
0001 表示 DELIVER 短信
0000 0000 0001 1111表示 message id.
紧接后面的 1, 表示HEADER_IND
第二个子字段:01 3e 20 f0 01 90 01 78 01 90 01 62 df ca 70 04 b1 ac b1 ab b4 23 96 14 c6 70 01 62 96 3b 2b 12 b9 82 7a e3 10 c0 01 72 9f 54 4c 0b 10 8b b4 23 91 8a 75 d0 01 63 31 7a 70 02 9f 52 e0 7c f0 f8
0×01, 字段类型
0x3e(62),字段长度
20 f0 01 === 0010 0000 1111 0000 0000 0001
0×20 的前5个bit为00100, 为0×04, 表示短信编码方式为RIL_CDMA_SMS_ENCODING_UNICODE (UNICODE)
0×20 的后3个bit, 0xf0的前5个bit,为 000 1111 0, 即0x1e (30),表示有30个UNICODE 字符。0xf0的后3个bit,0×01的8个bit,再加上0×90的前5个bit,
0000 0000 0011 0010 拼成一个16位数是 0×0032 表示字符 :2,在vim下了解一个字符的16进制码很简单,光标在该字符,按ga,底端显示结果如下:
依次下去,内容就是上面运行./test_pdu_decode 的结果: 2/2,对一阵阵的狂风,勇敢地作战.只要我的爱人,是一只小鸟
第三个子字段: 03 06 08 12 29 19 26 16
这是一个时间戳字段: 08年12月29号19时26分16秒(短消息发送时间)
字符串分析结束。当然,还有很多可选项在这条短信没有加上,更完整的SMS格式,请参考CDMA SMS standard on 3GPP2 website.
实际编码时,一个while循环遍历,再加上switch简单的状态机即可。
长短信何在?
用的这个模组,不支持长短信,厂家回答“作了预处理,把User Data Header去掉了,因为客户一般不愿意自行处理这个User Data Header,他们只要内容、号码等其它信息。所以,模块送出的PDU中不含有User Data Header。”
为实现长短信的拆分和组合功能,终端应支持 IS637C 协议中关于长短消息处理的参数 HEADER_IND,以及在短消息数据中增加对 User Data Subparameter 参数增加用户数据消息头(User Data Header)和短信拆分、组合的处理。HEADER_IND 为消息头标识位,用于指示 User Data Header 是否包含消息头, 若包含消息头则 HEADER_IND 设置为’1’,否则设置为’0’。具体的拆分与组合,请参考IS637C,或 《中国电信CDMA终端需求规范-SMS分册-V1.0》。需要说明的是,对长短信的处理,有的CDMA模组厂家为了让用户省事,帮你处理了用户数据头,正如前面所看到的,自动加上(1/2), (2/2)等,若想自己手动解析,务必跟模组厂家沟通确认好。
转自:http://blog.lytsing.org/archives/203.html
这里用的模组是 via威盛的cdma。首先,设置短信通知格式:
AT+CNMI=2,1
用一cdma手机给模组发一条彩信,由于URL 链接较长,网络可能会连续发送多条(常见是 2 条)Wap Push 短信,应根据长短信标准拼接后再做进一步处理。
+CMT:”RAM”,4,186,”000002fdea020602069966084006010008a8000310f130018e046
000188035000c2820c0008008fc02e11a4189185c1c1b1a58d85d1a5bdb8bdd9b990b9d
d85c0b9b5b5ccb5b595cdcd859d9402d21ebe12320a61113daddde108ccd5b191490402
36420da1d1d1c0e8bcbcc4c0b8c8ccd0b8c4ccdcb8c4c4e8e0c0e0c0bddd85ccbd113da
ddde108ccd5b1914904022016040c0a8c02243600c4cccce4c8e0dcc4c8d0d402280030
60907031436470a01400e06040d32cc1080″
+CMT:”RAM”,5,63,”000002fdea020602069966084006014c082d000310eb9001130088
00188035000850020000806023808a3dc003060907031436470a01400e06040d32cc1080″
分析一下第一条:
teleserviceId为65002,就可以判断这时一条彩信通知,GSM的是通过分析端口号来做判断。进一步分析,提取到 TP_UD为:
00 03 10 06 A0 01 85 04 18 00 10 01 1F 80 5C 23 48 31 23 0B 83 83 63 4B 1B 0B A34B 7B 71 7B B373 21 73 BB 0B 81 73 6B 6B 99 6B 6B 2B 9B 9B 0B 3B 28 05 A4 3D 7C 24 64 14 C2 227B 5B BB C2 1199 AB 63 22 92 08 04 6C 84 1B 43 A3 A3 81 D1 79 79 89 81 71 91 99 A1 71 89 99 B971 89 89 D1 C181 C1 81 7B BB 0B 99 7A 22 7B 5B BB C2 11 99 AB 63 22 92 08 04 40 2C 08 18 15 18 04 48 6C 01 8999 99 C9 91 C1 B9 89 91 A1 A8 04 50
Wap push短信 PDU 中的 User data,按照短信标准解析,前面部分是 Header信息,如 Msgid、Num_field 等,后面部分是 Chari 内容。Chari 内容需要再进一步解析,中国电信的 Wap Push 短信PDU 中的 User data 里的 Chari 也分为两部分,前半部分是 Header 信息,类似于 User data的 Header 信息,后面部分数据才是 WDP 数据,需要按照 WDP 协议(Wireless Datagram Protocol)进行解析。
WDP
Msg Indetifier:
SUBPARAMETER_ID 8 0000000
SUBPARAM_LEN 8 00000011
MESSAGE_TYPE 4 0001 (Deliver) /0010 (Submit)
MESSAGE_ID 16 -Generated -
HEADER_IND 1 0
RESERVED 3 000
User Data
SUBPARAMETER_ID 8 00000001
SUBPARAM_LEN 8 Number of Octets in this Sub Parameter, not including SUBPARAMETER_ID and SUBPARAM_LEN
MESSAGE_ENCODING 5 00000
MESSAGE_TYPE 0 Ignored
NUM_FIELDS 8 This field shall be set to the number of characters included in this subparameter.
CHARi Variable Characters. This shall include NUM_FIELDS occurrences of this field
RESERVED 0-7 All zeroes used for padding.
(This field shall contain the number of bits required to make the entire subparameter an integer number of octets in length.
CHARi
MSG_TYPE 8 00000000
TOTAL_SEGMENTS 8 Total number of segments
SEGMENT_NUMBER 8 The Segment Number
DATAGRAM (NUM_FIELDS – 3)*8 Segmented WDP Datagram
WDP Datagram Segment
SOURCE_PORT 16 Source Port
DESTINATION_PORT 16 Destination Port(2948)
DATA N*8 N bytes of Data from the Layer above WDP
按照上面的格式,解析CHARI就是
00 02 00 23 F0 0B 84 69 06 24 61 70 70 6C 69 63 61 74 69 6F 6E 2F 76 6E 64 2E 77 61 70 2E 6D 6D73 2D 6D 65 73 73 61 67 65 00 B4 87 AF 84 8C 82 98 44 4F 6B 77 78 42 33 35 6C 6452 41 00 8D 9083 68 74 74 70 3A 2F 2F 31 30 2E 32 33 34 2E 31 33 37 2E 31 31 3A 38 30 38 30 2F77 61 73 2F 444F 6B 77 78 42 33 35 6C 64 52 41 00 88 05 81 03 02 A3 00 89 0D 80 31 33 33 39 3238 37 31 32 3435 00 8A
00 MSG_TYPE
02 TOTAL_SEGMENTS
00 SEGMENT_NUMBER
23 F0 SOURCE_PORT
0B 84 DESTINATION_PORT
69 06 24 61 70 70 6C 69 63 61 74 69 6F 6E 2F 76 6E 64 2E 77 61 70 2E 6D 6D73 2D 6D 65 73 73 61 67 65 00 B4 87 AF 84 8C 82 98 44 4F 6B 77 78 42 33 35 6C 6452 41 00 8D 9083 68 74 74 70 3A 2F 2F 31 30 2E 32 33 34 2E 31 33 37 2E 31 31 3A 38 30 38 30 2F77 61 73 2F 444F 6B 77 78 42 33 35 6C 64 52 41 00 88 05 81 03 02 A3 00 89 0D 80 31 33 33 39 3238 37 31 32 3435 00 8A DATA
这是第一条的 DATA,同样分析第二条的 TP_UD为:
00 03 10 06 A0 01 0A 00 40 00 10 0C 04 70 11 47 B8
CHARI为
00 02 01 80 8E 02 28 F7
DATA为80 8E 02 28 F7
和第一条合并起来,那么DATA就是
69 06 24 61 70 70 6C 69 63 61 74 69 6F 6E 2F 76 6E 64 2E 77
61 70 2E 6D 6D73 2D 6D 65 73 73 61 67 65 00 B4 87 AF 84 8C 82 98 44 4F 6B 77 78 42 33 35 6C 6452 41 00 8D 9083 68 74 74 70 3A 2F 2F 31 30 2E 32 33 34 2E 31 33 37 2E 31 31 3A 38 30 38 30 2F77 61 73 2F 444F 6B 77 78 42 33 35 6C 64 52 41 00 88 05 81 03 02 A3 00 89 0D 80 31 33 33 39 3238 37 31 32 3435 00 8A80 8E 02 28 F7
61 70 70 6C 69 63 61 74 69 6F 6E 2F 76 6E 64 2E 7761 70 2E 6D 6D73 2D 6D 65 73 73 61 67 65 00 == application/vnd.wap.mms-message
B4 87: Push Flags: 87
AF 84: X-Wap-Application: 04
8C 82: X-Mms-Message-Type: m-notification-ind
98 44 4F 6B 77 78 42 33 35 6C 6452 41 00 Transaction-ID: DOkwxB35ldRA
8D 90 : X-Mms-mms-version : 1.0
83 68 74 74 70 3A 2F 2F 31 30 2E 32 33 34 2E 31 33 37 2E 31 31 3A 38 30 38 30 2F77 61 73 2F 444F 6B 77 78 42 33 35 6C 64 52 41 00 Content-location:http://10.234.137.11:8080/DOkwxB35ldRA
88 05 81 03 02 A3 00 expirty:
89 0D 80 31 33 33 39 3238 37 31 32 3435 From: 1339287124
8A80 message-class:”personal”
8E 02 28 F7 message-size:
注: B4,AF,8C,98 等,是高位加1(0×80)之后的content type.
转到Tele-Baseband组已经将近2个月了,这两个月中间夹杂着烦人的找房子,搬家等琐碎杂事。不过还是磕磕绊绊看了不少3Gpp协议以及AMSS代码的内容。
最大的感触就是QualComm的AMSS Modem部分的协议栈真TM复杂 3Gpp协议真TM复杂!!
其实之前工作中就多多少少看过一些 也对这部分非常感兴趣 所以成立Baseband组的时候 我就到了这个组工作
但是真正接触到了深层的协议内容和对应的协议栈实现之后才发现之前看到的是多么的肤浅,比如说就一个简单的注网流程,就能让我们很多人搞很久还没有完全理清思路。。。各种情况,各种条件,各种流程。。。
这两个月最大的体会是 现在自己的水平还是太差劲了,看AMSS代码感觉比较吃力 AMSS内部的各种宏定义,结构体 简直让人崩溃,对C的运用和理解还是有很大缺陷的,在基本功方面还有很长的路要走。
对于协议内容的理解也很不到位,其实到现在为止还没有真正静下心来认真的去阅读理解协议的内容,还是有些浮躁,遇到不明白的问题没有静下心来啃下去的耐心,总会烦躁,然后看不下去。。。
总之 对于这段时间的工作状况还是不太满意吧,觉得还有很多可以提升的空间 尤其是现在的工作内容很多东西需要静下心来才能啃得动的硬骨头啊
最近一些烦人的事情也都处理的差不多了 接下来的时间里 努力安心学习吧
昨天朋友不小心把我刚给他越狱的4.3的iPhone 直接用iTunes update了 这下杯具了 4.3.4只有不完美越狱 不完美越狱不适合不会折腾的朋友使用啊
满怀忧郁的上谷姐小搜一下 眼前一亮 似乎可以降级!!
于是从昨晚开始了蛋疼的降级之旅。。。 。。。
为了查询在cydia备份的shsh装了小雨伞 然后save一下 猛然看到4.3.3的SHSH一阵狂喜 apple还没关闭备份!!! 赶紧下载准备降级。。。
无奈下载速度不给力 600M下了2小时!!
。。。画圈圈2小时。。。。
兴致冲冲的去恢复4.3.3固件 发现报错。。。无法恢复到4.3.3
难道就差2小时apple就把4.3.3的SHSH毙掉了~?
幸亏备份了。。。于是打开小雨伞开始SHSH欺骗。。。果断出现20错误。。还是不让刷。。
无奈问姑姐 说要改host好用。。于是添加
74.208.105.171 gs.apple.com
再刷~!!
终于成功绕过apple验证开始走进度条 心里那个美啊~~
开始等待教程里说的10xx错误提示 果然没一会就出现了错误提示 也没仔细看直接打开小雨伞 退出恢复模式。。。
iphone开始重启。。。又进入恢复模式。。。再点退出。。再进入恢复模式。。。杯具了。。。
按照网上说的下载了传说中的fixrecovery43程序 还是不行。。难道真杯具了??
再恢复固件~ 仔细观察错误提示。。3194错误。。
继续姑姐 原来是要用redrsn0w引导进入DFU才能成功恢复。。。
Fix: 需要用如下Host:74.208.10.249 gs.apple.com 才会成功出现10xx错误
果断下载redsn0w引导DFU 开始恢复 终于成功看到了1013错误 心里那个激动啊~
打开fixrecovery43程序 然后操作机器进入DFU模式(忽略屏幕显示 按照红雪的提示顺序操作就OK了)
重启。。。
终于看到了久违的锁屏界面!!激动 各种激动!!
然后就是常规越狱 装软件 搞定收工 ~~~~~
一直以来都希望可以找到一个使用起来简单功能也不需要太强大的标记语言用来写Blog和简单文档
今天发现了MarkDown然后发现了VimRePress强大的Vim Blog插件
这篇文章就是用VimRePress写成的
测试一下Markdown效果:
# H1
H1
##H2
H2
###H3
H3
####H4
H4
#####H5
H5
######H6
H6
1. item1
* item2
+ item3
- item4
- item1
- item2
- item3
- item4
* item1
* item2
* item3
* item4
- item1
- item2
- item3
- item4
这些对于我这种不要求太多的用户已经够了。。。呵呵
更多的功能以后挖掘~!
