diff --git a/docs/udp_broadcast.md b/docs/udp_broadcast.md new file mode 100644 index 0000000..8e8cf46 --- /dev/null +++ b/docs/udp_broadcast.md @@ -0,0 +1,116 @@ +# UDP broadcast + +## Introduction + +The UDP broadcast code is used to handle incoming UDP datagrams. +there are currently 2 types of datagrams it processes: +- broadcasts: "Where are you?v1.0", replies with current owner details. +- change of details: "func1:name: ..., surname: ...", replies with changed owner details. + +It also writes the current owner's name on the screen and updates it everytime it's changed. + +## Table of contents +- [Introduction](#introduction) +- [Table of contents](#table-of-contents) +- [Usage of UDP broadcast](#usage-of-udp-broadcast) + - [Initialization of UDP broadcast](#initialization-of-udp-broadcast) + - [Initialization of UDP connection](#initialization-of-udp-connection) + - [Owner details interface](#owner-details-interface) + - [Setting owner details](#setting-owner-details) + - [Getting owner details](#getting-owner-details) + +## Usage of UDP broadcast +### Initialization of UDP broadcast +The 'udp_broadcast_init(uint16_t x_pos, uint16_t y_pos)' function does 4 things: +1. It initializes the coördinates of where the owner's name has to be written on the LCD. +2. [It initializes the UDP connection](#initialization-of-udp-connection) +3. It initializes the owner's details with a default name. +4. Returns the error value of [udp_broadcast_connection_init()](#initialization-of-udp-connection). This way the user can use some code to check whether the "connection" was initialized correctly. +```c +#include "UDP_broadcast.h' + +... + +void main(void){ + ... + if (udp_broadcast_init(270,255) != ERR_OK){ + ... + } + ... +} +``` + +### Initialization of UDP connection +The 'udp_broadcast_connection_init()' funciton does 2 things: +1. Initializes the UDP "connection" so that incoming datagrams can be processed and replied to. It binds to port 64000 and listens to every IP-address in the local network. +2. returns the LWIP error code so that [err_t udp_broadcast_init(uint16_t x_pos, uint16_t y_pos)](#initialization-of-udp-broadcast) knows the "connection" is initializes correctly + +This function can be used seperately from [err_t udp_broadcast_init(uint16_t x_pos, uint16_t y_pos)](#initialization-of-udp-broadcast), this gives the possibility to try "connecting" again after the first time failed. +```c +#include "UDP_broadcast.h' + +... + +void main(void){ + ... + if (udp_broadcast_init(10,255) == ERR_OK){ + goto connected; + } + LOG_WARN(TAG,"error initializing udp connection, trying again in 500ms"); + HAL_Delay(500); + if(udp_broadcast_connection_init() != ERR_OK){ + LOG_WARN(TAG,"error initializing udp connection, check warnings from udp_broadcast_init() or udp_broadcast_connection_init()"); + } + +connected: + ... +} + +``` +### Owner details interface +The interface to ask for the owner's details and change them is a modified version of the [Qt application](https://github.com/wimdams/Device_finder) Wim Dams build. His only has the functionality to ask for the owner's details. + +Just because the owner's details might want to be used in other code, some functions have been written for obtaining these in the STM32 code aswell. +#### Setting owner details +THe 'udp_broadcast_set_owner_details(const char* , const char*)' function does 2 things: +1. Set the owner details, the order of the parameters is: name, surname +2. Return 1 if the owner's details have been set correctly and 0 if not. +```c +#include "UDP_broadcast.h' + +... + +void main(void){ + ... + if (udp_broadcast_set_owner_details("Joran", "Van Nieuwenhoven") != ERR_OK){ + ... + } + ... +} +``` +#### Getting owner details +There are 3 functions: +- udp_broadcast_get_owner_details_name(): returns the owner's name. +- udp_broadcast_get_owner_details_surname(): returns the owner's surname. +- udp_broadcast_get_owner_details_reply(): returns what would be replied to a UDP broadcast with datagram "Where are you?v1.0". + +```c +#include +#include "UDP_broadcast.h' + +... + +void main(void){ + ... + char name[20]; + char surname[20]; + char reply[120]; + + strncp(name, udp_broadcast_get_owner_details_name(), sizeof(name) - 1); + + strncp(surname, udp_broadcast_get_owner_details_surname(), sizeof(surname) - 1); + + strncp(reply, udp_broadcast_get_owner_details_reply(), sizeof(reply) - 1); + ... +} +``` \ No newline at end of file diff --git a/project/Core/Inc/UDP_broadcast.h b/project/Core/Inc/UDP_broadcast.h new file mode 100644 index 0000000..ff26d10 --- /dev/null +++ b/project/Core/Inc/UDP_broadcast.h @@ -0,0 +1,127 @@ +/** + * @file UDP_broadcast.h + * + * @brief UDP broadcast handler + * Created on: Nov 6, 2023 + * Author: joran + */ + +#ifndef INC_UDP_BROADCAST_H_ +#define INC_UDP_BROADCAST_H_ + +// includes +#include +#include +#include +#include "lwip.h" +#include "lwip/netif.h" +#include "udp.h" + +#include "lcd_api.h" + +// Defines used by UDP callback +#define UDP_BROADCAST_MAX_DATA_SIZE ((UDP_BROADCAST_MAX_NAME_SIZE * 2) - 2 + 25) // Define the maximum expected data size +#define UDP_BROADCAST_UDP_QUESTION1 "Where are you?v1.0" // Expected question from UDP client +#define UDP_BROADCAST_MAX_FUNC_LEN 7 +#define UDP_BROADCAST_MAX_COLON_COMMA_COUNT 4 + +// Defines used by owner details +#define UDP_BROADCAST_MAX_REPLY_SIZE (UDP_BROADCAST_MAX_MAC_ADDR_LEN + sizeof(UDP_BROADCAST_REPLY_MIDDLE_TEXT) + (UDP_BROADCAST_MAX_NAME_SIZE * 2) + UDP_BROADCAST_MAX_REPLY_SIZE_EXTRA) +#define UDP_BROADCAST_REPLY_MIDDLE_TEXT "is present and my owner is" + +#define UDP_BROADCAST_MAX_MAC_ADDR_LEN 19 // Format is: "xx:xx:xx:xx:xx:xx" +#define UDP_BROADCAST_MAX_NAME_SIZE 21 // Code automatically leaves 1 char for '\0' (actual length = length - 1) +#define UDP_BROADCAST_MAX_REPLY_SIZE_EXTRA 20 // Just a bit extra + +#define UDP_BROADCAST_LCD_NAME_PRE_TEXT "New owner: " +#define UDP_BROADCAST_LCD_TEXT_SIZE (strlen(UDP_BROADCAST_LCD_NAME_PRE_TEXT) + UDP_BROADCAST_MAX_NAME_SIZE) + + +/** + * @struct owner_details_t + * @brief contains information about the owner + * + */ + +typedef struct { + char name[UDP_BROADCAST_MAX_NAME_SIZE]; + char surname[UDP_BROADCAST_MAX_NAME_SIZE]; + uint8_t mac_address[6]; + char reply[UDP_BROADCAST_MAX_REPLY_SIZE]; +} owner_details_t; + +// The following functions are used for owner details (those that must be available in main) + +/** + * @fn err_t udp_broadcast_set_owner_details(const char*, const char*) + * @brief udp_broadcast_set_owner_details() is the interface that can be used in other files + * to set the owner's details + * + * @param[in] name string containing the new owner's name + * @param[in] surname string containing the new owner's surname + * @return lwIP error code. + * - ERR_OK. Successful. No error occurred. + * - ERR_ARG. one or both arguments are NULL pointers + */ +err_t udp_broadcast_set_owner_details(const char*, const char*); + +/** + * @fn char udp_broadcast_get_owner_details_name*(void) + * @brief udp_broadcast_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(void); + +/** + * @fn char udp_broadcast_get_owner_details_surname*(void) + * @brief udp_broadcast_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(void); + +/** + * @fn char udp_broadcast_get_owner_details_reply*(void) + * @brief udp_broadcast_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(void); + +// Initialization functions + +/** + * @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 + * @param[in] y_pos : uint16_t that sets the y coordinate the owner's name will be written on the LCD + * @return lwIP error code. + * - ERR_OK. Successful. No error occurred. + * - ERR_USE. The specified ipaddr and port are already bound to by another UDP PCB. + * - ERR_MEM. udp pcb couldn't be created + * + * - ERR_ARG. one or both arguments of udp_broadcast_set_owner_details() are NULL pointers + */ + +err_t udp_broadcast_init(uint16_t x_pos, uint16_t y_pos); + +/** + * @fn err_t udp_broadcast_connection_init() + * @brief udp_broadcast_connection_init() initializes the UDP connection so that it listens for all traffic on + * port 6400 + * it is called by @see udp_broadcast_init() aswell but can be used separately if it failed before + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occurred. + * - ERR_USE. The specified ipaddr and port are already bound to by another UDP PCB. + * - ERR_MEM. udp pcb couldn't be created + */ + +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 new file mode 100644 index 0000000..d7261be --- /dev/null +++ b/project/Core/Src/UDP_broadcast.c @@ -0,0 +1,399 @@ +/** + * @file UDP_broadcast.c + * + * @brief UDP broadcast handler + * Created on: Nov 6, 2023 + * Author: joran + */ + +// Includes +#include "UDP_broadcast.h" +#define LOGGER_LEVEL_INFO +#include "log.h" + +// Global variables + +static const char* TAG = "UDP_broadcast"; // Tag used in logs +static owner_details_t udp_owner; +static uint16_t owner_name_x_pos; +static uint16_t owner_name_y_pos; + +// Functions +static void udp_broadcast_set_owner_details_mac(void); +static void udp_broadcast_name_to_lcd(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(void); +static void udp_receive_callback(void* arg, + struct udp_pcb* connection, + struct pbuf* p, + const ip_addr_t* addr, + u16_t port); + +/** + * @fn uint8_t udp_broadcast_set_owner_details_mac(owner_details_t*) + * @brief set_owner_details_mac() gets the MAC address from the default netif + * and sets it in the owner_details_t struct + */ + +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 + } +} + +/** + * @fn void udp_broadcast_name_to_lcd(void) + * @brief prints the owner's name with + * @see UDP_BROADCAST_LCD_NAME_PRE_TEXT in front of it + */ + +static void udp_broadcast_name_to_lcd(void){ + char text[UDP_BROADCAST_LCD_TEXT_SIZE]; + + memset(text,' ',UDP_BROADCAST_LCD_TEXT_SIZE); // Fill with spaces + text[UDP_BROADCAST_LCD_TEXT_SIZE - 1] = '\0'; // Make the last a NULL byte + lcd_display_text(text, owner_name_x_pos, owner_name_y_pos, LCD_BLACK, LCD_WHITE, LCD_FONT12); + + snprintf(text, UDP_BROADCAST_LCD_TEXT_SIZE, "%s%s",UDP_BROADCAST_LCD_NAME_PRE_TEXT, + udp_owner.name); + + lcd_display_text(text, owner_name_x_pos, owner_name_y_pos, LCD_BLACK, LCD_WHITE, LCD_FONT12); +} + + +/** + * @fn uint8_t udp_broadcast_set_owner_details_name(owner_details_t*, const char*) + * @brief set_owner_details_name() sets the owner's name in the owner_details_t struct + * strncpy is used to copy the function paremeter safely to the owner_details_t's name + * it also uses the lcd api to display the latest owner's name + * + * @param[in] name string containing the owner's name + * @return setting owner name error + * - 0: no error occured, name was set + * - 1: an error occured, name pointer is NULL + */ + +static uint8_t udp_broadcast_set_owner_details_name(const char* name) { + + if (name == NULL) { + LOG_WARN(TAG, "%s: string given is a NULL pointer", __func__); + return 1; + } + LOG_DEBUG(TAG, "set: %s", name); + strncpy(udp_owner.name, name, sizeof(udp_owner.name) - 1); // -1: compensate for '\0' + + udp_broadcast_name_to_lcd(); + return 0; +} + +/** + * @fn uint8_t udp_broadcast_set_owner_details_surname(owner_details_t*, const char*) + * @brief set_owner_details_surname() sets the owner's surname in the owner_details_t struct + * strncpy is used to copy the function paremeter safely to the owner_details_t's surname + * + * @param[in] surname string containing the owner's surname + * @return setting owner surname error + * - 0: no error occured, surname was set + * - 1: an error occured, surname pointer is NULL + */ +static uint8_t udp_broadcast_set_owner_details_surname(const char* surname) { + if (surname == NULL) { + LOG_WARN(TAG, "%s: string given is a NULL pointer", __func__); + return 1; + } + LOG_DEBUG(TAG, "set: %s", surname); + strncpy(udp_owner.surname, surname, sizeof(udp_owner.surname)-1); // -1: compensate for '\0' + return 0; +} + +/** + * @fn uint8_t udp_broadcast_set_owner_details_reply(const char*) + * @brief set_owner_details_reply() sets the UDP reply in the owner_details_t struct + * strncpy is used to copy the function paremeter safely to the owner_details_t's reply + * + * @param[in] reply string used to reply to the UDP broadcast + * @return setting owner reply error + * - 0: no error occured, reply was set + * - 1: an error occured, reply pointer is null + */ + +static uint8_t udp_broadcast_set_owner_details_reply(const char* reply) { + if (reply == NULL) { + LOG_WARN(TAG, "%s: string given is a NULL pointer", __func__); + return 1; + } + LOG_DEBUG(TAG, "set: %s", reply); + strncpy(udp_owner.reply, reply, sizeof(udp_owner.reply) - 1); // -1: compensate for '\0' + return 0; +} + +/** + * @fn uint8_t udp_broadcast_format_reply(const owner_details_t*) + * @brief format_reply() formats all the owner's details into a string + * it formats a string using the owner's details using snprintf + * it sets this reply with @see udp_broadcast_set_owner_details_reply() + */ + +static void udp_broadcast_format_reply(void) { + char mac_addr_str[UDP_BROADCAST_MAX_MAC_ADDR_LEN]; + char reply_buf[UDP_BROADCAST_MAX_REPLY_SIZE]; + + snprintf(mac_addr_str, sizeof(mac_addr_str), "%02X:%02X:%02X:%02X:%02X:%02X", udp_owner.mac_address[0], + udp_owner.mac_address[1], udp_owner.mac_address[2], udp_owner.mac_address[3], udp_owner.mac_address[4], + udp_owner.mac_address[5]); + + snprintf(reply_buf, UDP_BROADCAST_MAX_REPLY_SIZE, "%s %s %s %s", mac_addr_str, UDP_BROADCAST_REPLY_MIDDLE_TEXT, udp_owner.surname, + udp_owner.name); + udp_broadcast_set_owner_details_reply(reply_buf); +} + +/** + * @fn err_t udp_broadcast_set_owner_details(owner_details_t*, const char*, const char*) + * @brief set_owner_details() is the interface that can be used in other files + * to set the owner's details + * the pointers get checked by the functions that are called in this function + * + * @param[in] name string containing the new owner's name + * @param[in] surname string containing the new owner's surname + * @return lwIP error code. + * - ERR_OK. Successful. No error occurred. + * - ERR_ARG. one or both arguments are NULL pointers + */ +err_t udp_broadcast_set_owner_details(const char* name, const char* surname) { + if (!udp_broadcast_set_owner_details_name(name) && !udp_broadcast_set_owner_details_surname(surname)) { + + // If both return 0 it's okay + udp_broadcast_set_owner_details_mac(); + udp_broadcast_format_reply(); + return ERR_OK; + } + return ERR_ARG; +} + +/** + * @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(void) { + return udp_owner.name; +} + +/** + * @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(void) { + return udp_owner.surname; +} + +/** + * @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(void) { + return udp_owner.reply; +} + +/** + * @fn void udp_broadcast_check_function(const char[]) + * @brief checks what the UDP datagram asked to do + * and processes the datagram if it was not @see UDP_QUESTION1 + * + * @param[in] data the datagram received on port 64000 + * + * @return checked + * - 0: a function was found and processed if necessary + * - 1: datagram didn't have a known function + */ + +static uint8_t udp_broadcast_check_function(const char data[UDP_BROADCAST_MAX_DATA_SIZE]) { + char func[UDP_BROADCAST_MAX_FUNC_LEN]; + char buffer[UDP_BROADCAST_MAX_NAME_SIZE]; + uint8_t enders[UDP_BROADCAST_MAX_COLON_COMMA_COUNT]; + uint8_t counter = 0; + uint8_t data_len = strlen(data); + + if (strcmp(data, UDP_BROADCAST_UDP_QUESTION1) == 0) { + return 0; + } + + memset(func, 0, sizeof(func)); + memset(buffer, 0, sizeof(buffer)); + + memcpy(func,data,UDP_BROADCAST_MAX_FUNC_LEN - 1); + if (strcmp(func, "func1:") != 0) { + LOG_WARN(TAG, "%s: datagram does not contain function that's currently available", __func__); + return 1; + } + for (uint8_t i = 0; i < data_len && counter < UDP_BROADCAST_MAX_COLON_COMMA_COUNT; i++) { + if ((data[i] == ',' || data[i] == ':')) { + enders[counter] = i; + counter++; + } + } + if (enders[2] - enders[1] < UDP_BROADCAST_MAX_NAME_SIZE + 2 && data_len - enders[3] < UDP_BROADCAST_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]; i++) { + buffer[counter] = data[i]; + counter++; + } + if (buffer[0]=='\0') { + strncpy(buffer, "name", sizeof(buffer) - 1); // -1: compensate for '\0' + } + 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) - 1); // -1: compensate for '\0' + } + LOG_INFO(TAG, "new owner surname:%s", buffer); + udp_broadcast_set_owner_details_surname(buffer); + udp_broadcast_format_reply(); + return 0; + } + LOG_WARN(TAG,"%s: function didn't receive the right formatting", __func__); + return 1; +} + +/** + * @fn void udp_receive_callback(void*, struct udp_pcb*, struct pbuf*, const ip_addr_t*, u16_t) + * @brief udp_receive_callback() callback function for when a UDP packet has been received. + * it compares the data to a set string @see UDP_QUESTION1, if it's the same it sends the reply string, + * @see reply_str, back to the client + * if it was not @see UDP_QUESTION1, it checks what function was called with @see udp_broadcast_check_function() + * + * @param[in] arg a pointer to some user-defined data or context + * @param[in] connection UDP PCB to be bound with a local address ipaddr and port. + * @param[in] p packet buffer it holds the incoming UDP packet data, including its payload and length + * @param[in] addr ip_addr_t structure that contains the IP address of the sender of the UDP packet + * @param[in] port the source port number of the sender's UDP packet + */ + +static void udp_receive_callback(void* arg, + struct udp_pcb* connection, + struct pbuf* p, + const ip_addr_t* addr, + u16_t port) { + struct pbuf* p_data; + size_t len; + char* pc; + char data[UDP_BROADCAST_MAX_DATA_SIZE]; + char source_ip_str[16]; + + memset(data, 0, sizeof(data)); + + ipaddr_ntoa_r(addr, source_ip_str, sizeof(source_ip_str)); // Convert the source IP address to a string + + if (p == NULL) { + LOG_WARN(TAG, "%s: input buffer was a NULL pointer", __func__); + return; + } + pc = (char*)p->payload; + len = p->tot_len; + if (len >= UDP_BROADCAST_MAX_DATA_SIZE) { // >= : only if it's smaller to compensate for '\0' + LOG_WARN(TAG, "%s: input buffer was bigger than or was max size %d", __func__, UDP_BROADCAST_MAX_DATA_SIZE); + return; + } + + p_data = pbuf_alloc(PBUF_TRANSPORT, sizeof(udp_owner.reply), PBUF_RAM); + if (p_data == NULL) { + LOG_WARN(TAG, "%s: unable to allocate data buffer for reply", __func__); + goto defer; + } + for (size_t i = 0; i < len; i++) { + data[i] = pc[i]; + } + + LOG_INFO(TAG, "%s: received data from %s at port: %d: %s", __func__, source_ip_str, port, data); + LOG_INFO(TAG, "%s: checking which function was called", __func__); + + if(!udp_broadcast_check_function(data)){ // Should return 0 to reply + 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); // QT app listens on port 64000 + LOG_INFO(TAG, "%s: tried to reply to %s at port: %d: %s", __func__, source_ip_str, 64000, udp_owner.reply); + } + + +defer: + pbuf_free(p); + pbuf_free(p_data); +} + +/** + * @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 + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occurred. + * - ERR_USE. The specified ipaddr and port are already bound to by another UDP PCB. + * - ERR_MEM. udp pcb couldn't be created + */ + +err_t udp_broadcast_connection_init(void) { + struct udp_pcb* connection; + err_t err; + + LOG_INFO(TAG, "%s: initializing UDP server", __func__); + connection = udp_new(); + if (connection == NULL) { + LOG_WARN(TAG, "%s: Initializing UDP server failed, connection is null", __func__); + return ERR_MEM; + } + err = udp_bind(connection, IP_ANY_TYPE, 64000); + if (err != ERR_OK) { + LOG_WARN(TAG, "%s: Initializing UDP server failed, err not ok", __func__); + udp_remove(connection); + return err; + } + udp_recv(connection, udp_receive_callback, NULL); + LOG_INFO(TAG, "%s: Initializing UDP server successful, callback running", __func__); + 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() + * + * @return lwIP error code. + * - ERR_OK. Successful. No error occurred. + * - ERR_USE. The specified ipaddr and port are already bound to by another UDP PCB. + * - ERR_MEM. udp pcb couldn't be created + * + * - ERR_ARG. one or both arguments of udp_broadcast_set_owner_details() are NULL pointers + */ +err_t udp_broadcast_init(uint16_t x_pos, uint16_t y_pos) { + owner_name_x_pos = x_pos; + owner_name_y_pos = y_pos; + if(udp_broadcast_set_owner_details("name", "default") != ERR_OK){ + LOG_WARN(TAG, "%s: don't give NULL pointers as arguments for the owner's details", __func__); + return ERR_ARG; + } + return udp_broadcast_connection_init(); +} diff --git a/project/Core/Src/main.c b/project/Core/Src/main.c index 336157c..f564c3d 100644 --- a/project/Core/Src/main.c +++ b/project/Core/Src/main.c @@ -30,6 +30,7 @@ #include "lcd_api.h" #include "mqtt_application.h" #include "tftp.h" +#include "UDP_broadcast.h" /* USER CODE END Includes */ @@ -133,19 +134,30 @@ int main(void) /* Initialize the tftp server */ tftp_server_init(); - + + /* Initialize the MQTT application */ mqtt_application_init(); + + // Initialize the UDP broadcast service + + if (udp_broadcast_init(10,255) != ERR_OK){ + LOG_WARN(TAG,"error initializing udp connection, check warnings from udp_broadcast_init() or udp_broadcast_connection_init()"); + } + if (udp_broadcast_set_owner_details("Joran", "Van Nieuwenhoven") != ERR_OK){ + LOG_WARN(TAG,"error setting owner's details"); + } + /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { - /* USER CODE END WHILE */ + /* USER CODE END WHILE */ - /* USER CODE BEGIN 3 */ - MX_LWIP_Process(); + /* USER CODE BEGIN 3 */ + MX_LWIP_Process(); lcd_task(); } /* USER CODE END 3 */