stm32plus::net DHCP client module

The Dynamic Host Configuration Protocol (DHCP) is one of today’s key application layer protocols. It’s used to automatically assign your computer an IP address and subnet mask as well as to discover your nearest router and your DNS servers. It relies on the existence of a DHCP server on your network that’s willing to assign you an address. If you’re on a home network with an ADSL router then that router is also your DHCP server.

stm32plus::net provides a complete implementation of a DHCP client that operates automatically, announcing the details that it has received from the DHCP server by raising events and renewing your DHCP lease automatically when it becomes due.

DHCP implementation

DHCP uses UDP broadcast datagrams to operate, therefore it requires you to have configured UDP into your stack at the network layer. Please refer to the documentation for the UDP module for details. DHCP itself is configured thus:

typedef ApplicationLayer<MyTransportLayer,DhcpClient> MyApplicationLayer;

Note that this application layer only shows the DhcpClient module in the application layer. In practice you will most likely have more than one module.

Configuration Parameters

The following parameters are made available in the stack’s configuration object for customisation:

// number of seconds to wait for the UDP packets to get a response (default is 6)
uint32_t dhcp_responseTimeout;

// number of times to retry on failure (default is 5)
uint8_t dhcp_retries;

// true if the DHCP server should call back via unicast (default is false)
bool dhcp_expectUnicastResponse;          

// ask for the subnet mask (default is true)
bool dhcp_requestSubnetMask;							

// ask for the default gateway (default is true)
bool dhcp_requestDefaultGateway;

// ask for the DNS server (default is true)
bool dhcp_requestDnsServer;

// ask for the domain name (default is true)								
bool dhcp_requestDomainName;							

// we'll tell the DHCP server that this is your name
const char *dhcp_hostname;								

dhcp_responseTimeout is the number of seconds that the module will wait for a response before retrying. A DHCP server is generally located on your LAN and so you should not expect to wait long for a response.

If the above response timeout expires then dhcp_retries is the number of times that a retry will be attempted before the module gives up and reports an error.

dhcp_expectUnicastResponse is an advanced setting that requests the server to send its response back to you by layer 2 (datalink layer) unicast instead of the default broadcast. Generally you will not need to change this setting and the server may well ignore you anyway.

There are four boolean ‘request’ flags that allow you to choose what to request from the server in addition to an IP address. The default settings request everything.

dhcp_hostname is an optional pointer to a hostname that you would like to be called. This may give you a readable name in your DHCP server’s administration screen and if your DHCP server is also your DNS resolver then you may find this name automatically registered within the local DNS database. If you have a home router then this will probably appear on your ‘connected clients’ administration py th age. All of the stm32plus::net examples set this to ‘stm32plus’.

Methods exposed

bool dhcpClientAcquire();

dhcpClientAcquire() starts off the transaction with the DHCP server that should ultimately result in you being assigned the information that you asked for. You do not need to call this method, it is done automatically during the startup of the network stack and again when the module detects that the lease granted to you for your IP address is 50% expired and should therefore be renewed. It is safe to call this method from normal or IRQ code.

If the transaction was started then this method returns true, otherwise it returns false. If an error occurs during the transaction then it is raised asynchronously using the normal error event mechanism.

Events raised by the DHCP module

The DHCP module raises a number of events to inform you of progress:

sender NetworkNotificationEventSender
event IpAddressAnnouncementEvent
identifier NetEventType::IP_ADDRESS_ANNOUNCEMENT
context IRQ
purpose IP address assigned

		/**
		 * Event descriptor that announces a new client IP address
		 */

		struct IpAddressAnnouncementEvent : NetEventDescriptor {

			/**
			 * References to the value
			 */

			const IpAddress& ipAddress;						///< Your IP address


			/**
			 * Constructor
			 */

			IpAddressAnnouncementEvent(const IpAddress& address)
				: NetEventDescriptor(NetEventType::IP_ADDRESS_ANNOUNCEMENT),
					ipAddress(address) {
			}
		};

This event is raised to notify you that an IP address has been assigned to you by the DHCP server. Various modules within the stack subscribe to this event and you can do too if you need to know your IP address.

sender NetworkNotificationEventSender
event IpSubnetMaskAnnouncementEvent
identifier NetEventType::SUBNET_MASK_ANNOUNCEMENT
context IRQ
purpose Subnet mask assigned
		/**
		 * Event descriptor that announces a new subnet mask
		 */

		struct IpSubnetMaskAnnouncementEvent : NetEventDescriptor {

			/**
			 *  Your subnet mask
			 */

			const IpSubnetMask& subnetMask;


			/**
			 * Constructor
			 */

			IpSubnetMaskAnnouncementEvent(const IpSubnetMask& subnetMask)
				: NetEventDescriptor(NetEventType::SUBNET_MASK_ANNOUNCEMENT),
					subnetMask(subnetMask) {
			}
		};

This event is raised to inform you of the subnet mask assigned to you by the server.

sender NetworkNotificationEventSender
event IpDefaultGatewayAnnouncementEvent
identifier NetEventType::DEFAULT_GATEWAY_ANNOUNCEMENT
context IRQ
purpose Default gateway assigned
		/**
		 * Your default gateway (router)
		 */

		struct IpDefaultGatewayAnnouncementEvent : NetEventDescriptor {

			/**
			 * References to the values
			 */

			const IpAddress& defaultGateway;


			/**
			 * Constructor
			 */

			IpDefaultGatewayAnnouncementEvent(const IpAddress& gateway)
				: NetEventDescriptor(NetEventType::DEFAULT_GATEWAY_ANNOUNCEMENT),
					defaultGateway(gateway) {
			}
		};

This event is raised to inform you of the default gateway that’s been assigned to you. IP packets that do not match your subnet mask are send to the default gateway for forwarding. If you are on a home network then the default gateway is likely to be your home router.

sender NetworkNotificationEventSender
event IpDnsServersAnnouncementEvent
identifier NetEventType::DNS_SERVERS_ANNOUNCEMENT
context IRQ
purpose DNS servers assigned
		/**
		 * Event descriptor that announces a new set of DNS servers (up to 3)
		 */

		struct IpDnsServersAnnouncementEvent : NetEventDescriptor {

			/**
			 * Up to 3 DNS servers, call isValid() to find the end of the set if less than 3
			 */

			const IpAddress *ipDnsServers;


			/**
			 * Constructor
			 */

			IpDnsServersAnnouncementEvent(const IpAddress *dnsServers)
				: NetEventDescriptor(NetEventType::DNS_SERVERS_ANNOUNCEMENT),
					ipDnsServers(dnsServers) {
			}
		};

This event is sent to inform you of that at least one DNS server has been assigned to you. The stm32plus::net DNS module subscribes to this event, as can you if you’re interested in knowing what your DNS server IP addresses are.

Up to three IP addresses are held in the array pointed to by the ipDnsServers pointer. At least one will be valid. Call the ipAddress.isValid() member on each of the three to discover if it points to a valid address.

sender NetworkNotificationEventSender
event DhcpRenewalDueEvent
identifier NetEventType::DHCP_RENEWAL_DUE
context IRQ
purpose DHCP lease is going to be renewed
		/**
		 * Event descriptor that announces that the DHCP release
		 * is due for renewal
		 */

		struct DhcpRenewalDueEvent : NetEventDescriptor {

			/**
			 * The expiry time expressed as an RTC time in ticks. This is a time, not an offset.
			 */

			uint32_t renewalTime;

			DhcpRenewalDueEvent(uint32_t rt)
				: NetEventDescriptor(NetEventType::DHCP_RENEWAL_DUE),
				  renewalTime(rt) {
			}
		};

An IP address assigned to you by a DHCP server has a lease time, after which it must be renewed. The DHCP specification advises that clients renew their leases half-way through the validity period and stm32plus::net does just that. This notification event is sent to let you know that the stack is about to start the renewal process. You don’t have to do anything but you should be aware that this event is likely to be followed by further events announcing the renewed IP address, subnet mask etc.

Related examples

Almost all the stm32plus::net examples use the DHCP module as part of their initial setup. The net_dhcp example illustrates just the DHCP client in action.