EDK2 port of DMTF libredfish project. We clone the necessary files from open source project libredfish (https://github.com/DMTF/ libredfish) tag v1.0.0 and revise it to incorporate with edk2 firmware code base. The reason of cloning the necessary files instead of using extern submodule of libredfish project: libredfish as a C library which is executed under Windows and Linux. It could be binded with other programming languages such as java and python. The library uses curl library as the communication service with Redfish, which is not easy to be abstracted and replaced with EFI specific protocols (e.g. EFI_REST_EX_PROTOCOL or payload encode/decode library) and EFI data types. We had the conversation with DMTF community and they think edk2 is a firmware solution but not the programming language, therefore they rejected to have edk2 as a binding to libredfish. According to above, we decide to clone the necessary files from libredfish modify it to incorporate with edk2. Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com> Signed-off-by: Ting Ye <ting.ye@intel.com> Signed-off-by: Siyuan Fu <siyuan.fu@intel.com> Signed-off-by: Fan Wang <fan.wang@intel.com> Signed-off-by: Abner Chang <abner.chang@hpe.com> Cc: Nickle Wang <nickle.wang@hpe.com> Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
193 lines
4.6 KiB
C
193 lines
4.6 KiB
C
/** @file
|
|
This file is cloned from DMTF libredfish library tag v1.0.0 and maintained
|
|
by EDKII.
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Copyright Notice:
|
|
// Copyright 2017 Distributed Management Task Force, Inc. All rights reserved.
|
|
// License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libredfish/LICENSE.md
|
|
//----------------------------------------------------------------------------
|
|
|
|
Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
|
|
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
#include <redpath.h>
|
|
|
|
static char* getVersion(const char* path, char** end);
|
|
static void parseNode(const char* path, redPathNode* node, redPathNode** end);
|
|
|
|
static char* getStringTill(const char* string, const char* terminator, char** retEnd);
|
|
|
|
redPathNode* parseRedPath(const char* path)
|
|
{
|
|
redPathNode* node;
|
|
redPathNode* endNode;
|
|
char* curPath;
|
|
char* end;
|
|
|
|
if(!path || strlen(path) == 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
node = (redPathNode*)calloc(1, sizeof(redPathNode));
|
|
if(!node)
|
|
{
|
|
return NULL;
|
|
}
|
|
if(path[0] == '/')
|
|
{
|
|
node->isRoot = true;
|
|
if(path[1] == 'v')
|
|
{
|
|
node->version = getVersion(path+1, &curPath);
|
|
if(curPath == NULL)
|
|
{
|
|
return node;
|
|
}
|
|
if(curPath[0] == '/')
|
|
{
|
|
curPath++;
|
|
}
|
|
node->next = parseRedPath(curPath);
|
|
}
|
|
else
|
|
{
|
|
node->next = parseRedPath(path+1);
|
|
}
|
|
return node;
|
|
}
|
|
node->isRoot = false;
|
|
curPath = getStringTill(path, "/", &end);
|
|
endNode = node;
|
|
parseNode(curPath, node, &endNode);
|
|
free(curPath);
|
|
if(end != NULL)
|
|
{
|
|
endNode->next = parseRedPath(end+1);
|
|
}
|
|
return node;
|
|
}
|
|
|
|
void cleanupRedPath(redPathNode* node)
|
|
{
|
|
if(!node)
|
|
{
|
|
return;
|
|
}
|
|
cleanupRedPath(node->next);
|
|
node->next = NULL;
|
|
if(node->version)
|
|
{
|
|
free(node->version);
|
|
}
|
|
if(node->nodeName)
|
|
{
|
|
free(node->nodeName);
|
|
}
|
|
if(node->op)
|
|
{
|
|
free(node->op);
|
|
}
|
|
if(node->propName)
|
|
{
|
|
free(node->propName);
|
|
}
|
|
if(node->value)
|
|
{
|
|
free(node->value);
|
|
}
|
|
free(node);
|
|
}
|
|
|
|
static char* getVersion(const char* path, char** end)
|
|
{
|
|
return getStringTill(path, "/", end);
|
|
}
|
|
|
|
static void parseNode(const char* path, redPathNode* node, redPathNode** end)
|
|
{
|
|
char* indexStart;
|
|
char* index;
|
|
char* indexEnd;
|
|
char* nodeName = getStringTill(path, "[", &indexStart);
|
|
size_t tmpIndex;
|
|
char* opChars;
|
|
|
|
node->nodeName = nodeName;
|
|
if(indexStart == NULL)
|
|
{
|
|
*end = node;
|
|
return;
|
|
}
|
|
node->next = (redPathNode*)calloc(1, sizeof(redPathNode));
|
|
if(!node->next)
|
|
{
|
|
return;
|
|
}
|
|
//Skip past [
|
|
indexStart++;
|
|
*end = node->next;
|
|
index = getStringTill(indexStart, "]", NULL);
|
|
tmpIndex = (size_t)strtoull(index, &indexEnd, 0);
|
|
if(indexEnd != index)
|
|
{
|
|
free(index);
|
|
node->next->index = tmpIndex;
|
|
node->next->isIndex = true;
|
|
return;
|
|
}
|
|
opChars = strpbrk(index, "<>=~");
|
|
if(opChars == NULL)
|
|
{
|
|
//TODO handle last() and position()
|
|
node->next->op = strdup("exists");
|
|
node->next->propName = index;
|
|
return;
|
|
}
|
|
node->next->propName = (char*)malloc((opChars - index)+1);
|
|
memcpy(node->next->propName, index, (opChars - index));
|
|
node->next->propName[(opChars - index)] = 0;
|
|
|
|
tmpIndex = 1;
|
|
while(1)
|
|
{
|
|
if(opChars[tmpIndex] == '=' || opChars[tmpIndex] == '<' || opChars[tmpIndex] == '>' || opChars[tmpIndex] == '~')
|
|
{
|
|
tmpIndex++;
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
|
|
node->next->op = (char*)malloc(tmpIndex+1);
|
|
memcpy(node->next->op, opChars, tmpIndex);
|
|
node->next->op[tmpIndex] = 0;
|
|
|
|
node->next->value = strdup(opChars+tmpIndex);
|
|
free(index);
|
|
}
|
|
|
|
static char* getStringTill(const char* string, const char* terminator, char** retEnd)
|
|
{
|
|
char* ret;
|
|
char* end;
|
|
end = strstr((char*)string, terminator);
|
|
if(retEnd)
|
|
{
|
|
*retEnd = end;
|
|
}
|
|
if(end == NULL)
|
|
{
|
|
//No terminator
|
|
return strdup(string);
|
|
}
|
|
ret = (char*)malloc((end-string)+1);
|
|
memcpy(ret, string, (end-string));
|
|
ret[(end-string)] = 0;
|
|
return ret;
|
|
}
|