123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- #include <stdio.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <sys/select.h>
- #include <linux/input.h>
- #include "read_conf_file.h"
- #include <assert.h>
- /****************************************************************
- * Defines
- ****************************************************************/
- #define die(str, args...) do { \
- perror(str); \
- return(EXIT_FAILURE); \
- } while(0)
- #define DEBUG_READ_CONF_FILE_PRINTF (0)
- #define ERROR_READ_CONF_FILE_PRINTF (1)
- #if (DEBUG_READ_CONF_FILE_PRINTF)
- #define READ_CONF_FILE_PRINTF(...) printf(__VA_ARGS__);
- #else
- #define READ_CONF_FILE_PRINTF(...)
- #endif
- #if (ERROR_READ_CONF_FILE_PRINTF)
- #define ERROR_CONF_FILE_PRINTF(...) printf(__VA_ARGS__);
- #else
- #define ERROR_CONF_FILE_PRINTF(...)
- #endif
- /****************************************************************
- * Extern variables
- ****************************************************************/
- extern key_names_s key_names[];
- /****************************************************************
- * Static variables
- ****************************************************************/
- static STRUCT_MAPPED_GPIO * head_chained_list_mapping_gpio = NULL;
- static int count_valid_gpios = 0;
- static int gpio_pins[MAX_NUM_GPIO];
- static bool gpio_active_high[MAX_NUM_GPIO];
- /****************************************************************
- * Static functions
- ****************************************************************/
- /* Return linux Key code from corresponding str*/
- static int find_key(const char *name)
- {
- int i=0;
- while(key_names[i].code >= 0){
- if(!strncmp(key_names[i].name, name, 32))break;
- i++;
- }
- if(key_names[i].code < 0){
- i = 0;
- }
- return i;
- }
- /* Return pin idx in the array of instanciated pins */
- static int get_idx_pin(int* ptr_list_gpio_pins, int size_list_gpio_pins, int pin_number_to_find){
- int idx;
- for (idx=0; idx<size_list_gpio_pins; idx++){
- if(ptr_list_gpio_pins[idx] == pin_number_to_find){
- return idx;
- }
- }
- // if we get here, then we did not find the pin:
- idx=-1;
- return idx;
- }
- /* function to swap data of two nodes a and b in chained list */
- static void swap(STRUCT_MAPPED_GPIO *a, STRUCT_MAPPED_GPIO *b)
- {
- STRUCT_MAPPED_GPIO temp;
- memcpy(&temp, a, sizeof(STRUCT_MAPPED_GPIO));
- memcpy(a, b, sizeof(STRUCT_MAPPED_GPIO));
- memcpy(b, &temp, sizeof(STRUCT_MAPPED_GPIO));
- b->next_mapped_gpio = a->next_mapped_gpio;
- a->next_mapped_gpio = b;
- }
- /* Bubble sort the given linked list */
- static void bubbleSort(STRUCT_MAPPED_GPIO *head)
- {
- int swapped, i;
- STRUCT_MAPPED_GPIO *ptr1 = head;
- STRUCT_MAPPED_GPIO *lptr = NULL;
-
- /* Checking for empty list */
- if (ptr1 == NULL)
- return;
-
- do
- {
- swapped = 0;
- ptr1 = head;
-
- while (ptr1->next_mapped_gpio != lptr)
- {
- if (ptr1->nb_simultaneous_pins < ptr1->next_mapped_gpio->nb_simultaneous_pins)
- {
- swap(ptr1, ptr1->next_mapped_gpio);
- swapped = 1;
- }
- ptr1 = ptr1->next_mapped_gpio;
- }
- lptr = ptr1;
- }
- while (swapped);
- }
- /* Push new node in chained list */
- static void push(STRUCT_MAPPED_GPIO ** head, STRUCT_MAPPED_GPIO * new_mapping) {
- STRUCT_MAPPED_GPIO ** current = head;
- while (*current != NULL) {
- current = &(*current)->next_mapped_gpio;
- }
- /* now we can add a new variable */
- *current = malloc(sizeof(STRUCT_MAPPED_GPIO));
- memcpy(*current, new_mapping, sizeof(STRUCT_MAPPED_GPIO));
- (*current)->next_mapped_gpio = NULL;
- }
- /****************************************************************
- * Public functions
- ****************************************************************/
- void get_mapping_from_conf_file(STRUCT_MAPPED_GPIO ** chained_list_mapping,
- int* nb_valid_gpios, int ** valid_gpio_pins, bool ** gpio_pins_active_high){
- /* Variables */
- READ_CONF_FILE_PRINTF("Reading the config file:\n");
- FILE *fp;
- char ln[MAX_LN_LENGTH];
- int lnno = 0;
- char conffile[80];
- bool pins_declaration_line = true;
- /* search for the conf file in ~/.funkey_gpio_mapping.conf and /etc/funkey_gpio_mapping.conf */
- sprintf(conffile, "%s/.funkey_gpio_mapping.conf", getenv("HOME"));
- fp = fopen(conffile, "r");
- if(!fp){
- fp = fopen("/etc/funkey_gpio_mapping.conf", "r");
- if(!fp){
- fp = fopen("./funkey_gpio_mapping.conf", "r");
- if(!fp){
- perror(conffile);
- perror("/etc/funkey_gpio_mapping.conf");
- perror("./funkey_gpio_mapping.conf");
- }
- sprintf(conffile, "./funkey_gpio_mapping.conf");
- }
- else{
- sprintf(conffile, "/etc/funkey_gpio_mapping.conf");
- }
- }
- if(fp){
- printf("GPIO config file used: %s\n", conffile);
- }
- /* Main loop to read conf file (purposely exploded and not in multiple sub-functions) */
- while(fp && !feof(fp)){
- if(fgets(ln, MAX_LN_LENGTH, fp)){
- lnno++;
- if(strlen(ln) > 1){
- if(ln[0]=='#')continue;
- READ_CONF_FILE_PRINTF("\nCurrent line : %s\n", ln);
- // ************ Pins declaration ************
- if(pins_declaration_line){
- char* token;
- int token_int;
-
- //count nb valid GPIOs and store them
- token = strtok(ln, ",");
- while(token != NULL){
- // Search for char '*' which means active low
- bool cur_active_high = true;
- char *substr = strchr(token, '*');
- if(substr != NULL){
- // Save polarity and set this char to \0 to end string
- cur_active_high = false;
- substr[0] = 0;
- }
- // Read pin idx
- token_int = atoi(token);
- if(token_int || !strcmp(token, "0")){
- gpio_pins[count_valid_gpios] = token_int;
- gpio_active_high[count_valid_gpios] = cur_active_high;
- count_valid_gpios++;
- READ_CONF_FILE_PRINTF("GPIO %d declared - active %s\n", token_int, cur_active_high?"high":"low");
- }
- else{
- ERROR_CONF_FILE_PRINTF("Could not declare GPIO: %s\n", token);
- }
- token = strtok(NULL, ",");
- }
- pins_declaration_line = false;
- }
- // ************ Pins mapping ************
- else{
- STRUCT_MAPPED_GPIO cur_gpio_mapping;
- char* end_ln;
- char* token_comma;
- char * current_arg;
- int cur_arg_idx = MAPPING_ARG_PINS;
- int idx_pin = 0;
- int cur_pin;
- bool add_current_mapping = true;
- token_comma = strtok_r(ln, ",", &end_ln);
- while(token_comma != NULL && cur_arg_idx < NB_MAPPING_ARG_NAMES && add_current_mapping){
- current_arg= token_comma;
- //remove_initial_spaces:
- while(*current_arg==' ' && *current_arg!=0){current_arg++;}
- READ_CONF_FILE_PRINTF(" Current arg: %s\n", current_arg);
- //Handle current mapping arg
- switch(cur_arg_idx){
- case MAPPING_ARG_PINS:
- //count nb valid GPIOs and store them
- ;char* end_arg;
- char * token_plus = strtok_r(current_arg, "+", &end_arg);
- while(token_plus != NULL){
- cur_pin = atoi(token_plus);
- if(cur_pin || !strcmp(token_plus, "0")){
- int idx_cur_pin = get_idx_pin(gpio_pins, count_valid_gpios, cur_pin);
- if(idx_cur_pin == -1){
- ERROR_CONF_FILE_PRINTF(" Could not find GPIO: %s in previously instanciated GPIOs\n", token_plus);
- add_current_mapping = false;
- break;
- }
- cur_gpio_mapping.pins_idx[idx_pin] = idx_cur_pin;
- idx_pin++;
- READ_CONF_FILE_PRINTF(" GPIO %d in current mapping\n", cur_pin);
- }
- else{
- ERROR_CONF_FILE_PRINTF(" Could not find GPIO: %s\n", token_plus);
- add_current_mapping = false;
- break;
- }
- token_plus = strtok_r(NULL, "+", &end_arg);//strtok_r(NULL, ",");
- }
- cur_gpio_mapping.nb_simultaneous_pins = idx_pin;
- break;
- case MAPPING_ARG_TYPE:
- if(!strcmp(current_arg, "KEYBOARD")){
- cur_gpio_mapping.type_mapping = TYPE_MAPPING_KEYBOARD;
- }
- else if(!strcmp(current_arg, "SHELL_COMMAND")){
- cur_gpio_mapping.type_mapping = TYPE_MAPPING_SHELL_COMMAND;
- }
- else{
- ERROR_CONF_FILE_PRINTF(" %s is not a valid mapping type\n", current_arg);
- add_current_mapping = false;
- break;
- }
- break;
- case MAPPING_ARG_VALUE:
- switch (cur_gpio_mapping.type_mapping){
- case TYPE_MAPPING_KEYBOARD:
- cur_gpio_mapping.key_value = find_key(current_arg);
- if(!cur_gpio_mapping.key_value){
- ERROR_CONF_FILE_PRINTF(" Could not find Key: %s\n", current_arg);
- add_current_mapping = false;
- }
- break;
- case TYPE_MAPPING_SHELL_COMMAND:
- cur_gpio_mapping.shell_command = malloc(strlen(current_arg)*sizeof(char));
- strcpy(cur_gpio_mapping.shell_command, current_arg);
- break;
- default:
- ERROR_CONF_FILE_PRINTF(" %d is not a valid mapping type\n", cur_gpio_mapping.type_mapping);
- add_current_mapping = false;
- break;
- }
- break;
- case MAPPING_ARG_STR_HELP_PIN_NAME:
- if(!strlen(current_arg)) continue;
- cur_gpio_mapping.pin_help_str = malloc(strlen(current_arg)*sizeof(char));
- strcpy(cur_gpio_mapping.pin_help_str, current_arg);
- break;
- case MAPPING_ARG_STR_HELP_PIN_FCT:
- if(!strlen(current_arg)) continue;
- cur_gpio_mapping.fct_help_str = malloc(strlen(current_arg)*sizeof(char));
- strcpy(cur_gpio_mapping.fct_help_str, current_arg);
- break;
- default:
- break;
- }
- //next arg
- token_comma = strtok_r(NULL, ",", &end_ln);
- cur_arg_idx++;
- }
- if(add_current_mapping){
- push(&head_chained_list_mapping_gpio, &cur_gpio_mapping);
- READ_CONF_FILE_PRINTF("Current Mapping added successfully\n\n");
- }
- else{
- ERROR_CONF_FILE_PRINTF("Current Mapping not added\n\n");
- }
- }
- }
- }
- }
- READ_CONF_FILE_PRINTF("Sorting Chained list...\n");
- bubbleSort(head_chained_list_mapping_gpio);
- print_all_chained_list(head_chained_list_mapping_gpio);
- print_gpios(gpio_pins, count_valid_gpios);
- if(fp){
- fclose(fp);
- }
- /* Return parameters */
- *chained_list_mapping = head_chained_list_mapping_gpio;
- *nb_valid_gpios = count_valid_gpios;
- *valid_gpio_pins = gpio_pins;
- *gpio_pins_active_high = gpio_active_high;
- }
- /* Print all chained list content */
- void print_all_chained_list(STRUCT_MAPPED_GPIO * head){
- STRUCT_MAPPED_GPIO * current = head;
- int idx = 0;
- READ_CONF_FILE_PRINTF("Printing Chained list:\n ");
- while (current != NULL) {
- READ_CONF_FILE_PRINTF("Chained list Mapping GPIOs, idx: %d\n", idx);
-
- print_chained_list_node(current);
- idx++;
- current = current->next_mapped_gpio;
- }
- }
- /* Print one chained list node */
- void print_chained_list_node(STRUCT_MAPPED_GPIO * node){
- // Print Pins:
- if(node->nb_simultaneous_pins > 1){
- READ_CONF_FILE_PRINTF(" %d Simultaneous pins at following idx: [", node->nb_simultaneous_pins);
- int i;
- for (i=0; i < node->nb_simultaneous_pins; i++){
- READ_CONF_FILE_PRINTF("%d%s", node->pins_idx[i], (i==node->nb_simultaneous_pins-1)?"]\n":",");
- }
- }
- else{
- READ_CONF_FILE_PRINTF(" idx pin: %d\n", node->pins_idx[0]);
- }
- // Type mapping and Value
- if (node->type_mapping == TYPE_MAPPING_KEYBOARD){
- READ_CONF_FILE_PRINTF(" Type mapping: TYPE_MAPPING_KEYBOARD\n");
- READ_CONF_FILE_PRINTF(" Key: %d\n", node->key_value);
- }
- else if (node->type_mapping == TYPE_MAPPING_SHELL_COMMAND){
- READ_CONF_FILE_PRINTF(" Type mapping: TYPE_MAPPING_SHELL_COMMAND\n");
- READ_CONF_FILE_PRINTF(" Shell command: %s\n", node->shell_command);
- }
- // Pin help String
- if(node->pin_help_str[0]){
- READ_CONF_FILE_PRINTF(" Pins: %s\n", node->pin_help_str);
- }
- // Function help String
- if(node->fct_help_str[0]){
- READ_CONF_FILE_PRINTF(" Function: %s\n", node->fct_help_str);
- }
- }
- void print_gpios(int * valid_gpio_pins, int nb_valid_gpios){
- READ_CONF_FILE_PRINTF("GPIO pins:\n[");
- for(int i = 0; i< nb_valid_gpios; i++) {
- READ_CONF_FILE_PRINTF("%d%s", valid_gpio_pins[i], (i==nb_valid_gpios-1)?"]\n":",");
- }
- }
|