dhcp attempts
This commit is contained in:
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@@ -8,6 +8,13 @@
|
||||
"socket.h": "c",
|
||||
"type_traits": "c",
|
||||
"compare": "c",
|
||||
"uart.h": "c"
|
||||
"uart.h": "c",
|
||||
"mqttclient.h": "c",
|
||||
"config.h": "c",
|
||||
"dns.h": "c",
|
||||
"spi_dma.h": "c",
|
||||
"dhcp.h": "c",
|
||||
"debug.h": "c",
|
||||
"systick.h": "c"
|
||||
}
|
||||
}
|
||||
25
include/config.h
Normal file
25
include/config.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define DEBUG_MODE 1
|
||||
|
||||
#define DNS_RUN_INTERVAL_MS 100
|
||||
|
||||
// #define LOCAL_PORT 5000
|
||||
|
||||
// MQTT configuration
|
||||
#define CLIENT_ID "ch32_node"
|
||||
|
||||
#define MQTT_TARGET_IP {192, 168, 102, 147}
|
||||
#define MQTT_TARGET_PORT 1883
|
||||
|
||||
#define MQTT_KEEP_ALIVE_INTERVAL 60
|
||||
#define MQTT_TX_BUFFER_SIZE 128
|
||||
#define MQTT_RX_BUFFER_SIZE 128
|
||||
#define MQTT_COMMAND_TIMEOUT_MS 1000
|
||||
#define SUB_TOPIC "listen/world"
|
||||
#define PUB_TOPIC "hello/world"
|
||||
|
||||
#endif // CONFIG_H
|
||||
14
include/debug.h
Normal file
14
include/debug.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef DEBUG_MODE
|
||||
#define DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG_PRINT(fmt, ...)
|
||||
#endif
|
||||
|
||||
#endif // DEBUG_H
|
||||
14
include/systick.h
Normal file
14
include/systick.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef SYSTICK_H
|
||||
#define SYSTICK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define SYSTICK_ONE_MILLISECOND ((uint32_t)FUNCONF_SYSTEM_CORE_CLOCK / 1000)
|
||||
#define millis() (systick_millis)
|
||||
|
||||
void systick_init(void);
|
||||
|
||||
// ms counter incremented by SysTick
|
||||
extern volatile uint32_t systick_millis;
|
||||
|
||||
#endif // SYSTICK_H
|
||||
@@ -1,25 +1,25 @@
|
||||
#ifndef W5500_H
|
||||
#define W5500_H
|
||||
|
||||
#include <MQTT/MQTTClient.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Sets the CS pin low
|
||||
void w5500_select(void);
|
||||
// Definitions for socket indexes
|
||||
#define DHCP_SOCKET 0
|
||||
#define DNS_SOCKET 1
|
||||
#define TCP_SOCKET 2
|
||||
|
||||
// Sets the CS pin high
|
||||
void w5500_unselect(void);
|
||||
// Options structure for client identification
|
||||
typedef struct {
|
||||
char* clientid;
|
||||
char* username;
|
||||
char* password;
|
||||
int qos;
|
||||
} ch32_mqtt_options_t;
|
||||
|
||||
// Reads a byte via SPI
|
||||
uint8_t w5500_read_byte(void);
|
||||
extern volatile int ip_assigned;
|
||||
|
||||
// Writes a byte via SPI
|
||||
void w5500_write_byte(uint8_t byte);
|
||||
|
||||
// Reads multiple bytes via SPI
|
||||
void w5500_read_buffer(uint8_t* buff, uint16_t len);
|
||||
|
||||
// Writes multiple bytes via SPI
|
||||
void w5500_write_buffer(uint8_t* buff, uint16_t len);
|
||||
void handle_ip_assigned(void);
|
||||
|
||||
// Initializes the W5500 chip
|
||||
void configure_network(void);
|
||||
@@ -27,4 +27,14 @@ void configure_network(void);
|
||||
// resolves a domain name
|
||||
void resolve_domain_name(const char* domain_name);
|
||||
|
||||
// init and connect the MQTT client
|
||||
MQTTClient setup_mqtt_client(Network* network, ch32_mqtt_options_t* opts);
|
||||
|
||||
int subscribe_to_topic(MQTTClient* client, const char* topic, enum QoS qos,
|
||||
messageHandler message_callback);
|
||||
|
||||
// publish a message to a topic
|
||||
void publish_message(MQTTClient* client, const char* payload,
|
||||
const char* topic);
|
||||
|
||||
#endif // W5500_H
|
||||
|
||||
@@ -57,7 +57,7 @@ extern "C" {
|
||||
* @details If you want to display debug & processing message, Define _DHCP_DEBUG_
|
||||
* @note If defined, it depends on <stdio.h>
|
||||
*/
|
||||
#define _DHCP_DEBUG_
|
||||
// #define _DHCP_DEBUG_
|
||||
|
||||
|
||||
/* Retry to processing DHCP */
|
||||
|
||||
@@ -60,7 +60,7 @@ extern "C" {
|
||||
* @brief Define it for Debug & Monitor DNS processing.
|
||||
* @note If defined, it dependens on <stdio.h>
|
||||
*/
|
||||
#define _DNS_DEBUG_
|
||||
// #define _DNS_DEBUG_
|
||||
|
||||
#define MAX_DNS_BUF_SIZE 256 ///< maximum size of DNS buffer. */
|
||||
/*
|
||||
|
||||
8
mosquitto.conf
Normal file
8
mosquitto.conf
Normal file
@@ -0,0 +1,8 @@
|
||||
# mosquitto.conf - Basic Mosquitto configuration for development purposes
|
||||
|
||||
# Port to listen on (default is 1883)
|
||||
listener 1883
|
||||
|
||||
# Allow anonymous access (no authentication)
|
||||
allow_anonymous true
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
#define _FUNCONFIG_H
|
||||
|
||||
// board definition file will already take care of this
|
||||
//#define CH32V003 1
|
||||
// #define CH32V003 1
|
||||
|
||||
#define FUNCONF_USE_HSI 0 // Use HSI Internal Oscillator
|
||||
#define FUNCONF_USE_HSE 1 // Use External Oscillator
|
||||
#define FUNCONF_SYSTEM_CORE_CLOCK 144000000 // System Core Clock in Hz
|
||||
#define FUNCONF_USE_HSI 0 // Use HSI Internal Oscillator
|
||||
#define FUNCONF_USE_HSE 1 // Use External Oscillator
|
||||
#define FUNCONF_SYSTEM_CORE_CLOCK 144000000 // System Core Clock in Hz
|
||||
#define FUNCONF_USE_DEBUGPRINTF 0
|
||||
#define FUNCONF_USE_UARTPRINTF 0
|
||||
#define FUNCONF_UART_PRINTF_BAUD 115200 // Only used if FUNCONF_USE_UARTPRINTF is set.
|
||||
#define FUNCONF_USE_CLK_SEC 0
|
||||
#define FUNCONF_USE_UARTPRINTF 0
|
||||
#define FUNCONF_UART_PRINTF_BAUD \
|
||||
115200 // Only used if FUNCONF_USE_UARTPRINTF is set.
|
||||
#define FUNCONF_USE_CLK_SEC 0
|
||||
|
||||
#endif
|
||||
|
||||
105
src/main.c
105
src/main.c
@@ -1,26 +1,107 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <DHCP/dhcp.h>
|
||||
|
||||
#include "ch32v003fun.h"
|
||||
#include "debug.h"
|
||||
#include "gpio.h"
|
||||
#include "socket.h"
|
||||
#include "spi_dma.h"
|
||||
#include "systick.h"
|
||||
#include "uart.h"
|
||||
#include "w5500.h"
|
||||
|
||||
void init_system(void);
|
||||
|
||||
int main(void) {
|
||||
init_system();
|
||||
configure_network();
|
||||
resolve_domain_name("hye.su");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void init_system(void) {
|
||||
SystemInit();
|
||||
|
||||
init_gpio();
|
||||
init_uart(UART_BRR_APB1);
|
||||
// init_spi();
|
||||
init_spidma();
|
||||
// systick_init();
|
||||
}
|
||||
|
||||
// cb fn for when a message is received
|
||||
void message_arrived(MessageData* md) {
|
||||
if (md == NULL || md->message == NULL) {
|
||||
DEBUG_PRINT("Error: MessageData is NULL.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
MQTTMessage* message = md->message;
|
||||
DEBUG_PRINT("MQTT Message Arrived:\n");
|
||||
DEBUG_PRINT("QoS: %d\n", message->qos);
|
||||
DEBUG_PRINT("Retained: %d\n", message->retained);
|
||||
DEBUG_PRINT("Duplicate: %d\n", message->dup);
|
||||
DEBUG_PRINT("Message ID: %u\n", message->id);
|
||||
DEBUG_PRINT("Payload Length: %u\n", (unsigned int)message->payloadlen);
|
||||
|
||||
if (message->payload != NULL && message->payloadlen > 0) {
|
||||
DEBUG_PRINT("Payload: ");
|
||||
for (unsigned int i = 0; i < (unsigned int)message->payloadlen; ++i) {
|
||||
putchar(((unsigned char*)message->payload)[i]);
|
||||
}
|
||||
DEBUG_PRINT("\n");
|
||||
} else {
|
||||
DEBUG_PRINT("Payload: <No data>\n");
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
init_system();
|
||||
configure_network();
|
||||
|
||||
// todo: fucking systick
|
||||
// uint32_t dhcp_last_invocation = 0;
|
||||
// const uint32_t DHCP_INTERVAL = 100; // DHCP processing interval in ms
|
||||
|
||||
// // DHCP process blocking loop
|
||||
// while (!ip_assigned) {
|
||||
// if ((millis() - dhcp_last_invocation) >= DHCP_INTERVAL) {
|
||||
// dhcp_last_invocation = millis();
|
||||
// DEBUG_PRINT("Running DHCP...\n");
|
||||
// DHCP_run(); // Attempt to obtain an IP address
|
||||
// }
|
||||
// }
|
||||
|
||||
// Attempt to acquire an IP address using DHCP
|
||||
// const uint32_t max_attempts = 1e5;
|
||||
// for (uint32_t attempt = 0; !ip_assigned && attempt < max_attempts;
|
||||
// ++attempt) {
|
||||
// DHCP_run();
|
||||
// }
|
||||
|
||||
// if (!ip_assigned) {
|
||||
// DEBUG_PRINT("\r\nIP was not assigned :(\r\n");
|
||||
// return -1;
|
||||
// }
|
||||
// handle_ip_assigned();
|
||||
// ip_assigned = 0;
|
||||
|
||||
resolve_domain_name("hye.su");
|
||||
|
||||
Network network;
|
||||
ch32_mqtt_options_t opts = {CLIENT_ID, "", "", QOS0};
|
||||
|
||||
// Set up MQTT client
|
||||
MQTTClient client = setup_mqtt_client(&network, &opts);
|
||||
subscribe_to_topic(&client, SUB_TOPIC, QOS0, message_arrived);
|
||||
|
||||
// Publish a message
|
||||
publish_message(&client, "hi", PUB_TOPIC);
|
||||
|
||||
while (1) {
|
||||
// if ((millis() - dhcp_last_invocation) >= DHCP_INTERVAL) {
|
||||
// dhcp_last_invocation = millis();
|
||||
// DHCP_run(); // Run the DHCP processing function
|
||||
// }
|
||||
MQTTYield(&client, 1000); // Keep the connection alive
|
||||
|
||||
// if (ip_assigned) {
|
||||
// handle_ip_assigned();
|
||||
// ip_assigned = 0;
|
||||
// }
|
||||
}
|
||||
|
||||
MQTTDisconnect(&client);
|
||||
close(TCP_SOCKET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
50
src/systick.c
Normal file
50
src/systick.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "systick.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ch32v003fun.h"
|
||||
|
||||
// ms counter
|
||||
volatile uint32_t systick_millis = 0;
|
||||
|
||||
void systick_init(void) {
|
||||
// Reset any pre-existing configuration
|
||||
SysTick->CTLR = 0x0000;
|
||||
|
||||
// Set the compare register to trigger once per millisecond
|
||||
SysTick->CMP = SYSTICK_ONE_MILLISECOND - 1;
|
||||
|
||||
// Reset the Count Register and variables
|
||||
SysTick->CNT = 0x00000000;
|
||||
systick_millis = 0x00000000;
|
||||
|
||||
// Set the SysTick Configuration
|
||||
// NOTE: By not setting SYSTICK_CTLR_STRE, we maintain compatibility with
|
||||
// busywait delay funtions used by ch32v003_fun.
|
||||
SysTick->CTLR |= SYSTICK_CTLR_STE | // Enable Counter
|
||||
SYSTICK_CTLR_STIE | // Enable Interrupts
|
||||
SYSTICK_CTLR_STCLK; // Set Clock Source to HCLK/1
|
||||
|
||||
// Enable the SysTick IRQ
|
||||
NVIC_EnableIRQ(SysTicK_IRQn);
|
||||
}
|
||||
|
||||
/*
|
||||
* SysTick ISR - must be lightweight to prevent the CPU from bogging down.
|
||||
* Increments Compare Register and systick_millis when triggered (every 1ms)
|
||||
* NOTE: the `__attribute__((interrupt))` attribute is very important
|
||||
*/
|
||||
void SysTick_Handler(void) __attribute__((interrupt));
|
||||
void SysTick_Handler(void) {
|
||||
// Increment the Compare Register for the next trigger
|
||||
// If more than this number of ticks elapse before the trigger is reset,
|
||||
// you may miss your next interrupt trigger
|
||||
// (Make sure the IQR is lightweight and CMP value is reasonable)
|
||||
SysTick->CMP += SYSTICK_ONE_MILLISECOND;
|
||||
|
||||
// Clear the trigger state for the next IRQ
|
||||
SysTick->SR = 0x00000000;
|
||||
|
||||
// Increment the milliseconds count
|
||||
systick_millis++;
|
||||
}
|
||||
110
src/w5500.c
110
src/w5500.c
@@ -2,38 +2,26 @@
|
||||
|
||||
#include <DHCP/dhcp.h>
|
||||
#include <DNS/dns.h>
|
||||
#include <MQTT/MQTTClient.h>
|
||||
#include <W5500/w5500.h>
|
||||
#include <socket.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ch32v003fun.h"
|
||||
// #include "spi.h"
|
||||
#include "config.h"
|
||||
#include "debug.h"
|
||||
#include "spi_dma.h"
|
||||
|
||||
// Definitions for socket indexes
|
||||
#define DHCP_SOCKET 0
|
||||
#define DNS_SOCKET 1
|
||||
#define HTTP_SOCKET 2
|
||||
|
||||
// Global variables
|
||||
volatile uint32_t count = 0;
|
||||
volatile int ip_assigned = 0;
|
||||
|
||||
// Global buffers for DHCP and DNS
|
||||
uint8_t dhcp_buffer[1024];
|
||||
uint8_t dns_buffer[1024];
|
||||
|
||||
void w5500_select(void) {
|
||||
GPIOA->BCR = (1 << 4); // Set PA4 (CS) low
|
||||
}
|
||||
|
||||
void w5500_unselect(void) {
|
||||
GPIOA->BSHR = (1 << 4); // Set PA4 (CS) high
|
||||
}
|
||||
static uint8_t dhcp_buffer[512];
|
||||
static uint8_t dns_buffer[512];
|
||||
|
||||
// Function to handle IP assignment details
|
||||
void handle_ip_assigned(void) {
|
||||
printf("IP Assigned!\n");
|
||||
DEBUG_PRINT("IP Assigned!\n");
|
||||
|
||||
wiz_NetInfo net_info;
|
||||
getIPfromDHCP(net_info.ip);
|
||||
@@ -43,7 +31,7 @@ void handle_ip_assigned(void) {
|
||||
uint8_t dns[4];
|
||||
getDNSfromDHCP(dns);
|
||||
|
||||
printf(
|
||||
DEBUG_PRINT(
|
||||
"IP: %d.%d.%d.%d\nGW: %d.%d.%d.%d\nNet: %d.%d.%d.%d\nDNS: "
|
||||
"%d.%d.%d.%d\n",
|
||||
net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3],
|
||||
@@ -56,14 +44,15 @@ void handle_ip_assigned(void) {
|
||||
|
||||
// Callback functions
|
||||
void callback_ip_assigned(void) {
|
||||
printf("Callback: IP assigned! Leased time: %u sec\n", getDHCPLeasetime());
|
||||
DEBUG_PRINT("Callback: IP assigned! Leased time: %lu sec\n",
|
||||
getDHCPLeasetime());
|
||||
ip_assigned = 1;
|
||||
}
|
||||
|
||||
void callback_ip_conflict(void) { printf("Callback: IP conflict!\n"); }
|
||||
void callback_ip_conflict(void) { DEBUG_PRINT("Callback: IP conflict!\n"); }
|
||||
|
||||
void configure_network(void) {
|
||||
printf("Starting network configuration...\n");
|
||||
DEBUG_PRINT("Starting network configuration...\n");
|
||||
|
||||
// Setup chip select and SPI callbacks
|
||||
reg_wizchip_cs_cbfunc(spi_select, spi_unselect);
|
||||
@@ -85,21 +74,24 @@ void configure_network(void) {
|
||||
|
||||
// Attempt to acquire an IP address using DHCP
|
||||
const uint32_t max_attempts = 1e5;
|
||||
|
||||
// todo: run in a loop by a timer or sth
|
||||
for (uint32_t attempt = 0; !ip_assigned && attempt < max_attempts;
|
||||
++attempt) {
|
||||
DHCP_run();
|
||||
}
|
||||
|
||||
if (!ip_assigned) {
|
||||
printf("\r\nIP was not assigned :(\r\n");
|
||||
DEBUG_PRINT("\r\nIP was not assigned :(\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
handle_ip_assigned();
|
||||
}
|
||||
|
||||
// todo: rm
|
||||
void resolve_domain_name(const char* domain_name) {
|
||||
printf("Resolving domain name \"%s\"...\n", domain_name);
|
||||
DEBUG_PRINT("Resolving domain name \"%s\"...\n", domain_name);
|
||||
|
||||
DNS_init(DNS_SOCKET, dns_buffer);
|
||||
// cloudflare dns
|
||||
@@ -113,11 +105,75 @@ void resolve_domain_name(const char* domain_name) {
|
||||
|
||||
res = DNS_run(dns, (uint8_t*)domain_name, addr);
|
||||
if (res == 1) {
|
||||
printf("Result: %d.%d.%d.%d\n", addr[0], addr[1], addr[2], addr[3]);
|
||||
DEBUG_PRINT("Result: %d.%d.%d.%d\n", addr[0], addr[1], addr[2], addr[3]);
|
||||
break;
|
||||
} else {
|
||||
printf("DNS_run() failed, res = %d. Retries: %u\n", res, retries);
|
||||
DEBUG_PRINT("DNS_run() failed, res = %d. Retries: %u\n", res, retries);
|
||||
}
|
||||
retries++;
|
||||
}
|
||||
}
|
||||
|
||||
MQTTClient setup_mqtt_client(Network* network, ch32_mqtt_options_t* opts) {
|
||||
static unsigned char tx_buffer[MQTT_TX_BUFFER_SIZE];
|
||||
static unsigned char rx_buffer[MQTT_RX_BUFFER_SIZE];
|
||||
MQTTClient client;
|
||||
int rc;
|
||||
uint8_t target_ip[] = MQTT_TARGET_IP;
|
||||
|
||||
NewNetwork(network, TCP_SOCKET);
|
||||
if (ConnectNetwork(network, target_ip, MQTT_TARGET_PORT) != SOCK_OK) {
|
||||
DEBUG_PRINT("Network connection failed.\n");
|
||||
return (MQTTClient){0}; // Return an empty client on failure
|
||||
}
|
||||
|
||||
// Initialize the MQTT client
|
||||
MQTTClientInit(&client, network, MQTT_COMMAND_TIMEOUT_MS, tx_buffer,
|
||||
sizeof(tx_buffer), rx_buffer, sizeof(rx_buffer));
|
||||
|
||||
// Setup MQTT connection data
|
||||
MQTTPacket_connectData connect_data = MQTTPacket_connectData_initializer;
|
||||
connect_data.willFlag = 0;
|
||||
connect_data.MQTTVersion = 3;
|
||||
connect_data.clientID.cstring = opts->clientid;
|
||||
connect_data.username.cstring = opts->username;
|
||||
connect_data.password.cstring = opts->password;
|
||||
connect_data.keepAliveInterval = MQTT_KEEP_ALIVE_INTERVAL;
|
||||
connect_data.cleansession = 1;
|
||||
|
||||
// Connect to MQTT broker
|
||||
rc = MQTTConnect(&client, &connect_data);
|
||||
if (rc != 0) {
|
||||
DEBUG_PRINT("Failed to connect: %d\n", rc);
|
||||
return (MQTTClient){0}; // Return an empty client on failure
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
int subscribe_to_topic(MQTTClient* client, const char* topic, enum QoS qos,
|
||||
messageHandler message_callback) {
|
||||
int rc = MQTTSubscribe(client, topic, qos, message_callback);
|
||||
if (rc != 0) {
|
||||
DEBUG_PRINT("Failed to subscribe to %s: %d\n", topic, rc);
|
||||
return rc;
|
||||
}
|
||||
return 0; // Success
|
||||
}
|
||||
|
||||
void publish_message(MQTTClient* client, const char* payload,
|
||||
const char* topic) {
|
||||
MQTTMessage message = {.qos = QOS0,
|
||||
.retained = 0,
|
||||
.dup = 0,
|
||||
.payload = (void*)payload,
|
||||
.payloadlen = strlen(payload)
|
||||
|
||||
};
|
||||
|
||||
if (MQTTPublish(client, topic, &message) != 0) {
|
||||
DEBUG_PRINT("Publish failed\n");
|
||||
} else {
|
||||
DEBUG_PRINT("Message published successfully\n");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user