Beispiel #1
0
class AgpsServer(object):

    def __init__(self, conf_file):
        ConfHelper.load(conf_file)
        self.redis = MyRedis() 
        self._socket = None
        self.get_agps_thread = None
        
    def start(self):
        self.__start_get_agps_thread()
        try: 
            self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self._socket.bind((ConfHelper.AGPS_CONF['host'], int(ConfHelper.AGPS_CONF['port'])))
            self._socket.listen(int(ConfHelper.AGPS_CONF['count']))
            while True:
                try:
                    infds, _, _ = select.select([self._socket,],[],[],1)
                    if len(infds) > 0:
                        connection, address = self._socket.accept()
                        data = connection.recv(1024)
                        logging.info("[AGPS] Recv %d length request:\n%s", len(data), data)
                        agps_data = self.handle_request(data)
                        if agps_data:
                            connection.send(agps_data)
                            logging.info("[AGPS] Send response length:%s", len(agps_data))
                        connection.close()
                except KeyboardInterrupt:
                    logging.error("[AGPS] Ctrl-C is pressed.") 
                    self._socket.close()
        except:
            logging.exception("[AGPS] Socket exception.") 
        finally:
            try:
                self._socket.close()
            except:
                logging.exception("[AGPS] Socket close exception")

    def handle_request(self, data):
        try:
            packet = T_CLWCheck(data)
            command = packet.head.command
            if command == GATEWAY.T_MESSAGE_TYPE.AGPS:
                head = packet.head
                body = packet.body 
                args = DotDict(success=GATEWAY.RESPONSE_STATUS.SUCCESS,
                               agps_data=None)
                ap = AgpsParser(body, head)
                agps_sign = self.get_agps_sign(ap.ret, int(head.timestamp))
                if agps_sign != int(head.agps_sign, 16):
                    args.success = GATEWAY.RESPONSE_STATUS.INVALID_SESSIONID
                    logging.error("[AGPS] agps_sign invalid.")
                else:
                    agps = ap.ret
                    args.agps_data = self.get_agps_from_redis(agps)
                    if args.agps_data:
                        ac = AgpsComposer(args)
                        return ac.buf
                    else:
                        logging.error("[AGPS] there's no invalid agps data.")
                        return None 
        except:
            logging.exception("[AGPS] Handle agps request exception.")
            return None 

    def get_agps_sign(self, agps, timestamp):
        DEFAULT_KEY = 181084178
        lon = int(agps.lon)
        lat = int(agps.lat)
        agps_sign = DEFAULT_KEY ^ lon ^ lat ^ timestamp 
        return agps_sign 
                    
    def get_agps_from_ublox(self):
        LON_LAT = GATEWAY.LON_LAT
        for key, lon_lat in LON_LAT.items():
            u_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            try:
                request = "cmd=aid;user=%s;pwd=%s;lat=%s;lon=%s;pacc=%s\n" % (
                                                    ConfHelper.UBLOX_CONF.user,
                                                    ConfHelper.UBLOX_CONF.pwd,
                                                    lon_lat[1],
                                                    lon_lat[0],
                                                    ConfHelper.UBLOX_CONF.pacc)
                u_socket.connect((ConfHelper.UBLOX_CONF.host, int(ConfHelper.UBLOX_CONF.port)))
                u_socket.send(request)
                agps_data = self.recv_ublox(u_socket) 
                agps_key = get_agps_data_key(key)
                if agps_data:
                    self.redis.set(agps_key, base64.b64encode(agps_data))
                    logging.info("[AGPS] Get agps data [%s] from ublox success.", key)
                else:
                    self.redis.delete(agps_key)
                    logging.info("[AGPS] Get agps data [%s] from ublox faild.", key)
            except:
                logging.exception("[AGPS] Get agps from u-blox exception.")
            finally:
                try:
                    u_socket.close()
                except:
                    logging.exception("[AGPS] U-blox socket close exception.")               
            time.sleep(10)

    def recv_ublox(self, u_socket):
        default_length = 1024
        split_str = ("\r\n\r\n")
        agps_data = u_socket.recv(default_length)
        head = agps_data.split(split_str)[0]
        binary_length = int(head.split("\n")[1].split(": ")[1])
        logging.info("[AGPS] agps_data length:%d", binary_length)
        remain_length = binary_length - (default_length - (len(head) + len(split_str)))
        while remain_length:
            agps_buf = u_socket.recv(remain_length)
            if not agps_buf:
                logging.warn("[AGPS] recv empty response of socket!")
                u_socket.close() 
                raise socket.error(errno.EPIPE, "the pipe might be broken.")
            agps_data += agps_buf
            remain_length -= len(agps_buf)
        return agps_data[-binary_length:]

    def get_agps_from_redis(self, agps):
        try:
            logging.info("[AGPS] Terminal lon=%s, lat=%s", agps.lon, agps.lat)
            partition_key = self.get_partition_key(float(agps.lon), float(agps.lat))
            agps_key = get_agps_data_key(partition_key)
            agps_data = self.redis.get(agps_key)
            agps_data = agps_data if agps_data else ""
            return agps_data
        except:
            logging.exception("[AGPS] Get agps from redis exception.")
            return ""
 
    def get_partition_key(self, lon, lat):
        LON_LAT = GATEWAY.LON_LAT 
        partition_key = "default"
        for key, lon_lat in LON_LAT.items():
            if abs(float(lon_lat[0]) - lon / 3600000) <= 10 and \
               abs(float(lon_lat[1]) - lat / 3600000) <= 12.5:   
               partition_key = key
               break
        logging.info("[AGPS] agps partition is:%s", partition_key)
        return partition_key

    def __start_get_agps_thread(self):
        self.get_agps_thread = RepeatedTimer(int(ConfHelper.UBLOX_CONF.interval),
                                             self.get_agps_from_ublox)
        self.get_agps_thread.start()
        logging.info("[AGPS] Get agps thread is running...")

    def __stop_get_agps_thread(self):
        if self.get_agps_thread is not None:
            self.get_agps_thread.cancel()
            self.get_agps_thread.join()
            logging.info("[AGPS] Get agps thread stop.")
            self.get_agps_thread = None

    def stop(self):
        self.__stop_get_agps_thread() 
        self._socket.close()
Beispiel #2
0
class Test(object):
    def __init__(self):
        self.db = DBConnection().db
        self.redis = MyRedis()

    def test_session(self):
        tid = 'T123SIMULATOR'
        sessionID_key = get_terminal_sessionID_key(tid)
        old_sessionid = self.redis.get(sessionID_key)
        print  'session_id: %s' % old_sessionid
    
    def test_session(self):
        tid = 'T123SIMULATOR'
        sessionID_key = get_terminal_sessionID_key(tid)
        old_sessionid = self.redis.get(sessionID_key)
        print  'session_id: %s' % old_sessionid
    
    def test_mileage(self):
        tid = '361A000066'
        mileage_key = 'mileage:%s'  % tid
        #mileage = self.redis.getvalue(mileage_key)
    
        # for hmy
        #mileage = dict(lat=80547804,
        #               lon=408846024,
        #               dis=530, 
        #               gps_time=1400733148)
    
        # for lp 
        mileage = dict(lat=144089748,
                       lon=418702032,
                       dis=561, 
                       gps_time=1400732859)
        print  'mileage: %s' % mileage 
        #mileage['dis'] = 530
        self.redis.setvalue(mileage_key, mileage)
    
    def test_acc_status(self):
        #tid = '3489722632'
        tid = '1641486598'
        acc_status_info_key = 'acc_status_info:%s'  % tid
        #acc_status_info_key = "acc_status_info:T123SIMULATOR"
        acc_status_info = self.redis.getvalue(acc_status_info_key)
        print 'tid: %s, acc_status_info_key: %s, acc_status_info: %s' % (tid, 
               acc_status_info_key, acc_status_info)
    
    def test_alarm_info(self):
        tid = '1641486598'
        #tid = 'T123SIMULATOR'
        alarm_info_key = 'alarm_info:%s' % tid
        alarm_info = self.redis.getvalue(alarm_info_key)
        print 'tid: %s, alarm_info_key: %s, alarm_info: %s' % (tid, 
               alarm_info_key, alarm_info)

    def test_terminal_info(self):
        #tid = 'T123SIMULATOR'
        tid = '18701639494'
        terminal_info_key = "terminal_info:%s" % tid
        #self.redis.delete(terminal_info_key)
        terminal_info = self.redis.getvalue(terminal_info_key)
        print 'tid: %s, terminal_info_key: %s, terminal_info: %s' % (tid, 
               terminal_info_key, terminal_info)

    def test_location(self):
        #tid = 'T123SIMULATOR'
        tid = '369A400585'
        location_key = "location:%s" % tid
        #self.redis.delete(location_key)
        location = self.redis.getvalue(location_key)
        print 'tid: %s, location_key: %s, location: %s' % (tid, 
               location_key, location)

    def test_expire(self):
        key = 'jia_expire'
        timestamp = int(time.mktime(time.strptime("%s-%s-%s-%s-%s-%s"%(2014,11,21,16,40,0), "%Y-%m-%d-%H-%M-%S")))
        self.redis.set(key, '1')
        self.redis.expireat(key, timestamp)
Beispiel #3
0
class SimulatorTerminalTest(object):
    """Provide location for TEST Account. 
    """
    
    def __init__(self):
        """Provide some necessary info and create a socket.
        """
        self.tid = 'T123SIMULATOR' 
        self.tmobile = '13011292217'
        self.imsi = '18310505991'
        self.imei = '18310505991'

        self.login_mg = "[%s,,1,1.0.0,%s,T1,%s,18310505991,%s,%s,CLW,2,]"
        self.heartbeat_mg = "[%s,%s,1,1.0.0,%s,T2,23:9:95,1,0]"
        self.location_mg = "[%s,%s,1,1.0.0,%s,T3,1,E,113.25,N,22.564152,120.3,270.5,1,460:0:9876:3171,23:9:100,%s]"
        self.location_mg = "[%(time)s,%(sessionid)s,1,1.0.0,%(tid)s,T3,1,E,%(lon)s,N,%(lat)s,%(speed)s,%(degree)s,1,%(cellid)s,23:9:100,%(time)s]"

        self.db = DBConnection().db
        self.redis = MyRedis()

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        host = ConfHelper.GW_SERVER_CONF.host
        port = int(ConfHelper.GW_SERVER_CONF.port)
        self.socket.connect((host, port))

    #####NOTE: Send packet. 
    def login(self):
        """Send packet T1.
        """
        t_time = int(time.time())
        login_mg = self.login_mg % (t_time, self.tid, self.tmobile, self.imsi, self.imei)
        logging.info("[CK] Send login message:\n%s", login_mg) 
        self.socket.send(login_mg)
        time.sleep(1)
  
    def heartbeat(self):
        """Send packet T2.
        """
        time.sleep(300)
        logging.info("[CK] Simulator terminal heartbeat thread start...")
        while True:
            heartbeat_mg = self.heartbeat_mg % (int(time.time()), self.sessionID, self.tid)
            logging.info("[CK] Send heartbeat:\n%s", heartbeat_mg)
            self.socket.send(heartbeat_mg)
            time.sleep(300)

    def upload_position(self):
        """Send packet T3.
        """
        time.sleep(10)
        logging.info("[CK] Simulator terminal upload position thread start...")
        locations = self.db.query("SELECT latitude, longitude, speed, degree, cellid"
                                  " FROM T_LOCATION_SIMULATOR"
                                  "  WHERE type = 0" 
                                  " GROUP BY timestamp" 
                                  " ORDER BY timestamp")

        count = len(locations)
        self.redis.set('count',count)

        n = self.redis.get('n')
        if n:
            n = int(n)
        else:
            n = 0 
            self.redis.set('n',n)

        while True:
            if n == count:
              n = 0
              self.redis.set('n',n)
            loc = locations[n]
            t_time = int(time.time())
            r = dict(time=t_time,
                     sessionid=self.sessionID,
                     tid=self.tid,
                     lon=float(loc['longitude'])/3600000,
                     lat=float(loc['latitude'])/3600000,
                     speed=loc['speed'],
                     degree=loc['degree'],
                     cellid=loc['cellid'] if loc['cellid'] else '460:0:9876:3171')
            msg = self.location_mg % r

            logging.info("[CK] Upload location:\n%s", msg)
            self.socket.send(msg)
            n = n+1 
            self.redis.set('n',n)
            time.sleep(300) # 5 min

    #NOTE: Handle the response
    def pase_packet(self, packet):
        """Make some simple split
        """
        packet_info = packet[1:][:-1].split(",")
        return packet_info

    def handle_recv(self, packet_info):
        """Receive respnses from Gateway and handle them.
        """
        type = packet_info[1]
        if type == GATEWAY.S_MESSAGE_TYPE.LOGIN:
            self.login_response(packet_info)
        elif type == GATEWAY.S_MESSAGE_TYPE.HEARTBEAT:
            self.heartbeat_response(packet_info)
        elif type == GATEWAY.S_MESSAGE_TYPE.POSITION:
            self.upload_response(packet_info)
        else:
            pass

    def heartbeat_response(self, packet_info):
        """Receve response S2.
        """
        if packet_info[2] == "0":
            logging.info("[CK] Heartbeat send success!")
        else:
            logging.info("[CK] Login faild, login agin...")
            time.sleep(5)
            self.login()

    def upload_response(self, packet_info):
        """Receve response S3.
        """
        if packet_info[2] == "0":
            logging.info("[CK] Location upload success!")
        else:
            logging.info("[CK] Login faild, login agin...")
            time.sleep(5)
            self.login()

    def login_response(self, packet_info):
        """Receve response S1.
        """
        if packet_info[2] == "0":
            self.sessionID = packet_info[3]
            self.start_each_thread()
            logging.info("[CK] Login success!")
        else:
            logging.info("[CK] Login faild, login agin...")
            time.sleep(5)
            self.login()


    def start_each_thread(self):
        thread.start_new_thread(self.heartbeat, ())
        thread.start_new_thread(self.upload_position, ())

    def udp_client(self):
        """Main method.

        workflow:
        login:
        while True:
            receive response from GATEWAY
            handle_recv
        """
        try:
            self.login()
            while True:
                infds, _, _ = select.select([self.socket], [], [], 1)
                if len(infds) > 0:
                    dat = self.socket.recv(1024)
                    logging.info("[CK] Recv data: %s", dat)
                    packet_info = self.pase_packet(dat)
                    self.handle_recv(packet_info)
        except KeyboardInterrupt:
            logging.error("Ctrl-C is pressed.")
        except Exception as e:
            logging.error("[CK] What's wrong, reconnect it.%s", e.args)
        finally:
            self.socket.close()