blob: f5c9cf92d7d4b156c27eae5d734127486105f708 [file] [log] [blame]
Tang Cheng94fbfed2012-11-09 17:07:13 +08001# -*- coding: utf-8
Tang Chenge009afa2012-11-09 17:10:58 +08002""" 汇多协议封装
Tang Cheng94fbfed2012-11-09 17:07:13 +08003"""
4import codecs
5import struct
6
7IFT_NULL = 0
8IFT_ULONG = 1
9IFT_BYTE = 2
10IFT_USHORT = 3
11IFT_DATETIME = 4
12IFT_BUFFER = 5
13IFT_STRING = 6
14IFT_LONG = 7
15
Tang Chenge009afa2012-11-09 17:10:58 +080016# (0,0,1,IFT_BYTE,0,"msgtype","消息码"),
Tang Cheng94fbfed2012-11-09 17:07:13 +080017
18FLD_NO_IDX = 0
19FLD_LENGTH_IDX = 2
20FLD_TYPE_IDX = 3
21FLD_FLAG_IDX = 4
22FLD_NAME_IDX = 5
23FLD_DESC_IDX = 6
24
25HDFieldsDef = [
Tang Chenge009afa2012-11-09 17:10:58 +080026(1, 0, 0, IFT_NULL, 0, "extend", u"扩展域否"),
27(2, 0, 4, IFT_ULONG, 0, "terminalsn", u" 终端序列号"),
28(3, 0, 2, IFT_USHORT, 0, "address", u"CAN地址"),
29(4, 0, 4, IFT_ULONG, 0, "cardnumber", u"卡号"),
30(5, 0, 1, IFT_BYTE, 0, "indexofew", u" 钱包索引"),
31(6, 0, 2, IFT_USHORT, 0, "traceofew", u" 钱包流水号"),
32(7, 0, 4, IFT_LONG, 0, "amount", u" 交易金额"),
33(8, 0, 4, IFT_LONG, 0, "additionalamount1", u"附加金额"),
34(9, 0, 4, IFT_ULONG, 0, "traceofpos", u"POS流水号"),
35(10, 0, 4, IFT_ULONG, 0, "orgtranstrace", u"原交易流水号"),
36(11, 0, 7, IFT_DATETIME, 0, "datetime", u"交易日期和时间"),
37(12, 0, 1, IFT_BYTE, 0, "responsecode", u"响应码"),
38(13, 0, 2, IFT_USHORT, 0, "terminalid", u"终端号"),
39(14, 0, 2, IFT_USHORT, 0, "terminaltype", u"终端类型"),
40(15, 0, 2, IFT_USHORT, 0, "merchantid", u"商户(网点)号"),
41(16, 0, 4, IFT_ULONG, 0, "operatorid", u"操作员号"),
42(17, 0, 8, IFT_BUFFER, 0, "pin", u"个人识别码PIN"),
43(18, 0, 4, IFT_ULONG, 0, "veroflist", u"黑名单版本"),
44(19, 0, 4, IFT_ULONG, 0, "managefee", u"交易批次号(暂不用)"),
45(20, 0, 360, IFT_BUFFER, 2, "additionaldata1", u"附加信息1"),
46(21, 0, 528, IFT_BUFFER, 2, "additionaldata2", u"附加信息2"),
47(22, 0, 528, IFT_STRING, 2, "additionaldata3", u"附加信息3"),
48(23, 0, 528, IFT_STRING, 2, "additionaldata4", u"附加信息4"),
49(24, 0, 2, IFT_USHORT, 0, "mac", u"消息认证码")]
Tang Cheng94fbfed2012-11-09 17:07:13 +080050
51
Cheng Tang06013602014-04-18 21:12:55 +080052crc16_tab = [
53 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
54 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
55 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
56 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
57 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
58 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
59 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
60 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
61 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
62 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
63 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
64 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
65 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
66 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
67 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
68 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
69 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
70 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
71 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
72 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
73 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
74 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
75 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
76 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
77 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
78 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
79 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
80 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
81 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
82 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
83 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
84 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0]
85
86
87class HDPack(object):
88 """ 汇多 8583 协议包 """
Tang Cheng94fbfed2012-11-09 17:07:13 +080089 def __init__(self):
Cheng Tang06013602014-04-18 21:12:55 +080090 super(HDPack, self).__init__()
Tang Cheng94fbfed2012-11-09 17:07:13 +080091 self.msg_type = 0
92 self.value = {}
93 self.field_idx = {}
94 self.field_name = {}
95 self.msgtype = 0
96 self.load_config()
97
Cheng Tang06013602014-04-18 21:12:55 +080098 def _calc_crc(self, data, work_key):
99 """
100 uint16 crc;
101 unsigned char b, da;
102 uint16 charcnt;
103
104 crc = 0;
105 charcnt = 0;
106 while (len--)
107 {
108 da = (unsigned char)(crc / 256); /* 以8位二进制数的形式暂存CRC的高8位 */
109 crc <<= 8; /* 左移8位,相当于CRC的低8位乘以 */
110 b = pBuf[charcnt]; // 新移进来的字节值
111 crc ^= crc16_tab[da ^ b]; /* 高8位和当前字节相加后再查表求CRC ,再加上以前的CRC */
112 charcnt++;
113 }
114 """
115 datalen = len(data)
116 charcnt = 0
117 crc = 0
118 while datalen > 0:
119 datalen -= 1
120 t1 = crc / 256
121 crc <<= 8
122 t2 = ord(data[charcnt])
123 crc ^= crc16_tab[(t1 ^ t2) & 0xFF]
124 charcnt += 1
125 crc = struct.pack('>H', crc & 0xFFFF)
126 return self._encrypt_crc(crc, work_key)
127
128 def _encrypt_crc(self, crc, workkey):
129 t1 = ord(crc[0])
130 t2 = ord(crc[1])
131 for i in range(4):
132 t1 ^= ord(workkey[i * 2])
133 t2 ^= ord(workkey[i * 2 + 1])
134 return "".join([chr(t1 & 0xFF), chr(t2 & 0xFF)])
135
Tang Cheng94fbfed2012-11-09 17:07:13 +0800136 def __eq__(self, other):
137 if not isinstance(other, HDPack):
138 return False
139 return self.compare(other)
140
141 def __ne__(self, other):
142 if not isinstance(other, HDPack):
143 return True
144 return not self.compare(other)
145
146 def compare(self, other):
147 if self.msgtype != other.msgtype:
148 return False
149 for k, v in self.value.items():
150 if k not in other.value:
151 print "field [%s] not equal" % k
152 return False
153 if v != other.get(k):
154 print "field [%s] value not equal [%s,%s]" % (k, v, other.get(k))
155 return False
156 return True
157
158 def load_config(self):
159 for field in HDFieldsDef:
Cheng Tang06013602014-04-18 21:12:55 +0800160 index, _, _, _, _, name, _ = field
Tang Cheng94fbfed2012-11-09 17:07:13 +0800161 self.field_idx[index] = field
162 self.field_name[name] = field
163 #print self.field_name
164
165 def get_field_def(self, index):
166 field_def = None
167 if isinstance(index, int):
168 if index not in self.field_idx:
169 raise ValueError("field index %d not exists" % index)
170 field_def = self.field_idx[index]
171 elif isinstance(index, str):
172 if index not in self.field_name:
173 raise ValueError("field index %s not exists" % index)
174 field_def = self.field_name[index]
175 else:
176 raise ValueError("field index type not support")
177 return field_def
178
179 def set(self, index, value):
180 field_def = self.get_field_def(index)
181 t = field_def[FLD_TYPE_IDX]
182 n = field_def[FLD_NAME_IDX]
183 l = field_def[FLD_LENGTH_IDX]
184 f = field_def[FLD_FLAG_IDX]
185 if t == IFT_USHORT or t == IFT_ULONG or t == IFT_NULL or t == IFT_BYTE or t == IFT_LONG:
186 if isinstance(value, int):
187 b = value
Tang Cheng1a07ce72012-12-20 14:02:50 +0800188 elif isinstance(value, str) or isinstance(value, unicode):
Tang Cheng94fbfed2012-11-09 17:07:13 +0800189 if value.startswith('0x'):
190 b = int(value, 16)
191 else:
192 b = int(value)
193 else:
194 raise ValueError("field %s value type not integer" % n)
195 elif t == IFT_DATETIME:
196 if len(value) != 12 and len(value) != 14:
197 raise ValueError("field %s length must be 12 or 14" % n)
198 if len(value) == 14:
199 value = value[2:]
200 b = value + "00"
201 else:
202 if not isinstance(value, str):
Tang Cheng1a07ce72012-12-20 14:02:50 +0800203 if not isinstance(value, unicode):
204 raise ValueError("field %s value type not string" % n)
205 value = value.encode("utf-8")
Tang Cheng94fbfed2012-11-09 17:07:13 +0800206 if t == IFT_DATETIME:
207 l *= 2
208 elif value.startswith('0x'):
209 l *= 2
210 l += 2
211 if f != 2 and len(value) != l:
212 raise ValueError("field %s value data length not equal %d<>%d " %
213 (n, len(value), l))
214 elif len(value) > l:
215 raise ValueError("field %s value data length exceed %d " % (n, l))
216 b = value
217 self.value[n] = b
218
219 def get(self, index):
220 field_def = self.get_field_def(index)
221 #t = field_def[3]
222 n = field_def[5]
223 if n in self.value:
224 return self.value[n]
225 raise ValueError("Field %s not specified" % n)
226
Tang Cheng1a07ce72012-12-20 14:02:50 +0800227 def has_field(self, index):
228 field_def = self.get_field_def(index)
229 n = field_def[5]
230 return n in self.value
231
Tang Cheng94fbfed2012-11-09 17:07:13 +0800232 def encode_bitmap(self, bitmap):
Cheng Tang06013602014-04-18 21:12:55 +0800233 buf = []
Tang Cheng94fbfed2012-11-09 17:07:13 +0800234 offset = 0
235 #print "bit len[%d]" % len(bitmap)
236 while offset < len(bitmap):
237 bit = 0
238 for i in range(8):
239 t = ord(bitmap[offset + i]) - 0x30
240 if t == 0: continue
241 bit |= (1 << (7 - i % 8))
Cheng Tang06013602014-04-18 21:12:55 +0800242 buf.append(chr(bit & 0xFF))
Tang Cheng94fbfed2012-11-09 17:07:13 +0800243 offset += 8
Cheng Tang06013602014-04-18 21:12:55 +0800244 return "".join(buf)
Tang Cheng94fbfed2012-11-09 17:07:13 +0800245
246 def pack(self, workkey=None):
Cheng Tang06013602014-04-18 21:12:55 +0800247 buf = []
Tang Cheng94fbfed2012-11-09 17:07:13 +0800248 bitmap = ['0' for i in range(24)]
249 for field in HDFieldsDef:
Cheng Tang06013602014-04-18 21:12:55 +0800250 index, x, fl, t, flag, name, desc = field
Tang Cheng94fbfed2012-11-09 17:07:13 +0800251 if name not in self.value:
252 continue
253 if t == IFT_USHORT or t == IFT_ULONG or t == IFT_NULL or t == IFT_BYTE or t == IFT_LONG:
Cheng Tang06013602014-04-18 21:12:55 +0800254 buf.append(self.int_2_buffer(self.value[name], t, fl))
Tang Cheng94fbfed2012-11-09 17:07:13 +0800255 else:
Cheng Tang06013602014-04-18 21:12:55 +0800256 buf.append(self.string_2_buffer(self.value[name], t, fl, flag))
Tang Cheng94fbfed2012-11-09 17:07:13 +0800257 bitmap[index - 1] = '1'
Cheng Tang06013602014-04-18 21:12:55 +0800258 if workkey:
259 bitmap[23] = '1'
Tang Cheng94fbfed2012-11-09 17:07:13 +0800260 #print bitmap
261 bitmap_buffer = self.encode_bitmap(bitmap)
Cheng Tang06013602014-04-18 21:12:55 +0800262 full_data = chr(self.msgtype & 0xFF) + bitmap_buffer + "".join(buf)
263 if workkey:
264 crc = self._calc_crc(full_data, workkey)
265 full_data += crc
Tang Cheng94fbfed2012-11-09 17:07:13 +0800266 header = self.data_header(full_data)
267 #print "h[%s]d[%s]" % (codecs.encode(header,'hex'),codecs.encode(full_data,'hex'))
268 return header + full_data
269
Cheng Tang06013602014-04-18 21:12:55 +0800270 def data_header(self, buf):
271 if len(buf) > 0xFFFF:
272 raise ValueError("Buffer max length exceed %d", len(buf))
273 header = struct.pack('<H', len(buf))
Tang Cheng94fbfed2012-11-09 17:07:13 +0800274 return header
275
Cheng Tang06013602014-04-18 21:12:55 +0800276 def int_2_buffer(self, value, datatype, length):
277 buf = ''
278 if datatype == IFT_BYTE:
279 buf = chr(value % 0x100)
280 elif datatype == IFT_NULL:
281 return buf
282 elif datatype == IFT_USHORT:
Tang Cheng94fbfed2012-11-09 17:07:13 +0800283 v = value % 0x10000
Cheng Tang06013602014-04-18 21:12:55 +0800284 buf = struct.pack('<H', v)
285 elif datatype == IFT_ULONG:
286 buf = struct.pack('<I', value)
287 elif datatype == IFT_LONG:
288 buf = struct.pack('<i', value)
Tang Cheng94fbfed2012-11-09 17:07:13 +0800289 else:
290 raise ValueError('Input Error')
Cheng Tang06013602014-04-18 21:12:55 +0800291 return buf
Tang Cheng94fbfed2012-11-09 17:07:13 +0800292
293 def encode_bcd(self, value):
294 if len(value) % 2 != 0:
295 raise ValueError("value length must div 2")
296 i = 0
297 #print "value [%s]" % value
Cheng Tang06013602014-04-18 21:12:55 +0800298 buf = []
Tang Cheng94fbfed2012-11-09 17:07:13 +0800299 while i < len(value):
300 t1 = (ord(value[i]) - 0x30) & 0xFF
301 t2 = (ord(value[i + 1]) - 0x30) & 0xFF
302 #print "t1[%d]t2[%d]" % (t1,t2)
303 t = ((t1 << 4) | t2) & 0xFF
304 #print "t1[%d]t2[%d]t[%d]" % (t1,t2,t)
Cheng Tang06013602014-04-18 21:12:55 +0800305 buf.append(chr(t))
Tang Cheng94fbfed2012-11-09 17:07:13 +0800306 i += 2
Cheng Tang06013602014-04-18 21:12:55 +0800307 #print "bcd value[%s]" % codecs.encode(buf,'hex')
308 return "".join(buf)
Tang Cheng94fbfed2012-11-09 17:07:13 +0800309
310 def decode_bcd(self, value):
Cheng Tang06013602014-04-18 21:12:55 +0800311 buf = []
Tang Cheng94fbfed2012-11-09 17:07:13 +0800312 #print "bcd [%s]" % codecs.encode(value,'hex')
313 for c in value:
314 t = ord(c) & 0xFF
315 t1 = (t >> 4) & 0x0F
316 t2 = t & 0x0F
317 #print "t[%02x]t1[%d]t2[%d]" % (t,t1,t2)
Cheng Tang06013602014-04-18 21:12:55 +0800318 buf.append(chr(t1 + 0x30) + chr(t2 + 0x30))
319 #print "bcd value[%s]" % buf
320 return "".join(buf)
Tang Cheng94fbfed2012-11-09 17:07:13 +0800321
Cheng Tang06013602014-04-18 21:12:55 +0800322 def string_2_buffer(self, value, datatype, length, flag):
323 buf = ''
324 if datatype == IFT_STRING or datatype == IFT_BUFFER:
Tang Cheng94fbfed2012-11-09 17:07:13 +0800325 if value.startswith('0x'):
Cheng Tang06013602014-04-18 21:12:55 +0800326 buf = codecs.decode(value[2:], 'hex')
Tang Cheng94fbfed2012-11-09 17:07:13 +0800327 else:
Cheng Tang06013602014-04-18 21:12:55 +0800328 buf = value
329 elif datatype == IFT_DATETIME:
330 buf = ''
Tang Cheng94fbfed2012-11-09 17:07:13 +0800331 i = 0
332 while i < len(value):
333 t = int(value[i:i + 2])
Cheng Tang06013602014-04-18 21:12:55 +0800334 buf += chr(t & 0xFF)
Tang Cheng94fbfed2012-11-09 17:07:13 +0800335 i += 2
336 else:
337 raise ValueError('Input Error')
338 if flag == 2:
Cheng Tang06013602014-04-18 21:12:55 +0800339 header = struct.pack('<H', len(buf) % 0x10000)
340 return header + buf
Tang Cheng94fbfed2012-11-09 17:07:13 +0800341 else:
342 #if type == IFT_BUFFER:
343 # if len(buffer) % 2 <> 0 or len(buffer)/2 <> length:
344 # raise ValueError("Value length not matched [%s]" % value)
345 # buffer = codecs.decode(buffer,'hex')
Cheng Tang06013602014-04-18 21:12:55 +0800346 if len(buf) != length:
347 padlen = length - len(buf)
Tang Cheng94fbfed2012-11-09 17:07:13 +0800348 if padlen < 0:
349 raise ValueError("Value length not matched [%s]" % value)
350 pad = chr(0) * padlen
Cheng Tang06013602014-04-18 21:12:55 +0800351 buf = pad + buf
352 return buf
Tang Cheng94fbfed2012-11-09 17:07:13 +0800353
354 def decode_bitmap(self, bitmap):
355 if len(bitmap) != 3:
356 raise ValueError("bitmap length error")
357 #print "bitmap[%s]" % codecs.encode(bitmap,'hex')
Cheng Tang06013602014-04-18 21:12:55 +0800358 buf = []
Tang Cheng94fbfed2012-11-09 17:07:13 +0800359 for t in bitmap:
360 v = ord(t) & 0xFF
361 for i in range(8):
362 x = (v & (1 << (7 - i)))
363 if x > 0:
Cheng Tang06013602014-04-18 21:12:55 +0800364 buf.append('1')
Tang Cheng94fbfed2012-11-09 17:07:13 +0800365 else:
Cheng Tang06013602014-04-18 21:12:55 +0800366 buf.append('0')
367 return buf
Tang Cheng94fbfed2012-11-09 17:07:13 +0800368
369 def unpack(self, data):
370 self.value = {}
Tang Cheng94fbfed2012-11-09 17:07:13 +0800371 data_len = struct.unpack('<H', data[:2])[0]
372 if len(data) != data_len + 2:
373 print "input[%d] extually[%d]" % (data_len, len(data))
374 return False
375 offset = 2
376 self.msgtype = ord(data[offset]) & 0xFF
377 offset += 1
378 bitmap = self.decode_bitmap(data[offset:offset + 3])
379 offset += 3
380 #print bitmap
381 for i in range(len(bitmap)):
Cheng Tang06013602014-04-18 21:12:55 +0800382 if bitmap[i] == '0':
383 continue
Tang Cheng94fbfed2012-11-09 17:07:13 +0800384 findex = i + 1
385 field = self.get_field_def(findex)
386 ftype = field[FLD_TYPE_IDX]
387 flen = field[FLD_LENGTH_IDX]
388 fflag = field[FLD_FLAG_IDX]
389 #fname = field[FLD_NAME_IDX]
390 #print "parse field[%s] [%d]off[%d][%s]" % (fname,fflag,offset,codecs.encode(data[offset:offset+2],'hex'))
Tang Chenge009afa2012-11-09 17:10:58 +0800391 # 变长数据
Tang Cheng94fbfed2012-11-09 17:07:13 +0800392 if fflag == 2:
393 #print "len [%s]" % codecs.encode(data[offset:offset+2],'hex')
394 endpos = self.buffer_2_int(data[offset:offset + 2], IFT_USHORT)
395 offset += 2
396 endpos += offset
397 else:
398 endpos = offset + flen
399 if ftype == IFT_USHORT or ftype == IFT_ULONG or ftype == IFT_NULL or ftype == IFT_BYTE or ftype == IFT_LONG:
400 value = self.buffer_2_int(data[offset:endpos], ftype)
401 else:
Tang Cheng94fbfed2012-11-09 17:07:13 +0800402 value = self.buffer_2_string(data[offset:endpos], ftype)
Tang Cheng94fbfed2012-11-09 17:07:13 +0800403 self.set(findex, value)
404 #print "parse field[%s] OK =====" % fname
405 offset = endpos
406 #print self.value
407 return True
408
Cheng Tang06013602014-04-18 21:12:55 +0800409 def buffer_2_int(self, data, datatype):
410 if datatype == IFT_BYTE:
Tang Cheng94fbfed2012-11-09 17:07:13 +0800411 return ord(data)
Cheng Tang06013602014-04-18 21:12:55 +0800412 elif datatype == IFT_USHORT:
Tang Cheng94fbfed2012-11-09 17:07:13 +0800413 return struct.unpack('<H', data)[0]
Cheng Tang06013602014-04-18 21:12:55 +0800414 elif datatype == IFT_ULONG:
Tang Cheng94fbfed2012-11-09 17:07:13 +0800415 return struct.unpack('<I', data)[0]
Cheng Tang06013602014-04-18 21:12:55 +0800416 elif datatype == IFT_LONG:
Tang Cheng94fbfed2012-11-09 17:07:13 +0800417 return struct.unpack('<i', data)[0]
Cheng Tang06013602014-04-18 21:12:55 +0800418 elif datatype == IFT_NULL:
Tang Cheng94fbfed2012-11-09 17:07:13 +0800419 return None
420 else:
421 raise ValueError("input data type error")
422
423 def buffer_2_string(self, data, type):
424 if type == IFT_STRING:
425 return data
426 elif type == IFT_BUFFER:
427 return data
428 elif type == IFT_DATETIME:
429 return self.decode_bcd(data)
430 else:
431 raise ValueError("input data type error")
432
433 def get_2byte_int(self, data):
Tang Cheng1a07ce72012-12-20 14:02:50 +0800434 return struct.unpack("<H", data)[0]
Tang Cheng94fbfed2012-11-09 17:07:13 +0800435
436 def get_3byte_int(self, data):
437 temp = data + chr(0)
438 return struct.unpack("<I", temp)[0]
439
440 def get_4byte_int(self, data):
441 return struct.unpack("<I", data)[0]
442
Tang Cheng1a07ce72012-12-20 14:02:50 +0800443 def get_byte_int(self, data, signed=False):
444 dl = len(data)
445 if dl <= 0 or dl > 4:
446 raise ValueError(u"Data length must between 1 and 4")
Cheng Tang06013602014-04-18 21:12:55 +0800447 fmt = None
448 if dl == 2:
449 fmt = '<h' if signed else '<H'
450 elif dl == 4:
451 fmt = '<i' if signed else '<I'
452 elif dl == 1:
453 fmt = '<b' if signed else '<B'
Tang Cheng1a07ce72012-12-20 14:02:50 +0800454 else:
Cheng Tang06013602014-04-18 21:12:55 +0800455 fmt = '<i' if signed else '<I'
456 data += chr(0)
457 return struct.unpack(fmt, data)[0]
Tang Cheng1a07ce72012-12-20 14:02:50 +0800458
Tang Cheng94fbfed2012-11-09 17:07:13 +0800459 def set_2byte_int(self, data):
460 return struct.pack('<H', data)
461
462 def set_3byte_int(self, data):
463 temp = struct.pack('<H', data)
464 return temp[:-1]
465
466 def set_4byte_int(self, data):
467 return struct.pack('<I', data)
Cheng Tang06013602014-04-18 21:12:55 +0800468
469
470def test():
471 pack = HDPack()
472 pack.msgtype = 0xFF
473 pack.set(2, "0000000000")
474 print codecs.encode(pack.pack(), 'hex')
475
476 data = pack.pack(chr(0xFF) * 8)
477 print codecs.encode(data, 'hex')
478
479
480if __name__ == "__main__":
481 test()