/** @file\r
Dhcp6 internal functions implementation.\r
\r
- Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
}\r
\r
//\r
- // Save tx packet pointer, and it will be destoryed when reply received.\r
+ // Save tx packet pointer, and it will be destroyed when reply received.\r
//\r
TxCb->TxPacket = Packet;\r
TxCb->Xid = Packet->Dhcp6.Header.TransactionId;\r
return Dhcp6EnqueueRetry (Instance, Packet, Elapsed, NULL);\r
}\r
\r
+/**\r
+ Start the information request process.\r
+\r
+ @param[in] Instance The pointer to the Dhcp6 instance.\r
+ @param[in] SendClientId If TRUE, the client identifier option will be included in\r
+ information request message. Otherwise, the client identifier\r
+ option will not be included.\r
+ @param[in] OptionRequest The pointer to the option request option.\r
+ @param[in] OptionCount The number options in the OptionList.\r
+ @param[in] OptionList The array pointers to the appended options.\r
+ @param[in] Retransmission The pointer to the retransmission control.\r
+ @param[in] TimeoutEvent The event of timeout.\r
+ @param[in] ReplyCallback The callback function when the reply was received.\r
+ @param[in] CallbackContext The pointer to the parameter passed to the callback.\r
+\r
+ @retval EFI_SUCCESS Start the info-request process successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
+ @retval EFI_NO_MAPPING No source address is available for use.\r
+ @retval Others Failed to start the info-request process.\r
+\r
+**/\r
+EFI_STATUS\r
+Dhcp6StartInfoRequest (\r
+ IN DHCP6_INSTANCE *Instance,\r
+ IN BOOLEAN SendClientId,\r
+ IN EFI_DHCP6_PACKET_OPTION *OptionRequest,\r
+ IN UINT32 OptionCount,\r
+ IN EFI_DHCP6_PACKET_OPTION *OptionList[] OPTIONAL,\r
+ IN EFI_DHCP6_RETRANSMISSION *Retransmission,\r
+ IN EFI_EVENT TimeoutEvent OPTIONAL,\r
+ IN EFI_DHCP6_INFO_CALLBACK ReplyCallback,\r
+ IN VOID *CallbackContext OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ DHCP6_INF_CB *InfCb;\r
+ DHCP6_SERVICE *Service;\r
+ EFI_TPL OldTpl;\r
+\r
+ Service = Instance->Service;\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+ Instance->UdpSts = EFI_ALREADY_STARTED;\r
+ //\r
+ // Create and initialize the control block for the info-request.\r
+ //\r
+ InfCb = AllocateZeroPool (sizeof(DHCP6_INF_CB));\r
+\r
+ if (InfCb == NULL) {\r
+ gBS->RestoreTPL (OldTpl);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ InfCb->ReplyCallback = ReplyCallback;\r
+ InfCb->CallbackContext = CallbackContext;\r
+ InfCb->TimeoutEvent = TimeoutEvent;\r
+\r
+ InsertTailList (&Instance->InfList, &InfCb->Link);\r
+\r
+ //\r
+ // Send the info-request message to start exchange process.\r
+ //\r
+ Status = Dhcp6SendInfoRequestMsg (\r
+ Instance,\r
+ InfCb,\r
+ SendClientId,\r
+ OptionRequest,\r
+ OptionCount,\r
+ OptionList,\r
+ Retransmission\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Register receive callback for the stateless exchange process.\r
+ //\r
+ Status = UdpIoRecvDatagram(\r
+ Service->UdpIo,\r
+ Dhcp6ReceivePacket,\r
+ Service,\r
+ 0\r
+ );\r
+\r
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
+ goto ON_ERROR;\r
+ }\r
+ \r
+ gBS->RestoreTPL (OldTpl);\r
+ return EFI_SUCCESS;\r
+ \r
+ON_ERROR:\r
+ gBS->RestoreTPL (OldTpl); \r
+ RemoveEntryList (&InfCb->Link);\r
+ FreePool (InfCb);\r
+\r
+ return Status;\r
+}\r
\r
/**\r
Create the information request message and send it.\r
ClientId = Service->ClientId;\r
Status = EFI_SUCCESS;\r
\r
- if (Instance->InDestory || Instance->Config == NULL) {\r
+ if (Instance->InDestroy || Instance->Config == NULL) {\r
goto ON_CONTINUE;\r
}\r
\r
IsMatched = FALSE;\r
InfCb = NULL;\r
\r
- if (Instance->InDestory) {\r
+ if (Instance->InDestroy) {\r
goto ON_EXIT;\r
}\r
\r
//\r
// Handle the first rt in the transmission of solicit specially.\r
//\r
- if (TxCb->RetryCnt == 0 && TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit) {\r
+ if ((TxCb->RetryCnt == 0 || TxCb->SolicitRetry) && TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit) {\r
if (Instance->AdSelect == NULL) {\r
//\r
// Set adpref as 0xff here to indicate select any advertisement\r
// Retransmit the last sent packet again.\r
//\r
Dhcp6TransmitPacket (Instance, TxCb->TxPacket, TxCb->Elapsed);\r
+ TxCb->SolicitRetry = FALSE;\r
+ if (TxCb->TxPacket->Dhcp6.Header.MessageType == Dhcp6MsgSolicit) {\r
+ TxCb->SolicitRetry = TRUE;\r
+ }\r
}\r
}\r
\r