增加swagent 接口库
diff --git a/supwisdom/agentlink/__init__.py b/supwisdom/agentlink/__init__.py
new file mode 100644
index 0000000..1c7d390
--- /dev/null
+++ b/supwisdom/agentlink/__init__.py
@@ -0,0 +1,179 @@
+# -*- coding: utf-8
+"""
+agentlink 模块,提供与 swagent 通讯协议的封装
+"""
+import codecs
+import socket
+import struct
+import random
+import time
+import os
+import traceback
+
+__all__ = ['VERSION', 'SWAgentLink']
+
+VERSION = "4.0.0"
+
+
+class SWAgentLink(object):
+    """
+    agentlink 协议封装
+    """
+    MSG_LEN_FMT = '!H'
+    MSG_HEADER_FMT = '!IIIBB'
+    MSG_HEADER_DESC = ('major_version', 'minor_version', 'unique_no', 'msg_type', 'retcode')
+    # 协议版本号定义
+    MAJOR_VERSION = 1
+    MINOR_VERSION = 1
+
+    def __init__(self):
+        self.sock = None
+        self.ip = None
+        self.port = None
+        self.timeout = 10.0
+        self._is_login = False
+        self.unique_no = None
+        self.connection_id = None
+        random.seed(time.time())
+
+    def connect(self, ip, port):
+        self.close()
+        try:
+            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            sock.settimeout(self.timeout)
+            sock.connect((ip, port))
+            self.sock = sock
+            self.ip = ip
+            self.port = port
+            return True
+        except socket.error:
+            return False
+
+    def login(self):
+        msg_type = 0x30
+        process_id = struct.pack('!I', os.getpid())
+        message_header = self._new_message(msg_type)
+        login_data = self._pack_request(message_header, process_id)
+        data = self._send_and_recv(login_data, 5.0)
+        if not data:
+            return False
+        login_resp = self._unpack_request(data)
+        if not self._check_response(message_header, login_resp):
+            print u"Login response error"
+            return False
+        if login_resp['retcode'] != 0:
+            print u"Login error retcode={0}".format(login_resp['retcode'])
+            return False
+        self.connection_id = login_resp['data']
+        self._is_login = True
+        return True
+
+    def _send_and_recv(self, request, timeout):
+        header_len = struct.calcsize(self.MSG_LEN_FMT)
+        try:
+            self.sock.settimeout(timeout)
+            self.sock.send(request)
+            # print u"Send[{0}]".format(codecs.encode(request, 'hex'))
+            header = self.sock.recv(header_len)
+            if not header:
+                return None
+            body_len = struct.unpack(self.MSG_LEN_FMT, header)[0]
+            body = self.sock.recv(body_len)
+            # print u"Recv[{0}]".format(codecs.encode(body, 'hex'))
+            return body
+        except socket.error as e:
+            print u"socket send and recv error, error: <{0}>".format(e)
+            traceback.print_exc()
+            self.sock.close()
+            self.sock = None
+            self._is_login = False
+            return None
+
+    def get_data(self):
+        msg_type = 0x32
+        message_header = self._new_message(msg_type)
+        req_data = self._pack_request(message_header, self.connection_id)
+        data = self._send_and_recv(req_data, None)
+        if not data:
+            return False
+        getdata_resp = self._unpack_request(data)
+        if not self._check_response(message_header, getdata_resp):
+            print u"get data error"
+            return None
+        if getdata_resp['retcode'] != 0:
+            print u"GetData error retcode={0}".format(getdata_resp['retcode'])
+            return None
+        data = getdata_resp['data']
+        # print codecs.encode(data, 'hex')
+        data_head_len = struct.calcsize('!I')
+        data_len = struct.unpack('!I', data[:data_head_len])[0]
+        if data_len != len(data) - data_head_len:
+            return None
+        return data[data_head_len: data_head_len + data_len]
+
+    def answer_data(self, response):
+        msg_type = 0x34
+        message_header = self._new_message(msg_type)
+        req_data = self._pack_request(message_header, self.connection_id + response)
+        data = self._send_and_recv(req_data, None)
+        answer_resp = self._unpack_request(data)
+        if not self._check_response(message_header, answer_resp):
+            print u"answer data error"
+            return False
+        if answer_resp['retcode'] != 0:
+            print u"Answer error retcode={0}".format(answer_resp['retcode'])
+            return False
+        return True
+
+    def _new_message(self, msg_type):
+        unique_no = random.randint(0x10000000, 0xFFFFFFFF)
+        return dict(major_version=self.MAJOR_VERSION, minor_version=self.MINOR_VERSION,
+                    unique_no=unique_no, msg_type=msg_type, retcode=0)
+
+    def _pack_request(self, message_header, data):
+        header = struct.pack(self.MSG_HEADER_FMT, message_header['major_version'],
+                             message_header['minor_version'], message_header['unique_no'],
+                             message_header['msg_type'], message_header['retcode'])
+        r = []
+        if not data:
+            r.append(struct.pack(self.MSG_LEN_FMT, len(header)))
+            r.append(data)
+        else:
+            r.append(struct.pack(self.MSG_LEN_FMT, (len(header) + len(data))))
+            r.append(header)
+            r.append(data)
+        return ''.join(r)
+
+    def close(self):
+        if self.sock:
+            self.sock.close()
+            self.sock = None
+        self._is_login = False
+
+    def is_ok(self):
+        if not self.sock:
+            return False
+        if not self._is_login:
+            return False
+        return True
+
+    def _unpack_request(self, data):
+        if not data:
+            return None
+        header_len = struct.calcsize(self.MSG_HEADER_FMT)
+        if header_len > len(data):
+            return None
+        resp = struct.unpack(self.MSG_HEADER_FMT, data[:header_len])
+        resp_dict = dict(zip(self.MSG_HEADER_DESC, resp))
+        resp_dict['data'] = data[header_len:]
+        return resp_dict
+
+    def _check_response(self, message_header, response):
+        if not response:
+            return False
+        if (message_header['major_version'] != response['major_version']
+            or message_header['minor_version'] != response['minor_version']
+            or message_header['unique_no'] != response['unique_no']
+            or message_header['msg_type'] != response['msg_type']):
+            return False
+        return True
diff --git a/supwisdom/protocol/webservice.py b/supwisdom/protocol/webservice.py
index 2a1b7a1..f6fd39a 100644
--- a/supwisdom/protocol/webservice.py
+++ b/supwisdom/protocol/webservice.py
@@ -176,6 +176,7 @@
             http_request = HTTPRequest(url=self.service_url, method='POST',

                 headers={'Content-Type': 'application/json'},

                 connect_timeout=timeout,

+                request_timeout=timeout,

                 body=self._pack_body(request, timeout))

             http_resp = client.fetch(http_request)

         except HTTPError, ex: