自制应用层协议的编写
近日编写了一个手机的灯控系统:
因为添加了许多以前不具备的功能,并且为了数据传输更加稳定,格式更加规范,并且为了以后再进行同类项目的格式统一,本次特地根据计算机网络,在已有的协议HipulseU基础上进一步改造,自制了一套应用层的协议。
首先本套协议的格式定义如下:
协议格式:
SOI7EH起始位标志1字节ASCII: 7EH
VER10H1字节ASCII: 31H,30H
ADR01H1字节ASCII:30H,31H
CID1命令 41H 运行控制命令
42H配置文件读写命令
43H时钟控制命令
44H写EEPROM命令
45H写文件名
CID2辅助命令1字节
----------------------------------------------------------------------------------------------------------------------
CID1=41H时运行命令
CID2:
10H:参数配置信息n条每条14字节HEX(28字节ASCII码)
13H:参数运行EEPROM中的配置信息开机缺省。
14H:参数运行CID1=45H中指定的文件。
20H:停止命令
----------------------------------------------------------------------------------------------------------------------
CID1=42H时写配置文件
CID2:
00H:~FEH写配置文件
FFH:写配置文件,续写配置文件结束
CID1=43H:时钟
CID2:
00H:写时钟命令格式:年-月-日-星期-时-分-秒 (分别为两个字节ASCII码)
01H:读时钟命令格式:年-月-日-星期-时-分-秒
02H:设置开机关机时间
格式开始:(年-月-日-参数-时-分-秒)
结束:(年-月-日-参数-时-分-秒)
参数:两字节ASCII码
D7D6D5 D4 D3D2 D1 D0
011 1 11 1 1
星期日六五四三二一
10000 0 00
年月日十分秒
111
----------------------------------------------------------------------------------------------------------------------
CID1=44H时向EEPROM写配置信息
CID2:
00H:向EEPROM写配置信息
----------------------------------------------------------------------------------------------------------------------
CID1=45H:文件名
CID2:
00H:文件名(写入或运行的文件名,1字节)
----------------------------------------------------------------------------------------------------------------------
CID1=46H:预览设置
CID2:
00H: 1倍
01H: 10倍
02H:100倍
03H:1000倍
----------------------------------------------------------------------------------------------------------------------
LENGTH 2字节长度先传高字节再传低字节
其中:校验码:LCHKSUM=D15~D12
长度标示码:LENID=D11~D0表示INFO中传送的ASCII码字节数
校验码计算:D11~D8+D7~D4+D3~D0,求和后模16余数取反加1
INFO数据格式
COMMAND INFO
CHKSUM数据格式
CHKSUM的计算是除SOI,EOI和CHKSUM外,其它字符按ASCII码值累加求和,所得结果模65536余数取反加1
EOI 0DH结束码
响应信息
SOI7EH起始位标志1字节ASCII: 7EH
VER10H1字节ASCII: 31H,30H
ADR01H1字节ASCII:30H,31H
CID160H
CID2RTN
LENGTH2字节长度先传高字节再传低字节
其中:校验码:LCHKSUM=D15~D12
长度标示码:LENID=D11~D0表示INFO中传送的ASCII码字节数
校验码计算:D11~D8+D7~D4+D3~D0,求和后模16余数取反加1
INFO数据格式
DATA INFO
CHKSUM数据格式
CHKSUM的计算是除SOI,EOI和CHKSUM外,其它字符按ASCII码值累加求和,所得结果模65536余数取反加1
EOI 0DH结束码
RTN:
00:正常
01:VER错
02:CHKSUM错
03:LCHKSUM错
04:CID2无效
05:命令格式错
06:无效命令
E0:地址错
E1~EFH:其它错误
12H:参数文件名文件中存配置文件名每个配置文件名1字节(ASCII两字节)
11H:参数文件名每个1字节(两字节ASCII码)
协议中的所有内容都是把一字节的内容,用两字节的ascii码来替换,例如原本的内容是一字节0x2f,最终会被替换为
0x32 0x46(2的ascii码是0x32,f的ascii码是0x46)
由于本次使用的是Android编程所以最终协议被封装成java包,
首先定义数据格式类把要传输的数据定义为Data类:
publicclassData{privatebyte[]sol;privatebyte[]eol;privatebyte[]ver;privatebyte[]adr;privatebyte[]cid1;privatebyte[]cid2;privatebyte[]lenid;privatebyte[]info;privatebyte[]chksum;//以下定义Data类的各个数据成员变量的getter和setter方法}
再定义一个DataOperator类用对,Data类进行各种操作。
由于要进行十六进制代码与ascii码之间的转换所以,要创建一个静态数组来进行两者的对应:
publicclassAscii{publicstaticbyte[]ASCII=newbyte[]{0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46};}
下面主要介绍LCHKSUM的计算方法和CHKSUN的计算方法:
下面是LCHKSUM的计算方法,该方法通过对相应的LENGTH内容进行构造LCHKSUM
publicbyte[]createLength_chksum(byte[]src){byte[]result=newbyte[1];//用来记录计算len_chksum时的中间转换变量intlen_check=0;//计算len_chksum先计算长度每个字节所代表的ascii码的字符的真值和for(inti=0;i<3;i++){if(src[i]>0x39){len_check=len_check+(src[i]&0xff)-0x37;}else{len_check=len_check+(src[i]&0xff)-0x30;}}//System.out.println(len_check);//把相应的和模16len_check%=16;//再把结果取反len_check=16-len_check;//得到结果的ascii码的真值if(len_check==16){result[0]=0;}else{result[0]=Ascii.ASCII[len_check];}//System.out.println(result[0]);returnresult;}
下面是CHKSUM的计算方法,参数为整个数据(除了开始和结束位):
publicbyte[]createChksum(byte[]src){//用来记录计算chksum时的中间转换变量intcheck=0;//用来存放chksum结果byte[]result=newbyte[4];//计算每一字节的和for(inti=1;i<src.length;i++){//System.out.println(src[i]);inta=src[i]&0xff;check=check+a;}System.out.println(check);//把和对65535求余数check=check%65536;//再把求余之后的结果取反check=65536-check;//把最后的结果分为四字节的ascii码result[0]=Ascii.ASCII[((check>>12)&0x0000000f)];result[1]=Ascii.ASCII[((check>>8)&0x0000000f)];result[2]=Ascii.ASCII[((check>>4)&0x0000000f)];result[3]=Ascii.ASCII[((check&0x0000000f))];System.out.println(result[0]+""+result[1]+""+result[2]+""+result[3]);returnresult;}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。