diff --git a/project/Core/Inc/UDP_broadcast.h b/project/Core/Inc/UDP_broadcast.h index 7f9ccfc..2c5126c 100644 --- a/project/Core/Inc/UDP_broadcast.h +++ b/project/Core/Inc/UDP_broadcast.h @@ -15,8 +15,6 @@ #include #include "lwip.h" #include "lwip/netif.h" -#define LOGGER_LEVEL_INFO -#include "log.h" #include "udp.h" #include "lcd_api.h" @@ -33,8 +31,16 @@ #define F_REPLY "format_reply" // Defines used by UDP callback -#define MAX_DATA_SIZE 63 // Define the maximum expected data size -#define UDP_QUESTION1 "Where are you?v1.0" // Expected request from UDP client +#define MAX_DATA_SIZE 63 // Define the maximum expected data size +#define UDP_QUESTION1 "Where are you?v1.0" // Expected question from UDP client +#define FUNC_LEN 7 +#define MAX_COLON_COMMA_COUNT 4 + +// Defines used by owner details + +#define MAX_NAME_SIZE 20 +#define MAX_REPLY_SIZE 120 + /** * @struct owner_details_t @@ -43,10 +49,10 @@ */ typedef struct { - char name[20]; - char surname[20]; + char name[MAX_NAME_SIZE]; + char surname[MAX_NAME_SIZE]; uint8_t mac_address[6]; - char reply[120]; + char reply[MAX_REPLY_SIZE]; } owner_details_t; // The following functions are used for owner details (those that must be available in main) @@ -65,34 +71,34 @@ typedef struct { uint8_t udp_broadcast_set_owner_details(const char*, const char*); /** - * @fn char udp_broadcast_get_owner_details_name*(owner_details_t) + * @fn char udp_broadcast_get_owner_details_name*(void) * @brief get_owner_details_name() can be used to get the current owner's name * * @return name of owner * this name is set by @see udp_broadcast_set_owner_details_name() */ -char* udp_broadcast_get_owner_details_name(); +char* udp_broadcast_get_owner_details_name(void); /** - * @fn char udp_broadcast_get_owner_details_surname*(const owner_details_t) + * @fn char udp_broadcast_get_owner_details_surname*(void) * @brief get_owner_details_surname() can be used to get the current owner's surname * * @return surname of owner * this name is set by @see udp_broadcast_set_owner_details_surname() */ -char* udp_broadcast_get_owner_details_surname(); +char* udp_broadcast_get_owner_details_surname(void); /** - * @fn char udp_broadcast_get_owner_details_reply*() + * @fn char udp_broadcast_get_owner_details_reply*(void) * @brief get_owner_details_reply() can be used to get the current UDP reply * * @return reply for UDP broadcast * this reply is formatted by @see format_reply() */ -char* udp_broadcast_get_owner_details_reply(); +char* udp_broadcast_get_owner_details_reply(void); /** - * @fn err_t udp_broadcast_init() + * @fn err_t udp_broadcast_init(uint16_t x_pos, uint16_t y_pos) * @brief udp_broadcast_init() initializes the owner's variables and calls upon @see udp_broadcast_connection_init() * * @param[in] x_pos : uint16_t that sets the x coordinate the owner's name will be written on the LCD @@ -117,6 +123,6 @@ err_t udp_broadcast_init(uint16_t x_pos, uint16_t y_pos); * - ERR_USE. The specified ipaddr and port are already bound to by another UDP PCB. */ -err_t udp_broadcast_connection_init(); +err_t udp_broadcast_connection_init(void); #endif /* INC_UDP_BROADCAST_H_ */ diff --git a/project/Core/Src/UDP_broadcast.c b/project/Core/Src/UDP_broadcast.c index 78781c0..f7660cf 100644 --- a/project/Core/Src/UDP_broadcast.c +++ b/project/Core/Src/UDP_broadcast.c @@ -5,10 +5,11 @@ * Created on: Nov 6, 2023 * Author: joran */ -//| // Includes #include "UDP_broadcast.h" +#define LOGGER_LEVEL_INFO +#include "log.h" // Global variables @@ -18,11 +19,11 @@ static uint16_t owner_name_x_pos; static uint16_t owner_name_y_pos; // Functions -static void udp_broadcast_set_owner_details_mac(); +static void udp_broadcast_set_owner_details_mac(void); static uint8_t udp_broadcast_set_owner_details_name(const char* name); static uint8_t udp_broadcast_set_owner_details_surname(const char* surname); static uint8_t udp_broadcast_set_owner_details_reply(const char* reply); -static void udp_broadcast_format_reply(); +static void udp_broadcast_format_reply(void); static void udp_receive_callback(void* arg, struct udp_pcb* connection, struct pbuf* p, @@ -35,7 +36,7 @@ static void udp_receive_callback(void* arg, * and sets it in the owner_details_t struct */ -static void udp_broadcast_set_owner_details_mac() { +static void udp_broadcast_set_owner_details_mac(void) { for (uint8_t i = 0; i < 6; i++) { udp_owner.mac_address[i] = netif_default->hwaddr[i]; // Access the MAC address } @@ -59,9 +60,9 @@ static uint8_t udp_broadcast_set_owner_details_name(const char* name) { return 0; } LOG_DEBUG(TAG, "set: %s", name); - lcd_display_text(" ", owner_name_x_pos, owner_name_y_pos, LCD_GREEN, LCD_BLACK, LCD_FONT16); + lcd_display_text(" ", owner_name_x_pos, owner_name_y_pos, LCD_GREEN,LCD_FONT16); strncpy(udp_owner.name, name, sizeof(udp_owner.name)); - lcd_display_text(name, owner_name_x_pos, owner_name_y_pos, LCD_GREEN, LCD_BLACK, LCD_FONT16); + lcd_display_text(name, owner_name_x_pos, owner_name_y_pos, LCD_GREEN, LCD_FONT16); return 1; } @@ -113,10 +114,10 @@ static uint8_t udp_broadcast_set_owner_details_reply(const char* reply) { * it sets this reply with @see udp_broadcast_set_owner_details_reply() */ -static void udp_broadcast_format_reply() { +static void udp_broadcast_format_reply(void) { size_t reply_len = 0; char mac_addr_str[18]; - char reply_buf[120]; + char reply_buf[MAX_REPLY_SIZE]; reply_len = 27 + sizeof(mac_addr_str) + sizeof(udp_owner.surname) + sizeof(udp_owner.name); @@ -153,38 +154,38 @@ uint8_t udp_broadcast_set_owner_details(const char* name, const char* surname) { } /** - * @fn char udp_broadcast_get_owner_details_name*(owner_details_t) + * @fn char udp_broadcast_get_owner_details_name*(void) * @brief get_owner_details_name() can be used to get the current owner's name * * @return name of owner * this name is set by @see udp_broadcast_set_owner_details_name() */ -char* udp_broadcast_get_owner_details_name() { +char* udp_broadcast_get_owner_details_name(void) { return udp_owner.name; } /** - * @fn char udp_broadcast_get_owner_details_surname*(const owner_details_t) + * @fn char udp_broadcast_get_owner_details_surname*(void) * @brief get_owner_details_surname() can be used to get the current owner's surname * * @return surname of owner * this name is set by @see udp_broadcast_set_owner_details_surname() */ -char* udp_broadcast_get_owner_details_surname() { +char* udp_broadcast_get_owner_details_surname(void) { return udp_owner.surname; } /** - * @fn char udp_broadcast_get_owner_details_reply*() + * @fn char udp_broadcast_get_owner_details_reply*(void) * @brief get_owner_details_reply() can be used to get the current UDP reply * * @return reply for UDP broadcast * this reply is formatted by @see format_reply() */ -char* udp_broadcast_get_owner_details_reply() { +char* udp_broadcast_get_owner_details_reply(void) { return udp_owner.reply; } @@ -197,51 +198,50 @@ char* udp_broadcast_get_owner_details_reply() { */ static void udp_broadcast_check_function(const char data[MAX_DATA_SIZE]) { - char func[7]; - char buffer[20]; - uint8_t enders[4]; + char func[FUNC_LEN]; + char buffer[MAX_NAME_SIZE]; + uint8_t enders[MAX_COLON_COMMA_COUNT]; uint8_t counter = 0; + size_t data_len = strlen(data); + memset(func, 0, sizeof(func)); memset(buffer, 0, sizeof(buffer)); - for (uint8_t i = 0; i < 6; i++) { - func[i] = data[i]; + memcpy(func,data,FUNC_LEN-1); + if (strcmp(func, "func1:") != 0) { + LOG_WARN(TAG, "udp_broadcast_check_function: datagram does not contain function that's currently available"); + return; } - if (strcmp(func, "func1:") == 0) { - for (uint8_t i = 0; i < strlen(data); i++) { - if (data[i] == ',' || data[i] == ':') { - enders[counter] = i; - counter++; - } + for (uint8_t i = 0; i < data_len; i++) { + if ((data[i] == ',' || data[i] == ':') && counter <= MAX_COLON_COMMA_COUNT) { + enders[counter] = i; + counter++; } - LOG_DEBUG(TAG, "%d-%d=%d, %d-%d=%d", enders[2], enders[1], enders[2] - enders[1], strlen(data), enders[3], - strlen(data) - enders[3]); - if (enders[2] - enders[1] < 22 && strlen(data) - enders[3] < 22 && strncmp(data + enders[0], ":name", 5) == 0 + } + if (enders[2] - enders[1] < MAX_NAME_SIZE + 2 && data_len - enders[3] < MAX_NAME_SIZE + 2 && strncmp(data + enders[0], ":name", 5) == 0 && strncmp(data + enders[2], ", surname", 9) == 0) { - counter = 0; - for (uint8_t i = enders[1] + 2; i < enders[2] && data[i] != '\0'; i++) { - buffer[counter] = data[i]; - LOG_DEBUG(TAG, "%d", counter); - counter++; - } - if (strcmp(buffer, "") == 0) { - strncpy(buffer, "name", sizeof(buffer)); - } - LOG_INFO(TAG, "new owner name:%s", buffer); - udp_broadcast_set_owner_details_name(buffer); - memset(buffer, 0, sizeof(buffer)); - counter = 0; - for (uint8_t i = enders[3] + 2; i < strlen(data) && data[i] != '\0'; i++) { - buffer[counter] = data[i]; - counter++; - } - if (strcmp(buffer, "") == 0) { - strncpy(buffer, "default", sizeof(buffer)); - } - LOG_INFO(TAG, "new owner surname:%s", buffer); - udp_broadcast_set_owner_details_surname(buffer); - udp_broadcast_format_reply(); + counter = 0; + for (uint8_t i = enders[1] + 2; i < enders[2] && data[i] != '\0'; i++) { + buffer[counter] = data[i]; + counter++; } + if (strcmp(buffer, "") == 0) { + strncpy(buffer, "name", sizeof(buffer)); + } + LOG_INFO(TAG, "new owner name:%s", buffer); + udp_broadcast_set_owner_details_name(buffer); + memset(buffer, 0, sizeof(buffer)); + counter = 0; + for (uint8_t i = enders[3] + 2; i < data_len; i++) { + buffer[counter] = data[i]; + counter++; + } + if (buffer[0]=='\0') { + strncpy(buffer, "default", sizeof(buffer)); + } + LOG_INFO(TAG, "new owner surname:%s", buffer); + udp_broadcast_set_owner_details_surname(buffer); + udp_broadcast_format_reply(); } } @@ -274,51 +274,52 @@ static void udp_receive_callback(void* arg, ipaddr_ntoa_r(addr, source_ip_str, sizeof(source_ip_str)); // Convert the source IP address to a string - if (p != NULL) { - pc = (char*)p->payload; - len = p->tot_len; - p_data = pbuf_alloc(PBUF_TRANSPORT, sizeof(udp_owner.reply), PBUF_RAM); - if (p_data == NULL) { - LOG_WARN(TAG, "udp_receive_callback: unable to allocate data buffer for reply"); - } else if (len <= MAX_DATA_SIZE) { - for (size_t i = 0; i < len; i++) { - data[i] = pc[i]; - } - - LOG_INFO(TAG, "udp_receive_callback: received data from %s at port: %d: %s", source_ip_str, port, data); - if (strcmp(data, UDP_QUESTION1) == 0) { - p_data->payload = udp_owner.reply; - p_data->len = strlen(udp_owner.reply); - p_data->tot_len = strlen(udp_owner.reply); - udp_sendto(connection, p_data, addr, 64000); /* Was using the sending port of the pc, - * this is not the port that Qt is listening to - */ - LOG_INFO(TAG, "tried to reply to %s at port: %d: %s", source_ip_str, 64000, udp_owner.reply); - } else { - LOG_INFO(TAG, "other function called"); - udp_broadcast_check_function(data); - p_data->payload = udp_owner.reply; - p_data->len = strlen(udp_owner.reply); - p_data->tot_len = strlen(udp_owner.reply); - udp_sendto(connection, p_data, addr, 64000); /* Was using the sending port of the pc, - * this is not the port that Qt is listening to - */ - LOG_INFO(TAG, "tried to reply to %s at port: %d: %s", source_ip_str, 64000, udp_owner.reply); - } - - } else { - LOG_WARN(TAG, "udp_receive_callback: input buffer was bigger than max size %d", MAX_DATA_SIZE); - } - - } else { + if (p == NULL) { LOG_WARN(TAG, "udp_receive_callback: input buffer was a NULL pointer"); + return; } + pc = (char*)p->payload; + len = p->tot_len; + p_data = pbuf_alloc(PBUF_TRANSPORT, sizeof(udp_owner.reply), PBUF_RAM); + if (p_data == NULL) { + LOG_WARN(TAG, "udp_receive_callback: unable to allocate data buffer for reply"); + goto defer; + } if (len > MAX_DATA_SIZE) { + LOG_WARN(TAG, "udp_receive_callback: input buffer was bigger than max size %d", MAX_DATA_SIZE); + goto defer; + } + for (size_t i = 0; i < len; i++) { + data[i] = pc[i]; + } + + LOG_INFO(TAG, "udp_receive_callback: received data from %s at port: %d: %s", source_ip_str, port, data); + if (strcmp(data, UDP_QUESTION1) == 0) { + p_data->payload = udp_owner.reply; + p_data->len = strlen(udp_owner.reply); + p_data->tot_len = strlen(udp_owner.reply); + udp_sendto(connection, p_data, addr, 64000); /* Was using the sending port of the pc, + * this is not the port that Qt is listening to + */ + LOG_INFO(TAG, "tried to reply to %s at port: %d: %s", source_ip_str, 64000, udp_owner.reply); + goto defer; + } + LOG_INFO(TAG, "other function called"); + udp_broadcast_check_function(data); + p_data->payload = udp_owner.reply; + p_data->len = strlen(udp_owner.reply); + p_data->tot_len = strlen(udp_owner.reply); + udp_sendto(connection, p_data, addr, 64000); /* Was using the sending port of the pc, + * this is not the port that Qt is listening to + */ + LOG_INFO(TAG, "tried to reply to %s at port: %d: %s", source_ip_str, 64000, udp_owner.reply); + +defer: pbuf_free(p); pbuf_free(p_data); } /** - * @fn err_t udp_broadcast_init() + * @fn err_t udp_broadcast_init(void) * @brief init_UDP_server() initialises the UDP connection so that it listens for all traffic on * port 6400 * it makes a udp_pcb, binds it to port 64000 and initializes the callback function for when data is received @@ -328,27 +329,28 @@ static void udp_receive_callback(void* arg, * - ERR_USE. The specified ipaddr and port are already bound to by another UDP PCB. */ -err_t udp_broadcast_connection_init() { +err_t udp_broadcast_connection_init(void) { struct udp_pcb* connection; err_t err; LOG_INFO(TAG, "initialising UDP server"); connection = udp_new(); - if (connection != NULL) { - err = udp_bind(connection, IP_ANY_TYPE, 64000); - if (err == ERR_OK) { - udp_recv(connection, udp_receive_callback, NULL); - LOG_INFO(TAG, "initialising UDP server succesfull, callback running"); - } else { - udp_remove(connection); - LOG_WARN(TAG, "initialising UDP server failed, err not ok"); - } - } else { - LOG_WARN(TAG, "initialising UDP server failed, connection is null"); + if (connection == NULL) { + LOG_WARN(TAG, "Initializing UDP server failed, connection is null"); } + err = udp_bind(connection, IP_ANY_TYPE, 64000); + if (err != ERR_OK) { + LOG_WARN(TAG, "Initializing UDP server failed, err not ok"); + udp_remove(connection); + return err; + } + udp_recv(connection, udp_receive_callback, NULL); + LOG_INFO(TAG, "Initializing UDP server successful, callback running"); return err; } + + /** * @fn err_t udp_broadcast_init() * @brief udp_broadcast_init() initializes the owner's variables and calls upon @see udp_broadcast_connection_init() @@ -358,10 +360,8 @@ err_t udp_broadcast_connection_init() { * - ERR_USE. The specified ipaddr and port are already bound to by another UDP PCB. */ err_t udp_broadcast_init(uint16_t x_pos, uint16_t y_pos) { - err_t err; owner_name_x_pos = x_pos; owner_name_y_pos = y_pos; udp_broadcast_set_owner_details("name", "default"); - err = udp_broadcast_connection_init(); - return err; + return udp_broadcast_connection_init(); } diff --git a/project/Core/Src/main.c b/project/Core/Src/main.c index 14db670..0678478 100644 --- a/project/Core/Src/main.c +++ b/project/Core/Src/main.c @@ -29,6 +29,7 @@ #include "llfs.h" #include "lcd_api.h" #include "tftp.h" +#include "UDP_broadcast.h" /* USER CODE END Includes */ @@ -132,6 +133,15 @@ int main(void) /* Initialize the tftp server */ tftp_server_init(); + + // Initialize the UDP broadcast service + if (udp_broadcast_init(270,255) != ERR_OK || udp_broadcast_connection_init() != ERR_OK){ + LOG_WARN(TAG,"error initializing udp connection"); + } + if (!udp_broadcast_set_owner_details("Joran", "Van Nieuwenhoven")){ + LOG_WARN(TAG,"error setting owner's details"); + } + /* USER CODE END 2 */ /* Infinite loop */