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()
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)
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()