mirror of
git://github.com/kovidgoyal/calibre.git
synced 2025-12-06 14:26:06 +01:00
163 lines
7.9 KiB
Python
Executable file
163 lines
7.9 KiB
Python
Executable file
#!/usr/bin/env python
|
|
## Copyright (C) 2006 Kovid Goyal kovid@kovidgoyal.net
|
|
## This program is free software; you can redistribute it and/or modify
|
|
## it under the terms of the GNU General Public License as published by
|
|
## the Free Software Foundation; either version 2 of the License, or
|
|
## (at your option) any later version.
|
|
##
|
|
## This program is distributed in the hope that it will be useful,
|
|
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
## GNU General Public License for more details.
|
|
##
|
|
## You should have received a copy of the GNU General Public License along
|
|
## with this program; if not, write to the Free Software Foundation, Inc.,
|
|
## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
import sys, re
|
|
from prstypes import *
|
|
|
|
# The sequence of control commands to send the device before attempting any operations. Should be preceeded by a reset?
|
|
initialization = []
|
|
initialization.append(\
|
|
ControlQuery(TransferBuffer((0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0)),\
|
|
TransferBuffer((0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), bulkTransfer=24))
|
|
initialization.append(\
|
|
ControlQuery(TransferBuffer((0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), \
|
|
TransferBuffer((0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))))
|
|
initialization.append(\
|
|
ControlQuery(TransferBuffer((7, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 128, 2, 0)), \
|
|
TransferBuffer((0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))))
|
|
initialization.append(\
|
|
ControlQuery(TransferBuffer((0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0)), \
|
|
TransferBuffer((0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), bulkTransfer=24))
|
|
initialization.append(\
|
|
ControlQuery(TransferBuffer((0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), \
|
|
TransferBuffer((0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))))
|
|
initialization.append(\
|
|
ControlQuery(TransferBuffer((6, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 45, 49, 0, 0, 0, 0, 0, 0)), \
|
|
TransferBuffer((0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))))
|
|
initialization.append(\
|
|
ControlQuery(TransferBuffer((1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0)), \
|
|
TransferBuffer((0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))))
|
|
|
|
end_transaction = \
|
|
ControlQuery(TransferBuffer((1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0)),\
|
|
TransferBuffer((0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)))
|
|
|
|
def string_to_buffer(string):
|
|
""" Convert a string to a TransferBuffer """
|
|
return TransferBuffer([ ord(ch) for ch in string ])
|
|
|
|
class LSQuery(ControlQuery):
|
|
"""
|
|
Contains all the device specific data (packet formats) needed to implement a simple ls command.
|
|
See PRS500Device.ls() to understand how it is used.
|
|
"""
|
|
PATH_NOT_FOUND_RESPONSE = (0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 215, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
IS_FILE_RESPONSE = (0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 210, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
NOT_MOUNTED_RESPONSE = (0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 200, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
INVALID_PATH_RESPONSE = (0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 24, 0, 0, 0, 249, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
ACKNOWLEDGE_RESPONSE = (0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0x35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
ACKNOWLEDGE_COMMAND = (0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
SEND_NAME_COMMAND = (53, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4 , 0, 0, 0, 0, 0, 0, 0)
|
|
EOL_RESPONSE = (0, 16, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 53, 0, 0, 0, 250, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
|
|
|
|
def __init__(self, path, type=1):
|
|
self.path = path
|
|
if len(self.path) >= 8:
|
|
self.path_fragment = self.path[8:]
|
|
for i in range(4 - len(self.path_fragment)):
|
|
self.path_fragment += '\x00'
|
|
self.path_fragment = [ ord(self.path_fragment[i]) for i in range(4) ]
|
|
else:
|
|
self.path_fragment = [ 0x00 for i in range(4) ]
|
|
src = [ 0x00 for i in range(20) ]
|
|
if type == 1:
|
|
src[0] = 0x18
|
|
elif type == 2:
|
|
src[0] = 0x33
|
|
src[4], src[12], src[16] = 0x01, len(path)+4, len(path)
|
|
query = TransferBuffer(src) + string_to_buffer(path)
|
|
src = [ 0x00 for i in range(32) ]
|
|
src[1], src[4], src[12], src[16] = 0x10, 0x01, 0x0c, 0x18
|
|
if type == 2: src[16] = 0x33
|
|
ControlQuery.__init__(self, query, TransferBuffer(src), bulkTransfer = 0x28)
|
|
|
|
def acknowledge_query(self, type, error_type=0):
|
|
"""
|
|
Return the acknowledge query used after receiving data as part of an ls query
|
|
|
|
type - should only take values 0,1,2,3 corresponding to the 4 different types of acknowledge queries.
|
|
If it takes any other value it is assumed to be zero.
|
|
|
|
error_type - 0 = no error, 1 = path not found, 2 = is file, 3 = not mounted, 4 = invalid path
|
|
"""
|
|
if error_type == 1:
|
|
response = list(LSQuery.PATH_NOT_FOUND_RESPONSE)
|
|
response[4] = 0x00
|
|
elif error_type == 2:
|
|
response = list(LSQuery.IS_FILE_RESPONSE)
|
|
response[4] = 0x00
|
|
elif error_type == 3:
|
|
response = list(LSQuery.NOT_MOUNTED_RESPONSE)
|
|
response[4] = 0x00
|
|
elif error_type == 4:
|
|
response = list(LSQuery.INVALID_PATH_RESPONSE)
|
|
response[4] = 0x00
|
|
else: response = list(LSQuery.ACKNOWLEDGE_RESPONSE)
|
|
query = list(LSQuery.ACKNOWLEDGE_COMMAND)
|
|
response[-4:] = self.path_fragment
|
|
if type == 1:
|
|
query[16] = 0x03
|
|
response[16] = 0x18
|
|
elif type == 2:
|
|
query[16] = 0x06
|
|
response[16] = 0x33
|
|
elif type == 3:
|
|
query[16] = 0x07
|
|
response[16] = 0x35
|
|
else: # All other type values are mapped to 0, which is an EOL condition
|
|
response[20], response[21], response[22], response[23] = 0xfa, 0xff, 0xff, 0xff
|
|
|
|
return ControlQuery(TransferBuffer(query), TransferBuffer(response))
|
|
|
|
def send_name_query(self, buffer):
|
|
"""
|
|
Return a ControlQuery that will cause the device to send the next name in the list
|
|
|
|
buffer - TransferBuffer that contains 4 bytes of information that identify the directory we are listing.
|
|
|
|
Note that the response to this command contains information (the size of the receive buffer for the next bulk read) thus
|
|
the expected response is set to null.
|
|
"""
|
|
query = list(LSQuery.SEND_NAME_COMMAND)
|
|
query[-4:] = list(buffer)[-4:]
|
|
response = [ 0x00 for i in range(32) ]
|
|
return ControlQuery(TransferBuffer(query), TransferBuffer(response))
|
|
|
|
|
|
def main(file):
|
|
""" Convenience method for converting spike.pl output to python code. Used to read control packet data from USB logs """
|
|
PSF = open(file, 'r')
|
|
lines = PSF.readlines()
|
|
|
|
packets = []
|
|
temp = []
|
|
for line in lines:
|
|
if re.match("\s+$", line):
|
|
temp = "".join(temp)
|
|
packet = []
|
|
for i in range(0, len(temp), 2):
|
|
packet.append(int(temp[i]+temp[i+1], 16))
|
|
temp = []
|
|
packets.append(tuple(packet))
|
|
continue
|
|
temp = temp + line.split()
|
|
print r"seq = []"
|
|
for i in range(0, len(packets), 2):
|
|
print "seq.append(ControlQuery(TransferBuffer(" + str(packets[i]) + "), TransferBuffer(" + str(packets[i+1]) + ")))"
|
|
|
|
if __name__ == "__main__":
|
|
main(sys.argv[1])
|