fac86401
孙向锦
初始化C5 Vote
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
|
package com.sunvote.cmd.app;
import com.sunvote.cmd.BaseCmd;
import com.sunvote.cmd.ICmd;
import com.sunvote.cmd.push.PushBaseCmd;
import java.io.ByteArrayOutputStream;
import java.util.Arrays;
/**
* Created by Elvis on 2017/8/29.
* Email:Eluis@psunsky.com
* 版权所有:长沙中天电子设计开发有限公司
* Description:平板模块键盘投票功能模块
*
* 6.1 概述
下载多包类主要用于下载一批数据。例如项目名称表、评议规则表等。
我们统一使用《广播式下载方式》来下载多包(即数据表),具体原理参见《表决系统通讯协议-应用文档-原理》。
6.2 进入和退出下载状态
通知表决器进入下载模式的好处:
1、在重新下载未成功的表决器时候,仅通知未成功的进入下载状态,其他成功的表决器就可以不处理下载数据;
2、能立即知道是否在线,表决器可以准备擦除FLASH,V4.52对于支持文件下载的就按文件名称创建文件;
3、退出时,表决器能知道下载完成。
字节 标识符 描述
1 DOWNCMD 0x40 下载多包类指令
2-3 KEYID 表决器编号,2字节,高位在前
一般要指定表决器编号使指定键盘进入或退出下载状态
但0x0000广播时候,键盘也执行
FF01到FFFE时候,是用序列号指定键盘 V4.74
低位字节01-FE,表示下载次序,由SDK管理,新下载变化一次,
键盘收到的时候,记录下,同时,此次序也出现在下载数据包中,这样键盘可判断是否是我可以下载的数据,避免上次下载状态没正常退出而错误接受数据
4 DOWNCMD 1 进入或退出下载状态
5 DOWNTYPE 多包类型
6 DOWNID 数据包标识码
7 DCMD 模式 1进入下载 0退出下载
8-24 FILENAME 在DOWNTYPE=40下载文件模式时候,是下载文件名称,16字符
其他模式参数无意义
SN 序列号模式时候,6字节键盘序列号,用于指定键盘
暂不支持文件下载
表决器回应结果状态:
字节 标识符 描述
1 DOWNCMD 0xC0 下载多包类指令应答
2-3 KEYID 表决器编号,2字节,高位在前
不是0000也不是FFFF,是要询问的表决器的编号
FFFF 表示用SN号代表键盘
4 DOWNCMD 1回应下载状态
5 DOWNTYPE 多包类型
6 DOWNID 数据包标识码
7 DCMDACK 现在模式 1已经进入下载模式 0已经退出下载模式
8-24 SN 使用SN号模式时候,键盘的SN,6字节
否则参数无意义
6.3 广播式下载数据包和查询状态
具体原理参见《表决系统通讯协议-应用文档-原理》。
下载数据包指令结构如下:
字节 标识符 描述
1 DOWNCMD 0x40 下载多包类指令
2-3 KEYID 表决器编号,2字节,高位在前
0xFFFF的时候是部分表决器下载,是常用模式,进入下载模式的表决器才处理数据
0x0000时候是广播下载,所有表决器都接收和处理
其他值是指定下载,编号和KEYID相同的才处理数据
FF01到FFFE时候,是序列号模式 V4.74
低位字节和进入下载模式时候的低位字节相同,用于键盘判断是否是当前下载数据
4 DOWNCMD 2 广播式下载具体数据
5 DOWNTYPE 多包类型
6 DOWNID 数据包标识码
文件下载模式时候是最高位地址 V4.52
由于非文件下载模式PACKH加上PACKL,只能下载65536字节,文件下载模式为支持大文件,用DOWNID作为高位地址,可以下载16384K字节
7 PACKH 数据段编号,0-255
8 PACKL 数据片编号, 0-15
9-24 PACKDATA 16字节的数据
备注:
1、 投票器先判断PACKH是否发生变化,发生变化就表示新的16片数据下载开始了,要把标志16片段下载成功状态的OKBITS全置1;
2、 然后计算地址,把PACKDATA16字节数据写到指定位置,对于非文件下载,地址=(PACKH*16+PACKL)*16,对于文件下载,地址=((DOWNID*256+PACKH)*16+PACKL)*16;
3、 然后把OKBITS中对应PACKL的比特位置0表示已经对应片段下载成功,用于应答下面的下载状态询问指令
询问下载成功状态指令结构:
字节 标识符 描述
1 DOWNCMD 0x40 下载多包类指令
2-3 KEYID 表决器编号,2字节,高位在前
使用键盘编号模式时候,不是0000也不是FFFF,是要询问的表决器的编号
FFFF,使用SN号询问键盘
4 DOWNCMD 3 询问广播式下载的执行状态
5 DOWNTYPE 多包类型
6 DOWNID 数据包标识码
7 PACKH 数据段编号
8-24 SN 指定键盘的SN号,6字节
参数无意义
表决器回应下载成功状态:
字节 标识符 描述
1 DOWNCMD 0xC0 下载多包类指令应答
2-3 KEYID 表决器编号,2字节,高位在前
不是0000也不是FFFF,是要询问的表决器的编号
FFFF,使用SN号回答
4 DOWNCMD 3 回应广播式下载的执行状态
5 DOWNTYPE 多包类型
6 DOWNID 数据包标识码
7 PACKH 数据段编号
8-9 OKBITS_L
OKBITS_H 下载成功状态,共16Bit,代表0-15号数据片,Bit=0表示下载成功
注意是低位字节在前,例如OKBITS_L=3,OKBITS_H=128时候,表示第1、2、16个数据片没下载成功,即0、1号和15号数据片不成功
10-24 SN 指定键盘的SN号,6字节
不是SN模式时参数无意义
6.4 数据包类型分类
通过DOWNTYPE和DOWNID两个字节的组合,可以决定下载数据包的类型。
下面列出目前使用的几种类型。具体数据包的格式和含义,请参见《数据表规范-政务商务》。
DOWNTYPE值 DOWNID值 数据包类型
1 1 固定编号项目名称表
1 2 随机名称编号表
1 3 二维评测指标名称表
2 1 评议规则表
2 2 评议规则说明信息表
3 1 评分规则表
3 2 评分规则说明信息表
10 变化 即时信息
11 变化 短消息
12 页号 屏幕点阵显示信息
12 1或2 股东信息
20 1 空闲液晶信息
20 2 开机信息
30 1 汉字自造字字库,16x16点阵
31 1 多国语言资源包(未实现)
40 高位地址 指定文件名称(可含目录)下载文件
50 xPad的透传多包信息
6.4.1 关于即时信息和短信的特殊说明
即时信息定义为马上显示在屏幕上的信息,不保存,看完即丢。
短信定义为保存的,可查看,即时显示或提醒。
下载数据包指令结构不变,但DOWNID和PACKH含义不同:
字节 标识符 描述
1 DOWNCMD 0x40 下载多包类指令
2-3 KEYID 表决器编号,2字节,高位在前
0x0000时候是广播发信息,所有表决器都接收和处理,不需进入下载模式
0xFFFF的时候是对多个表决器发信息,已经进入下载模式的才处理
其他值是指定下载,编号和KEYID相同的才接收信息
4 DOWNCMD 2 广播式下载具体数据
5 DOWNTYPE 固定为10即时信息或11短信
50是xPad透传多包信息,一般是字符串信息
6 DOWNID 发一次信息就变化一次,表决器据此可知道是新的信息来了
7 PACKH 数据片总数,0表示1,F表示最多16片,也就是所短信息最多256字符,但一般限定64字符以内
8 PACKL 0-15,当前发送的数据片的编号
9-24 PACKDATA 16字节的数据
对于短信接收,表决器只要判断DOWNTYPE为10或11,然后DOWNID和以前的不同,就知道是新短信过来,并根据PACKH知道信息的长度,建立新的下载状态位。
然后根据PACKH判断所有片段是否都接收完毕,可以自动显示。
对于广播给所有表决器的信息,表决器不需单个单个进入下载模式,由SDK控制各片段信息多广播几次,表决器自己判断接收完整就显示。
对应指定单个表决器发信息,为提高速度,不对表决器执行进入下载模式,但要查询下载状态,确保信息完整下载,并且不执行退出下载模式。
对应指定多个表决器发信息,就必须进入下载模式,然后下载,然后查询,为提高下载速度,对表决器不执行退出下载模式。
所以,因为不执行退出下载状态,要注意的是,表决器要对短信模式下的进入下载状态要单独处理,避免和指定多个的表决器下载项目名称表等其他操作搞混。
6.4.2 桌牌点阵显示信息数据格式
桌牌点阵显示信息一般是按规则排布的点阵亮灭二进制字节数据。例如96x32点阵的显示屏,实际的数据是96x32/8=384字节。为保证以后点阵屏幕变更,在实际点阵数据前加16字节的格式说明。
字节 标识符 描述
1 TYPE 点阵格式
1 96x32点阵,(排列方式?)
2-16 根据点阵格式有不同含义,暂时为空
17-… BITMAP 显示点阵数据,根据不同格式有不同的长度
这样,如果格式为1,实际要传输的数据是16+384=400字节。
6.4.3 股东信息
特定型号需要显示股东姓名等信息。
请参考6.4.1节短信,下载方法一样,就是国外应用需要考虑unicode编码,所以DOWNID来标志。
字节 标识符 描述
1 DOWNCMD 0x40 下载多包类指令
2-3 KEYID 表决器编号,2字节,高位在前
0x0000时候是广播发信息,所有表决器都接收和处理,不需进入下载模式
0xFFFF的时候是对多个表决器发信息,已经进入下载模式的才处理
其他值是指定下载,编号和KEYID相同的才接收信息
FF01到FFFE时候,是用序列号指定键盘 V4.77
(采用SN号模式下载股东信息时候,键盘先进入下载状态,参见6.6节序列号下载多包方法,和6.2节进入和退出下载状态)
4 DOWNCMD 2 广播式下载具体数据
5 DOWNTYPE 12 股东信息
6 DOWNID 0 GB2312编码
1 UTF8编码
2 Unicode编码
7 PACKH 数据片总数,0表示1,F表示最多16片,也就是所短信息最多256字符,但一般限定64字符以内
8 PACKL 0-15,当前发送的数据片的编号
9-24 PACKDATA 16字节的数据
6.5 简单下载模式(不使用)
简单下载方式只是作为解决方案提出,因为效率比广播式低,没有采用。
下载数据包指令结构如下:
字节 标识符 描述
1 DOWNCMD 0x40 下载多包类指令
2-3 KEYID 表决器编号,2字节,高位在前
必须指定一个具体的表决器编号
4 DOWNCMD 4 简单下载模式
5 DOWNTYPE 多包类型
6 DOWNID 数据包标识码
7 PACKH 数据段编号
8 PACKL 0-7,数据片编号
9-24 PACKDATA 16字节的数据
表决器回应下载成功状态:
字节 标识符 描述
1 DOWNCMD 0xB0 下载多包类指令应答
2-3 KEYID 表决器编号,2字节,高位在前
不是0000也不是FFFF,是要询问的表决器的编号
4 DOWNCMD 4 回应下载状态
5 DOWNTYPE 多包类型
6 DOWNID 数据包标识码
7 PACKH 数据段编号
8 PACKL 0-7,数据片编号
9 STATUS 1 成功
0 不成功
10-24 参数无意义
6.6 序列号下载多包
键盘使用序列号模式时,也分广播、指定多个、指定单个键盘下载。
指定多个,修改了6.2节指定键盘进入下载状态和退出下载状态,可用SN号指定,同样,6.3节的询问下载结果,修改为同样支持SN号。而下载数据,仍然沿用原来的ID=FFFF,在下载模式的才接受。
指定单个,包含到指定多个里面,这样,即使单个发短信,也要先进入下载模式。
广播,则沿用ID=0000的原来模式。
然后,发现一个问题,如果上次键盘没能正常退出下载模式,就有可能错误接受数据,包括原来使用键盘编号的,都有这个可能。所以,进入和退出下载模式,广播数据时,原来的FFFF改为FF01到FFFE,低字节01-FE表示次序,SDK管理,下载一次改变一次,这样键盘就能判断数据是不是这次的,同时如果不是,键盘改自己次序为0。
*
*/
public class MutiPkgDownCmd extends BaseCmd {
/***
* 下载数据包指令结构如下:
字节 标识符 描述
1 DOWNCMD 0x40 下载多包类指令
2-3 KEYID 表决器编号,2字节,高位在前
0xFFFF的时候是部分表决器下载,是常用模式,进入下载模式的表决器才处理数据
0x0000时候是广播下载,所有表决器都接收和处理
其他值是指定下载,编号和KEYID相同的才处理数据
FF01到FFFE时候,是序列号模式 V4.74
低位字节和进入下载模式时候的低位字节相同,用于键盘判断是否是当前下载数据
4 DOWNCMD 2 广播式下载具体数据
5 DOWNTYPE 多包类型
6 DOWNID 数据包标识码
文件下载模式时候是最高位地址 V4.52
由于非文件下载模式PACKH加上PACKL,只能下载65536字节,文件下载模式为支持大文件,用DOWNID作为高位地址,可以下载16384K字节
7 PACKH 数据段编号,0-255
8 PACKL 数据片编号, 0-15
9-24 PACKDATA 16字节的数据
* @return
*/
public static final byte DOWNCMD = 0x40 ;
private byte cmd = DOWNCMD;
private byte[] keyId = new byte[2];
private byte downType ;
private byte downid ;
private byte packh;
private byte packl;
private byte[] packdata = new byte[16];
/**
* 1 进入或退出下载状态
* 2 广播式下载具体数据
* 3 询问广播式下载的执行状态
*/
private byte cmd1 ;
@Override
public byte[] toBytes() {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try{
outputStream.write(getCmd());
outputStream.write(getKeyId());
outputStream.write(getCmd1());
outputStream.write(getDownType());
outputStream.write(getDownid());
outputStream.write(getPackh());
outputStream.write(getPackl());
outputStream.write(getPackdata());
return outputStream.toByteArray();
}catch (Exception e){}
return new byte[0];
}
@Override
public ICmd parseCmd(byte[] source, int start) {
if(source.length > start){
setCmd(source[start]);
}
if(source.length > start + 2){
setKeyId(Arrays.copyOfRange(source,start+2,start+4));
}
if(source.length > start + 4){
setCmd1(source[start+4]);
}
if(source.length > start + 5){
setDownType(source[start+5]);
}
if(source.length > start + 6){
setDownid(source[start+6]);
}
if(source.length > start + 7){
setPackh(source[start+7]);
}
if(source.length > start + 8){
setPackl(source[start+8]);
}
if(source.length > start + 24){
setPackdata(Arrays.copyOfRange(source,start+9,start+24));
}
return this;
}
public static MutiPkgDownCmd parseRequest(byte[] bytes, int length){
MutiPkgDownCmd mutiPkgDownCmd = new MutiPkgDownCmd();
mutiPkgDownCmd.parseCmd(bytes);
return mutiPkgDownCmd;
}
public byte getCmd() {
return cmd;
}
public void setCmd(byte cmd) {
this.cmd = cmd;
}
public byte[] getKeyId() {
return keyId;
}
public void setKeyId(byte[] keyId) {
this.keyId = keyId;
}
public byte getDownType() {
return downType;
}
public void setDownType(byte downType) {
this.downType = downType;
}
public byte getDownid() {
return downid;
}
public void setDownid(byte downid) {
this.downid = downid;
}
public byte getPackh() {
return packh;
}
public void setPackh(byte packh) {
this.packh = packh;
}
public byte getPackl() {
return packl;
}
public void setPackl(byte packl) {
this.packl = packl;
}
public byte[] getPackdata() {
return packdata;
}
public void setPackdata(byte[] packdata) {
this.packdata = packdata;
}
public byte getCmd1() {
return cmd1;
}
public void setCmd1(byte cmd1) {
this.cmd1 = cmd1;
}
}
|