def _read_data(con, buff, is_push=0):
    '''
    Read a package
    '''
    global last_sync
    buff.truncate(0)
    buff.seek(0)
    while True:
        data = con.recv(1)
        if data==None or data == '':
            raise socket.error("socket connection broken")        
        if data == ETB: 
            break       
        if data == BEL: 
            last_push[is_push] = datetime.datetime.now()
            raise socket.timeout("PING")        
        else:     
            buff.write(data)
    if buff.len>0:
        ca = con.recv(1)
        data = buff.getvalue()
        h = steelsquid_utils.mini_hash(data)
        if h == ca:
            data = data.split("|")
            return data
        else:
            return None
    else:
        return []
def _read_data(con, buff, is_push=0):
    '''
    Read a package
    '''
    global last_sync
    buff.truncate(0)
    buff.seek(0)
    while True:
        data = con.recv(1)
        if data == None or data == '':
            raise socket.error("socket connection broken")
        if data == ETB:
            break
        if data == BEL:
            last_push[is_push] = datetime.datetime.now()
            raise socket.timeout("PING")
        else:
            buff.write(data)
    if buff.len > 0:
        ca = con.recv(1)
        data = buff.getvalue()
        h = steelsquid_utils.mini_hash(data)
        if h == ca:
            data = data.split("|")
            return data
        else:
            return None
    else:
        return []
def _write_err(con, error):
    '''
    Send a package
    '''
    if error==None:
        con.sendall(NAK + ETB)
    else:
        h = steelsquid_utils.mini_hash(error)
        con.sendall(NAK + error + ETB + h)
def _write_err(con, error):
    '''
    Send a package
    '''
    if error == None:
        con.sendall(NAK + ETB)
    else:
        h = steelsquid_utils.mini_hash(error)
        con.sendall(NAK + error + ETB + h)
def _write_ok(con, data):
    '''
    Send a package
    '''
    if data==None:
        con.sendall(ACK + ETB)
    else:
        data = '|'.join([str(mli) for mli in data])
        h = steelsquid_utils.mini_hash(data)
        con.sendall(ACK + data + ETB + h)
def _write_ok(con, data):
    '''
    Send a package
    '''
    if data == None:
        con.sendall(ACK + ETB)
    else:
        data = '|'.join([str(mli) for mli in data])
        h = steelsquid_utils.mini_hash(data)
        con.sendall(ACK + data + ETB + h)
def _read_command(con, buff):
    '''
    Read a package
    '''
    global last_command
    global ping_time
    buff.truncate(0)
    buff.seek(0)
    while True:
        data = con.recv(1)
        if data==None or data == '':
            raise socket.error("socket connection broken")        
        if data == ETB: 
            break       
        if data == BEL: 
            last_command = datetime.datetime.now()
            try:
                start = datetime.datetime.now()
                con.sendall(BEL)
                data = con.recv(1)
                ping_time = (datetime.datetime.now() - start).total_seconds()
            except Exception as e:
                ping_time = 99
                raise e
            raise socket.timeout("PING")        
        else:     
            buff.write(data)
    
    command = buff.getvalue()
    
    buff.truncate(0)
    buff.seek(0)
    while True:
        data = con.recv(1)
        if data==None or data == '':
            raise socket.error("socket connection broken")        
        if data == ETB: 
            break       
        buff.write(data)
    if buff.len>0:
        ca = con.recv(1)
        data = buff.getvalue()
        h = steelsquid_utils.mini_hash(data)
        if h == ca:
            data = data.split("|")
            return command, data
        else:
            return None, None        
    else:
        return command, []
def _read_command(con, buff):
    '''
    Read a package
    '''
    global last_command
    global ping_time
    buff.truncate(0)
    buff.seek(0)
    while True:
        data = con.recv(1)
        if data == None or data == '':
            raise socket.error("socket connection broken")
        if data == ETB:
            break
        if data == BEL:
            last_command = datetime.datetime.now()
            try:
                start = datetime.datetime.now()
                con.sendall(BEL)
                data = con.recv(1)
                ping_time = (datetime.datetime.now() - start).total_seconds()
            except Exception as e:
                ping_time = 99
                raise e
            raise socket.timeout("PING")
        else:
            buff.write(data)

    command = buff.getvalue()

    buff.truncate(0)
    buff.seek(0)
    while True:
        data = con.recv(1)
        if data == None or data == '':
            raise socket.error("socket connection broken")
        if data == ETB:
            break
        buff.write(data)
    if buff.len > 0:
        ca = con.recv(1)
        data = buff.getvalue()
        h = steelsquid_utils.mini_hash(data)
        if h == ca:
            data = data.split("|")
            return command, data
        else:
            return None, None
    else:
        return command, []
def _read_ok_err(con, buff):
    '''
    Read a package
    '''
    global last_command
    buff.truncate(0)
    buff.seek(0)
    is_ok = None
    while True:
        data = con.recv(1)
        if data==None or data == '':
            raise socket.error("socket connection broken")        
        if data == ETB: 
            break       
        if is_ok==None:
            if data == ACK: 
                is_ok = True
            if data == NAK: 
                is_ok = False
        else:     
            buff.write(data)
    if buff.len>0:
        ca = con.recv(1)
        data = buff.getvalue()
        h = steelsquid_utils.mini_hash(data)
        if h == ca:
            if is_ok:
                return True, data.split("|")
            else:
                return False, data
        else:
            raise socket.timeout("CRC error")        
    else:
        if is_ok:
            return True, []
        else:
            return False, ""
def _read_ok_err(con, buff):
    '''
    Read a package
    '''
    global last_command
    buff.truncate(0)
    buff.seek(0)
    is_ok = None
    while True:
        data = con.recv(1)
        if data == None or data == '':
            raise socket.error("socket connection broken")
        if data == ETB:
            break
        if is_ok == None:
            if data == ACK:
                is_ok = True
            if data == NAK:
                is_ok = False
        else:
            buff.write(data)
    if buff.len > 0:
        ca = con.recv(1)
        data = buff.getvalue()
        h = steelsquid_utils.mini_hash(data)
        if h == ca:
            if is_ok:
                return True, data.split("|")
            else:
                return False, data
        else:
            raise socket.timeout("CRC error")
    else:
        if is_ok:
            return True, []
        else:
            return False, ""