diff --git a/.vscode/launch.json b/.vscode/launch.json index 87d9011..67c7659 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "name": "Debug", "type": "cppdbg", "request": "launch", - "args": [], + "args": ["khkokhot.csv"], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], diff --git a/.vscode/settings.json b/.vscode/settings.json index 18bd204..3117456 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,8 @@ "fcntl.h": "c", "file_operations.h": "c", "string.h": "c", - "termios.h": "c" + "termios.h": "c", + "typeinfo": "c" }, "C_Cpp.errorSquiggles": "enabled" } \ No newline at end of file diff --git a/include/db_handler.h b/include/db_handler.h new file mode 100644 index 0000000..549e08d --- /dev/null +++ b/include/db_handler.h @@ -0,0 +1,17 @@ +/** + * @brief Provizorni modul pro praci se seznamy uzivatelu. Priprava pro implementaci uziti PostgreSQL + * +*/ + +#ifndef __DB_HANDLER_H__ +#define __DB_HANDLER_H__ + +#include "main.h" +#include "users.h" +#include + +int loadListFromCSV(char* _filename, list_t * _list); + +int saveListToCSV(char* _filename, list_t * _list); + +#endif \ No newline at end of file diff --git a/include/rfid_handler.h b/include/rfid_handler.h index 0e555c7..f6938e8 100644 --- a/include/rfid_handler.h +++ b/include/rfid_handler.h @@ -13,7 +13,7 @@ typedef struct // UART handler thread void *uartListener(void *arg); -void parseIncommingPacket(list_t *_head, BYTE *_packet); +uint16_t parseIncommingPacket(BYTE *_packet); void sendPacketToDevice(BYTE * _packet); diff --git a/include/tui.h b/include/tui.h index 05c926f..adb03e6 100644 --- a/include/tui.h +++ b/include/tui.h @@ -5,8 +5,10 @@ #include #include #include "main.h" - +#include "users.h" void uartDialog(char *uart_adress, int terminal_x, int terminal_y); +void mainMenu(list_t * person_list, int terminal_x, int terminal_y); + #endif \ No newline at end of file diff --git a/include/users.h b/include/users.h index 24d3f3b..d8a2802 100644 --- a/include/users.h +++ b/include/users.h @@ -45,7 +45,7 @@ typedef struct list * @param _head Pointer to the head node of the linked list. * @return A 16-bit unsigned integer representing the generated UUID. */ -uint16_t generateUUID(node_t *_head); +uint16_t generateUUID(list_t *_list); /** * @brief Searches for a UUID associated with a user by their name and surname. @@ -59,7 +59,7 @@ uint16_t generateUUID(node_t *_head); * @param _surname Pointer to a string containing the user's surname. * @return Pointer to the UUID of the user if found, or 0 if no match is found. */ -uint16_t *searchUUIDByName(node_t *_head, char *_name, char *_surname); +uint16_t *searchUUIDByName(list_t *_list, char *_name, char *_surname); /** * @brief Searches for a person in a linked list by their UUID. @@ -72,7 +72,7 @@ uint16_t *searchUUIDByName(node_t *_head, char *_name, char *_surname); * @return Pointer to the node containing the person with the matching UUID, * or NULL if no such person is found. */ -node_t *searchPersonByUUID(node_t *_head, uint16_t _uuid); +node_t *searchPersonByUUID(list_t *_list, uint16_t _uuid); /** * @brief Adds a new person to the linked list. @@ -101,7 +101,9 @@ node_t *searchPersonByUUID(node_t *_head, uint16_t _uuid); * } * ``` */ -int addPersonToList(node_t **_head, char *_name, char *_surname, uint32_t _department); +int addPersonToList(list_t *_list, char *_name, char *_surname, uint32_t _department); + +int loadPersonToList(list_t *_list, uint16_t _uuid, char *_name, char *_surname, uint32_t _department, time_t _last_event, time_t _total, BYTE _available); /** * @brief Adds a time event to the specified person's event list. @@ -114,7 +116,7 @@ int addPersonToList(node_t **_head, char *_name, char *_surname, uint32_t _depar * @return An integer indicating the success or failure of the operation. * Typically, 1 for success and a 0 for failure. */ -int addTimeEvent(node_t *_person); +int addTimeEvent(node_t *_person, list_t *_list); /** * @brief Removes a person node from a linked list. @@ -127,5 +129,6 @@ int addTimeEvent(node_t *_person); * @param _person Double pointer to the node representing the person to remove. * @return int Returns 0 on success, or a negative value on failure. */ -int removePersonFromList(node_t **_head, node_t **_person); +int removePersonFromList(list_t *_list, node_t **_person); + #endif \ No newline at end of file diff --git a/khkokhot.csv b/khkokhot.csv new file mode 100644 index 0000000..4a0c5e2 --- /dev/null +++ b/khkokhot.csv @@ -0,0 +1 @@ +1,Kamil,Novak,2504,0,0,0 \ No newline at end of file diff --git a/src/db_handler.c b/src/db_handler.c new file mode 100644 index 0000000..c9d99a0 --- /dev/null +++ b/src/db_handler.c @@ -0,0 +1,27 @@ +#include "db_handler.h" + + +int loadListFromCSV(char *_filename, list_t *_list) +{ + FILE *f_in = fopen(_filename, "r"); + if (f_in == NULL) + { + // doprasit + exit(-1); + } + + char *buffer = NULL; + size_t buffer_size = 0; + + int load_sum = 0; + + char _name[128], _surname[128]; uint32_t _department; uint16_t _uuid; time_t _last_event, _total; BYTE _avail; + while (-1 != getline(&buffer, &buffer_size, f_in)) + { + sscanf(buffer, "%hu,%127[^,],%127[^,],%u,%ld,%ld,%hhu", &_uuid, _name, _surname, &_department, &_last_event, &_total, &_avail); + loadPersonToList(_list, _uuid, _name, _surname, _department, _last_event, _total, _avail); + load_sum++; + } + fclose(f_in); + return load_sum; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 8f45c1c..643fe25 100644 --- a/src/main.c +++ b/src/main.c @@ -7,14 +7,25 @@ #include #include #include +#include #include "main.h" #include "users.h" #include "tui.h" #include "rfid_handler.h" +#include "db_handler.h" + +void handle_sigint(int sig) +{ + clear(); + endwin(); + exit(0); +} int main(int argc, char const **argv) { + signal(SIGINT, handle_sigint); + if (argc != 2) { printf("filename argument required\nUsage: %s [User database]\n", argv[0]); @@ -48,6 +59,8 @@ int main(int argc, char const **argv) person_list.head = person_list_head; pthread_mutex_init(&person_list.lock, NULL); + loadListFromCSV(argv[1], &person_list); + noecho(); noraw(); cbreak(); diff --git a/src/rfid_handler.c b/src/rfid_handler.c index 63b103f..fb42bc9 100644 --- a/src/rfid_handler.c +++ b/src/rfid_handler.c @@ -16,7 +16,7 @@ void *uartListener(void *arg) UartThreadArgs *thread_args = (UartThreadArgs *)arg; char *uart_address = thread_args->uart_address; - list_t *person_list_head = thread_args->person_list_head; + list_t *person_list = thread_args->person_list_head; int uart = open(uart_address, O_RDWR | O_NOCTTY | O_NDELAY); if (uart == -1) @@ -105,7 +105,8 @@ void *uartListener(void *arg) if (crc == packet[5]) { - parseIncommingPacket(person_list_head, packet); + uint16_t r_uuid = parseIncommingPacket(packet); + addTimeEvent(searchPersonByUUID(person_list, r_uuid), person_list); } else { @@ -121,12 +122,12 @@ void *uartListener(void *arg) return NULL; } -void parseIncommingPacket(list_t *_head, BYTE *_packet) +uint16_t parseIncommingPacket(BYTE *_packet) { uint16_t r_id; BYTE r_event_type; memcpy(&r_id, &_packet[2], 2); memcpy(&r_event_type, &_packet[4], 1); - addTimeEvent(searchPersonByUUID(_head->head, r_id)); + return r_id; } \ No newline at end of file diff --git a/src/tui.c b/src/tui.c index 63f52d6..e18bd00 100644 --- a/src/tui.c +++ b/src/tui.c @@ -3,7 +3,7 @@ #include #include #include "main.h" - +#include "tui.h" void uartDialog(char *uart_adress, int terminal_x, int terminal_y) { @@ -105,3 +105,25 @@ void uartDialog(char *uart_adress, int terminal_x, int terminal_y) } } } + +void mainMenu(list_t *person_list, int terminal_x, int terminal_y) +{ + int win_height = 15; + int win_width = 80; + int start_y = (terminal_y - win_height) / 2; + int start_x = (terminal_x - win_width) / 2; + + start_color(); + init_pair(1, COLOR_BLACK, COLOR_WHITE); + init_pair(2, COLOR_WHITE, COLOR_RED); + + WINDOW *uartwin = newwin(win_height, win_width, start_y, start_x); + + wbkgd(uartwin, COLOR_PAIR(1)); + + box(uartwin, 0, 0); + wattron(uartwin, COLOR_PAIR(1)); + + wattroff(uartwin, COLOR_PAIR(1)); + wrefresh(uartwin); +} diff --git a/src/users.c b/src/users.c index 5079f4e..586e83c 100644 --- a/src/users.c +++ b/src/users.c @@ -11,17 +11,17 @@ #include uint16_t generateUUID( - node_t *_head) + list_t *_list) { uint16_t uuid; int found; - do { found = 0; uuid = (uint16_t)(rand() % (UINT16_MAX + 1)); - node_t *current = _head; + pthread_mutex_lock(&_list->lock); + node_t *current = _list->head; while (current != NULL) { if (current->user.uuid == uuid) @@ -31,36 +31,42 @@ uint16_t generateUUID( current = current->next; } } while (found); - + pthread_mutex_unlock(&_list->lock); return uuid; } node_t *searchPersonByUUID( - node_t *_head, + list_t *_list, uint16_t _uuid) { - node_t *current = _head; + pthread_mutex_lock(&_list->lock); + + node_t *current = _list->head; while (current != NULL) { if (current->user.uuid == _uuid) { + pthread_mutex_unlock(&_list->lock); + return current; } current = current->next; } + pthread_mutex_unlock(&_list->lock); return NULL; } uint16_t *searchUUIDByName( - node_t *_head, + list_t *_list, char *_name, char *_surname) { int sum = 0; uint16_t *uuids = malloc(sizeof(uint16_t)); - node_t *current = _head; + pthread_mutex_lock(&_list->lock); + node_t *current = _list->head; - if (_head == NULL) + if (_list->head == NULL) { return 0; } @@ -87,13 +93,16 @@ uint16_t *searchUUIDByName( uuids[sum - 1] = current->user.uuid; } } + pthread_mutex_unlock(&_list->lock); + if (sum == 0) + return NULL; return uuids; } int addPersonToList( - node_t **_head, + list_t *_list, char *_name, char *_surname, uint32_t _department) @@ -109,7 +118,7 @@ int addPersonToList( return 0; } - new_node->user.uuid = generateUUID(*_head); + new_node->user.uuid = generateUUID(_list); new_node->user.name = (char *)malloc(strlen(_name) + 1); new_node->user.surname = (char *)malloc(strlen(_surname) + 1); @@ -130,24 +139,85 @@ int addPersonToList( new_node->next = NULL; - if (*_head == NULL) + pthread_mutex_lock(&_list->lock); + + if (_list->head == NULL) { - *_head = new_node; + _list->head = new_node; + pthread_mutex_unlock(&_list->lock); + return 0; } - node_t *current = *_head; + node_t *current = _list->head; while (current->next != NULL) { current = current->next; } current->next = new_node; + pthread_mutex_unlock(&_list->lock); + + return 1; +} + +int loadPersonToList(list_t *_list, uint16_t _uuid, char *_name, char *_surname, uint32_t _department, time_t _last_event, time_t _total, BYTE _available) +{ + node_t *new_node = (node_t *)malloc(sizeof(node_t)); + if (new_node == NULL) + return 0; + + if (!strlen(_name) || !strlen(_surname)) + { + free(new_node); + new_node = NULL; + return 0; + } + + new_node->user.uuid = _uuid; + new_node->user.name = (char *)malloc(strlen(_name) + 1); + new_node->user.surname = (char *)malloc(strlen(_surname) + 1); + + if (new_node->user.name == NULL || new_node->user.surname == NULL) + { + free(new_node->user.name); + free(new_node->user.surname); + free(new_node); + return 0; + } + + strcpy(new_node->user.name, _name); + strcpy(new_node->user.surname, _surname); + new_node->user.department = _department; + new_node->user.last_time_event = _last_event; + new_node->user.total = _total; + new_node->user.available = _available; + + new_node->next = NULL; + + pthread_mutex_lock(&_list->lock); + + if (_list->head == NULL) + { + _list->head = new_node; + pthread_mutex_unlock(&_list->lock); + + return 0; + } + + node_t *current = _list->head; + while (current->next != NULL) + { + current = current->next; + } + current->next = new_node; + pthread_mutex_unlock(&_list->lock); return 1; } int addTimeEvent( - node_t *_person) + node_t *_person, + list_t *_list) { time_t current_time = time(0); @@ -156,6 +226,7 @@ int addTimeEvent( return 0; } + pthread_mutex_lock(&_list->lock); if (_person->user.available) { _person->user.total += (current_time - _person->user.last_time_event); @@ -163,16 +234,18 @@ int addTimeEvent( _person->user.available = !_person->user.available; _person->user.last_time_event = current_time; + pthread_mutex_unlock(&_list->lock); return 1; } -int removePersonFromList(node_t **_head, node_t **_person) +int removePersonFromList(list_t *_list, node_t **_person) { - if (_head == NULL || *_head == NULL || _person == NULL || *_person == NULL) + if (_list == NULL || _list->head == NULL || _person == NULL || *_person == NULL) return 0; - node_t *current = *_head; + pthread_mutex_lock(&_list->lock); + node_t *current = _list->head; node_t *prev = NULL; while (current != NULL) @@ -181,7 +254,7 @@ int removePersonFromList(node_t **_head, node_t **_person) { if (prev == NULL) { - *_head = current->next; + _list->head = current->next; } else { @@ -196,5 +269,6 @@ int removePersonFromList(node_t **_head, node_t **_person) prev = current; current = current->next; } + pthread_mutex_unlock(&_list->lock); return 0; } \ No newline at end of file