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.
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 <stdio.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 "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()
{
// List all usb devices obtaining 'vendor:product'
// Call corresponding driver if it exists, so
// that we get a peripheral handle
// Init drivers
usb_drivers_init();
// Init libusb
if(libusb_init(NULL))
{
fprintf(stderr, "Error: Could not initialize libusb\n");
return;
}
// List all usb devices obtaining 'vendor:product'
// Call corresponding driver if it exists, so
// that we get a peripheral handle
libusb_device** list;
ssize_t device_count = libusb_get_device_list(NULL, &list);
if(device_count <= 0) return;
@ -28,5 +92,13 @@ void usb_init()
printf("Found usb device %04x:%04x\n", desc.idVendor, desc.idProduct);
array_t* array = device_get_array();
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