Added driver interface, loading, hashmap

master
vhaudiquet 1 year ago
parent 53d65a235a
commit 0543d56dd5
  1. 14
      README.md
  2. 78
      src/device/usb/usb.c
  3. 76
      src/utils/hashmap.c
  4. 15
      src/utils/hashmap.h

@ -4,3 +4,17 @@ Manage the settings of your keyboard, mouse, ... with a simple GUI.
This is for the internal settings of your devices, not for the OS settings. This is for the internal settings of your devices, not for the OS settings.
For example, you can change the mouse DPI, polling rate, rgb, ... For example, you can change the mouse DPI, polling rate, rgb, ...
## Driver interface
Drivers **must** expose the following symbols:
```c
void driver_init(); // Initialization
uint32_t driver_getkey(); // Calls to this function must return USB keys that this driver registers, until 0
char* driver_get_name(); // Returns peripheral name
char* driver_get_image(); // Returns peripheral image
device_type_t driver_get_type(); // Returns device type
// Mouse drivers
```

@ -1,20 +1,84 @@
#include <libusb.h> #include <libusb.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <dirent.h>
#include <dlfcn.h>
#include <string.h>
#include <linux/limits.h>
#include <unistd.h>
#include <libgen.h>
#include "device/device.h" #include "device/device.h"
#include "utils/hashmap.h"
hashmap_t* usb_drivers;
void usb_drivers_init()
{
// Initialize hashmap
usb_drivers = hashmap_alloc();
// Obtain current executable path
char exe_path[PATH_MAX];
readlink("/proc/self/exe", exe_path, PATH_MAX);
char* path = dirname(exe_path);
size_t path_len = strlen(path);
char driver_path[PATH_MAX];
memcpy(driver_path, path, path_len);
memcpy(driver_path + path_len, "/drivers/", 10);
// Open driver directory and load all symbols
DIR* directory = opendir(driver_path);
if(!directory)
{
fprintf(stderr, "Error: Could not open '%s' directory\n", driver_path);
return;
}
printf("Opened drivers directory: %s\n", driver_path);
struct dirent* entry;
while((entry = readdir(directory)))
{
if(entry->d_type & DT_DIR) continue;
size_t entry_name_len = strlen(entry->d_name);
char fullpath[PATH_MAX];
memcpy(fullpath, driver_path, path_len + 9);
memcpy(fullpath + path_len + 9, entry->d_name, entry_name_len);
*(fullpath + path_len + 9 + entry_name_len) = 0;
void* driver = dlopen(fullpath, RTLD_LAZY | RTLD_LOCAL);
void (*init_fn)(void) = dlsym(driver, "driver_init");
init_fn();
uint32_t (*getkey_fn)(void) = dlsym(driver, "driver_getkey");
uint32_t key;
while((key = getkey_fn()))
hashmap_put(usb_drivers, key, driver);
}
closedir(directory);
}
void usb_init() void usb_init()
{ {
// List all usb devices obtaining 'vendor:product' // Init drivers
// Call corresponding driver if it exists, so usb_drivers_init();
// that we get a peripheral handle
// Init libusb
if(libusb_init(NULL)) if(libusb_init(NULL))
{ {
fprintf(stderr, "Error: Could not initialize libusb\n"); fprintf(stderr, "Error: Could not initialize libusb\n");
return; return;
} }
// List all usb devices obtaining 'vendor:product'
// Call corresponding driver if it exists, so
// that we get a peripheral handle
libusb_device** list; libusb_device** list;
ssize_t device_count = libusb_get_device_list(NULL, &list); ssize_t device_count = libusb_get_device_list(NULL, &list);
if(device_count <= 0) return; if(device_count <= 0) return;
@ -28,5 +92,13 @@ void usb_init()
printf("Found usb device %04x:%04x\n", desc.idVendor, desc.idProduct); printf("Found usb device %04x:%04x\n", desc.idVendor, desc.idProduct);
array_t* array = device_get_array(); array_t* array = device_get_array();
array_add(array, 0); array_add(array, 0);
libusb_device_handle* handle;
libusb_open(current, &handle);
char buf[4096] = {0};
libusb_get_string_descriptor_ascii(handle, 1, buf, 4096);
printf("Device desc (1): %s\n", buf);
libusb_get_string_descriptor_ascii(handle, 2, buf, 4096);
printf("Device desc (2): %s\n", buf);
} }
} }

@ -0,0 +1,76 @@
#include "hashmap.h"
#include <stdlib.h>
#define HASHMAP_ARRAY_SIZE 512
struct HASHMAP_ENTRY
{
uint32_t key;
void* elem;
struct HASHMAP_ENTRY* next;
};
struct HASHMAP
{
struct HASHMAP_ENTRY** array;
};
size_t _hashmap_hash(uint32_t key)
{
return key % HASHMAP_ARRAY_SIZE;
}
hashmap_t* hashmap_alloc()
{
hashmap_t* tr = malloc(sizeof(hashmap_t));
tr->array = calloc(sizeof(struct HASHMAP_ENTRY*), HASHMAP_ARRAY_SIZE);
return tr;
}
void hashmap_free(hashmap_t* hashmap)
{
for(size_t i = 0; i < HASHMAP_ARRAY_SIZE; i++)
{
struct HASHMAP_ENTRY* current = hashmap->array[i];
while(current)
{
struct HASHMAP_ENTRY* old = current;
current = current->next;
free(old);
}
}
free(hashmap->array);
free(hashmap);
}
void hashmap_put(hashmap_t* hashmap, uint32_t key, void* elem)
{
size_t index = _hashmap_hash(key);
struct HASHMAP_ENTRY** current = &hashmap->array[index];
while(*current)
{
current = &(*current)->next;
}
(*current) = malloc(sizeof(struct HASHMAP_ENTRY));
(*current)->key = key;
(*current)->elem = elem;
(*current)->next = 0;
}
void* hashmap_get(hashmap_t* hashmap, uint32_t key)
{
size_t index = _hashmap_hash(key);
struct HASHMAP_ENTRY* current = hashmap->array[index];
while(current)
{
if(current->key == key) return current->elem;
current = current->next;
}
return 0;
}

@ -0,0 +1,15 @@
#ifndef HASHMAP_H
#define HASHMAP_H
#include <stddef.h>
#include <stdint.h>
typedef struct HASHMAP hashmap_t;
hashmap_t* hashmap_alloc();
void hashmap_free(hashmap_t* hashmap);
void hashmap_put(hashmap_t* hashmap, uint32_t key, void* elem);
void* hashmap_get(hashmap_t* hashmap, uint32_t key);
#endif
Loading…
Cancel
Save