Dnešní hrátky se omezili na testování výpisu big endianu a úpravu skriptu. S tím BE to nebyl dobrý/funkční nápad. Výstupy byli ještě více "ošklivé"/nic neříkající. Avšak úprava skriptu se mi docela povedla. Jsem ho udělal trochu univerzálnější:
#! /usr/bin/env python3
import argparse
import usb.core
import usb.util
arr = argparse.ArgumentParser(description="Program na výpis raw událostí"
"z usb zařízení.\n"
"Program nemá ošetřené vstupy!!!\n"
"Spouštět jako obyčejný uživatel.",
formatter_class=argparse.RawTextHelpFormatter)
arr.add_argument("vendor", help="idVendor zařízení")
arr.add_argument("product", help="idProduct zařízení")
arr.add_argument("-o", "--output", default="dec",
help=("povolené hodnoty:\n"
"\tbin: binární\n"
"\tdec: desítkový\n"
"\thex: šestnáctkový\n"
"\toct: osmičkový"))
argumenty = arr.parse_args()
# my_remote = usb.core.find(idVendor=0x0471, idProduct=0x20cc)
my_remote = usb.core.find(idVendor=int(argumenty.vendor, 16),
idProduct=int(argumenty.product, 16))
try:
# nastavení do "úvodního" stavu
my_remote.reset()
except Exception:
print('Zařízení není připojené, nebo není typu usb')
exit(1)
rozhrani = 0
endpoint = my_remote[0][(0, 0)][0]
# odpojení zařízení od jaderných modulů
if my_remote.is_kernel_driver_active(rozhrani) is True:
my_remote.detach_kernel_driver(rozhrani)
usb.util.claim_interface(my_remote, rozhrani)
def raw_input_from_device(vst):
print("Pro ukončení zmáčkni ctr+c")
while True:
try:
data = my_remote.read(endpoint.bEndpointAddress,
endpoint.wMaxPacketSize)
print(kostra_fce(data, argumenty.output))
except usb.core.USBError as e:
data = None
print(e)
continue
except KeyboardInterrupt:
usb.util.release_interface(my_remote, rozhrani)
my_remote.attach_kernel_driver(rozhrani)
exit(0)
except Exception:
print("Něco se pos...")
exit(1)
def kostra_fce(a, b):
k_tisku = b + ": "
i = 0
vst: dict = {"bin": (bin, 2, 8),
"hex": (hex, 2, 2),
"dec": (str, 0, 0),
"oct": (oct, 2, 3)}
for i in a:
fce, zacatek, kolik = vst[b]
k_tisku += fce(i)[zacatek:].zfill(kolik) + " | "
return k_tisku
# spuštění hlavní fce
raw_input_from_device(argumenty.output)
Skript má povinné dva argumenty a to IDVendor a IDProduct USB INPUT zařízení z kterého chcete dostat informace. Třetí argument je -o nebo --output s volbou [bin|dec|hex|oct]. Asi není třeba popisovat co udělá jaký výpis. Vím, že pomocí wireshark to jde také. Ale ten mne několikrát spadnul. Tak jsem to napsal takto. On ten hexdump je také fajn, ale dopracovat se k nějakému kýženému výstupu trvá a trvá a ... Navíc cesta kterou jsem zvolil je plná sladkého poznávání.
Poznámka ke kódu skriptu. Pokud by někdo hledal podmínky if určující jaký výpis se má provést, tak takhle to v pythonu nefunguje. Respektive funguje, ale je to náročnější na prostředky PC. Python má lepší řešení ve formě volání funkcí ze slovníku:
vst: dict = {"bin": (bin, 2, 8),
"hex": (hex, 2, 2),
"dec": (str, 0, 0),
"oct": (oct, 2, 3)}
vst je zvolený název slovníku obsahující klíč: hodnota/y. Hodnoty jsem zvolil jako ntici kde prví položka je volaná funkce a další jsou dodatečné parametry.
Řádkemfce, zacatek, kolik = vst[b]
se přiřadí záznam slovníku s klíčem v proměnné b do proměnných fce, zacatek a kolik
fce(i)[zacatek:].zfill(kolik)
už jen promění díky kulatým závorkám proměnnou na volání funkce s parametrem i. Protože všechny zvolené funkce mají řetězcový výstup, dají se oříznout což zabezpečí údaje v hranatých závorkách. Proměnná zacatek určí kolik bude od počátku řetězce uříznuto. Poslední proměnná kolik určí kolik nul má příkaz zfill vyplnit do výsledku. Pokud se zadá neplatný klíč, je to odchyceno pomocí konstrukce try a skipt je ukončen.
Suma sumárum není třeba na každou požadovanou formu výpisu vytvářet extra funkce. Funkce lišící se jen v jednom řádku! A ty funkce volat podle série podmínek if. Přitom si stačí jen osvojit takovýto konstrukt formy volání.