Skip to content

Instantly share code, notes, and snippets.

@amalbuquerque
Created March 2, 2020 22:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amalbuquerque/53453d118f0c4fb0d5a18c42852a8245 to your computer and use it in GitHub Desktop.
Save amalbuquerque/53453d118f0c4fb0d5a18c42852a8245 to your computer and use it in GitHub Desktop.
Configuring an HID device by "manually" interacting with ConfigFS via /sys/kernel/config
defmodule ElixirKeeb.ManualConfig do
@moduledoc """
Manually create a Keyboard HID and writes to its device.
"""
@usb_gadget_root "/sys/kernel/config/usb_gadget"
def configure_device do
create_gadget_dir("mygadget")
write_to_gadget_file("mygadget/idVendor", "0x1d6b")
write_to_gadget_file("mygadget/idProduct", "0x0104")
write_to_gadget_file("mygadget/bcdDevice", "0x0100")
write_to_gadget_file("mygadget/bcdUSB", "0x0200")
create_gadget_dir("mygadget/strings/0x409")
write_to_gadget_file("mygadget/strings/0x409/serialnumber", "fedcba9876543210")
write_to_gadget_file("mygadget/strings/0x409/manufacturer", "Easter Lejboua")
write_to_gadget_file("mygadget/strings/0x409/product", "Lejboua USB device")
create_gadget_dir("mygadget/configs/c.1/strings/0x409")
write_to_gadget_file("mygadget/configs/c.1/strings/0x409/configuration", "Config 1: HID device")
create_gadget_dir("mygadget/functions/hid.usb0")
write_to_gadget_file("mygadget/functions/hid.usb0/protocol", "1")
write_to_gadget_file("mygadget/functions/hid.usb0/subclass", "1")
write_to_gadget_file("mygadget/functions/hid.usb0/report_length", "8")
report_desc = "\x05\x01\x09\x06\xa1\x01\x05\x07\x19\xe0\x29\xe7\x15\x00\x25\x01\x75\x01\x95\x08\x81\x02\x95\x01\x75\x08\x81\x03\x95\x05\x75\x01\x05\x08\x19\x01\x29\x05\x91\x02\x95\x01\x75\x03\x91\x03\x95\x06\x75\x08\x15\x00\x25\x65\x05\x07\x19\x00\x29\x65\x81\x00\xc0"
write_to_gadget_file("mygadget/functions/hid.usb0/report_desc", report_desc)
existing = Path.join(@usb_gadget_root, "mygadget/functions/hid.usb0")
new = Path.join(@usb_gadget_root, "mygadget/configs/c.1/hid.usb0")
# to remove the device, it's just a matter of
# rm'ing the symlink
:ok = File.ln_s(existing, new)
# we only have one USB device
[usb_device] = File.ls!("/sys/class/udc")
write_to_gadget_file("mygadget/UDC", usb_device)
end
@doc """
Works like mkdir -p, if it is passed a hierarchy of folders,
say /a/b/c/d/e/f/g/i, it will create them on the USB gadget root,
given by @usb_gadget_root
"""
defp create_gadget_dir(dir) do
dir
|> String.split("/")
|> Enum.reject(&(String.length(&1) == 0))
|> Enum.reduce([], fn (dir, acc) ->
to_create = acc
|> Enum.reverse()
|> Enum.join("/")
|> Kernel.<>("/" <> dir)
:ok = Path.join(@usb_gadget_root, to_create)
|> create_if_not_exists()
[dir | acc]
end)
end
defp create_if_not_exists(dir) do
case File.exists?(dir) do
true -> :ok
_ -> File.mkdir(dir)
end
end
defp write_to_gadget_file(path, content) do
path_to_write = Path.join(@usb_gadget_root, path)
:ok = File.write(path_to_write, content)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment