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.
 | 
					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);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										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