/*
LUFA Library
Copyright (C) Dean Camera, 2010.
-
+
dean [at] fourwalledcubicle [dot] com
- www.fourwalledcubicle.com
+ www.lufa-lib.org
*/
/*
Copyright 2010 Dean Camera (dean [at] fourwalledcubicle [dot] com)
- Permission to use, copy, modify, distribute, and sell this
+ Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
+ without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
- permission notice and warranty disclaimer appear in supporting
- documentation, and that the name of the author not be used in
- advertising or publicity pertaining to distribution of the
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
{
/* Create a new UDP connection to the DHCP server port for the DHCP solicitation */
struct uip_udp_conn* Connection = uip_udp_new(&uip_broadcast_addr, HTONS(DHCPC_SERVER_PORT));
-
+
/* If the connection was successfully created, bind it to the local DHCP client port */
if (Connection != NULL)
{
uip_udp_appstate_t* const AppState = &Connection->appstate;
uip_udp_bind(Connection, HTONS(DHCPC_CLIENT_PORT));
-
+
/* Set the initial client state */
AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
timer_set(&AppState->DHCPClient.Timeout, CLOCK_SECOND / 2);
}
}
-
-/** uIP stack application callback for the DHCP client. This function must be called each time the TCP/IP stack
+
+/** uIP stack application callback for the DHCP client. This function must be called each time the TCP/IP stack
* needs a UDP packet to be processed.
*/
void DHCPClientApp_Callback(void)
uip_udp_appstate_t* const AppState = &uip_udp_conn->appstate;
DHCP_Header_t* const AppData = (DHCP_Header_t*)uip_appdata;
uint16_t AppDataSize = 0;
-
+
switch (AppState->DHCPClient.CurrentState)
{
case DHCP_STATE_SendDiscover:
/* Fill out the DHCP response header */
AppDataSize += DHCPClientApp_FillDHCPHeader(AppData, DHCP_DISCOVER, AppState);
-
+
/* Add the required DHCP options list to the packet */
uint8_t RequiredOptionList[] = {DHCP_OPTION_SUBNET_MASK, DHCP_OPTION_ROUTER, DHCP_OPTION_DNS_SERVER};
AppDataSize += DHCPClientApp_SetOption(AppData->Options, DHCP_OPTION_REQ_LIST, sizeof(RequiredOptionList),
- RequiredOptionList);
-
+ RequiredOptionList);
+
/* Send the DHCP DISCOVER packet */
uip_udp_send(AppDataSize);
/* Reset the timeout timer, progress to next state */
timer_reset(&AppState->DHCPClient.Timeout);
- AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForOffer;
-
+ AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForOffer;
+
break;
case DHCP_STATE_WaitForOffer:
if (!(uip_newdata()))
/* Check if the DHCP timeout period has expired while waiting for a response */
if (timer_expired(&AppState->DHCPClient.Timeout))
AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
-
+
break;
}
-
+
uint8_t OfferResponse_MessageType;
if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &OfferResponse_MessageType) &&
DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SUBNET_MASK, &AppState->DHCPClient.DHCPOffer_Data.Netmask);
DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_ROUTER, &AppState->DHCPClient.DHCPOffer_Data.GatewayIP);
DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_SERVER_ID, &AppState->DHCPClient.DHCPOffer_Data.ServerIP);
-
+
timer_reset(&AppState->DHCPClient.Timeout);
AppState->DHCPClient.CurrentState = DHCP_STATE_SendRequest;
}
/* Send the DHCP REQUEST packet */
uip_udp_send(AppDataSize);
-
+
/* Reset the timeout timer, progress to next state */
timer_reset(&AppState->DHCPClient.Timeout);
AppState->DHCPClient.CurrentState = DHCP_STATE_WaitForACK;
/* Check if the DHCP timeout period has expired while waiting for a response */
if (timer_expired(&AppState->DHCPClient.Timeout))
AppState->DHCPClient.CurrentState = DHCP_STATE_SendDiscover;
-
+
break;
}
-
+
uint8_t RequestResponse_MessageType;
if ((AppData->TransactionID == DHCP_TRANSACTION_ID) &&
DHCPClientApp_GetOption(AppData->Options, DHCP_OPTION_MSG_TYPE, &RequestResponse_MessageType) &&
uip_sethostaddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.AllocatedIP);
uip_setnetmask((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.Netmask);
uip_setdraddr((uip_ipaddr_t*)&AppState->DHCPClient.DHCPOffer_Data.GatewayIP);
-
+
/* Indicate to the user that we now have a valid IP configuration */
HaveIPConfiguration = true;
- AppState->DHCPClient.CurrentState = DHCP_STATE_AddressLeased;
+ AppState->DHCPClient.CurrentState = DHCP_STATE_AddressLeased;
}
-
+
break;
}
}
memcpy(&DHCPHeader->NextServerIP, &AppState->DHCPClient.DHCPOffer_Data.ServerIP, sizeof(uip_ipaddr_t));
memcpy(&DHCPHeader->ClientHardwareAddress, &MACAddress, sizeof(struct uip_eth_addr));
DHCPHeader->Cookie = DHCP_MAGIC_COOKIE;
-
+
/* Add a DHCP message type and terminator options to the start of the DHCP options field */
DHCPHeader->Options[0] = DHCP_OPTION_MSG_TYPE;
DHCPHeader->Options[1] = 1;
DHCPHeader->Options[2] = DHCPMessageType;
DHCPHeader->Options[3] = DHCP_OPTION_END;
-
+
/* Calculate the total number of bytes added to the outgoing packet */
return (sizeof(DHCP_Header_t) + 4);
}
DHCPOptionList[1] = DataLen;
memcpy(&DHCPOptionList[2], OptionData, DataLen);
DHCPOptionList[2 + DataLen] = DHCP_OPTION_END;
-
+
/* Calculate the total number of bytes added to the outgoing packet */
return (2 + DataLen);
}
{
/* Copy request option's data to the destination buffer */
memcpy(Destination, &DHCPOptionList[2], DHCPOptionList[1]);
-
+
/* Indicate that the requested option data was successfully retrieved */
return true;
}
-
+
/* Skip to next DHCP option in the options list */
DHCPOptionList += (DHCPOptionList[1] + 2);
}
-
+
/* Requested option not found in the incoming packet's DHCP options list */
return false;
}
#endif
+