Class: Uhid
- Inherits:
-
Object
- Object
- Uhid
- Defined in:
- lib/uhid.rb
Overview
Linux UHID class.
This class allows the creation of virtual USB HID devices on Linux using the ‘uhid` kernel module.
Constant Summary collapse
- RD_FIDO =
FIDO2/U2F USB report descriptor
"\x06\xd0\xf1\x09\x01\xa1\x01\x09"\ "\x20\x15\x00\x26\xff\x00\x75\x08"\ "\x95\x40\x81\x02\x09\x21\x15\x00"\ "\x26\xff\x00\x75\x08\x95\x40\x91"\ "\x02\xc0".force_encoding("BINARY")
Instance Method Summary collapse
-
#initialize(name = "ruby-fido", rd = RD_FIDO, vendor = 0x15d9, product = 0x0a37, path = "/dev/uhid") ⇒ Uhid
constructor
Create a new virtual HID device.
-
#read ⇒ Object
Read data from the host.
-
#write(data) ⇒ Object
Write the given data to the host.
Constructor Details
#initialize(name = "ruby-fido", rd = RD_FIDO, vendor = 0x15d9, product = 0x0a37, path = "/dev/uhid") ⇒ Uhid
Create a new virtual HID device.
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/uhid.rb', line 22 def initialize( name = "ruby-fido", rd = RD_FIDO, vendor = 0x15d9, product = 0x0a37, path = "/dev/uhid" ) @file = File.open(path, "r+", File::NONBLOCK) ObjectSpace.define_finalizer(self, method(:finalize)) self.create(name, vendor, product, rd) end |
Instance Method Details
#read ⇒ Object
Read data from the host.
All returned hashes contain the type key that specifies the type of the received packet. Valid types are: START, STOP, OPEN, CLOSE, OUTPUT. Only OUTPUT Hashes contain a data field that holds the data received by the host.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'ext/uhid/uhid.c', line 123
static VALUE
cuhid_read_data(VALUE self)
{
ID file_var = rb_intern("@file");
VALUE file = rb_ivar_get(self, file_var);
Check_Type(file, T_FILE);
VALUE file_fileno = rb_funcall(file, rb_intern("fileno"), 0);
int fd = NUM2INT(file_fileno);
struct uhid_event ev;
memset(&ev, 0, sizeof(ev));
ssize_t ret = read(fd, &ev, sizeof(ev));
if (ret == -1) { // EAGAIN
return Qnil;
}
VALUE h = rb_hash_new();
switch (ev.type) {
case UHID_START:
rb_hash_aset(h, rb_str_new_cstr("type"), rb_str_new_cstr("START"));
return h;
case UHID_STOP:
rb_hash_aset(h, rb_str_new_cstr("type"), rb_str_new_cstr("STOP"));
return h;
case UHID_OPEN:
rb_hash_aset(h, rb_str_new_cstr("type"), rb_str_new_cstr("OPEN"));
return h;
case UHID_CLOSE:
rb_hash_aset(h, rb_str_new_cstr("type"), rb_str_new_cstr("CLOSE"));
return h;
case UHID_OUTPUT:
rb_hash_aset(h, rb_str_new_cstr("type"), rb_str_new_cstr("OUTPUT"));
rb_hash_aset(h, rb_str_new_cstr("data"), rb_str_new((const char *) ev.u.output.data, ev.u.output.size));
return h;
default:
return Qnil;
}
}
|
#write(data) ⇒ Object
Write the given data to the host.
Make sure you send the data in a format, expected by the host, e.g. in 64 byte chunks.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'ext/uhid/uhid.c', line 84
static VALUE
cuhid_write_data(VALUE self, VALUE data)
{
const char* d = RSTRING_PTR(StringValue(data));
size_t l = RSTRING_LEN(StringValue(data));
size_t size = l;
if (size > UHID_DATA_MAX) {
size = UHID_DATA_MAX;
}
struct uhid_event ev;
memset(&ev, 0, sizeof(ev));
ev.type = UHID_INPUT2;
memcpy(ev.u.input2.data, d, size);
ev.u.input2.size = size;
ID file_var = rb_intern("@file");
VALUE file = rb_ivar_get(self, file_var);
Check_Type(file, T_FILE);
VALUE file_fileno = rb_funcall(file, rb_intern("fileno"), 0);
int fd = NUM2INT(file_fileno);
cuhid_write(fd, &ev);
// We the number of processed bytes
return INT2NUM(size);
}
|