This commit is contained in:
joran2738
2023-11-26 22:33:23 +01:00
4 changed files with 658 additions and 4 deletions

116
docs/udp_broadcast.md Normal file
View File

@@ -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 <string.h>
#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);
...
}
```

View File

@@ -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 <stdint.h>
#include <stdlib.h>
#include <string.h>
#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_ */

View File

@@ -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();
}

View File

@@ -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 */