/** Starts the DHCPv6 standard S.A.R.R. process. The Start() function starts the DHCPv6 standard process. This function can be called only when the state of Dhcp6 instance is in the Dhcp6Init state. If the DHCP process completes successfully, the state of the Dhcp6 instance will be transferred through Dhcp6Selecting and Dhcp6Requesting to the Dhcp6Bound state. Refer to rfc-3315 for precise state transitions during this process. At the time when each event occurs in this process, the callback function that was set by EFI_DHCP6_PROTOCOL.Configure() will be called, and the user can take this opportunity to control the process. @param[in] This The pointer to Dhcp6 protocol. @retval EFI_SUCCESS The DHCPv6 standard process has started, or it has completed when CompletionEvent is NULL. @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_TIMEOUT The DHCPv6 configuration process failed because no response was received from the server within the specified timeout value. @retval EFI_ABORTED The user aborted the DHCPv6 process. @retval EFI_ALREADY_STARTED Some other Dhcp6 instance already started the DHCPv6 standard process. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_NO_MEDIA There was a media error. **/ EFI_STATUS EFIAPI EfiDhcp6Start ( IN EFI_DHCP6_PROTOCOL *This ) { EFI_STATUS Status; EFI_TPL OldTpl; DHCP6_INSTANCE *Instance; DHCP6_SERVICE *Service; if (This == NULL) { return EFI_INVALID_PARAMETER; } Instance = DHCP6_INSTANCE_FROM_THIS (This); Service = Instance->Service; // // The instance hasn't been configured. // if (Instance->Config == NULL) { return EFI_ACCESS_DENIED; } ASSERT (Instance->IaCb.Ia != NULL); // // The instance has already been started. // if (Instance->IaCb.Ia->State != Dhcp6Init) { return EFI_ALREADY_STARTED; } OldTpl = gBS->RaiseTPL (TPL_CALLBACK); Instance->UdpSts = EFI_ALREADY_STARTED; // // Need to clear initial time to make sure that elapsed-time // is set to 0 for first Solicit. // Instance->StartTime = 0; // // Send the solicit message to start S.A.R.R process. // Status = Dhcp6SendSolicitMsg (Instance); if (EFI_ERROR (Status)) { goto ON_ERROR; } // // Register receive callback for the stateful exchange process. // Status = UdpIoRecvDatagram( Service->UdpIo, Dhcp6ReceivePacket, Service, 0 ); if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { goto ON_ERROR; } gBS->RestoreTPL (OldTpl); // // Poll udp out of the net tpl if synchronous call. // if (Instance->Config->IaInfoEvent == NULL) { while (Instance->UdpSts == EFI_ALREADY_STARTED) { Service->UdpIo->Protocol.Udp6->Poll (Service->UdpIo->Protocol.Udp6); } return Instance->UdpSts; } return EFI_SUCCESS; ON_ERROR: gBS->RestoreTPL (OldTpl); return Status; }
/** Starts the DHCPv6 standard S.A.R.R. process. The Start() function starts the DHCPv6 standard process. This function can be called only when the state of Dhcp6 instance is in the Dhcp6Init state. If the DHCP process completes successfully, the state of the Dhcp6 instance will be transferred through Dhcp6Selecting and Dhcp6Requesting to the Dhcp6Bound state. Refer to rfc-3315 for precise state transitions during this process. At the time when each event occurs in this process, the callback function that was set by EFI_DHCP6_PROTOCOL.Configure() will be called, and the user can take this opportunity to control the process. @param[in] This The pointer to Dhcp6 protocol. @retval EFI_SUCCESS The DHCPv6 standard process has started, or it has completed when CompletionEvent is NULL. @retval EFI_ACCESS_DENIED The EFI DHCPv6 Child instance hasn't been configured. @retval EFI_INVALID_PARAMETER This is NULL. @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. @retval EFI_TIMEOUT The DHCPv6 configuration process failed because no response was received from the server within the specified timeout value. @retval EFI_ABORTED The user aborted the DHCPv6 process. @retval EFI_ALREADY_STARTED Some other Dhcp6 instance already started the DHCPv6 standard process. @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. @retval EFI_NO_MEDIA There was a media error. **/ EFI_STATUS EFIAPI EfiDhcp6Start ( IN EFI_DHCP6_PROTOCOL *This ) { EFI_STATUS Status; EFI_TPL OldTpl; DHCP6_INSTANCE *Instance; DHCP6_SERVICE *Service; EFI_STATUS MediaStatus; if (This == NULL) { return EFI_INVALID_PARAMETER; } Instance = DHCP6_INSTANCE_FROM_THIS (This); Service = Instance->Service; // // The instance hasn't been configured. // if (Instance->Config == NULL) { return EFI_ACCESS_DENIED; } ASSERT (Instance->IaCb.Ia != NULL); // // The instance has already been started. // if (Instance->IaCb.Ia->State != Dhcp6Init) { return EFI_ALREADY_STARTED; } OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // // Check Media Satus. // MediaStatus = EFI_SUCCESS; NetLibDetectMediaWaitTimeout (Service->Controller, DHCP_CHECK_MEDIA_WAITING_TIME, &MediaStatus); if (MediaStatus != EFI_SUCCESS) { Status = EFI_NO_MEDIA; goto ON_ERROR; } Instance->UdpSts = EFI_ALREADY_STARTED; // // Send the solicit message to start S.A.R.R process. // Status = Dhcp6SendSolicitMsg (Instance); if (EFI_ERROR (Status)) { goto ON_ERROR; } // // Register receive callback for the stateful exchange process. // Status = UdpIoRecvDatagram( Service->UdpIo, Dhcp6ReceivePacket, Service, 0 ); if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { goto ON_ERROR; } gBS->RestoreTPL (OldTpl); // // Poll udp out of the net tpl if synchronous call. // if (Instance->Config->IaInfoEvent == NULL) { while (Instance->UdpSts == EFI_ALREADY_STARTED) { Service->UdpIo->Protocol.Udp6->Poll (Service->UdpIo->Protocol.Udp6); } return Instance->UdpSts; } return EFI_SUCCESS; ON_ERROR: gBS->RestoreTPL (OldTpl); return Status; }