mirror of
https://github.com/MatMoul/g810-led.git
synced 2024-12-23 09:16:11 +00:00
Switch to hidapi
This commit is contained in:
parent
cdaae30aa2
commit
bcdcee88f1
28
INSTALL.md
28
INSTALL.md
@ -6,21 +6,29 @@
|
|||||||
* make
|
* make
|
||||||
|
|
||||||
## Dependencies :</br>
|
## Dependencies :</br>
|
||||||
* libusb
|
* hidapi or libusb
|
||||||
* systemd
|
|
||||||
|
## hidapi vs libusb :</br>
|
||||||
|
hidapi is the new implementation but need to be tested.</br>
|
||||||
|
hidapi is very more speed than libusb (~20ms vs ~150ms).</br>
|
||||||
|
hidapi seem not work on CentOS, writing on hidraw is not allowed.</br>
|
||||||
|
hidapi is recommended but if you encounter problem on your system, switch to libusb.</br>
|
||||||
|
|
||||||
## Installation of dependencies :</br>
|
## Installation of dependencies :</br>
|
||||||
ArchLinux :</br>
|
ArchLinux :</br>
|
||||||
`sudo pacman -S git gcc make libusb`</br>
|
`sudo pacman -S git gcc make hidapi` (for hidapi)</br>
|
||||||
|
`sudo pacman -S git gcc make libusb` (for libusb)</br>
|
||||||
Debian :</br>
|
Debian :</br>
|
||||||
`sudo apt-get install git g++ make libusb-1.0-0-dev`</br>
|
`sudo apt-get install git g++ make libhidapi-dev` (for hidapi)</br>
|
||||||
|
`sudo apt-get install git g++ make libusb-1.0-0-dev` (for libusb)</br>
|
||||||
Fedora :</br>
|
Fedora :</br>
|
||||||
`sudo dnf install git make gcc-c++ libusb-devel`</br>
|
`sudo dnf install git make gcc-c++ hidapi-devel` (for hidapi)</br>
|
||||||
|
`sudo dnf install git make gcc-c++ libusbx-devel` (for libusb)</br>
|
||||||
|
|
||||||
## Installation :</br>
|
## Installation :</br>
|
||||||
`git clone https://github.com/MatMoul/g810-led.git`</br>
|
`git clone https://github.com/MatMoul/g810-led.git`</br>
|
||||||
`cd g810-led`</br>
|
`cd g810-led`</br>
|
||||||
`make`</br>
|
`make` or `make LIB=libusb`</br>
|
||||||
`sudo make install`</br>
|
`sudo make install`</br>
|
||||||
|
|
||||||
## Update :</br>
|
## Update :</br>
|
||||||
@ -30,8 +38,8 @@ Same as install, but your profile and reboot files are preserved.</br>
|
|||||||
`sudo make uninstall`</br>
|
`sudo make uninstall`</br>
|
||||||
|
|
||||||
## Boot profiles :</br>
|
## Boot profiles :</br>
|
||||||
g810-led has 2 systemd units (g810-led and g810-led-reboot).</br>
|
If your system use systemd, g810-led has 2 systemd units (g810-led and g810-led-reboot).</br>
|
||||||
These 2 units set the keyboard profile on boot and reboot.</br>
|
These 2 units set the keyboard profile on boot and reboot.</br>
|
||||||
Profiles are stored in /etc/g810 :</br>
|
Profiles are stored in /etc/g810-led :</br>
|
||||||
* /etc/g810/profile
|
* /etc/g810-led/profile
|
||||||
* /etc/g810/reboot
|
* /etc/g810-led/reboot
|
||||||
|
52
makefile
52
makefile
@ -1,16 +1,23 @@
|
|||||||
CC=g++
|
CC=g++
|
||||||
CFLAGS=-Wall -O2 -std=gnu++11
|
CFLAGS=-Wall -O2 -std=gnu++11
|
||||||
|
LIB?=hidapi
|
||||||
|
ifeq ($(LIB),libusb)
|
||||||
|
CPPFLAGS=-Dlibusb
|
||||||
LDFLAGS=-lusb-1.0
|
LDFLAGS=-lusb-1.0
|
||||||
|
else
|
||||||
|
CPPFLAGS=-Dhidapi
|
||||||
|
LDFLAGS=-lhidapi-hidraw
|
||||||
|
endif
|
||||||
PROGN=g810-led
|
PROGN=g810-led
|
||||||
SYSTEMDDIR?=/usr/lib/systemd
|
SYSTEMDDIR?=/usr/lib/systemd
|
||||||
|
|
||||||
.PHONY: all debug clean
|
.PHONY: all debug clean install uninstall
|
||||||
|
|
||||||
all: bin/$(PROGN)
|
all: bin/$(PROGN)
|
||||||
|
|
||||||
bin/$(PROGN): src/main.cpp src/helpers/*.cpp src/helpers/*.h src/classes/*.cpp src/classes/*.h
|
bin/$(PROGN): src/main.cpp src/helpers/*.cpp src/helpers/*.h src/classes/*.cpp src/classes/*.h
|
||||||
@mkdir -p bin
|
@mkdir -p bin
|
||||||
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
|
$(CC) $(CPPFLAGS) $(CFLAGS) $^ -o $@ $(LDFLAGS)
|
||||||
|
|
||||||
debug: CFLAGS += -g -Wextra -pedantic
|
debug: CFLAGS += -g -Wextra -pedantic
|
||||||
debug: bin/$(PROGN)
|
debug: bin/$(PROGN)
|
||||||
@ -20,36 +27,43 @@ clean:
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
@install -m 755 -d \
|
@install -m 755 -d \
|
||||||
$(DESTDIR)/etc/$(PROGN)/samples \
|
|
||||||
$(DESTDIR)/etc/udev/rules.d \
|
$(DESTDIR)/etc/udev/rules.d \
|
||||||
$(DESTDIR)$(SYSTEMDDIR)/system \
|
|
||||||
$(DESTDIR)/usr/bin
|
$(DESTDIR)/usr/bin
|
||||||
@cp bin/$(PROGN) $(DESTDIR)/usr/bin
|
@cp bin/$(PROGN) $(DESTDIR)/usr/bin
|
||||||
@test -s $(DESTDIR)/usr/bin/g410-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g410-led
|
@test -s $(DESTDIR)/usr/bin/g410-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g410-led
|
||||||
@test -s $(DESTDIR)/usr/bin/g610-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g610-led
|
@test -s $(DESTDIR)/usr/bin/g610-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g610-led
|
||||||
@test -s $(DESTDIR)/usr/bin/g910-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g910-led
|
@test -s $(DESTDIR)/usr/bin/g910-led || ln -s /usr/bin/$(PROGN) $(DESTDIR)/usr/bin/g910-led
|
||||||
|
|
||||||
@cp udev/$(PROGN).rules $(DESTDIR)/etc/udev/rules.d
|
@cp udev/$(PROGN).rules $(DESTDIR)/etc/udev/rules.d
|
||||||
@cp sample_profiles/* $(DESTDIR)/etc/$(PROGN)/samples
|
|
||||||
@test -s $(DESTDIR)/etc/$(PROGN)/profile || cp $(DESTDIR)/etc/$(PROGN)/samples/group_keys $(DESTDIR)/etc/$(PROGN)/profile
|
|
||||||
@test -s $(DESTDIR)/etc/$(PROGN)/reboot || cp $(DESTDIR)/etc/$(PROGN)/samples/all_off $(DESTDIR)/etc/$(PROGN)/reboot
|
|
||||||
@cp systemd/$(PROGN).service $(DESTDIR)$(SYSTEMDDIR)/system
|
|
||||||
@cp systemd/$(PROGN)-reboot.service $(DESTDIR)$(SYSTEMDDIR)/system
|
|
||||||
@udevadm control --reload-rules
|
@udevadm control --reload-rules
|
||||||
@systemctl daemon-reload
|
|
||||||
@systemctl start $(PROGN)
|
@test -s /usr/bin/systemd-run && \
|
||||||
@systemctl enable $(PROGN)
|
install -m 755 -d \
|
||||||
@systemctl enable $(PROGN)-reboot
|
$(DESTDIR)/etc/$(PROGN)/samples \
|
||||||
|
$(DESTDIR)$(SYSTEMDDIR)/system && \
|
||||||
|
cp sample_profiles/* $(DESTDIR)/etc/$(PROGN)/samples && \
|
||||||
|
test -s $(DESTDIR)/etc/$(PROGN)/profile || cp $(DESTDIR)/etc/$(PROGN)/samples/group_keys $(DESTDIR)/etc/$(PROGN)/profile && \
|
||||||
|
test -s $(DESTDIR)/etc/$(PROGN)/reboot || cp $(DESTDIR)/etc/$(PROGN)/samples/all_off $(DESTDIR)/etc/$(PROGN)/reboot && \
|
||||||
|
cp systemd/$(PROGN).service $(DESTDIR)$(SYSTEMDDIR)/system && \
|
||||||
|
cp systemd/$(PROGN)-reboot.service $(DESTDIR)$(SYSTEMDDIR)/system && \
|
||||||
|
systemctl daemon-reload && \
|
||||||
|
systemctl start $(PROGN) && \
|
||||||
|
systemctl enable $(PROGN) && \
|
||||||
|
systemctl enable $(PROGN)-reboot
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
@systemctl disable $(PROGN)
|
@test -s /usr/bin/systemd-run && \
|
||||||
@systemctl disable $(PROGN)-reboot
|
systemctl disable $(PROGN) && \
|
||||||
@rm $(SYSTEMDDIR)/system/$(PROGN).service
|
systemctl disable $(PROGN)-reboot && \
|
||||||
@rm $(SYSTEMDDIR)/system/$(PROGN)-reboot.service
|
rm $(SYSTEMDDIR)/system/$(PROGN).service && \
|
||||||
@systemctl daemon-reload
|
rm $(SYSTEMDDIR)/system/$(PROGN)-reboot.service && \
|
||||||
|
systemctl daemon-reload && \
|
||||||
|
rm -R /etc/$(PROGN)
|
||||||
|
|
||||||
@rm /usr/bin/g410-led
|
@rm /usr/bin/g410-led
|
||||||
@rm /usr/bin/g610-led
|
@rm /usr/bin/g610-led
|
||||||
@rm /usr/bin/g910-led
|
@rm /usr/bin/g910-led
|
||||||
@rm /usr/bin/$(PROGN)
|
@rm /usr/bin/$(PROGN)
|
||||||
@rm -R /etc/$(PROGN)
|
|
||||||
@rm /etc/udev/rules.d/$(PROGN).rules
|
@rm /etc/udev/rules.d/$(PROGN).rules
|
||||||
@udevadm control --reload-rules
|
@udevadm control --reload-rules
|
||||||
|
@ -4,7 +4,11 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined(hidapi)
|
||||||
|
#include "hidapi/hidapi.h"
|
||||||
|
#elif defined(libusb)
|
||||||
#include "libusb-1.0/libusb.h"
|
#include "libusb-1.0/libusb.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -17,6 +21,33 @@ LedKeyboard::~LedKeyboard() {
|
|||||||
|
|
||||||
|
|
||||||
bool LedKeyboard::listKeyboards() {
|
bool LedKeyboard::listKeyboards() {
|
||||||
|
#if defined(hidapi)
|
||||||
|
if (hid_init() < 0) return false;
|
||||||
|
|
||||||
|
struct hid_device_info *devs, *dev;
|
||||||
|
devs = hid_enumerate(0x0, 0x0);
|
||||||
|
dev = devs;
|
||||||
|
while (dev) {
|
||||||
|
for (int i=0; i<(int)SuportedKeyboards.size(); i++) {
|
||||||
|
if (dev->vendor_id == SuportedKeyboards[i][0]) {
|
||||||
|
if (dev->product_id == SuportedKeyboards[i][1]) {
|
||||||
|
cout<<"0x"<<std::hex<<dev->vendor_id \
|
||||||
|
<<" 0x"<<std::hex<<dev->product_id \
|
||||||
|
<<" "<<dev->serial_number \
|
||||||
|
<<" "<<dev->path<<" ";
|
||||||
|
dev = dev->next;
|
||||||
|
cout<<dev->serial_number<<" "<<dev->path<<endl;
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dev = dev->next;
|
||||||
|
}
|
||||||
|
hid_free_enumeration(devs);
|
||||||
|
|
||||||
|
hid_exit();
|
||||||
|
#elif defined(libusb)
|
||||||
libusb_context *ctx = NULL;
|
libusb_context *ctx = NULL;
|
||||||
if(libusb_init(&m_ctx) < 0) return false;
|
if(libusb_init(&m_ctx) < 0) return false;
|
||||||
|
|
||||||
@ -55,6 +86,7 @@ bool LedKeyboard::listKeyboards() {
|
|||||||
libusb_free_device_list(devs, 1);
|
libusb_free_device_list(devs, 1);
|
||||||
libusb_exit(m_ctx);
|
libusb_exit(m_ctx);
|
||||||
} else return false;
|
} else return false;
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -67,6 +99,45 @@ bool LedKeyboard::isOpen() {
|
|||||||
bool LedKeyboard::open() {
|
bool LedKeyboard::open() {
|
||||||
if (m_isOpen) return true;
|
if (m_isOpen) return true;
|
||||||
|
|
||||||
|
#if defined(hidapi)
|
||||||
|
if (hid_init() < 0) return false;
|
||||||
|
|
||||||
|
if (m_keyboardModel == KeyboardModel::unknown) {
|
||||||
|
struct hid_device_info *devs, *dev;
|
||||||
|
devs = hid_enumerate(0x0, 0x0);
|
||||||
|
dev = devs;
|
||||||
|
m_keyboardModel = KeyboardModel::unknown;
|
||||||
|
while (dev) {
|
||||||
|
for (int i=0; i<(int)SuportedKeyboards.size(); i++) {
|
||||||
|
if (dev->vendor_id == SuportedKeyboards[i][0]) {
|
||||||
|
if (dev->product_id == SuportedKeyboards[i][1]) {
|
||||||
|
m_vendorID = dev->vendor_id;
|
||||||
|
m_productID = dev->product_id;
|
||||||
|
m_keyboardModel = (KeyboardModel)SuportedKeyboards[i][2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_keyboardModel != KeyboardModel::unknown) break;
|
||||||
|
dev = dev->next;
|
||||||
|
}
|
||||||
|
hid_free_enumeration(devs);
|
||||||
|
|
||||||
|
if (! dev) {
|
||||||
|
cout<<"Keyboard not found"<<endl;
|
||||||
|
m_keyboardModel = KeyboardModel::unknown;
|
||||||
|
hid_exit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hidHandle = hid_open(m_vendorID, m_productID, NULL);
|
||||||
|
|
||||||
|
if(m_hidHandle == 0) {
|
||||||
|
hid_exit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#elif defined(libusb)
|
||||||
if(libusb_init(&m_ctx) < 0) return false;
|
if(libusb_init(&m_ctx) < 0) return false;
|
||||||
|
|
||||||
if (m_keyboardModel == KeyboardModel::unknown) {
|
if (m_keyboardModel == KeyboardModel::unknown) {
|
||||||
@ -143,15 +214,21 @@ bool LedKeyboard::open() {
|
|||||||
m_ctx = NULL;
|
m_ctx = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
m_isOpen = true;
|
m_isOpen = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LedKeyboard::close() {
|
bool LedKeyboard::close() {
|
||||||
if (! m_isOpen) return false;
|
if (! m_isOpen) return true;
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
|
|
||||||
|
#if defined(hidapi)
|
||||||
|
hid_close(m_hidHandle);
|
||||||
|
m_hidHandle = 0;
|
||||||
|
hid_exit();
|
||||||
|
#elif defined(libusb)
|
||||||
if(libusb_release_interface(m_hidHandle, 1) != 0) return false;
|
if(libusb_release_interface(m_hidHandle, 1) != 0) return false;
|
||||||
if(m_isKernellDetached==true) {
|
if(m_isKernellDetached==true) {
|
||||||
libusb_attach_kernel_driver(m_hidHandle, 1);
|
libusb_attach_kernel_driver(m_hidHandle, 1);
|
||||||
@ -161,6 +238,8 @@ bool LedKeyboard::close() {
|
|||||||
m_hidHandle = NULL;
|
m_hidHandle = NULL;
|
||||||
libusb_exit(m_ctx);
|
libusb_exit(m_ctx);
|
||||||
m_ctx = NULL;
|
m_ctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,8 +517,21 @@ bool LedKeyboard::setNativeEffect(NativeEffect effect, NativeEffectPart part, ui
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool LedKeyboard::sendDataInternal(const byte_buffer_t &data) {
|
bool LedKeyboard::sendDataInternal(byte_buffer_t &data) {
|
||||||
if (! m_isOpen) return false;
|
if (! m_isOpen) return false;
|
||||||
|
|
||||||
|
if (data.size() > 0) {
|
||||||
|
#if defined(hidapi)
|
||||||
|
data.insert(data.begin(), 0x00);
|
||||||
|
if (hid_write(m_hidHandle, const_cast<unsigned char*>(data.data()), data.size()) < 0) {
|
||||||
|
std::cout<<"Error: Can not write to hidraw, try with the libusb version"<<std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
usleep(500);
|
||||||
|
byte_buffer_t data2;
|
||||||
|
data2.resize(21, 0x00);
|
||||||
|
hid_read_timeout(m_hidHandle, const_cast<unsigned char*>(data2.data()), data2.size(), 0);
|
||||||
|
#elif defined(libusb)
|
||||||
int r;
|
int r;
|
||||||
if (data.size() > 20) r = libusb_control_transfer(m_hidHandle, 0x21, 0x09, 0x0212, 1, const_cast<unsigned char*>(data.data()), data.size(), 2000);
|
if (data.size() > 20) r = libusb_control_transfer(m_hidHandle, 0x21, 0x09, 0x0212, 1, const_cast<unsigned char*>(data.data()), data.size(), 2000);
|
||||||
else r = libusb_control_transfer(m_hidHandle, 0x21, 0x09, 0x0211, 1, const_cast<unsigned char*>(data.data()), data.size(), 2000);
|
else r = libusb_control_transfer(m_hidHandle, 0x21, 0x09, 0x0211, 1, const_cast<unsigned char*>(data.data()), data.size(), 2000);
|
||||||
@ -448,6 +540,9 @@ bool LedKeyboard::sendDataInternal(const byte_buffer_t &data) {
|
|||||||
unsigned char buffer[64];
|
unsigned char buffer[64];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
r = libusb_interrupt_transfer(m_hidHandle, 0x82, buffer, sizeof(buffer), &len, 1);
|
r = libusb_interrupt_transfer(m_hidHandle, 0x82, buffer, sizeof(buffer), &len, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,11 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined(hidapi)
|
||||||
|
#include "hidapi/hidapi.h"
|
||||||
|
#elif defined(libusb)
|
||||||
#include "libusb-1.0/libusb.h"
|
#include "libusb-1.0/libusb.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
class LedKeyboard {
|
class LedKeyboard {
|
||||||
@ -180,15 +184,20 @@ class LedKeyboard {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool m_isOpen = false;
|
bool m_isOpen = false;
|
||||||
bool m_isKernellDetached = false;
|
|
||||||
uint16_t m_vendorID = 0;
|
uint16_t m_vendorID = 0;
|
||||||
uint16_t m_productID = 0;
|
uint16_t m_productID = 0;
|
||||||
KeyboardModel m_keyboardModel = KeyboardModel::unknown;
|
KeyboardModel m_keyboardModel = KeyboardModel::unknown;
|
||||||
|
|
||||||
|
#if defined(hidapi)
|
||||||
|
hid_device *m_hidHandle;
|
||||||
|
#elif defined(libusb)
|
||||||
|
bool m_isKernellDetached = false;
|
||||||
libusb_device_handle *m_hidHandle;
|
libusb_device_handle *m_hidHandle;
|
||||||
libusb_context *m_ctx = NULL;
|
libusb_context *m_ctx = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
bool sendDataInternal(const byte_buffer_t &data);
|
bool sendDataInternal(byte_buffer_t &data);
|
||||||
byte_buffer_t getKeyGroupAddress(KeyAddressGroup keyAddressGroup);
|
byte_buffer_t getKeyGroupAddress(KeyAddressGroup keyAddressGroup);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -186,7 +186,6 @@ int pipeProfile(LedKeyboard &kbd) {
|
|||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
|
||||||
std::string arg = argv[1];
|
std::string arg = argv[1];
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c331", MODE="660", GROUP="users"
|
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c331", MODE="666"
|
||||||
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c337", MODE="660", GROUP="users"
|
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c337", MODE="666"
|
||||||
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c330", MODE="660", GROUP="users"
|
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c330", MODE="666"
|
||||||
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c333", MODE="660", GROUP="users"
|
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c333", MODE="666"
|
||||||
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c338", MODE="660", GROUP="users"
|
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c338", MODE="666"
|
||||||
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c32b", MODE="660", GROUP="users"
|
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c32b", MODE="666"
|
||||||
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c335", MODE="660", GROUP="users"
|
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c335", MODE="666"
|
||||||
|
Loading…
Reference in New Issue
Block a user