diff options
| -rw-r--r-- | .gitignore | 2 | ||||
| -rw-r--r-- | Makefile | 30 | ||||
| -rw-r--r-- | README | 2 | ||||
| -rw-r--r-- | res/dockd.service | 7 | ||||
| -rwxr-xr-x | src/check_docked.sh | 3 | ||||
| -rw-r--r-- | src/config.h | 13 | ||||
| -rwxr-xr-x | src/dock_checker.sh | 34 | ||||
| -rw-r--r-- | src/logger.h | 19 | ||||
| -rw-r--r-- | src/main.c | 71 |
9 files changed, 143 insertions, 38 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1005f6f --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin +*.swp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2763637 --- /dev/null +++ b/Makefile @@ -0,0 +1,30 @@ +CC=gcc +CFLAGS=`pkg-config --cflags --libs libusb-1.0` + +all: bin bin/dockd + +bin: + mkdir bin + +bin/dockd: src/main.c + gcc -o $@ $< ${CFLAGS} + +clean: + rm -rf bin + +run: all + bin/dockd + +install: all + mkdir ~/.local/dockd + cp -pf bin/dockd ~/.local/bin + ln -s ${PWD}/src/sh/docked.sh ~/.local/dockd/on_docked + ln -s ${PWD}/src/sh/undocked.sh ~/.local/dockd/on_undocked +# cp -pf res/dockd.service ~/.config/systemd/user/ +# ln -fs ~/.config/systemd/user/dockd.service ~/.config/systemd/user/default.target.wants/dockd.service + +uninstall: + rm -rf ~/.local/dockd + rm ~/.local/bin/dockd +# rm ~/.config/systemd/user/dockd.service +# rm ~/.config/systemd/user/default.target.wants/dockd.service @@ -5,4 +5,4 @@ poll usb for thinkpad ultra dock, run scripts in folder when status changes. roadmap ------- - [ ] c rewrite, fuck your 6-digit PIDs + [x] c rewrite, fuck your 6-digit PIDs diff --git a/res/dockd.service b/res/dockd.service new file mode 100644 index 0000000..0e09403 --- /dev/null +++ b/res/dockd.service @@ -0,0 +1,7 @@ +[Unit] +Description=mein klein dockd + +[Service] +Type=exec +ExecStart=/usr/bin/bash -c '$HOME/.local/bin/dockd 2>&1 > /tmp/dockdlog' +Restart=always diff --git a/src/check_docked.sh b/src/check_docked.sh deleted file mode 100755 index 81019dc..0000000 --- a/src/check_docked.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env zsh - -lsusb | grep -q "ThinkPad Ultra Dock" && echo docked || echo undocked diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..2ec1d3d --- /dev/null +++ b/src/config.h @@ -0,0 +1,13 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#define DOCK_VENDOR 0x17ef +#define DOCK_PRODUCT 0x100f + +#define ON_DOCKED "/home/spv/.local/dockd/on_docked" +#define ON_UNDOCKED "/home/spv/.local/dockd/on_undocked" + +#define LOG_FP stderr +#define LOG_LEVEL LOG_INFO + +#endif diff --git a/src/dock_checker.sh b/src/dock_checker.sh deleted file mode 100755 index 5b4f1f8..0000000 --- a/src/dock_checker.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env zsh - -SCRIPT_DIR=$(dirname $(realpath $0)) -cd $SCRIPT_DIR - -rm .{un,}docked - -while true; do - if [ "$(./check_docked.sh)" = "docked" ]; then - if [ -e .docked ]; then - continue - fi - - echo docking... - - rm -f .undocked - sh/docked.sh - - touch .docked - else - if [ -e .undocked ]; then - continue - fi - - echo undocking... - - rm -f .docked - sh/undocked.sh - - touch .undocked - fi - - sleep 5 -done diff --git a/src/logger.h b/src/logger.h new file mode 100644 index 0000000..99b7b04 --- /dev/null +++ b/src/logger.h @@ -0,0 +1,19 @@ +#ifndef LOGGER_H +#define LOGGER_H + +#include <stdio.h> + +enum log_levels { + LOG_ERROR, + LOG_INFO, + LOG_DEBUG, + LOG_INSANEDEBUG, +}; + +#define LOG(LEVEL, args...) do { \ + if (LEVEL <= LOG_LEVEL) { \ + fprintf(LOG_FP, args); \ + } \ +} while (0) + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..80598e1 --- /dev/null +++ b/src/main.c @@ -0,0 +1,71 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <libusb.h> +#include "config.h" +#include "logger.h" + +static char* on_docked; +static char* on_undocked; + +int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev, + libusb_hotplug_event event, void *user_data) { + static libusb_device_handle *dev_handle = NULL; + struct libusb_device_descriptor desc; + + (void)libusb_get_device_descriptor(dev, &desc); + + LOG(LOG_DEBUG, "device: 0x%04x 0x%04x\n", desc.idVendor, desc.idProduct); + + if (desc.idVendor == DOCK_VENDOR && desc.idProduct == DOCK_PRODUCT) { + if (event == LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED) { + if (fork() == 0) { + execl(ON_DOCKED, ON_DOCKED, NULL); + } + LOG(LOG_DEBUG, "docked\n"); + } else { + if (fork() == 0) { + execl(ON_UNDOCKED, ON_UNDOCKED, NULL); + } + LOG(LOG_DEBUG, "undocked\n"); + } + } else { + LOG(LOG_DEBUG, "not dock\n"); + } + + return 0; +} + +int main(int argc, char* argv[]) { + libusb_hotplug_callback_handle callback_handle; + int rc; + + LOG(LOG_INFO, "starting dockd...\n"); + + libusb_init_context(NULL, NULL, 0); + + LOG(LOG_DEBUG, "init'd libusb context.\n"); + + rc = libusb_hotplug_register_callback(NULL, + LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | + LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, + LIBUSB_HOTPLUG_MATCH_ANY, + LIBUSB_HOTPLUG_MATCH_ANY, + LIBUSB_HOTPLUG_MATCH_ANY, + hotplug_callback, NULL, + &callback_handle); + + if (rc != LIBUSB_SUCCESS) { + LOG(LOG_ERROR, "failed to register libusb callback.\n"); + exit(rc); + } else { + LOG(LOG_DEBUG, "registered libusb hotplub callback.\n"); + } + + LOG(LOG_DEBUG, "beginning event loop...\n"); + + while (1) { + libusb_handle_events_completed(NULL, NULL); + nanosleep(&(struct timespec){0, 10000000UL}, NULL); + } +} |
