/** @file
  HII Config Access protocol implementation of VLAN configuration module.

Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "VlanConfigImpl.h"

CHAR16                           mVlanStorageName[] = L"VlanNvData";
EFI_HII_CONFIG_ROUTING_PROTOCOL  *mHiiConfigRouting = NULL;

VLAN_CONFIG_PRIVATE_DATA  mVlanConfigPrivateDateTemplate = {
  VLAN_CONFIG_PRIVATE_DATA_SIGNATURE,
  {
    VlanExtractConfig,
    VlanRouteConfig,
    VlanCallback
  }
};

VENDOR_DEVICE_PATH  mHiiVendorDevicePathNode = {
  {
    HARDWARE_DEVICE_PATH,
    HW_VENDOR_DP,
    {
      (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
      (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
    }
  },
  VLAN_CONFIG_FORM_SET_GUID
};

/**
  This function allows a caller to extract the current configuration for one
  or more named elements from the target driver.

  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Request            A null-terminated Unicode string in
                                 <ConfigRequest> format.
  @param[out]  Progress          On return, points to a character in the Request
                                 string. Points to the string's null terminator if
                                 request was successful. Points to the most recent
                                 '&' before the first failing name/value pair (or
                                 the beginning of the string if the failure is in
                                 the first name/value pair) if the request was not
                                 successful.
  @param[out]  Results           A null-terminated Unicode string in
                                 <ConfigAltResp> format which has all values filled
                                 in for the names in the Request string. String to
                                 be allocated by the called function.

  @retval EFI_SUCCESS            The Results is filled with the requested values.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
                                 driver.

**/
EFI_STATUS
EFIAPI
VlanExtractConfig (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN CONST EFI_STRING                      Request,
  OUT EFI_STRING                           *Progress,
  OUT EFI_STRING                           *Results
  )
{
  EFI_STATUS                Status;
  UINTN                     BufferSize;
  VLAN_CONFIGURATION        Configuration;
  VLAN_CONFIG_PRIVATE_DATA  *PrivateData;
  EFI_STRING                ConfigRequestHdr;
  EFI_STRING                ConfigRequest;
  BOOLEAN                   AllocatedRequest;
  UINTN                     Size;

  if ((Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gVlanConfigFormSetGuid, mVlanStorageName)) {
    return EFI_NOT_FOUND;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  AllocatedRequest = FALSE;
  Size             = 0;

  //
  // Retrieve the pointer to the UEFI HII Config Routing Protocol
  //
  if (mHiiConfigRouting == NULL) {
    gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&mHiiConfigRouting);
  }

  ASSERT (mHiiConfigRouting != NULL);

  //
  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
  //
  PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);
  ZeroMem (&Configuration, sizeof (VLAN_CONFIGURATION));
  BufferSize    = sizeof (Configuration);
  ConfigRequest = Request;
  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
    //
    // Request has no request element, construct full request string.
    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
    //
    ConfigRequestHdr = HiiConstructConfigHdr (&gVlanConfigFormSetGuid, mVlanStorageName, PrivateData->DriverHandle);
    Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest    = AllocateZeroPool (Size);
    ASSERT (ConfigRequest != NULL);
    AllocatedRequest = TRUE;
    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
    FreePool (ConfigRequestHdr);
  }

  Status = mHiiConfigRouting->BlockToConfig (
                                mHiiConfigRouting,
                                ConfigRequest,
                                (UINT8 *)&Configuration,
                                BufferSize,
                                Results,
                                Progress
                                );
  //
  // Free the allocated config request string.
  //
  if (AllocatedRequest) {
    FreePool (ConfigRequest);
    ConfigRequest = NULL;
  }

  //
  // Set Progress string to the original request string.
  //
  if (Request == NULL) {
    *Progress = NULL;
  } else if (StrStr (Request, L"OFFSET") == NULL) {
    *Progress = Request + StrLen (Request);
  }

  return Status;
}

/**
  This function processes the results of changes in configuration.

  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Configuration      A null-terminated Unicode string in <ConfigResp>
                                 format.
  @param[out]  Progress          A pointer to a string filled in with the offset of
                                 the most recent '&' before the first failing
                                 name/value pair (or the beginning of the string if
                                 the failure is in the first name/value pair) or
                                 the terminating NULL if all was successful.

  @retval EFI_SUCCESS            The Results is processed successfully.
  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
                                 driver.

**/
EFI_STATUS
EFIAPI
VlanRouteConfig (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN CONST EFI_STRING                      Configuration,
  OUT EFI_STRING                           *Progress
  )
{
  if ((Configuration == NULL) || (Progress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Configuration;
  if (!HiiIsConfigHdrMatch (Configuration, &gVlanConfigFormSetGuid, mVlanStorageName)) {
    return EFI_NOT_FOUND;
  }

  *Progress = Configuration + StrLen (Configuration);
  return EFI_SUCCESS;
}

/**
  This function processes the results of changes in configuration.

  @param[in]  This               Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Action             Specifies the type of action taken by the browser.
  @param[in]  QuestionId         A unique value which is sent to the original
                                 exporting driver so that it can identify the type
                                 of data to expect.
  @param[in]  Type               The type of value for the question.
  @param[in]  Value              A pointer to the data being sent to the original
                                 exporting driver.
  @param[out] ActionRequest      On return, points to the action requested by the
                                 callback function.

  @retval EFI_SUCCESS            The callback successfully handled the action.
  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
                                 variable and its data.
  @retval EFI_DEVICE_ERROR       The variable could not be saved.
  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
                                 callback.

**/
EFI_STATUS
EFIAPI
VlanCallback (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN     EFI_BROWSER_ACTION                Action,
  IN     EFI_QUESTION_ID                   QuestionId,
  IN     UINT8                             Type,
  IN     EFI_IFR_TYPE_VALUE                *Value,
  OUT EFI_BROWSER_ACTION_REQUEST           *ActionRequest
  )
{
  VLAN_CONFIG_PRIVATE_DATA  *PrivateData;
  VLAN_CONFIGURATION        *Configuration;
  EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;
  UINTN                     Index;
  EFI_HANDLE                VlanHandle;

  PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);

  if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
    return EFI_SUCCESS;
  }

  if ((Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_CHANGING)) {
    //
    // All other action return unsupported.
    //
    return EFI_UNSUPPORTED;
  }

  //
  // Get Browser data
  //
  Configuration = AllocateZeroPool (sizeof (VLAN_CONFIGURATION));
  ASSERT (Configuration != NULL);
  HiiGetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *)Configuration);

  VlanConfig = PrivateData->VlanConfig;

  if (Action == EFI_BROWSER_ACTION_CHANGED) {
    switch (QuestionId) {
      case VLAN_ADD_QUESTION_ID:
        //
        // Add a VLAN
        //
        VlanConfig->Set (VlanConfig, Configuration->VlanId, Configuration->Priority);
        VlanUpdateForm (PrivateData);

        //
        // Connect the newly created VLAN device
        //
        VlanHandle = NetLibGetVlanHandle (PrivateData->ControllerHandle, Configuration->VlanId);
        if (VlanHandle == NULL) {
          //
          // There may be no child handle created for VLAN ID 0, connect the parent handle
          //
          VlanHandle = PrivateData->ControllerHandle;
        }

        gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);

        //
        // Clear UI data
        //
        *ActionRequest          = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        Configuration->VlanId   = 0;
        Configuration->Priority = 0;
        break;

      case VLAN_REMOVE_QUESTION_ID:
        //
        // Remove VLAN
        //
        ASSERT (PrivateData->NumberOfVlan <= MAX_VLAN_NUMBER);
        for (Index = 0; Index < PrivateData->NumberOfVlan; Index++) {
          if (Configuration->VlanList[Index] != 0) {
            //
            // Checkbox is selected, need remove this VLAN
            //
            VlanConfig->Remove (VlanConfig, PrivateData->VlanId[Index]);
          }
        }

        VlanUpdateForm (PrivateData);
        if (PrivateData->NumberOfVlan == 0) {
          //
          // No VLAN device now, connect the physical NIC handle.
          // Note: PrivateData->NumberOfVlan has been updated by VlanUpdateForm()
          //
          gBS->ConnectController (PrivateData->ControllerHandle, NULL, NULL, TRUE);
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        ZeroMem (Configuration->VlanList, MAX_VLAN_NUMBER);
        break;

      default:
        break;
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
    switch (QuestionId) {
      case VLAN_UPDATE_QUESTION_ID:
        //
        // Update current VLAN list into Form.
        //
        VlanUpdateForm (PrivateData);
        break;

      default:
        break;
    }
  }

  HiiSetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *)Configuration, NULL);
  FreePool (Configuration);
  return EFI_SUCCESS;
}

/**
  This function update VLAN list in the VLAN configuration Form.

  @param[in, out]  PrivateData   Points to VLAN configuration private data.

**/
VOID
VlanUpdateForm (
  IN OUT VLAN_CONFIG_PRIVATE_DATA  *PrivateData
  )
{
  EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;
  UINT16                    NumberOfVlan;
  UINTN                     Index;
  EFI_VLAN_FIND_DATA        *VlanData;
  VOID                      *StartOpCodeHandle;
  EFI_IFR_GUID_LABEL        *StartLabel;
  VOID                      *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL        *EndLabel;
  CHAR16                    *String;
  CHAR16                    VlanStr[30];
  CHAR16                    VlanIdStr[6];
  UINTN                     DigitalCount;
  EFI_STRING_ID             StringId;

  //
  // Find current VLAN configuration
  //
  VlanData     = NULL;
  NumberOfVlan = 0;
  VlanConfig   = PrivateData->VlanConfig;
  VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);

  //
  // Update VLAN configuration in PrivateData
  //
  if (NumberOfVlan > MAX_VLAN_NUMBER) {
    NumberOfVlan = MAX_VLAN_NUMBER;
  }

  PrivateData->NumberOfVlan = NumberOfVlan;

  //
  // Init OpCode Handle
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode as the start opcode
  //
  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
                                       StartOpCodeHandle,
                                       &gEfiIfrTianoGuid,
                                       NULL,
                                       sizeof (EFI_IFR_GUID_LABEL)
                                       );
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number       = LABEL_VLAN_LIST;

  //
  // Create Hii Extend Label OpCode as the end opcode
  //
  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
                                     EndOpCodeHandle,
                                     &gEfiIfrTianoGuid,
                                     NULL,
                                     sizeof (EFI_IFR_GUID_LABEL)
                                     );
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number       = LABEL_END;

  ZeroMem (PrivateData->VlanId, MAX_VLAN_NUMBER);
  for (Index = 0; Index < NumberOfVlan; Index++) {
    String = VlanStr;

    StrCpyS (String, (sizeof (VlanStr) /sizeof (CHAR16)), L"  VLAN ID:");
    String += 10;
    //
    // Pad VlanId string up to 4 characters with space
    //
    UnicodeValueToStringS (VlanIdStr, sizeof (VlanIdStr), 0, VlanData[Index].VlanId, 5);
    DigitalCount = StrnLenS (VlanIdStr, ARRAY_SIZE (VlanIdStr));
    SetMem16 (String, (4 - DigitalCount) * sizeof (CHAR16), L' ');
    StrCpyS (String + 4 - DigitalCount, (sizeof (VlanStr) /sizeof (CHAR16)) - 10 - (4 - DigitalCount), VlanIdStr);
    String += 4;

    StrCpyS (String, (sizeof (VlanStr) /sizeof (CHAR16)) - 10 - (4 - DigitalCount) - 4, L", Priority:");
    String += 11;
    UnicodeValueToStringS (
      String,
      sizeof (VlanStr) - ((UINTN)String - (UINTN)VlanStr),
      0,
      VlanData[Index].Priority,
      4
      );
    String += StrnLenS (String, ARRAY_SIZE (VlanStr) - ((UINTN)String - (UINTN)VlanStr) / sizeof (CHAR16));
    *String = 0;

    StringId = HiiSetString (PrivateData->HiiHandle, 0, VlanStr, NULL);
    ASSERT (StringId != 0);

    HiiCreateCheckBoxOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(VLAN_LIST_VAR_OFFSET + Index),
      VLAN_CONFIGURATION_VARSTORE_ID,
      (UINT16)(VLAN_LIST_VAR_OFFSET + Index),
      StringId,
      STRING_TOKEN (STR_VLAN_VLAN_LIST_HELP),
      0,
      0,
      NULL
      );

    //
    // Save VLAN id to private data
    //
    PrivateData->VlanId[Index] = VlanData[Index].VlanId;
  }

  HiiUpdateForm (
    PrivateData->HiiHandle,     // HII handle
    &gVlanConfigFormSetGuid,    // Formset GUID
    VLAN_CONFIGURATION_FORM_ID, // Form ID
    StartOpCodeHandle,          // Label for where to insert opcodes
    EndOpCodeHandle             // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  if (VlanData != NULL) {
    FreePool (VlanData);
  }
}

/**
  This function publish the VLAN configuration Form for a network device. The
  HII Config Access protocol will be installed on a child handle of the network
  device.

  @param[in, out]  PrivateData   Points to VLAN configuration private data.

  @retval EFI_SUCCESS            HII Form is installed for this network device.
  @retval EFI_OUT_OF_RESOURCES   Not enough resource for HII Form installation.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
InstallVlanConfigForm (
  IN OUT VLAN_CONFIG_PRIVATE_DATA  *PrivateData
  )
{
  EFI_STATUS                      Status;
  EFI_HII_HANDLE                  HiiHandle;
  EFI_HANDLE                      DriverHandle;
  CHAR16                          Str[26 + sizeof (EFI_MAC_ADDRESS) * 2 + 1];
  CHAR16                          *MacString;
  EFI_DEVICE_PATH_PROTOCOL        *ChildDevicePath;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
  EFI_VLAN_CONFIG_PROTOCOL        *VlanConfig;

  //
  // Create child handle and install HII Config Access Protocol
  //
  ChildDevicePath = AppendDevicePathNode (
                      PrivateData->ParentDevicePath,
                      (CONST EFI_DEVICE_PATH_PROTOCOL *)&mHiiVendorDevicePathNode
                      );
  if (ChildDevicePath == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  PrivateData->ChildDevicePath = ChildDevicePath;

  DriverHandle = NULL;
  ConfigAccess = &PrivateData->ConfigAccess;
  Status       = gBS->InstallMultipleProtocolInterfaces (
                        &DriverHandle,
                        &gEfiDevicePathProtocolGuid,
                        ChildDevicePath,
                        &gEfiHiiConfigAccessProtocolGuid,
                        ConfigAccess,
                        NULL
                        );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  PrivateData->DriverHandle = DriverHandle;

  //
  // Establish the parent-child relationship between the new created
  // child handle and the ControllerHandle.
  //
  Status = gBS->OpenProtocol (
                  PrivateData->ControllerHandle,
                  &gEfiVlanConfigProtocolGuid,
                  (VOID **)&VlanConfig,
                  PrivateData->ImageHandle,
                  PrivateData->DriverHandle,
                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Publish the HII package list
  //
  HiiHandle = HiiAddPackages (
                &gVlanConfigFormSetGuid,
                DriverHandle,
                VlanConfigDxeStrings,
                VlanConfigBin,
                NULL
                );
  if (HiiHandle == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  PrivateData->HiiHandle = HiiHandle;

  //
  // Update formset title help string.
  //
  MacString = NULL;
  Status    = NetLibGetMacString (PrivateData->ControllerHandle, PrivateData->ImageHandle, &MacString);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  PrivateData->MacString = MacString;

  StrCpyS (Str, sizeof (Str) / sizeof (CHAR16), L"VLAN Configuration (MAC:");
  StrCatS (Str, sizeof (Str) / sizeof (CHAR16), MacString);
  StrCatS (Str, sizeof (Str) / sizeof (CHAR16), L")");
  HiiSetString (
    HiiHandle,
    STRING_TOKEN (STR_VLAN_FORM_SET_TITLE_HELP),
    Str,
    NULL
    );

  //
  // Update form title help string.
  //
  HiiSetString (
    HiiHandle,
    STRING_TOKEN (STR_VLAN_FORM_HELP),
    Str,
    NULL
    );

  return EFI_SUCCESS;
}

/**
  This function remove the VLAN configuration Form for a network device. The
  child handle for HII Config Access protocol will be destroyed.

  @param[in, out]  PrivateData   Points to VLAN configuration private data.

  @retval EFI_SUCCESS            HII Form has been uninstalled successfully.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
UninstallVlanConfigForm (
  IN OUT VLAN_CONFIG_PRIVATE_DATA  *PrivateData
  )
{
  EFI_STATUS                Status;
  EFI_VLAN_CONFIG_PROTOCOL  *VlanConfig;

  //
  // End the parent-child relationship.
  //
  Status = gBS->CloseProtocol (
                  PrivateData->ControllerHandle,
                  &gEfiVlanConfigProtocolGuid,
                  PrivateData->ImageHandle,
                  PrivateData->DriverHandle
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Uninstall HII Config Access Protocol
  //
  if (PrivateData->DriverHandle != NULL) {
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    PrivateData->DriverHandle,
                    &gEfiDevicePathProtocolGuid,
                    PrivateData->ChildDevicePath,
                    &gEfiHiiConfigAccessProtocolGuid,
                    &PrivateData->ConfigAccess,
                    NULL
                    );
    if (EFI_ERROR (Status)) {
      gBS->OpenProtocol (
             PrivateData->ControllerHandle,
             &gEfiVlanConfigProtocolGuid,
             (VOID **)&VlanConfig,
             PrivateData->ImageHandle,
             PrivateData->DriverHandle,
             EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
             );
      return Status;
    }

    PrivateData->DriverHandle = NULL;

    if (PrivateData->ChildDevicePath != NULL) {
      FreePool (PrivateData->ChildDevicePath);
      PrivateData->ChildDevicePath = NULL;
    }
  }

  //
  // Free MAC string
  //
  if (PrivateData->MacString != NULL) {
    FreePool (PrivateData->MacString);
    PrivateData->MacString = NULL;
  }

  //
  // Uninstall HII package list
  //
  if (PrivateData->HiiHandle != NULL) {
    HiiRemovePackages (PrivateData->HiiHandle);
    PrivateData->HiiHandle = NULL;
  }

  return EFI_SUCCESS;
}
