修改bug
diff --git a/supwisdom/protocol/amassprotocol.py b/supwisdom/protocol/amassprotocol.py
index 574e765..f5c9cf9 100644
--- a/supwisdom/protocol/amassprotocol.py
+++ b/supwisdom/protocol/amassprotocol.py
@@ -49,9 +49,45 @@
 (24, 0, 2, IFT_USHORT, 0, "mac", u"消息认证码")]

 

 

-class HDPack:

-    ''' 汇多 8583 协议包 '''

+crc16_tab = [

+    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,

+    0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,

+    0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,

+    0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,

+    0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,

+    0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,

+    0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,

+    0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,

+    0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,

+    0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,

+    0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,

+    0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,

+    0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,

+    0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,

+    0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,

+    0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,

+    0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,

+    0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,

+    0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,

+    0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,

+    0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,

+    0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,

+    0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,

+    0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,

+    0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,

+    0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,

+    0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,

+    0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,

+    0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,

+    0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,

+    0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,

+    0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0]

+

+

+class HDPack(object):

+    """ 汇多 8583 协议包 """

     def __init__(self):

+        super(HDPack, self).__init__()

         self.msg_type = 0

         self.value = {}

         self.field_idx = {}

@@ -59,6 +95,44 @@
         self.msgtype = 0

         self.load_config()

 

+    def _calc_crc(self, data, work_key):

+        """

+        uint16 crc;

+        unsigned char b, da;

+        uint16 charcnt;

+

+        crc = 0;

+        charcnt = 0;

+        while (len--)

+        {

+        da = (unsigned char)(crc / 256);			/* 以8位二进制数的形式暂存CRC的高8位 */

+        crc <<= 8;						/* 左移8位,相当于CRC的低8位乘以 */

+        b = pBuf[charcnt];				// 新移进来的字节值

+        crc ^= crc16_tab[da ^ b];		/* 高8位和当前字节相加后再查表求CRC ,再加上以前的CRC */

+        charcnt++;

+        }

+        """

+        datalen = len(data)

+        charcnt = 0

+        crc = 0

+        while datalen > 0:

+            datalen -= 1

+            t1 = crc / 256

+            crc <<= 8

+            t2 = ord(data[charcnt])

+            crc ^= crc16_tab[(t1 ^ t2) & 0xFF]

+            charcnt += 1

+        crc = struct.pack('>H', crc & 0xFFFF)

+        return self._encrypt_crc(crc, work_key)

+

+    def _encrypt_crc(self, crc, workkey):

+        t1 = ord(crc[0])

+        t2 = ord(crc[1])

+        for i in range(4):

+            t1 ^= ord(workkey[i * 2])

+            t2 ^= ord(workkey[i * 2 + 1])

+        return "".join([chr(t1 & 0xFF), chr(t2 & 0xFF)])

+

     def __eq__(self, other):

         if not isinstance(other, HDPack):

             return False

@@ -83,7 +157,7 @@
 

     def load_config(self):

         for field in HDFieldsDef:

-            index, t, len, type, flag, name, desc = field

+            index, _, _, _, _, name, _ = field

             self.field_idx[index] = field

             self.field_name[name] = field

         #print self.field_name

@@ -156,7 +230,7 @@
         return n in self.value

 

     def encode_bitmap(self, bitmap):

-        buffer = []

+        buf = []

         offset = 0

         #print "bit len[%d]" % len(bitmap)

         while offset < len(bitmap):

@@ -165,131 +239,135 @@
                 t = ord(bitmap[offset + i]) - 0x30

                 if t == 0: continue

                 bit |= (1 << (7 - i % 8))

-            buffer.append(chr(bit & 0xFF))

+            buf.append(chr(bit & 0xFF))

             offset += 8

-        return "".join(buffer)

+        return "".join(buf)

 

     def pack(self, workkey=None):

-        buffer = []

+        buf = []

         bitmap = ['0' for i in range(24)]

         for field in HDFieldsDef:

-            index, x, len, t, flag, name, desc = field

+            index, x, fl, t, flag, name, desc = field

             if name not in self.value:

                 continue

             if t == IFT_USHORT or t == IFT_ULONG or t == IFT_NULL or t == IFT_BYTE or t == IFT_LONG:

-                buffer.append(self.int_2_buffer(self.value[name], t, len))

+                buf.append(self.int_2_buffer(self.value[name], t, fl))

             else:

-                buffer.append(self.string_2_buffer(self.value[name], t, len, flag))

+                buf.append(self.string_2_buffer(self.value[name], t, fl, flag))

             bitmap[index - 1] = '1'

+        if workkey:

+            bitmap[23] = '1'

         #print bitmap

         bitmap_buffer = self.encode_bitmap(bitmap)

-        full_data = chr(self.msgtype & 0xFF) + bitmap_buffer + "".join(buffer)

+        full_data = chr(self.msgtype & 0xFF) + bitmap_buffer + "".join(buf)

+        if workkey:

+            crc = self._calc_crc(full_data, workkey)

+            full_data += crc

         header = self.data_header(full_data)

         #print "h[%s]d[%s]" % (codecs.encode(header,'hex'),codecs.encode(full_data,'hex'))

         return header + full_data

 

-    def data_header(self, buffer):

-        if len(buffer) > 0xFFFF:

-            raise ValueError("Buffer max length exceed %d", len(buffer))

-        header = struct.pack('<H', len(buffer))

+    def data_header(self, buf):

+        if len(buf) > 0xFFFF:

+            raise ValueError("Buffer max length exceed %d", len(buf))

+        header = struct.pack('<H', len(buf))

         return header

 

-    def int_2_buffer(self, value, type, length):

-        buffer = ''

-        if type == IFT_BYTE:

-            buffer = chr(value % 0x100)

-        elif type == IFT_NULL:

-            return buffer

-        elif type == IFT_USHORT:

+    def int_2_buffer(self, value, datatype, length):

+        buf = ''

+        if datatype == IFT_BYTE:

+            buf = chr(value % 0x100)

+        elif datatype == IFT_NULL:

+            return buf

+        elif datatype == IFT_USHORT:

             v = value % 0x10000

-            buffer = struct.pack('<H', v)

-        elif type == IFT_ULONG:

-            buffer = struct.pack('<I', value)

-        elif type == IFT_LONG:

-            buffer = struct.pack('<i', value)

+            buf = struct.pack('<H', v)

+        elif datatype == IFT_ULONG:

+            buf = struct.pack('<I', value)

+        elif datatype == IFT_LONG:

+            buf = struct.pack('<i', value)

         else:

             raise ValueError('Input Error')

-        return buffer

+        return buf

 

     def encode_bcd(self, value):

         if len(value) % 2 != 0:

             raise ValueError("value length must div 2")

         i = 0

         #print "value [%s]" % value

-        buffer = []

+        buf = []

         while i < len(value):

             t1 = (ord(value[i]) - 0x30) & 0xFF

             t2 = (ord(value[i + 1]) - 0x30) & 0xFF

             #print "t1[%d]t2[%d]" % (t1,t2)

             t = ((t1 << 4) | t2) & 0xFF

             #print "t1[%d]t2[%d]t[%d]" % (t1,t2,t)

-            buffer.append(chr(t))

+            buf.append(chr(t))

             i += 2

-        #print "bcd value[%s]" % codecs.encode(buffer,'hex')

-        return "".join(buffer)

+        #print "bcd value[%s]" % codecs.encode(buf,'hex')

+        return "".join(buf)

 

     def decode_bcd(self, value):

-        buffer = []

+        buf = []

         #print "bcd [%s]" % codecs.encode(value,'hex')

         for c in value:

             t = ord(c) & 0xFF

             t1 = (t >> 4) & 0x0F

             t2 = t & 0x0F

             #print "t[%02x]t1[%d]t2[%d]" % (t,t1,t2)

-            buffer.append(chr(t1 + 0x30) + chr(t2 + 0x30))

-        #print "bcd value[%s]" % buffer

-        return "".join(buffer)

+            buf.append(chr(t1 + 0x30) + chr(t2 + 0x30))

+        #print "bcd value[%s]" % buf

+        return "".join(buf)

 

-    def string_2_buffer(self, value, type, length, flag):

-        buffer = ''

-        if type == IFT_STRING or type == IFT_BUFFER:

+    def string_2_buffer(self, value, datatype, length, flag):

+        buf = ''

+        if datatype == IFT_STRING or datatype == IFT_BUFFER:

             if value.startswith('0x'):

-                buffer = codecs.decode(value[2:], 'hex')

+                buf = codecs.decode(value[2:], 'hex')

             else:

-                buffer = value

-        elif type == IFT_DATETIME:

-            buffer = ''

+                buf = value

+        elif datatype == IFT_DATETIME:

+            buf = ''

             i = 0

             while i < len(value):

                 t = int(value[i:i + 2])

-                buffer += chr(t & 0xFF)

+                buf += chr(t & 0xFF)

                 i += 2

         else:

             raise ValueError('Input Error')

         if flag == 2:

-            header = struct.pack('<H', len(buffer) % 0x10000)

-            return header + buffer

+            header = struct.pack('<H', len(buf) % 0x10000)

+            return header + buf

         else:

             #if type == IFT_BUFFER:

             #    if len(buffer) % 2 <> 0 or len(buffer)/2 <> length:

             #        raise ValueError("Value length not matched [%s]" % value)

             #    buffer = codecs.decode(buffer,'hex')

-            if len(buffer) != length:

-                padlen = length - len(buffer)

+            if len(buf) != length:

+                padlen = length - len(buf)

                 if padlen < 0:

                     raise ValueError("Value length not matched [%s]" % value)

                 pad = chr(0) * padlen

-                buffer = pad + buffer

-            return buffer

+                buf = pad + buf

+            return buf

 

     def decode_bitmap(self, bitmap):

         if len(bitmap) != 3:

             raise ValueError("bitmap length error")

         #print "bitmap[%s]" % codecs.encode(bitmap,'hex')

-        buffer = []

+        buf = []

         for t in bitmap:

             v = ord(t) & 0xFF

             for i in range(8):

                 x = (v & (1 << (7 - i)))

                 if x > 0:

-                    buffer.append('1')

+                    buf.append('1')

                 else:

-                    buffer.append('0')

-        return buffer

+                    buf.append('0')

+        return buf

 

     def unpack(self, data):

         self.value = {}

-        #print "data[%s]" % codecs.encode(data,'hex')

         data_len = struct.unpack('<H', data[:2])[0]

         if len(data) != data_len + 2:

             print "input[%d] extually[%d]" % (data_len, len(data))

@@ -301,7 +379,8 @@
         offset += 3

         #print bitmap

         for i in range(len(bitmap)):

-            if bitmap[i] == '0': continue

+            if bitmap[i] == '0':

+                continue

             findex = i + 1

             field = self.get_field_def(findex)

             ftype = field[FLD_TYPE_IDX]

@@ -320,33 +399,23 @@
             if ftype == IFT_USHORT or ftype == IFT_ULONG or ftype == IFT_NULL or ftype == IFT_BYTE or ftype == IFT_LONG:

                 value = self.buffer_2_int(data[offset:endpos], ftype)

             else:

-                #temp = self.buffer_2_string(data[offset:endpos],ftype)

-                #if fflag != 2 and ftype == IFT_STRING:

-                #    for i in temp:

-                #        print "char [%02x]" % ord(i)

-                #        if ord(i) > 0:

-                #            value += i

-                #else:

-                #    value = temp

                 value = self.buffer_2_string(data[offset:endpos], ftype)

-                # if fflag != 2 and ftype == IFT_BUFFER:

-                #     value = '0x' + codecs.encode(value, 'hex')

             self.set(findex, value)

             #print "parse field[%s] OK =====" % fname

             offset = endpos

         #print self.value

         return True

 

-    def buffer_2_int(self, data, type):

-        if type == IFT_BYTE:

+    def buffer_2_int(self, data, datatype):

+        if datatype == IFT_BYTE:

             return ord(data)

-        elif type == IFT_USHORT:

+        elif datatype == IFT_USHORT:

             return struct.unpack('<H', data)[0]

-        elif type == IFT_ULONG:

+        elif datatype == IFT_ULONG:

             return struct.unpack('<I', data)[0]

-        elif type == IFT_LONG:

+        elif datatype == IFT_LONG:

             return struct.unpack('<i', data)[0]

-        elif type == IFT_NULL:

+        elif datatype == IFT_NULL:

             return None

         else:

             raise ValueError("input data type error")

@@ -375,12 +444,17 @@
         dl = len(data)

         if dl <= 0 or dl > 4:

             raise ValueError(u"Data length must between 1 and 4")

-        if dl < 4:

-            data = data + chr(0) * (4 - dl)

-        if signed:

-            return struct.unpack('<i', data)[0]

+        fmt = None

+        if dl == 2:

+            fmt = '<h' if signed else '<H'

+        elif dl == 4:

+            fmt = '<i' if signed else '<I'

+        elif dl == 1:

+            fmt = '<b' if signed else '<B'

         else:

-            return struct.unpack('<I', data)[0]

+            fmt = '<i' if signed else '<I'

+            data += chr(0)

+        return struct.unpack(fmt, data)[0]

 

     def set_2byte_int(self, data):

         return struct.pack('<H', data)

@@ -391,3 +465,17 @@
 

     def set_4byte_int(self, data):

         return struct.pack('<I', data)

+

+

+def test():

+    pack = HDPack()

+    pack.msgtype = 0xFF

+    pack.set(2, "0000000000")

+    print codecs.encode(pack.pack(), 'hex')

+

+    data = pack.pack(chr(0xFF) * 8)

+    print codecs.encode(data, 'hex')

+

+

+if __name__ == "__main__":

+    test()

diff --git a/supwisdom/protocol/webservice.py b/supwisdom/protocol/webservice.py
index 29cd25f..418c671 100644
--- a/supwisdom/protocol/webservice.py
+++ b/supwisdom/protocol/webservice.py
@@ -104,6 +104,8 @@
     def _sign_data(self, key, data):

         import hmac

         import hashlib

+        if isinstance(key, unicode):

+            key = key.encode('utf-8')

         h = hmac.new(key, digestmod=hashlib.sha1)

         h.update(data)

         return (h.hexdigest(), 'HMAC')

@@ -181,11 +183,13 @@
             http_resp = client.fetch(http_request)

         except HTTPError, ex:

             http_resp = ex.response

-        except:

+            print u"Error<{0}>".format(http_resp)

+        except BaseException:

             traceback.print_exc()

             return False

 

         if not http_resp:

+            print u"Response is empty"

             return False

         self.status_code = http_resp.code

         if http_resp.code != 200:

@@ -195,7 +199,8 @@
             try:

                 response.unserialize(http_resp.body)

                 return True

-            except:

+            except BaseException as e:

+                print u"Decode Error<{0}>".format(e)

                 return False

 

     def _pack_body(self, request, timeout):