Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,64 @@
# SPDX-License-Identifier: MPL-2.0
import ctypes
from pathlib import Path
import sys
import tempfile
from types import SimpleNamespace
import unittest
from unittest.mock import Mock, patch
sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'tools'))
import usb_protocol as usb
# Captured through sysfs from the actual Sargo diagnostic, high-speed config 1.
SARGO = bytes.fromhex('12011002000000406b1d04010904010203010902200001010080fa0904000002ff0000040705810200020007050102000200')
class USBTransportTests(unittest.TestCase):
def test_pixel_remapped_endpoint(self):
self.assertEqual(usb.parse_endpoints(SARGO,1),{'interface':0,'in':0x81,'out':0x01})
def test_original_endpoint_and_different_interface(self):
descriptors=bytearray(SARGO)
descriptors[-5]=2
descriptors[29]=4
self.assertEqual(usb.parse_endpoints(descriptors,1),{'interface':4,'in':0x81,'out':0x02})
def test_invalid_and_ambiguous_descriptors_rejected(self):
both_in=bytearray(SARGO);both_in[-5]=0x82
interrupt=bytearray(SARGO);interrupt[-4]=3
for data in (b'',b'\0\2',SARGO[:-1],both_in,interrupt,SARGO+SARGO[27:]):
with self.subTest(data=data):
with self.assertRaises(ValueError):
usb.parse_endpoints(data,1)
with self.assertRaises(ValueError):
usb.parse_endpoints(SARGO,2)
def test_transfer_uses_discovered_addresses_and_claims_interface(self):
layout={'interface':4,'out':1,'in':0x81}
endpoints=[]
response=b'TUNDRA_USB_STATUS protocol=1 readOnly=true\nEND\n'
def ioctl(fd,code,pointer):
request=ctypes.cast(pointer,ctypes.POINTER(usb.Bulk)).contents
endpoints.append(request.ep)
if len(endpoints)==1:
self.assertEqual(request.ep,1)
self.assertEqual(ctypes.string_at(request.data,request.length),b'status\n')
return request.length
self.assertEqual(request.ep,0x81)
ctypes.memmove(request.data,response,len(response))
return len(response)
with tempfile.TemporaryFile() as stream, \
patch.object(usb,'device_layout',return_value=layout), \
patch.object(usb.Path,'open',return_value=stream), \
patch.object(usb.fcntl,'ioctl') as claim, \
patch.object(usb.ctypes,'CDLL',return_value=SimpleNamespace(ioctl=Mock(side_effect=ioctl))):
self.assertEqual(usb.exchange('/dev/bus/usb/003/011',('status',)),{'status':response.decode()})
self.assertEqual(claim.call_args.args[2],usb.struct.pack('I',4))
self.assertEqual(endpoints,[1,0x81])
def test_invalid_command_rejected_before_device_access(self):
with patch.object(usb,'device_layout') as layout:
with self.assertRaises(ValueError):
usb.exchange('/dev/bus/usb/003/011',('status\nversion',))
layout.assert_not_called()