sdwire 0.2.4__py3-none-any.whl → 0.3.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
sdwire/backend/detect.py CHANGED
@@ -1,23 +1,38 @@
1
+ """SDWire device detection module.
2
+
3
+ This module provides functions to detect and enumerate SDWire devices
4
+ connected to the system via USB, including both SDWire3 and SDWireC variants.
5
+ """
6
+
1
7
  import logging
2
- from typing import List
8
+ from typing import List, Union
3
9
 
4
10
  from sdwire import constants
5
- from .device.sdwire import SDWire, SDWIRE_GENERATION_SDWIRE3
6
- from .device.sdwirec import SDWireC
7
- from .device.usb_device import PortInfo
11
+ from sdwire.backend.device.sdwire import SDWire, SDWIRE_GENERATION_SDWIRE3
12
+ from sdwire.backend.device.sdwirec import SDWireC
13
+ from sdwire.backend.device.usb_device import PortInfo
8
14
 
9
- import pyudev
10
15
  import usb.core
11
16
  import usb.util
12
- from usb.core import Device
13
17
 
14
18
  log = logging.getLogger(__name__)
15
19
 
16
20
 
17
21
  def get_sdwirec_devices() -> List[SDWireC]:
18
- devices: List[Device] = usb.core.find(find_all=True)
22
+ """Detect and return all connected SDWireC devices.
23
+
24
+ Returns:
25
+ List of SDWireC device instances found on the system
26
+ """
27
+ try:
28
+ found_devices = usb.core.find(find_all=True)
29
+ devices = list(found_devices or [])
30
+ except Exception as e:
31
+ log.debug("Error finding USB devices: %s", e)
32
+ return []
33
+
19
34
  if not devices:
20
- log.info("no usb devices found while searching for SDWireC..")
35
+ log.debug("No USB devices found while searching for SDWireC")
21
36
  return []
22
37
 
23
38
  device_list = []
@@ -26,9 +41,10 @@ def get_sdwirec_devices() -> List[SDWireC]:
26
41
  serial = None
27
42
  manufacturer = None
28
43
  try:
29
- product = device.product
30
- serial = device.serial_number
31
- manufacturer = device.manufacturer
44
+ # Safe attribute access
45
+ product = getattr(device, "product", None)
46
+ serial = getattr(device, "serial_number", None)
47
+ manufacturer = getattr(device, "manufacturer", None)
32
48
  except Exception as e:
33
49
  log.debug(
34
50
  "not able to get usb product, serial_number and manufacturer information, err: %s",
@@ -44,48 +60,64 @@ def get_sdwirec_devices() -> List[SDWireC]:
44
60
  return device_list
45
61
 
46
62
 
47
- def get_sdwire_devices() -> List[SDWire]:
48
- # Badgerd SDWire3
49
- # VID = 0bda PID = 0316
50
- # Badgerd SDWireC
51
- # VID = 0x04e8 PID = 0x6001
52
- result = []
53
- devices: List[Device] = pyudev.Context().list_devices(
54
- subsystem="usb",
55
- ID_VENDOR_ID=f"{constants.SDWIRE3_VID:04x}",
56
- ID_MODEL_ID=f"{constants.SDWIRE3_PID:04x}",
57
- )
63
+ def get_sdwire_devices() -> List[Union[SDWire, SDWireC]]:
64
+ """Detect and return all connected SDWire devices (both SDWire3 and SDWireC).
65
+
66
+ This function searches for:
67
+ - SDWire3 devices (VID: 0x0bda, PID: 0x0316)
68
+ - SDWireC devices (VID: 0x04e8, PID: 0x6001)
69
+
70
+ Returns:
71
+ List of SDWire device instances (SDWire or SDWireC) found on the system
72
+ """
73
+ result: List[Union[SDWire, SDWireC]] = []
74
+ try:
75
+ found_devices = usb.core.find(
76
+ find_all=True,
77
+ idVendor=constants.SDWIRE3_VID,
78
+ idProduct=constants.SDWIRE3_PID,
79
+ )
80
+ devices = list(found_devices or [])
81
+ except Exception as e:
82
+ log.debug("Error finding SDWire3 devices: %s", e)
83
+ devices = []
84
+
58
85
  if not devices:
59
86
  log.info("no usb devices found while searching for SDWire..")
60
- return []
61
-
62
- for device in devices:
63
- product = None
64
- serial = None
65
- bus = None
66
- address = None
67
- try:
68
- product = int(f"0x{device.get('ID_MODEL_ID')}", 16)
69
- vendor = int(f"0x{device.get('ID_VENDOR_ID')}", 16)
70
- bus = int(device.get("BUSNUM"))
71
- address = int(device.get("DEVNUM"))
72
- serial = f"{device.get('ID_USB_SERIAL_SHORT')}:{bus}.{address}"
73
- except Exception as e:
74
- log.debug(
75
- "not able to get usb product, serial_number and manufacturer information, err: %s",
76
- e,
77
- )
87
+ else:
88
+ for device in devices:
89
+ product = None
90
+ serial = None
91
+ vendor = None
92
+ bus = None
93
+ address = None
94
+ try:
95
+ # Safe attribute access
96
+ product = getattr(device, "idProduct", None)
97
+ vendor = getattr(device, "idVendor", None)
98
+ bus = getattr(device, "bus", None)
99
+ address = getattr(device, "address", None)
100
+ serial_num = getattr(device, "serial_number", None) or "unknown"
101
+ port_numbers = getattr(device, "port_numbers", None)
102
+ serial = (
103
+ f"{serial_num}.{'.'.join(map(str, port_numbers))}"
104
+ if port_numbers
105
+ else f"{serial_num}:{bus}.{address}"
106
+ )
107
+ except Exception as e:
108
+ log.debug(
109
+ "not able to get usb product, serial_number and manufacturer information, err: %s",
110
+ e,
111
+ )
78
112
 
79
- if product == constants.SDWIRE3_PID and vendor == constants.SDWIRE3_VID:
80
- usb_device: List[Device] = usb.core.find(
81
- idVendor=vendor, idProduct=product, bus=bus, address=address
82
- )
83
- result.append(
84
- SDWire(
85
- port_info=PortInfo(device, product, vendor, serial, usb_device),
86
- generation=SDWIRE_GENERATION_SDWIRE3,
113
+ if product == constants.SDWIRE3_PID and vendor == constants.SDWIRE3_VID:
114
+ result.append(
115
+ SDWire(
116
+ port_info=PortInfo(device, product, vendor, serial, device),
117
+ generation=SDWIRE_GENERATION_SDWIRE3,
118
+ )
87
119
  )
88
- )
120
+
89
121
  # Search for legacy SDWireC devices
90
122
  legacy_devices = get_sdwirec_devices()
91
123
 
@@ -1,5 +1,8 @@
1
1
  import logging
2
- from .usb_device import USBDevice, PortInfo
2
+ from typing import Optional
3
+ import usb.core
4
+ from sdwire.backend.device.usb_device import USBDevice, PortInfo
5
+ from sdwire.backend.block_device_utils import map_usb_device_to_block_device
3
6
 
4
7
  log = logging.getLogger(__name__)
5
8
 
@@ -12,15 +15,13 @@ class SDWire(USBDevice):
12
15
  def __init__(self, port_info: PortInfo, generation: int):
13
16
  super().__init__(port_info)
14
17
  self.generation = generation
15
- for sibling in self.dev_string.parent.children:
16
- if (
17
- self.dev_string.device_path != sibling.device_path
18
- and sibling.device_type == "disk"
19
- ):
20
- self.__block_dev = f"/dev/{sibling.device_path.split('/')[-1]}"
21
- break
22
-
23
- def switch_ts(self):
18
+ self._update_block_device()
19
+
20
+ def switch_ts(self) -> None:
21
+ if not self.usb_device:
22
+ log.error("USB device not available")
23
+ return
24
+
24
25
  try:
25
26
  self.usb_device.attach_kernel_driver(0)
26
27
  self.usb_device.reset()
@@ -30,7 +31,11 @@ class SDWire(USBDevice):
30
31
  e,
31
32
  )
32
33
 
33
- def switch_dut(self):
34
+ def switch_dut(self) -> None:
35
+ if not self.usb_device:
36
+ log.error("USB device not available")
37
+ return
38
+
34
39
  try:
35
40
  self.usb_device.detach_kernel_driver(0)
36
41
  self.usb_device.reset()
@@ -40,12 +45,41 @@ class SDWire(USBDevice):
40
45
  e,
41
46
  )
42
47
 
48
+ def _update_block_device(self) -> None:
49
+ """Update block device detection based on current device state."""
50
+ if not self.usb_device:
51
+ self.__block_dev = None
52
+ return
53
+
54
+ try:
55
+ storage_device = self.storage_device
56
+ if storage_device is not None:
57
+ self.__block_dev = map_usb_device_to_block_device(storage_device)
58
+ log.debug(f"SDWire3: Found block device: {self.__block_dev}")
59
+ else:
60
+ self.__block_dev = None
61
+ except Exception as e:
62
+ log.debug(f"SDWire3: Block device detection failed: {e}")
63
+ self.__block_dev = None
64
+
43
65
  @property
44
- def block_dev(self):
66
+ def block_dev(self) -> Optional[str]:
45
67
  return self.__block_dev
46
68
 
47
- def __str__(self):
48
- return f"{self.serial_string}\t[{int(self.manufacturer_string):04x}::{int(self.product_string):04x}]\t\t{self.block_dev}"
69
+ @property
70
+ def storage_device(self) -> Optional[usb.core.Device]:
71
+ """Return the USB device that corresponds to the storage interface.
72
+
73
+ For SDWire3, this is the same device we control (direct media controller).
74
+
75
+ Returns:
76
+ usb.core.Device: The USB device for storage, or None if not available
77
+ """
78
+ return self.usb_device
79
+
80
+ def __str__(self) -> str:
81
+ block_dev_str = self.block_dev if self.block_dev is not None else "None"
82
+ return f"{self.serial_string:<30}[{int(self.manufacturer_string):04x}::{int(self.product_string):04x}]\t\t{block_dev_str}"
49
83
 
50
- def __repr__(self):
84
+ def __repr__(self) -> str:
51
85
  return self.__str__()
@@ -1,6 +1,12 @@
1
1
  import logging
2
+ from typing import Optional
2
3
  from pyftdi.ftdi import Ftdi
3
- from .usb_device import USBDevice, PortInfo
4
+ import usb.core
5
+ from sdwire.backend.device.usb_device import USBDevice, PortInfo
6
+ from sdwire.backend.block_device_utils import (
7
+ map_usb_device_to_block_device,
8
+ find_sibling_storage_device,
9
+ )
4
10
 
5
11
  log = logging.getLogger(__name__)
6
12
 
@@ -10,35 +16,63 @@ class SDWireC(USBDevice):
10
16
 
11
17
  def __init__(self, port_info: PortInfo):
12
18
  super().__init__(port_info)
13
- for d in self._pyudev_context.list_devices(ID_MODEL="sd-wire"):
14
- d_serial = d.get("ID_USB_SERIAL_SHORT", None)
15
- if d_serial is not None and d_serial == self.serial_string:
16
- for sibling in d.parent.children:
17
- if (
18
- d.device_path != sibling.device_path
19
- and sibling.device_type == "disk"
20
- ):
21
- self.__block_dev = f"/dev/{sibling.device_path.split('/')[-1]}"
22
- break
23
- break
24
-
25
- def __str__(self):
26
- return f"{self.serial_string}\t[{self.product_string}::{self.manufacturer_string}]\t{self.block_dev}"
27
-
28
- def __repr__(self):
19
+ self._update_block_device()
20
+
21
+ def _update_block_device(self) -> None:
22
+ """Update block device detection for SDWireC."""
23
+ if not self.usb_device:
24
+ self.__block_dev = None
25
+ return
26
+
27
+ try:
28
+ storage_device = self.storage_device
29
+ if storage_device is not None:
30
+ self.__block_dev = map_usb_device_to_block_device(storage_device)
31
+ log.debug(f"SDWireC: Found block device: {self.__block_dev}")
32
+ else:
33
+ self.__block_dev = None
34
+ except Exception as e:
35
+ log.debug(f"SDWireC: Block device detection failed: {e}")
36
+ self.__block_dev = None
37
+
38
+ def __str__(self) -> str:
39
+ block_dev_str = self.block_dev if self.block_dev is not None else "None"
40
+ return f"{self.serial_string:<30}[{self.product_string}::{self.manufacturer_string}]\t\t{block_dev_str}"
41
+
42
+ def __repr__(self) -> str:
29
43
  return self.__str__()
30
44
 
31
45
  @property
32
- def block_dev(self):
46
+ def block_dev(self) -> Optional[str]:
33
47
  return self.__block_dev
34
48
 
35
- def switch_ts(self):
49
+ @property
50
+ def storage_device(self) -> Optional[usb.core.Device]:
51
+ """Return the USB device that corresponds to the storage interface.
52
+
53
+ For SDWireC, this is a sibling mass storage device under the same hub,
54
+ not the FTDI device we control.
55
+
56
+ Returns:
57
+ USB device object for the sibling mass storage device, or None if
58
+ not found
59
+ """
60
+ return find_sibling_storage_device(self.usb_device)
61
+
62
+ def switch_ts(self) -> None:
36
63
  self._set_sdwire(1)
37
64
 
38
- def switch_dut(self):
65
+ def switch_dut(self) -> None:
39
66
  self._set_sdwire(0)
40
67
 
41
- def _set_sdwire(self, target):
68
+ def _set_sdwire(self, target: int) -> None:
69
+ if not self.usb_device:
70
+ log.error("USB device not available")
71
+ import sys
72
+
73
+ print("USB device not available")
74
+ sys.exit(1)
75
+
42
76
  try:
43
77
  ftdi = Ftdi()
44
78
  ftdi.open_from_device(self.usb_device)
@@ -48,6 +82,6 @@ class SDWireC(USBDevice):
48
82
  except Exception as e:
49
83
  import sys
50
84
 
51
- log.debug("error while updating ftdi device", exc_info=1)
85
+ log.debug("error while updating ftdi device: %s", e, exc_info=True)
52
86
  print("couldnt switch sdwire device")
53
87
  sys.exit(1)
@@ -1,5 +1,7 @@
1
1
  from collections import namedtuple
2
- import pyudev
2
+ from typing import Optional
3
+ import usb.core
4
+
3
5
 
4
6
  PortInfo = namedtuple(
5
7
  "PortInfo", ("device", "product", "manufacturer", "serial", "usb_device")
@@ -7,29 +9,39 @@ PortInfo = namedtuple(
7
9
 
8
10
 
9
11
  class USBDevice:
10
- __port_info = None
11
- _pyudev_context = None
12
+ __port_info: Optional[PortInfo] = None
13
+
12
14
 
13
15
  def __init__(self, port_info: PortInfo):
14
16
  self.__port_info = port_info
15
- self._pyudev_context = pyudev.Context()
17
+
16
18
 
17
19
  @property
18
- def usb_device(self):
19
- return self.__port_info.usb_device
20
+ def usb_device(self) -> Optional[usb.core.Device]:
21
+ if self.__port_info:
22
+ return self.__port_info.usb_device
23
+ return None
20
24
 
21
25
  @property
22
26
  def dev_string(self) -> str:
23
- return self.__port_info.device
27
+ if self.__port_info and self.__port_info.device:
28
+ return self.__port_info.device
29
+ return ""
24
30
 
25
31
  @property
26
32
  def product_string(self) -> str:
27
- return self.__port_info.product
33
+ if self.__port_info and self.__port_info.product:
34
+ return str(self.__port_info.product)
35
+ return ""
28
36
 
29
37
  @property
30
38
  def manufacturer_string(self) -> str:
31
- return self.__port_info.manufacturer
39
+ if self.__port_info and self.__port_info.manufacturer:
40
+ return str(self.__port_info.manufacturer)
41
+ return ""
32
42
 
33
43
  @property
34
44
  def serial_string(self) -> str:
35
- return self.__port_info.serial
45
+ if self.__port_info and self.__port_info.serial:
46
+ return str(self.__port_info.serial)
47
+ return ""
sdwire/backend/utils.py CHANGED
@@ -1,30 +1,62 @@
1
+ """Utility functions for SDWire CLI operations."""
1
2
  import sys
2
3
  import logging
4
+
3
5
  import click
4
- from .device.sdwire import SDWire
5
- from .device.sdwirec import SDWireC
6
- from . import detect
6
+ from sdwire.backend.device.sdwire import SDWire
7
+ from sdwire.backend.device.sdwirec import SDWireC
8
+ from sdwire.backend import detect
7
9
 
8
10
  log = logging.getLogger(__name__)
9
11
 
10
12
 
11
- def handle_switch_host_command(ctx):
12
- device = ctx.obj["device"]
13
- device.switch_ts()
13
+ def handle_switch_host_command(ctx: click.Context) -> None:
14
+ """Handle switching device to host/TS mode.
15
+
16
+ Args:
17
+ ctx: Click context containing device information
18
+ """
19
+ try:
20
+ device = ctx.obj["device"]
21
+ device.switch_ts()
22
+ except Exception as e:
23
+ log.error(f"Failed to switch to host mode: {e}")
24
+ print(f"Error: Failed to switch device to host mode: {e}")
25
+ sys.exit(1)
14
26
 
15
27
 
16
- def handle_switch_target_command(ctx):
17
- device = ctx.obj["device"]
18
- device.switch_dut()
28
+ def handle_switch_target_command(ctx: click.Context) -> None:
29
+ """Handle switching device to target/DUT mode.
19
30
 
31
+ Args:
32
+ ctx: Click context containing device information
33
+ """
34
+ try:
35
+ device = ctx.obj["device"]
36
+ device.switch_dut()
37
+ except Exception as e:
38
+ log.error(f"Failed to switch to target mode: {e}")
39
+ print(f"Error: Failed to switch device to target mode: {e}")
40
+ sys.exit(1)
20
41
 
21
- def handle_switch_off_command(ctx):
22
- device = ctx.obj["device"]
23
- if isinstance(device, SDWireC) or isinstance(device, SDWire):
24
- log.info(
25
- "SDWire3, SDWireC or legacy sdwire devices dont have off functionality"
26
- )
27
- print("SDWireC and SDWire3 dont have off functionality implemented")
42
+
43
+ def handle_switch_off_command(ctx: click.Context) -> None:
44
+ """Handle switching device to off mode.
45
+
46
+ Args:
47
+ ctx: Click context containing device information
48
+ """
49
+ try:
50
+ device = ctx.obj["device"]
51
+ if isinstance(device, (SDWireC, SDWire)):
52
+ log.info(
53
+ "SDWire3, SDWireC or legacy sdwire devices don't have off functionality"
54
+ )
55
+ print("SDWireC and SDWire3 don't have off functionality implemented")
56
+ sys.exit(1)
57
+ except Exception as e:
58
+ log.error(f"Failed to process off command: {e}")
59
+ print(f"Error: Failed to process off command: {e}")
28
60
  sys.exit(1)
29
61
 
30
62
 
sdwire/constants.py CHANGED
@@ -3,3 +3,5 @@ SDWIRE3_PID = 0x0316
3
3
  SDWIREC_VID = 0x04E8
4
4
  SDWIREC_PID = 0x6001
5
5
  SDWIREC_PRODUCT_STRING = "sd-wire"
6
+
7
+ USB_MASS_STORAGE_CLASS_ID = 8
sdwire/main.py CHANGED
@@ -1,20 +1,30 @@
1
1
  #!/usr/bin/env python
2
+ """SDWire CLI main entry point.
3
+
4
+ This module provides the command-line interface for controlling SDWire devices,
5
+ including listing devices and switching between host and DUT modes.
6
+ """
2
7
  import logging
8
+ from typing import Optional
9
+ import importlib.metadata
3
10
  import click
4
- from .backend import utils
5
- from .backend import detect
11
+ from sdwire.backend import utils
12
+ from sdwire.backend import detect
6
13
 
7
14
 
8
15
  @click.group()
9
16
  @click.option("--debug", required=False, is_flag=True, help="Enable debug output")
10
- def main(debug=None):
17
+ @click.version_option(version=importlib.metadata.version("sdwire"), prog_name="sdwire")
18
+ def main(debug: Optional[bool] = None) -> None:
19
+ """SDWire CLI - Control SDWire devices from command line."""
11
20
  if debug:
12
21
  logging.basicConfig(level=logging.DEBUG)
13
22
 
14
23
 
15
24
  @main.command()
16
- def list():
17
- print("Serial\t\t\tProduct Info\t\tBlock Dev")
25
+ def list() -> None:
26
+ """List all connected SDWire devices with their block device information."""
27
+ print(f"{'Serial':<30}Product Info\t\tBlock Dev")
18
28
  for sdwire in detect.get_sdwire_devices():
19
29
  print(sdwire)
20
30
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sdwire
3
- Version: 0.2.4
3
+ Version: 0.3.0
4
4
  Summary: CLI application to interact with Badgerd SDWire devices
5
5
  License: GPL-3
6
6
  Author: Talha Can Havadar
@@ -11,7 +11,6 @@ Classifier: Programming Language :: Python :: 3
11
11
  Classifier: Programming Language :: Python :: 3.12
12
12
  Requires-Dist: click (>=8.1.7,<9.0.0)
13
13
  Requires-Dist: pyftdi (>=0.56.0,<0.57.0)
14
- Requires-Dist: pyudev (>=0.24.3,<0.25.0)
15
14
  Requires-Dist: pyusb (>=1.2.1,<2.0.0)
16
15
  Description-Content-Type: text/markdown
17
16
 
@@ -0,0 +1,15 @@
1
+ sdwire/__init__.py,sha256=ioDFD-3xGgXt2IdyywicNr8TgeYrdSV8EAunyXBiqIo,86
2
+ sdwire/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ sdwire/backend/block_device_utils.py,sha256=1V9c8Edzwazu7-nWZ9o7l4tUBChvuuRB8UtAXLTyZhI,30585
4
+ sdwire/backend/detect.py,sha256=k_ByGolWXFpF9ajbWuTeenkOOR7T-bmKe_GovqBybcA,4165
5
+ sdwire/backend/device/sdwire.py,sha256=SXItShyfJZN3Jn4kRGDdgz3QPnnkyNgBzrz_HRpIOPQ,2767
6
+ sdwire/backend/device/sdwirec.py,sha256=S_J6RY002bco0gKn3ybd-8-dK5URwdGsjZADz3hv1ZM,2759
7
+ sdwire/backend/device/usb_device.py,sha256=FHgBE9rdpH8Ie8Y_tJlaJp-LV3677QG0uUQUf18bEAk,1206
8
+ sdwire/backend/utils.py,sha256=8oPvoDBsjvIHFWLN5oCui_V03oASkyYlkHVGyQV_6XM,2603
9
+ sdwire/constants.py,sha256=pBHotAmBpvhiCKBkFYOB5eMOeNulWxr98epFTJRUVz4,150
10
+ sdwire/main.py,sha256=n7W1uDUlkJ4f80xS5YLvMq0bjLuiO1P-ePpfAaA9Eew,2654
11
+ sdwire-0.3.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
12
+ sdwire-0.3.0.dist-info/METADATA,sha256=U55zUtw8G49BLoqGY_Zyc4Swvh78L_1qm8LIzO55kZo,3063
13
+ sdwire-0.3.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
14
+ sdwire-0.3.0.dist-info/entry_points.txt,sha256=pxy0zJKVcNWXPk5PtNjTLExOBpqFNth37wtdYdYRXCE,43
15
+ sdwire-0.3.0.dist-info/RECORD,,
@@ -1,14 +0,0 @@
1
- sdwire/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- sdwire/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- sdwire/backend/detect.py,sha256=jiQ2JS9sMGUuymwyUO4FaGzIkXK3J7Ci45V1X8c94b4,2931
4
- sdwire/backend/device/sdwire.py,sha256=5Glk4M20sY7EJA5XDewT1F5F1-AUW1fG7mI9_wrABoM,1518
5
- sdwire/backend/device/sdwirec.py,sha256=imkj2ObrgowiM7DP9TnVbCES-8bju0T69Qzdw5OURgE,1657
6
- sdwire/backend/device/usb_device.py,sha256=5sdyOyPikIpFydKywzDkvvgLHFdMcsBC8tKosHRhfvQ,808
7
- sdwire/backend/utils.py,sha256=kMEyBbRO91REgvgICuBONGiImO6jTr6EpqkZaxQH4aU,1507
8
- sdwire/constants.py,sha256=s5mCx5NlJUM3aBbCPq2y3oOFoPPJ5wA3BR1snyK-cMg,119
9
- sdwire/main.py,sha256=G1WaVd4kBR3bTfbmHekjx1yObiz4f1NLGqznFepd2NY,2132
10
- sdwire-0.2.4.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
11
- sdwire-0.2.4.dist-info/METADATA,sha256=ZtSg0QMJGsQF52Aa_GlRkwbjn6mxK0EAiv15r_ITW-E,3104
12
- sdwire-0.2.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
13
- sdwire-0.2.4.dist-info/entry_points.txt,sha256=pxy0zJKVcNWXPk5PtNjTLExOBpqFNth37wtdYdYRXCE,43
14
- sdwire-0.2.4.dist-info/RECORD,,
File without changes