Added driver interface, loading, hashmap
This commit is contained in:
		
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								README.md
									
									
									
									
									
								
							@@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										76
									
								
								src/utils/hashmap.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/utils/hashmap.c
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								src/utils/hashmap.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/utils/hashmap.h
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
		Reference in New Issue
	
	Block a user