[edk2-devel] [edk2-staging][PATCH v2 08/15] edk2-staging/RedfishClientPkg: Update Redfish feature core driver

Nickle Wang nickle.wang at hpe.com
Mon Jul 25 01:35:48 UTC 2022


Update Redfish feature core driver to support Redfish resource with
multiple parents. A resource may be presented in different resource and
the link in different resource point to the same location. Also add
interchange data interface in feature core driver so feature core
driver can talk to feature drivers directly.

Signed-off-by: Nickle Wang <nickle.wang at hpe.com>
Cc: Abner Chang <abner.chang at amd.com>
Cc: Yang Atom <Atom.Yang at amd.com>
Cc: Nick Ramirez <nramirez at nvidia.com>
---
 .../Include/Protocol/EdkIIRedfishFeature.h    |  20 +-
 .../RedfishFeatureCoreDxe.c                   | 290 ++++++++++++++++--
 .../RedfishFeatureCoreDxe.h                   |  20 +-
 .../RedfishFeatureCoreDxe.inf                 |   5 +-
 4 files changed, 278 insertions(+), 57 deletions(-)

diff --git a/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h b/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
index 036622128d..26814c8786 100644
--- a/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
+++ b/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
@@ -1,7 +1,7 @@
 /** @file
   This file defines the EDKII_REDFISH_FEATURE_PROTOCOL interface.
 
-  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -10,6 +10,8 @@
 #ifndef EDKII_REDFISH_FEATURE_H_
 #define EDKII_REDFISH_FEATURE_H_
 
+#include <Protocol/EdkIIRedfishInterchangeData.h>
+
 typedef struct _EDKII_REDFISH_FEATURE_PROTOCOL EDKII_REDFISH_FEATURE_PROTOCOL;
 
 #define EDKII_REDFISH_FEATURE_PROTOCOL_GUID \
@@ -23,25 +25,13 @@ typedef enum {
   CallbackActionMax
 } FEATURE_CALLBACK_ACTION;
 
-typedef enum {
-  InformationTypeNone = 0,            ///< Invalid information.
-  InformationTypeCollectionMemberUri, ///< URI to the new created collection member.
-  InformationTypeMax
-} FEATURE_RETURNED_INFORMATION_TYPE;
-
-typedef struct {
-  FEATURE_RETURNED_INFORMATION_TYPE Type;
-} FEATURE_RETURNED_INFORMATION;
-
 /**
   The callback function provided by Redfish Feature driver.
 
   @param[in]     This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL instance.
   @param[in]     FeatureAction       The action Redfish feature driver should take.
   @param[in]     Context             The context of Redfish feature driver.
-  @param[in,out] InformationReturned The pointer to retrive the pointer to
-                                     FEATURE_RETURNED_INFOMATION. The memory block of this
-                                     information should be freed by caller.
+  @param[in,out] ExchangeInformation The pointer to RESOURCE_INFORMATION_EXCHANGE.
 
   @retval EFI_SUCCESS              Redfish feature driver callback is executed successfully.
   @retval Others                   Some errors happened.
@@ -53,7 +43,7 @@ EFI_STATUS
   IN     EDKII_REDFISH_FEATURE_PROTOCOL *This,
   IN     FEATURE_CALLBACK_ACTION        FeatureAction,
   IN     VOID                           *Context,
-  IN OUT FEATURE_RETURNED_INFORMATION   **InformationReturned
+  IN OUT RESOURCE_INFORMATION_EXCHANGE  *ExchangeInformation
 );
 /**
   The registration function for the Redfish Feature driver.
diff --git a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
index 49e1cd6b60..3414f0c942 100644
--- a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
+++ b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
@@ -2,7 +2,7 @@
   RedfishFeatureCoreDxe produces EdkIIRedfishFeatureCoreProtocol
   for EDK2 Redfish Feature driver registration.
 
-  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -13,38 +13,188 @@
 EFI_EVENT mEdkIIRedfishFeatureDriverStartupEvent;
 REDFISH_FEATURE_STARTUP_CONTEXT mFeatureDriverStartupContext;
 REDFISH_FEATURE_INTERNAL_DATA *ResourceUriNodeList;
+RESOURCE_INFORMATION_EXCHANGE *mInformationExchange;
+
+/**
+  Setup the information to deliver to child feature/collection driver.
+
+  @param[in]  ThisList                 REDFISH_FEATURE_INTERNAL_DATA instance.
+  @param[in]  ParentConfgLanguageUri   Parent configure language URI.
+
+**/
+EFI_STATUS
+SetupExchangeInformationInfo (
+  IN REDFISH_FEATURE_INTERNAL_DATA *ThisList,
+  IN EFI_STRING                    ParentConfgLanguageUri
+  )
+{
+  ThisList->InformationExchange->SendInformation.ParentUri = (EFI_STRING)AllocateZeroPool (MaxParentUriLength * sizeof (CHAR16));
+  if (ThisList->InformationExchange->SendInformation.ParentUri == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  ThisList->InformationExchange->SendInformation.PropertyName = (EFI_STRING)AllocateZeroPool(MaxNodeNameLength * sizeof (CHAR16));
+  if (ThisList->InformationExchange->SendInformation.PropertyName == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  ThisList->InformationExchange->SendInformation.FullUri = (EFI_STRING)AllocateZeroPool(MaxParentUriLength * sizeof (CHAR16));
+  if (ThisList->InformationExchange->SendInformation.FullUri == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Setup property name
+  //
+  StrCpyS (ThisList->InformationExchange->SendInformation.PropertyName, MaxNodeNameLength, ThisList->NodeName);
+
+  //
+  // Setup parent config language URI
+  //
+  StrCpyS (ThisList->InformationExchange->SendInformation.ParentUri, MaxParentUriLength, ParentConfgLanguageUri);
+
+  //
+  // Full config language URI
+  //
+  StrCpyS (ThisList->InformationExchange->SendInformation.FullUri,
+           MaxParentUriLength,
+           ThisList->InformationExchange->SendInformation.ParentUri
+           );
+  if (StrLen (ThisList->InformationExchange->SendInformation.FullUri) != 0) {
+    StrCatS (ThisList->InformationExchange->SendInformation.FullUri, MaxParentUriLength, L"/");
+  }
+  StrCatS (ThisList->InformationExchange->SendInformation.FullUri, MaxParentUriLength, ThisList->InformationExchange->SendInformation.PropertyName);
+  return EFI_SUCCESS;
+}
+
+/**
+  Destroy the exchange information.
+
+  @param[in]  ThisList  REDFISH_FEATURE_INTERNAL_DATA instance.
+
+**/
+EFI_STATUS
+DestroryExchangeInformation (
+  IN REDFISH_FEATURE_INTERNAL_DATA *ThisList
+  )
+{
+
+  if (ThisList->InformationExchange != NULL) {
+    if (ThisList->InformationExchange->SendInformation.Type == InformationTypeCollectionMemberUri) {
+      if (ThisList->InformationExchange->SendInformation.ParentUri != NULL) {
+        FreePool (ThisList->InformationExchange->SendInformation.ParentUri);
+        ThisList->InformationExchange->SendInformation.ParentUri = NULL;
+      }
+      if (ThisList->InformationExchange->SendInformation.PropertyName != NULL) {
+        FreePool (ThisList->InformationExchange->SendInformation.PropertyName);
+        ThisList->InformationExchange->SendInformation.PropertyName = NULL;
+      }
+      if (ThisList->InformationExchange->SendInformation.FullUri != NULL) {
+        FreePool (ThisList->InformationExchange->SendInformation.FullUri);
+        ThisList->InformationExchange->SendInformation.FullUri = NULL;
+      }
+    }
+
+    if (ThisList->InformationExchange->ReturnedInformation.Type == InformationTypeCollectionMemberConfigLanguage) {
+      DestroyConfiglanguageList (&ThisList->InformationExchange->ReturnedInformation.ConfigureLanguageList);
+    }
+
+    ThisList->InformationExchange->SendInformation.Type = InformationTypeNone;
+    ThisList->InformationExchange->ReturnedInformation.Type = InformationTypeNone;
+
+  }
+  return EFI_SUCCESS;
+}
 
 /**
   Startup child feature drivers and it's sibing feature drivers.
 
-  @param[in]  ThisFeatureDriverList This feature driver list.
-  @param[in]  StartupContext        Start up information
+  @param[in]  ThisFeatureDriverList    This feature driver list.
+  @param[in]  CurrentConfigLanguageUri The current parent configure language URI.
+  @param[in]  StartupContext           Start up information
 
 **/
 VOID
 StartUpFeatureDriver (
   IN REDFISH_FEATURE_INTERNAL_DATA *ThisFeatureDriverList,
+  IN EFI_STRING                    CurrentConfigLanguageUri,
   IN REDFISH_FEATURE_STARTUP_CONTEXT *StartupContext
 )
 {
   EFI_STATUS Status;
+  UINTN Index;
   REDFISH_FEATURE_INTERNAL_DATA *ThisList;
+  REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG_LIST ConfigLangList;
+  EFI_STRING NextParentUri;
+
+  NextParentUri = (EFI_STRING)AllocateZeroPool (MaxParentUriLength * sizeof (CHAR16));
+  if (NextParentUri == NULL) {
+    DEBUG((DEBUG_ERROR, "%a: Fail to allocate memory for parent configure language.\n", __FUNCTION__));
+    return;
+  }
+  if (CurrentConfigLanguageUri != NULL) {
+    StrCpyS(NextParentUri, MaxParentUriLength, CurrentConfigLanguageUri);
+  }
 
   ThisList = ThisFeatureDriverList;
   while (TRUE) {
     if (ThisList->Callback != NULL) {
-      Status = ThisList->Callback(
-                           StartupContext->This,
-                           StartupContext->Action,
-                           ThisList->Context,
-                           &ThisList->ReturnedInformation
-                           );
+      ThisList->InformationExchange = mInformationExchange;
+      Status = SetupExchangeInformationInfo (ThisList, NextParentUri);
+      if (!EFI_ERROR (Status)) {
+        Status = ThisList->Callback(
+                               StartupContext->This,
+                               StartupContext->Action,
+                               ThisList->Context,
+                               ThisList->InformationExchange
+                               );
+      }
       if (EFI_ERROR (Status)) {
-        DEBUG((DEBUG_ERROR, "%a: Callback to EDK2 Redfish feature driver fail.", __FUNCTION__));
+        DEBUG((DEBUG_ERROR, "%a: Callback to EDK2 Redfish feature driver fail: %s.\n", __FUNCTION__, ThisList->InformationExchange->SendInformation.FullUri));
       }
     }
-    if (ThisList->ChildList != NULL) {
-      StartUpFeatureDriver (ThisList->ChildList, StartupContext);
+    if (!EFI_ERROR (Status) && ThisList->Callback != NULL && ThisList->ChildList != NULL) {
+      //
+      // Go through child list only when the parent node is managed by feature driver.
+      //
+      if (ThisList->Flags & REDFISH_FEATURE_INTERNAL_DATA_IS_COLLECTION) {
+        //
+        // The collection driver's callback is invoked. InformationTypeCollectionMemberConfigLanguage
+        // should be returned in RESOURCE_INFORMATION_RETURNED.
+        //
+        if (ThisList->InformationExchange->ReturnedInformation.Type == InformationTypeCollectionMemberConfigLanguage) {
+          //
+          // Copy RESOURCE_INFORMATION_RETURNED then destroy the exchange information.
+          //
+          CopyConfiglanguageList (&ThisList->InformationExchange->ReturnedInformation.ConfigureLanguageList, &ConfigLangList);
+          DestroryExchangeInformation(ThisList);
+          //
+          // Modify the collection instance according to the returned InformationTypeCollectionMemberConfigLanguage.
+          //
+          for (Index = 0; Index < ConfigLangList.Count; Index ++) {
+            StrCatS (NextParentUri, MaxParentUriLength, ThisList->NodeName);
+            StrCatS (NextParentUri, MaxParentUriLength, NodeIsCollectionSymbol);
+            SetResourceConfigLangMemberInstance (&NextParentUri, MaxParentUriLength, (REDFISH_FEATURE_ARRAY_TYPE_CONFIG_LANG *)&ConfigLangList.List[Index]);
+            StartUpFeatureDriver(ThisList->ChildList, NextParentUri, StartupContext);
+          }
+          DestroyConfiglanguageList (&ConfigLangList);
+        } else {
+          DEBUG((DEBUG_ERROR, "%a: No InformationTypeCollectionMemberConfigLanguage of %s returned.\n", __FUNCTION__, ThisList->InformationExchange->SendInformation.FullUri));
+          DEBUG((DEBUG_ERROR, "%a: Redfish service maybe not connected or the network has problems.\n", __FUNCTION__));
+          return;
+        }
+      } else {
+        StrCatS (NextParentUri, MaxParentUriLength, ThisList->NodeName);
+        StartUpFeatureDriver(ThisList->ChildList, NextParentUri, StartupContext);
+      }
+      //
+      // Restore the parent configure language URI for this level.
+      //
+      if (CurrentConfigLanguageUri != NULL) {
+        StrCpyS(NextParentUri, MaxParentUriLength, CurrentConfigLanguageUri);
+      } else{
+        NextParentUri [0] = 0;
+      }
+    } else {
+      DestroryExchangeInformation (ThisList);
     }
     //
     // Check sibling Redfish feature driver.
@@ -57,6 +207,10 @@ StartUpFeatureDriver (
     //
     ThisList = ThisList->SiblingList;
   };
+  if (NextParentUri != NULL) {
+    FreePool (NextParentUri);
+  }
+
 }
 
 /**
@@ -85,10 +239,30 @@ RedfishFeatureDriverStartup(
   if (ResourceUriNodeList == NULL) {
     return;
   }
+
+  //
+  // Initial dispatcher variables.
+  //
+  mInformationExchange = (RESOURCE_INFORMATION_EXCHANGE *)AllocateZeroPool (sizeof (RESOURCE_INFORMATION_EXCHANGE));
+  if (mInformationExchange == NULL) {
+    DEBUG((DEBUG_ERROR, "%a: Fail to allocate memory for exchange information.\n", __FUNCTION__));
+    return;
+  }
+
+  //
+  // Signal event before doing provisioning
+  //
+  SignalReadyToProvisioningEvent ();
+
   //
   // Invoke the callback by the hierarchy level
   //
-  StartUpFeatureDriver (ResourceUriNodeList, StartupContext);
+  StartUpFeatureDriver (ResourceUriNodeList, NULL, StartupContext);
+
+  //
+  // Signal event after provisioning finished
+  //
+  SignalAfterProvisioningEvent ();
 }
 
 /**
@@ -97,6 +271,8 @@ RedfishFeatureDriverStartup(
   @param[in,out] PtrToNewInternalData  Pointer to receive new instance of
                                        REDFISH_FEATURE_INTERNAL_DATA.
   @param[in]     NodeName              Name of URI node.
+  @param[in]     NodeIsCollection      TRUE means the node to add is the collection node.
+                                       Otherwise it is a resource node.
 
   @retval EFI_SUCCESS              New entry is inserted successfully.
   @retval EFI_INVALID_PARAMETER    Improper given parameters.
@@ -106,7 +282,8 @@ RedfishFeatureDriverStartup(
 EFI_STATUS
 NewInternalInstance (
   IN OUT REDFISH_FEATURE_INTERNAL_DATA **PtrToNewInternalData,
-  IN EFI_STRING NodeName
+  IN EFI_STRING NodeName,
+  IN BOOLEAN NodeIsCollection
   )
 {
   REDFISH_FEATURE_INTERNAL_DATA *NewInternalData;
@@ -126,8 +303,7 @@ NewInternalInstance (
   StrnCpyS (NewInternalData->NodeName, StrSize (NodeName), (CONST CHAR16 *)NodeName, StrLen (NodeName));
   NewInternalData->SiblingList = NULL;
   NewInternalData->ChildList = NULL;
-  if (NodeName[0] == (UINT16)NodeIsCollectionLeftBracket &&
-      NodeName [StrLen (NodeName) - 1] == (UINT16)NodeIsCollectionRightBracket) {
+  if (NodeIsCollection) {
     NewInternalData->Flags |= REDFISH_FEATURE_INTERNAL_DATA_IS_COLLECTION;
   }
   *PtrToNewInternalData = NewInternalData;
@@ -138,11 +314,15 @@ NewInternalInstance (
   Insert the URI node into internal data structure
 
   @param[in]        HeadEntryToInsert  The head entry to start the searching.
+  @param[in]        PrevisouEntry      Previsou entry.
   @param[in]        NodeName           Name of URI node.
+  @param[in]        NodeIsCollection   TRUE means the node to add is the collection node.
+                                       Otherwise it is a resource node.
   @param[in, out]   NextNodeEntry      Pointer to receive the pointer of next head
                                        entry for inserting the follow up nodes.
                                        The returned LIST_ENTRY is the address of
                                        ChildList link list.
+  @param[out]       MatchNodeEntry     The matched node entry.
   @retval EFI_SUCCESS              New entry is inserted successfully.
   @retval EFI_INVALID_PARAMETER    Improper given parameters.
   @retval EFI_OUT_OF_RESOURCES     Lack of memory for the internal data structure.
@@ -151,8 +331,11 @@ NewInternalInstance (
 EFI_STATUS
 InsertRedfishFeatureUriNode (
   IN REDFISH_FEATURE_INTERNAL_DATA      *HeadEntryToInsert,
+  IN REDFISH_FEATURE_INTERNAL_DATA      **PrevisouEntry,
   IN EFI_STRING                         NodeName,
-  IN OUT REDFISH_FEATURE_INTERNAL_DATA  **NextNodeEntry
+  IN BOOLEAN                            NodeIsCollection,
+  IN OUT REDFISH_FEATURE_INTERNAL_DATA  **NextNodeEntry,
+  OUT REDFISH_FEATURE_INTERNAL_DATA     **MatchNodeEntry
   )
 {
   EFI_STATUS Status;
@@ -160,6 +343,7 @@ InsertRedfishFeatureUriNode (
   REDFISH_FEATURE_INTERNAL_DATA *ThisInternalData;
   REDFISH_FEATURE_INTERNAL_DATA *SiblingList;
 
+  *MatchNodeEntry = NULL;
   if (NodeName == NULL) {
     DEBUG((DEBUG_ERROR, "%a: Node name is NULL.\n", __FUNCTION__));
     return EFI_INVALID_PARAMETER;
@@ -169,17 +353,18 @@ InsertRedfishFeatureUriNode (
     return EFI_INVALID_PARAMETER;
   }
 
-  if (HeadEntryToInsert == NULL || HeadEntryToInsert->ChildList == NULL) {
-    Status = NewInternalInstance (&NewInternalData, NodeName);
+  if (HeadEntryToInsert == NULL) {
+    Status = NewInternalInstance (&NewInternalData, NodeName, NodeIsCollection);
     if (EFI_ERROR (Status)) {
       return Status;
     }
-    if (HeadEntryToInsert == NULL) {
+    if (HeadEntryToInsert == NULL && ResourceUriNodeList == NULL) {
       ResourceUriNodeList = NewInternalData;
     } else {
-      HeadEntryToInsert->ChildList = NewInternalData;
+      (*PrevisouEntry)->ChildList = NewInternalData;
     }
-    *NextNodeEntry = NewInternalData;
+    *PrevisouEntry = NewInternalData;
+    *NextNodeEntry = NewInternalData->ChildList;
     return EFI_SUCCESS;
   }
   //
@@ -189,22 +374,26 @@ InsertRedfishFeatureUriNode (
   SiblingList = ThisInternalData->SiblingList;
   while (TRUE) {
     if (StrCmp((CONST CHAR16 *)ThisInternalData->NodeName, (CONST CHAR16 *)NodeName) == 0) {
+      *MatchNodeEntry = ThisInternalData;
       *NextNodeEntry = ThisInternalData->ChildList;
+      *PrevisouEntry = ThisInternalData;
       return EFI_SUCCESS;
     }
     //
     // If sibing exist?
     //
     if (SiblingList == NULL) {
-      Status = NewInternalInstance (&NewInternalData, NodeName);
+      Status = NewInternalInstance (&NewInternalData, NodeName, NodeIsCollection);
       if (EFI_ERROR (Status)) {
         return Status;
       }
       ThisInternalData->SiblingList = NewInternalData;
+      *PrevisouEntry = NewInternalData;
       *NextNodeEntry = NewInternalData->ChildList;
       return EFI_SUCCESS;
     }
-    SiblingList = SiblingList->SiblingList;
+    ThisInternalData = SiblingList;
+    SiblingList = ThisInternalData->SiblingList;
   };
   return EFI_SUCCESS;
 }
@@ -250,7 +439,12 @@ RedfishFeatureRegister (
   UINTN Index;
   UINTN AnchorIndex;
   UINTN UriLength;
+  BOOLEAN NewUri;
   REDFISH_FEATURE_INTERNAL_DATA *ThisUriNode;
+  REDFISH_FEATURE_INTERNAL_DATA *PreUriNode;
+  REDFISH_FEATURE_INTERNAL_DATA *NewUriNode;
+  REDFISH_FEATURE_INTERNAL_DATA *MatchNodeEntry;
+  BOOLEAN ItsCollection;
 
   if (FeatureManagedUri == NULL || Callback == NULL) {
     DEBUG((DEBUG_ERROR, "%a: The given parameter is invalid\n", __FUNCTION__));
@@ -263,27 +457,62 @@ RedfishFeatureRegister (
   Index = 0;
   AnchorIndex = 0;
   ThisUriNode = ResourceUriNodeList;
-  do {
+  PreUriNode = ResourceUriNodeList;
+  NewUri = FALSE;
+  while ((Index < UriLength)) {
     if ((Index - AnchorIndex + 1) >= MaxNodeNameLength) { // Increase one for the NULL terminator
       DEBUG((DEBUG_ERROR, "%a: the length of node name is >= MaxNodeNameLength\n", __FUNCTION__));
       ASSERT (FALSE);
     }
     NodeName[Index - AnchorIndex] = *(FeatureManagedUri + Index);
-    if (NodeName [Index - AnchorIndex] == NodeSeperator || NodeName [Index - AnchorIndex] == (CHAR16)0) {
+    if (NodeName [Index - AnchorIndex] == NodeSeperator || NodeName [Index - AnchorIndex] == UriSeperator || NodeName [Index - AnchorIndex] == (CHAR16)0) {
+      if (NodeName [Index - AnchorIndex] == UriSeperator) {
+        NewUri = TRUE;
+      }
       NodeName [Index - AnchorIndex] = 0;
       AnchorIndex = Index + 1;
       //
       // Insert node
       //
       if (StrLen(NodeName) != 0) {
-        Status = InsertRedfishFeatureUriNode(ThisUriNode, NodeName, &ThisUriNode);
+        ItsCollection = FALSE;
+        if ((Index + StrLen(NodeIsCollectionSymbol)) < UriLength &&
+            *(FeatureManagedUri + Index + 1) == NodeIsCollectionLeftBracket &&
+            *(FeatureManagedUri + Index + 2) == NodeIsCollectionRightBracket) {
+          Index += (StrLen(NodeIsCollectionSymbol));
+          AnchorIndex += (StrLen(NodeIsCollectionSymbol));
+          ItsCollection = TRUE;
+          if (*(FeatureManagedUri + Index) == UriSeperator) {
+            NewUri = TRUE;;
+          }
+        }
+        Status = InsertRedfishFeatureUriNode(ThisUriNode, &PreUriNode, NodeName, ItsCollection, &NewUriNode, &MatchNodeEntry);
         if (EFI_ERROR (Status)) {
           return Status;
         }
+        ThisUriNode = NewUriNode;
+      }
+      if (NewUri || ((Index + 1) >= UriLength)) {
+        //
+        // Setup the callabck and restart the searching for the
+        // next URI.
+        //
+        if (MatchNodeEntry != NULL) {
+          MatchNodeEntry->Callback = Callback;
+          MatchNodeEntry->Context = Context;
+          MatchNodeEntry = NULL;
+        } else {
+          PreUriNode->Callback = Callback;
+          PreUriNode->Context = Context;
+        }
+        NewUri = FALSE;
+        ThisUriNode = ResourceUriNodeList;
+        Index ++;
+        continue;
       }
     }
     Index ++;
-  } while ((Index < UriLength));
+  };
 
   if (ThisUriNode == NULL) {
     //
@@ -292,11 +521,6 @@ RedfishFeatureRegister (
     DEBUG((DEBUG_ERROR, "%a: No URI node is added\n", __FUNCTION__));
     return EFI_INVALID_PARAMETER;
   }
-  //
-  // Add feature driver info to internal data instance.
-  //
-  ThisUriNode->Callback = Callback;
-  ThisUriNode->Context = Context;
   return EFI_SUCCESS;
 }
 
diff --git a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
index 7b1778b038..84b5e456d1 100644
--- a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
+++ b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
@@ -1,7 +1,7 @@
 /** @file
   Definitions of RedfishFeatureCoreDxe
 
-  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -16,22 +16,26 @@
 #include <Library/BaseMemoryLib.h>
 #include <Library/DebugLib.h>
 #include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
 #include <Library/UefiBootServicesTableLib.h>
+#include <Library/RedfishEventLib.h>
+#include <Library/RedfishFeatureUtilityLib.h>
 
 #define MaxNodeNameLength 64
+#define MaxParentUriLength 512
 #define NodeSeperator L'/'
-#define NodeIsCollectionLeftBracket '{'
-#define NodeIsCollectionRightBracket '}'
+#define UriSeperator L';'
+#define NodeIsCollectionLeftBracket L'{'
+#define NodeIsCollectionRightBracket L'}'
+#define NodeIsCollectionSymbol       L"/{}"
 
 typedef struct _REDFISH_FEATURE_INTERNAL_DATA REDFISH_FEATURE_INTERNAL_DATA;
 struct _REDFISH_FEATURE_INTERNAL_DATA {
   REDFISH_FEATURE_INTERNAL_DATA *SiblingList; ///< Next same level in hierarchy of resource URI.
   REDFISH_FEATURE_INTERNAL_DATA *ChildList;   ///< Next level in hierarchy of resource URI.
-  EFI_STRING               NodeName;    ///< Name of the node in hierarchy of resource URI.
-  REDFISH_FEATURE_CALLBACK Callback;    ///< Callback function of Redfish feature driver.
-  VOID                     *Context;    ///< Context of feature driver.
-  FEATURE_RETURNED_INFORMATION *ReturnedInformation; ///< Information returned from Redfish feature driver.
+  EFI_STRING               NodeName;          ///< Name of the node in hierarchy of resource URI.
+  REDFISH_FEATURE_CALLBACK Callback;          ///< Callback function of Redfish feature driver.
+  VOID                     *Context;          ///< Context of feature driver.
+  RESOURCE_INFORMATION_EXCHANGE *InformationExchange; ///< Information returned from Redfish feature driver.
   UINT32         Flags;
 };
 #define REDFISH_FEATURE_INTERNAL_DATA_IS_COLLECTION 0x00000001
diff --git a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
index 5a2cd7fecc..ddcf991006 100644
--- a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
+++ b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
@@ -3,7 +3,7 @@
 #  EdkIIRedfishFeatureCoreProtocol to EDK2 Redfish Feature
 #  drivers for the registration.
 #
-#  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+#  (C) Copyright 2021-2022 Hewlett Packard Enterprise Development LP<BR>
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 ##
@@ -27,6 +27,7 @@
 [Packages]
   MdePkg/MdePkg.dec
   MdeModulePkg/MdeModulePkg.dec
+  RedfishPkg/RedfishPkg.dec
   RedfishClientPkg/RedfishClientPkg.dec
 
 [LibraryClasses]
@@ -35,6 +36,8 @@
   DebugLib
   MemoryAllocationLib
   PrintLib
+  RedfishEventLib
+  RedfishFeatureUtilityLib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
   UefiLib
-- 
2.32.0.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#91787): https://edk2.groups.io/g/devel/message/91787
Mute This Topic: https://groups.io/mt/92596791/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list