Skip to content

Commit bd081a0

Browse files
committed
More listdir work
1 parent 82c571b commit bd081a0

File tree

2 files changed

+80
-27
lines changed

2 files changed

+80
-27
lines changed

adafruit_ble_file_transfer.py

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -103,29 +103,47 @@ class FileTransferService(Service):
103103

104104
ERR_NO_FILE = 0xb0
105105

106+
106107
class FileTransferClient:
107108
def __init__(self, service):
108109
self._service = service
109110

111+
def _write(self, buffer):
112+
sent = 0
113+
while sent < len(buffer):
114+
remaining = len(buffer) - sent
115+
next_send = min(self._service.raw.outgoing_packet_length, remaining)
116+
self._service.raw.write(buffer[sent:sent+next_send])
117+
sent += next_send
118+
119+
def _readinto(self, buffer):
120+
read = 0
121+
# Read back how much we can write
122+
while read == 0:
123+
try:
124+
read = self._service.raw.readinto(buffer)
125+
except ValueError:
126+
long_buffer = bytearray(512)
127+
read = self._service.raw.readinto(long_buffer)
128+
print("long packet", long_buffer[:read])
129+
return read
130+
110131
def read(self, path):
111132
print("read", path)
112133
path = path.encode("utf-8")
113134
chunk_size = 10
114135
encoded = struct.pack(">BIH", FileTransferService.READ, chunk_size, len(path)) + path
115-
# TODO: we may need to split this packet up.
116-
r = self._service.raw.write(encoded)
136+
r = self._write(encoded)
117137
b = bytearray(struct.calcsize(">BBII") + chunk_size)
118-
print("write", r, encoded)
119138
contents_read = 0
120139
content_length = None
121140
buf = None
122141
while content_length is None or contents_read < content_length:
123-
read = 0
124-
# Read back how much we can write
125-
while read == 0:
126-
read = self._service.raw.readinto(b)
142+
read = self._readinto(b)
127143
cmd, status, content_length, chunk_length = struct.unpack_from(">BBII", b)
128144
print("got reply", cmd, status, content_length, chunk_length)
145+
if status != FileTransferService.OK:
146+
raise ValueError("Missing file")
129147
if buf is None:
130148
buf = bytearray(content_length)
131149
header_size = struct.calcsize(">BBII")
@@ -144,16 +162,12 @@ def write(self, path, contents):
144162
print("write", path, contents)
145163
path = path.encode("utf-8")
146164
encoded = struct.pack(">BIH", FileTransferService.WRITE, len(contents), len(path)) + path
147-
# TODO: we may need to split this packet up.
148-
r = self._service.raw.write(encoded)
165+
r = self._write(encoded)
149166
b = bytearray(struct.calcsize(">BBI"))
150167
print("write", r, encoded)
151168
written = 0
152169
while written < len(contents):
153-
read = 0
154-
# Read back how much we can write
155-
while read == 0:
156-
read = self._service.raw.readinto(b)
170+
read = self._readinto(b)
157171
cmd, status, free_space = struct.unpack(">BBI", b)
158172
print(cmd, status, free_space)
159173
self._service.raw.write(contents[written:written+free_space])
@@ -163,19 +177,32 @@ def mkdir(self, path):
163177
print("mkdir", path)
164178
path = path.encode("utf-8")
165179
encoded = struct.pack(">BH", FileTransferService.MKDIR, len(path)) + path
166-
# TODO: we may need to split this packet up.
167-
r = self._service.raw.write(encoded)
180+
r = self._write(encoded)
168181

169182
b = bytearray(struct.calcsize(">BB"))
170-
read = 0
171-
# Read back how much we can write
172-
while read == 0:
173-
read = self._service.raw.readinto(b)
183+
read = self._readinto(b)
174184
cmd, status = struct.unpack(">BB", b)
175185
print(cmd, status)
176186

177187
def listdir(self, path):
178188
print("listdir", path)
189+
path = path.encode("utf-8")
190+
chunk_size = 10
191+
encoded = struct.pack(">BH", FileTransferService.LISTDIR, len(path)) + path
192+
r = self._write(encoded)
193+
b = bytearray(struct.calcsize(">BBIIBIH"))
194+
i = 0
195+
total = 10
196+
while i < total:
197+
read = self._readinto(b)
198+
cmd, status, i, total, flags, file_size, path_length = struct.unpack(">BBIIBIH", b)
199+
if i >= total:
200+
break
201+
if len(b) < path_length:
202+
b = bytearray(path_length)
203+
read = self._readinto(b)
204+
path = str(b[:read], "utf-8")
205+
print(i, total, flags, file_size, path)
179206

180207
def delete(self, path):
181208
print("delete", path)

examples/ble_file_transfer_stub_server.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def find_dir(path):
3232
piece = pieces[i]
3333
if piece not in parent:
3434
return None
35-
parent = piece
35+
parent = parent[piece]
3636
i += 1
3737
return parent
3838

@@ -59,7 +59,9 @@ def find_dir(path):
5959
contents_read = 0
6060
contents = bytearray(content_length)
6161
print("write", content_length, path)
62-
print(path.split("/"))
62+
d = find_dir(path)
63+
filename = path.split("/")[-1]
64+
print(filename)
6365
while contents_read < content_length:
6466
next_amount = min(10, content_length - contents_read)
6567
#print(FileTransferService.WRITE, FileTransferService.OK)
@@ -69,27 +71,28 @@ def find_dir(path):
6971
read = service.raw.readinto(packet_buffer)
7072
contents[contents_read:contents_read+read] = packet_buffer[:read]
7173
contents_read += read
72-
#print(read, packet_buffer[:read])
73-
stored_data[path] = contents
74+
print(read, packet_buffer[:read])
75+
d[filename] = contents
7476

7577
elif command == adafruit_ble_file_transfer.FileTransferService.READ:
7678
free_space, path_length = struct.unpack_from(">IH", p, offset=1)
7779
path_start = struct.calcsize(">BIH")
7880
path = str(p[path_start:path_start+path_length], "utf-8")
7981
print("read", path)
8082
d = find_dir(path)
81-
if path not in d:
83+
filename = path.split("/")[-1]
84+
if filename not in d:
8285
print("missing path")
83-
service.raw.write(struct.pack(">BBB", FileTransferService.READ, FileTransferService.ERR, FileTransferService.ERR_NO_FILE))
86+
service.raw.write(struct.pack(">BBII", FileTransferService.READ, FileTransferService.ERR, 0, 0))
8487
continue
8588

8689
contents_sent = 0
87-
contents = stored_data[path]
90+
contents = stored_data[filename]
8891
while contents_sent < len(contents):
8992
remaining = len(contents) - contents_sent
9093
next_amount = min(remaining, free_space)
9194
print("sending", next_amount)
92-
header = struct.pack(">BBII", FileTransferService.WRITE, FileTransferService.OK, len(contents), next_amount)
95+
header = struct.pack(">BBII", FileTransferService.READ, FileTransferService.OK, len(contents), next_amount)
9396
service.raw.write(header + contents[contents_sent:contents_sent + next_amount])
9497
contents_sent += next_amount
9598

@@ -122,6 +125,29 @@ def find_dir(path):
122125
else:
123126
header = struct.pack(">BB", FileTransferService.WRITE, FileTransferService.ERR)
124127
service.raw.write(header)
128+
elif command == adafruit_ble_file_transfer.FileTransferService.LISTDIR:
129+
path_length = struct.unpack_from(">H", p, offset=1)[0]
130+
path_start = struct.calcsize(">BH")
131+
path = str(p[path_start:path_start+path_length], "utf-8")
132+
print("listdir", path)
133+
134+
# cmd, status, i, total, flags, file_size, path_length = struct.unpack(">BBIIBIH", b)
135+
136+
d = find_dir(path)
137+
if d is None:
138+
error = struct.pack(">BBIIBIH", FileTransferService.WRITE, FileTransferService.ERR, 0, 0, 0, 0, 0)
139+
service.raw.write(error)
140+
141+
print(d, type(d))
142+
filenames = sorted(d.keys())
143+
total_files = len(filenames)
144+
for i, filename in enumerate(filenames):
145+
print(i, filename)
146+
header = struct.pack(">BBIIBIH", FileTransferService.WRITE, FileTransferService.OK, i, total_files, 0, 0, 0)
147+
service.raw.write(header + filename.encode("utf-8"))
148+
print("send last entry")
149+
header = struct.pack(">BBIIBIH", FileTransferService.WRITE, FileTransferService.OK, total_files, total_files, 0, 0, 0)
150+
service.raw.write(header)
125151
else:
126152
print("unknown command", command)
127153
print("disconnected")

0 commit comments

Comments
 (0)