From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-002e3701.pphosted.com (mx0b-002e3701.pphosted.com [148.163.143.35]) by mx.groups.io with SMTP id smtpd.web11.7756.1607569695961969563 for ; Wed, 09 Dec 2020 19:08:16 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@hpe.com header.s=pps0720 header.b=CthueR/d; spf=pass (domain: hpe.com, ip: 148.163.143.35, mailfrom: prvs=061307e4aa=nickle.wang@hpe.com) Received: from pps.filterd (m0134423.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 0BA35dox030851 for ; Thu, 10 Dec 2020 03:08:15 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hpe.com; h=from : to : cc : subject : date : message-id : references : in-reply-to : content-type : content-transfer-encoding : mime-version; s=pps0720; bh=EvOqRyyy/b0/3aaL6whwdietfO5Ex1MNMwwiz+tb5oA=; b=CthueR/dC0e0JtxB479FFRjlU88Sx/RTnMFBir9Se2SAaSa5XICCFQGnXI81h3ihJehT 9rMbkIMacg6nK375ymTaPRPs/E+UKEnhhAsvO8LBnez6HMZ2wLLPtmCVLCUBn6jC4XxQ gz0THU5V129YBAMtKLh/ieo8xbMbXyGhIN7kN/nZuT0cF+cscbQuusWL3nECeA7lvr8Q EEssUT2i5McSxGf5XKV1POV43Tdz+2CP22xuSZHCgVXzxde6dwytq6r3UugLjOrS01/G sxbT9gjeB69nzAtoT5vB80hRi2lwDWGlDQsY3IrFLMq/iCDWpSAIj93S7/QXp3ab7H1Q Yg== Received: from g9t5008.houston.hpe.com (g9t5008.houston.hpe.com [15.241.48.72]) by mx0b-002e3701.pphosted.com with ESMTP id 35aeyj4tkv-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 10 Dec 2020 03:08:14 +0000 Received: from G2W6310.americas.hpqcorp.net (g2w6310.austin.hp.com [16.197.64.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by g9t5008.houston.hpe.com (Postfix) with ESMTPS id 8F4D156 for ; Thu, 10 Dec 2020 03:08:13 +0000 (UTC) Received: from G9W8453.americas.hpqcorp.net (2002:10d8:a0d3::10d8:a0d3) by G2W6310.americas.hpqcorp.net (2002:10c5:4034::10c5:4034) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 10 Dec 2020 03:08:12 +0000 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (15.241.52.11) by G9W8453.americas.hpqcorp.net (16.216.160.211) with Microsoft SMTP Server (TLS) id 15.0.1497.2 via Frontend Transport; Thu, 10 Dec 2020 03:08:12 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=EojPCE+lDg0VV9fTA9QPULwrD20uQ5FPqeB454NJFZHo/2J4GRWM9PD3Je4TijxYXN7fs9soHcgE3snTzQlAaGcbUW0mXt/lKti73OBrhbAh44mD7ixMrM1vEwahYVCFcOCypHAdF+bQ7eeK0s6iFcSrpQT+j6zKxsMzCr4Y7nWcEd1/3MtCU3zuHOoLVydm1Ep22Ub9/P0FKT2Jj1y8KN/qJvf/N2i9Wfh6Lqc1TYtl2o4KtIx8Vejww2L6xxz2FVNOcut1i2WYsU2vXuqSsvMGNhm8u8lcKxegCeBlAsg5MHb9rVn7hg1GD5XmrKjXjIX6+HDYauj16QptX/368A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jQaf/2CZm5mgRn1mwu+ar+m1h5URrsc8EQiRCpeC1hQ=; b=J3UQu1cSL+BJjtrbPKx8yLVY3D+8ZE3ufO4OSYjPXcPoGAL0vJStu2J1bmZYJTeXQCUGFOed64MU494ycYW+a7fcdX506QATbhoBXXgDRSX5mhotWsXlDId+HY8iyxKnRH+SuAXAPWgsr36eZK3BFNFnaFSF21UPUKkA2HRMbmg5HqrwRZcBiZAlPru6oC0c+57QfCliyWdJB6SH7wccroL1a/gTJRwWPFNyIU9LROCS/9Eobcow7yv5WfiZJJRueKLigvMBMjrasVOTGRmi0LVdWfZmcX7E0+H8hxu2rht4ttjGuSx2AlF1yxkMRIbulEMdxu4ihleUQsOQ2JShXg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=hpe.com; dmarc=pass action=none header.from=hpe.com; dkim=pass header.d=hpe.com; arc=none Received: from DF4PR8401MB0812.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:760d::7) by DF4PR8401MB1241.NAMPRD84.PROD.OUTLOOK.COM (2a01:111:e400:7613::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3654.12; Thu, 10 Dec 2020 03:08:08 +0000 Received: from DF4PR8401MB0812.NAMPRD84.PROD.OUTLOOK.COM ([fe80::e475:6a2b:ed1c:a060]) by DF4PR8401MB0812.NAMPRD84.PROD.OUTLOOK.COM ([fe80::e475:6a2b:ed1c:a060%11]) with mapi id 15.20.3654.014; Thu, 10 Dec 2020 03:08:08 +0000 From: "Nickle Wang" To: "Chang, Abner (HPS SW/FW Technologist)" , "devel@edk2.groups.io" CC: Jiaxin Wu , Siyuan Fu , Fan Wang , Jiewen Yao , "O'Hanley, Peter (EXL)" Subject: Re: [PATCH] RedfishPkg/RedfishRestExDxe: Implementation of EFI REST EX Protocol Thread-Topic: [PATCH] RedfishPkg/RedfishRestExDxe: Implementation of EFI REST EX Protocol Thread-Index: AQHWzGxIFU3TKb21jkiEpEi8oO+TG6nvqnuQ Date: Thu, 10 Dec 2020 03:08:08 +0000 Message-ID: References: <20201207065404.31257-1-abner.chang@hpe.com> In-Reply-To: <20201207065404.31257-1-abner.chang@hpe.com> Accept-Language: zh-TW, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: hpe.com; dkim=none (message not signed) header.d=none;hpe.com; dmarc=none action=none header.from=hpe.com; x-originating-ip: [2001:b011:5c04:5ee2:852e:ddde:5093:2eac] x-ms-publictraffictype: Email x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: a792f097-9679-4694-ff28-08d89cb8d22e x-ms-traffictypediagnostic: DF4PR8401MB1241: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:1923; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: xPTE2qnlRboVvAdhqOYpC4N/cPkAB7asvgKaa5w8EtsfHsR0eLIhKcC8/WP9Jr2M8FmNI3tG0JNuetldrq1hT6Pl0KImORdpHs0XN8Hp6iEVO+DAMqI/t5vT1TJS12RKw1Le0SEGRtviAzwmv+MVGazHSB8vpVlYkzwYTy1H1DsDIgLD6JpoaeQF37xHLZpAgnQSDnKWOc9/+/rheJtYQTBqwukWljXk7a+unjU8vZFNh4DcVokHRjQN9UKoaw+83fMo74b8qBnIBPkqclsxpIaoYgdtarRrLucNbvvhqNQbvz7rdQax6FVu4eM+dn4FzbRta5mPEcZkmtTjvsl38wQtv27XJ1sYb/Twh0jCHNpSqV+hFjRB1oqBuRviGt0cv5+TntYp9Pt8Io5W+JAube1D+glxCQmnDDOH0wGtFuJKwgWn+vuOI+3W3kNunqVH x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DF4PR8401MB0812.NAMPRD84.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(6029001)(376002)(136003)(366004)(346002)(64756008)(66556008)(9686003)(83380400001)(8676002)(66446008)(71200400001)(66946007)(53546011)(52536014)(966005)(5660300002)(33656002)(7696005)(6506007)(4326008)(66476007)(110136005)(55016002)(186003)(8936002)(86362001)(54906003)(30864003)(508600001)(19627235002)(76116006)(2906002)(579004)(569008);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?sPtVNQY+HMZVfKJXEXuv0Q1rZWjz7UkeGmHBbp54pKF7GhNKXHjtkSJVg9wq?= =?us-ascii?Q?oceEQ5jMSFo1/fbe1aSCb+bYTb2spg15JrPwKtnX+5856s/xsXN4c6dOxN31?= =?us-ascii?Q?8YQ5mxwGCsu2Fv0VA/u8A7qbGq5niPkmE/lj2DWAJTP/if1Fd7tvI89mPDyM?= =?us-ascii?Q?nPlss0XlfWg6C16lZLDsuMdF7u4jeTbX8H45xLt3k4vqPIY8yQy8iio7SSBl?= =?us-ascii?Q?HHZZf4ZaED+ABg3LxnLMZwOHdw//4iB/9lY97BWAU+Y2oWttcqFmZnEQfArC?= =?us-ascii?Q?DvJ7UdA5DbRWBZe2xGn5gvCqWen/qP5UdIOaauvBWeZ+ZNeWnMN9UTDKMe96?= =?us-ascii?Q?k+6HdAH21zgR/tfadqwiDlWPnepRQ+zzESbDu2yw2j6TLbtfKOkEDaarQcT3?= =?us-ascii?Q?pqW49ZJv01B3Iy2kO9lLtxrvbpz1kC3oVVAfiJj+jg3VBLP0Lh+4bfRPbO16?= =?us-ascii?Q?gxKcwI5lK5GKGYwjdeZH6J4U6Vy2tJNNnGoAUnPpls7h9l6MOuHAJO8kQJXz?= =?us-ascii?Q?3gRYtbKIKa01jnme3us2uFQWiUaxJUDWDn/HGE4x8Z+hY7NzjAMws1CN70tf?= =?us-ascii?Q?EBlgTXKQFpPY/MakrpBaq0G/XOSAhykf19xJJ4cpgMBIrduOP4qJTU9suWmJ?= =?us-ascii?Q?2jimsWaoRWhmA7+6pEY7+FTUTUuN6U/tDrBcsgypH0YWWkzfehpqs//z/CEW?= =?us-ascii?Q?PSlnfdlwqcFzxodcIv0i+GrQijxMNXEb4EJEXBoYsFOQvFGTkP5c4vYO3z6o?= =?us-ascii?Q?fMPNXuVrfQ7YeHdtJ478wfQxdpSL9HXJdFJQI/Poy4giLtxZs1mD8iBRxwyg?= =?us-ascii?Q?zWLaQKCjYHLLihFUZpVH0u58PX84Y7t1MVpzL+IgW7WB7em6c09wYvV36OtA?= =?us-ascii?Q?bFnDvKmBYyGXxAuCpCY2N2nV9uugjXuprcwIl68C2P+O90zNT16SXqthyofG?= =?us-ascii?Q?WOArEMSWCXqTKmC+QJxEml4xFabmmQ49yw8F4FcIgiF75zMu+ATd7fhHofnZ?= =?us-ascii?Q?qqJcJFH5817ahw7CjTl46eKOuHBlBK04/GSR/vq2rHKDyIM=3D?= X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: DF4PR8401MB0812.NAMPRD84.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-Network-Message-Id: a792f097-9679-4694-ff28-08d89cb8d22e X-MS-Exchange-CrossTenant-originalarrivaltime: 10 Dec 2020 03:08:08.5616 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 105b2061-b669-4b31-92ac-24d304d195dc X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: PuyJp72KpTTylAcK3zI2YzjwwjB9VEVCiZzqjo2ImvzVFeLjyT0I1jeRUte78RQVs9m7GQ8Eo4M3wYJ22YRCiA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DF4PR8401MB1241 X-OriginatorOrg: hpe.com X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.343,18.0.737 definitions=2020-12-10_01:2020-12-09,2020-12-10 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 mlxlogscore=999 lowpriorityscore=0 mlxscore=0 suspectscore=0 impostorscore=0 bulkscore=0 adultscore=0 malwarescore=0 spamscore=0 priorityscore=1501 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2012100020 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Nickle Wang > -----Original Message----- > From: Chang, Abner (HPS SW/FW Technologist) > Sent: Monday, December 7, 2020 2:54 PM > To: devel@edk2.groups.io > Cc: Jiaxin Wu ; Siyuan Fu ; Fan > Wang ; Jiewen Yao ; Wang, > Nickle (HPS SW) ; O'Hanley, Peter (EXL) > > Subject: [PATCH] RedfishPkg/RedfishRestExDxe: Implementation of EFI REST > EX Protocol >=20 > BZ#: 2908 > https://bugzilla.tianocore.org/show_bug.cgi?id=3D2908 >=20 > Implementation of EFI EX Protocol according to UEFI spec > 2.8 Section 29.7.2 EFI REST EX Protocol. > This is the network stack based EFI REST EX protocol instance. >=20 > Signed-off-by: Jiaxin Wu > Signed-off-by: Siyuan Fu > Signed-off-by: Fan Wang > Signed-off-by: Ting Ye > Signed-off-by: Abner Chang >=20 > Cc: Jiaxin Wu > Cc: Siyuan Fu > Cc: Fan Wang > Cc: Jiewen Yao > Cc: Nickle Wang > Cc: Peter O'Hanley > --- > RedfishPkg/Redfish.fdf.inc | 1 + > RedfishPkg/RedfishComponents.dsc.inc | 1 + > RedfishPkg/RedfishPkg.dsc | 4 + > RedfishPkg/RedfishRestExDxe/ComponentName.c | 222 +++++ > .../RedfishRestExDxe/RedfishRestExDriver.c | 831 ++++++++++++++++++ > .../RedfishRestExDxe/RedfishRestExDriver.h | 650 ++++++++++++++ > .../RedfishRestExDxe/RedfishRestExDxe.inf | 63 ++ > .../RedfishRestExDxe/RedfishRestExDxe.uni | 16 + > .../RedfishRestExDxeExtra.uni | 15 + > .../RedfishRestExDxe/RedfishRestExImpl.c | 157 ++++ > .../RedfishRestExDxe/RedfishRestExInternal.h | 611 +++++++++++++ > .../RedfishRestExDxe/RedfishRestExProtocol.c | 735 ++++++++++++++++ > 12 files changed, 3306 insertions(+) > create mode 100644 RedfishPkg/RedfishRestExDxe/ComponentName.c > create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c > create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.h > create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf > create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.uni > create mode 100644 > RedfishPkg/RedfishRestExDxe/RedfishRestExDxeExtra.uni > create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c > create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExInternal.h > create mode 100644 RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c >=20 > diff --git a/RedfishPkg/Redfish.fdf.inc b/RedfishPkg/Redfish.fdf.inc > index 19de479a80..429156aa78 100644 > --- a/RedfishPkg/Redfish.fdf.inc > +++ b/RedfishPkg/Redfish.fdf.inc > @@ -13,4 +13,5 @@ > !if $(REDFISH_ENABLE) =3D=3D TRUE > INF RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf > INF RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf > + INF RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf > !endif > diff --git a/RedfishPkg/RedfishComponents.dsc.inc > b/RedfishPkg/RedfishComponents.dsc.inc > index ac1b57ed8f..3b9429db09 100644 > --- a/RedfishPkg/RedfishComponents.dsc.inc > +++ b/RedfishPkg/RedfishComponents.dsc.inc > @@ -15,4 +15,5 @@ > !if $(REDFISH_ENABLE) =3D=3D TRUE > RedfishPkg/RestJsonStructureDxe/RestJsonStructureDxe.inf > RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf > + RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf > !endif > diff --git a/RedfishPkg/RedfishPkg.dsc b/RedfishPkg/RedfishPkg.dsc > index 94e7127bc6..c05e81af7b 100644 > --- a/RedfishPkg/RedfishPkg.dsc > +++ b/RedfishPkg/RedfishPkg.dsc > @@ -32,6 +32,10 @@ >=20 > DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/Bas > eDebugPrintErrorLevelLib.inf > PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf >=20 > RedfishPlatformHostInterfaceLib|RedfishPkg/Library/PlatformHostInterface > LibNull/PlatformHostInterfaceLibNull.inf > + HttpLib|NetworkPkg/Library/DxeHttpLib/DxeHttpLib.inf > + HttpIoLib|NetworkPkg/Library/DxeHttpIoLib/DxeHttpIoLib.inf > + NetLib|NetworkPkg/Library/DxeNetLib/DxeNetLib.inf > + DpcLib|NetworkPkg/Library/DxeDpcLib/DxeDpcLib.inf >=20 > [LibraryClasses.ARM, LibraryClasses.AARCH64] > # > diff --git a/RedfishPkg/RedfishRestExDxe/ComponentName.c > b/RedfishPkg/RedfishRestExDxe/ComponentName.c > new file mode 100644 > index 0000000000..3674178412 > --- /dev/null > +++ b/RedfishPkg/RedfishRestExDxe/ComponentName.c > @@ -0,0 +1,222 @@ > +/** @file > + Implementation of EFI_COMPONENT_NAME_PROTOCOL and > EFI_COMPONENT_NAME2_PROTOCOL > + protocol. > + > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > +#include > + > +#include > + > +#include > +#include > + > +// > +// EFI Component Name Functions > +// > +/** > + Retrieves a Unicode string that is the user-readable name of the EFI D= river. > + > + @param[in] This A pointer to the > EFI_COMPONENT_NAME_PROTOCOL instance. > + @param[in] Language A pointer to a three-character ISO 639-2 langu= age > identifier. > + This is the language of the driver name that t= hat the caller > + is requesting, and it must match one of the la= nguages specified > + in SupportedLanguages. The number of language= s supported > by a > + driver is up to the driver writer. > + @param[out] DriverName A pointer to the Unicode string to return. Th= is > Unicode string > + is the name of the driver specified by This in= the language > + specified by Language. > + > + @retval EFI_SUCCESS The Unicode string for the Driver specified b= y This > + and the language specified by Language was re= turned > + in DriverName. > + @retval EFI_INVALID_PARAMETER Language is NULL. > + @retval EFI_INVALID_PARAMETER DriverName is NULL. > + @retval EFI_UNSUPPORTED The driver specified by This does not > support the > + language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExComponentNameGetDriverName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN CHAR8 *Language, > + OUT CHAR16 **DriverName > + ); > + > +/** > + Retrieves a Unicode string that is the user readable name of the contr= oller > + that is being managed by an EFI Driver. > + > + @param[in] This A pointer to the > EFI_COMPONENT_NAME_PROTOCOL instance. > + @param[in] ControllerHandle The handle of a controller that the driv= er > specified by > + This is managing. This handle specifies= the controller > + whose name is to be returned. > + @param[in] ChildHandle The handle of the child controller to re= trieve > the name > + of. This is an optional parameter that m= ay be NULL. It > + will be NULL for device drivers. It wil= l also be NULL > + for a bus drivers that wish to retrieve = the name of the > + bus controller. It will not be NULL for= a bus driver > + that wishes to retrieve the name of a ch= ild controller. > + @param[in] Language A pointer to a three character ISO 639-2 > language > + identifier. This is the language of the = controller name > + that the caller is requesting, and it mu= st match one > + of the languages specified in SupportedL= anguages. The > + number of languages supported by a drive= r is up to the > + driver writer. > + @param[out] ControllerName A pointer to the Unicode string to retur= n. > This Unicode > + string is the name of the controller spe= cified by > + ControllerHandle and ChildHandle in the = language specified > + by Language, from the point of view of t= he driver specified > + by This. > + > + @retval EFI_SUCCESS The Unicode string for the user-readable= name > in the > + language specified by Language for the d= river > + specified by This was returned in Driver= Name. > + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. > + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a > valid EFI_HANDLE. > + @retval EFI_INVALID_PARAMETER Language is NULL. > + @retval EFI_INVALID_PARAMETER ControllerName is NULL. > + @retval EFI_UNSUPPORTED The driver specified by This is not curr= ently > managing > + the controller specified by ControllerHa= ndle and > + ChildHandle. > + @retval EFI_UNSUPPORTED The driver specified by This does not > support the > + language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExComponentNameGetControllerName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN EFI_HANDLE ChildHandle OPTIONAL, > + IN CHAR8 *Language, > + OUT CHAR16 **ControllerName > + ); > + > +/// > +/// Component Name Protocol instance > +/// > +GLOBAL_REMOVE_IF_UNREFERENCED > +EFI_COMPONENT_NAME_PROTOCOL gRedfishRestExComponentName =3D { > + RedfishRestExComponentNameGetDriverName, > + RedfishRestExComponentNameGetControllerName, > + "eng" > +}; > + > +/// > +/// Component Name 2 Protocol instance > +/// > +GLOBAL_REMOVE_IF_UNREFERENCED > +EFI_COMPONENT_NAME2_PROTOCOL gRedfishRestExComponentName2 > =3D { > + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) > RedfishRestExComponentNameGetDriverName, > + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) > RedfishRestExComponentNameGetControllerName, > + "en" > +}; > + > +/// > +/// Table of driver names > +/// > +GLOBAL_REMOVE_IF_UNREFERENCED > +EFI_UNICODE_STRING_TABLE mRedfishRestExDriverNameTable[] =3D { > + { "eng;en", (CHAR16 *)L"Redfish RestEx Network Service Driver" }, > + { NULL, NULL } > +}; > + > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE > *gRedfishRestExControllerNameTable =3D NULL; > + > +/** > + Retrieves a Unicode string that is the user-readable name of the EFI D= river. > + > + @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL > instance. > + @param[in] Language A pointer to a three-character ISO 639-2 langua= ge > identifier. > + This is the language of the driver name that th= at the caller > + is requesting, and it must match one of the lan= guages specified > + in SupportedLanguages. The number of languages= supported > by a > + driver is up to the driver writer. > + @param[out] DriverName A pointer to the Unicode string to return. T= his > Unicode string > + is the name of the driver specified by This i= n the language > + specified by Language. > + > + @retval EFI_SUCCESS The Unicode string for the Driver specif= ied by > This > + and the language specified by Language w= as returned > + in DriverName. > + @retval EFI_INVALID_PARAMETER Language is NULL. > + @retval EFI_INVALID_PARAMETER DriverName is NULL. > + @retval EFI_UNSUPPORTED The driver specified by This does not > support the > + language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExComponentNameGetDriverName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN CHAR8 *Language, > + OUT CHAR16 **DriverName > + ) > +{ > + return LookupUnicodeString2 ( > + Language, > + This->SupportedLanguages, > + mRedfishRestExDriverNameTable, > + DriverName, > + (BOOLEAN)(This =3D=3D &gRedfishRestExComponentName) > + ); > +} > + > +/** > + Retrieves a Unicode string that is the user readable name of the contr= oller > + that is being managed by an EFI Driver. > + > + @param[in] This A pointer to the > EFI_COMPONENT_NAME_PROTOCOL instance. > + @param[in] ControllerHandle The handle of a controller that the dri= ver > specified by > + This is managing. This handle specifie= s the controller > + whose name is to be returned. > + @param[in] ChildHandle The handle of the child controller to r= etrieve > the name > + of. This is an optional parameter that= may be NULL. It > + will be NULL for device drivers. It wi= ll also be NULL > + for a bus drivers that wish to retrieve= the name of the > + bus controller. It will not be NULL fo= r a bus driver > + that wishes to retrieve the name of a c= hild controller. > + @param[in] Language A pointer to a three character ISO 639-2 lang= uage > + identifier. This is the language of the cont= roller name > + that the caller is requesting, and it must ma= tch one > + of the languages specified in SupportedLangua= ges. The > + number of languages supported by a driver is = up to the > + driver writer. > + @param[out] ControllerName A pointer to the Unicode string to retu= rn. > This Unicode > + string is the name of the controller s= pecified by > + ControllerHandle and ChildHandle in th= e language specified > + by Language, from the point of view of= the driver specified > + by This. > + > + @retval EFI_SUCCESS The Unicode string for the user-readable= name > in the > + language specified by Language for the d= river > + specified by This was returned in Driver= Name. > + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. > + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a > valid EFI_HANDLE. > + @retval EFI_INVALID_PARAMETER Language is NULL. > + @retval EFI_INVALID_PARAMETER ControllerName is NULL. > + @retval EFI_UNSUPPORTED The driver specified by This is not curr= ently > managing > + the controller specified by ControllerHa= ndle and > + ChildHandle. > + @retval EFI_UNSUPPORTED The driver specified by This does not > support the > + language specified by Language. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExComponentNameGetControllerName ( > + IN EFI_COMPONENT_NAME_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN EFI_HANDLE ChildHandle OPTIONAL, > + IN CHAR8 *Language, > + OUT CHAR16 **ControllerName > + ) > +{ > + return EFI_UNSUPPORTED; > +} > diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c > b/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c > new file mode 100644 > index 0000000000..87327a8549 > --- /dev/null > +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.c > @@ -0,0 +1,831 @@ > +/** @file > + The driver binding and service binding protocol for Redfish RestExDxe > driver. > + > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > +#include "RedfishRestExDriver.h" > + > +EFI_DRIVER_BINDING_PROTOCOL gRedfishRestExDriverBinding =3D { > + RedfishRestExDriverBindingSupported, > + RedfishRestExDriverBindingStart, > + RedfishRestExDriverBindingStop, > + REDFISH_RESTEX_DRIVER_VERSION, > + NULL, > + NULL > +}; > + > +EFI_SERVICE_BINDING_PROTOCOL mRedfishRestExServiceBinding =3D { > + RedfishRestExServiceBindingCreateChild, > + RedfishRestExServiceBindingDestroyChild > +}; > + > +/** > + Callback function which provided by user to remove one node in > NetDestroyLinkList process. > + > + @param[in] Entry The entry to be removed. > + @param[in] Context Pointer to the callback context correspo= nds to > the Context in NetDestroyLinkList. > + > + @retval EFI_SUCCESS The entry has been removed successfully. > + @retval Others Fail to remove the entry. > + > +**/ > +EFI_STATUS > +EFIAPI > +RestExDestroyChildEntryInHandleBuffer ( > + IN LIST_ENTRY *Entry, > + IN VOID *Context > + ) > +{ > + RESTEX_INSTANCE *Instance; > + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; > + UINTN NumberOfChildren; > + EFI_HANDLE *ChildHandleBuffer; > + > + if (Entry =3D=3D NULL || Context =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Instance =3D NET_LIST_USER_STRUCT_S (Entry, RESTEX_INSTANCE, Link, > RESTEX_INSTANCE_SIGNATURE); > + ServiceBinding =3D ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT > *) Context)->ServiceBinding; > + NumberOfChildren =3D > ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)- > >NumberOfChildren; > + ChildHandleBuffer =3D > ((RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT *) Context)- > >ChildHandleBuffer; > + > + if (!NetIsInHandleBuffer (Instance->ChildHandle, NumberOfChildren, > ChildHandleBuffer)) { > + return EFI_SUCCESS; > + } > + > + return ServiceBinding->DestroyChild (ServiceBinding, Instance- > >ChildHandle); > +} > + > +/** > + Destroy the RestEx instance and recycle the resources. > + > + @param[in] Instance The pointer to the RestEx instance. > + > +**/ > +VOID > +RestExDestroyInstance ( > + IN RESTEX_INSTANCE *Instance > + ) > +{ > + HttpIoDestroyIo (&(Instance->HttpIo)); > + > + FreePool (Instance); > +} > + > +/** > + Create the RestEx instance and initialize it. > + > + @param[in] Service The pointer to the RestEx service. > + @param[out] Instance The pointer to the RestEx instance. > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. > + @retval EFI_SUCCESS The RestEx instance is created. > + > +**/ > +EFI_STATUS > +RestExCreateInstance ( > + IN RESTEX_SERVICE *Service, > + OUT RESTEX_INSTANCE **Instance > + ) > +{ > + RESTEX_INSTANCE *RestExIns; > + EFI_STATUS Status; > + > + *Instance =3D NULL; > + Status =3D EFI_SUCCESS; > + > + RestExIns =3D AllocateZeroPool (sizeof (RESTEX_INSTANCE)); > + if (RestExIns =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + RestExIns->Signature =3D RESTEX_INSTANCE_SIGNATURE; > + InitializeListHead (&RestExIns->Link); > + RestExIns->InDestroy =3D FALSE; > + RestExIns->Service =3D Service; > + > + CopyMem (&RestExIns->RestEx, &mRedfishRestExProtocol, sizeof > (RestExIns->RestEx)); > + > + // > + // Create a HTTP_IO to access the HTTP service. > + // > + Status =3D HttpIoCreateIo ( > + RestExIns->Service->ImageHandle, > + RestExIns->Service->ControllerHandle, > + IP_VERSION_4, > + NULL, > + NULL, > + NULL, > + &(RestExIns->HttpIo) > + ); > + if (EFI_ERROR (Status)) { > + FreePool (RestExIns); > + return Status; > + } > + > + *Instance =3D RestExIns; > + > + return EFI_SUCCESS; > +} > + > +/** > + Release all the resource used the RestEx service binding instance. > + > + @param[in] RestExSb The RestEx service binding instanc= e. > + > +**/ > +VOID > +RestExDestroyService ( > + IN RESTEX_SERVICE *RestExSb > + ) > +{ > + if (RestExSb->HttpChildHandle !=3D NULL) { > + gBS->CloseProtocol ( > + RestExSb->HttpChildHandle, > + &gEfiHttpProtocolGuid, > + RestExSb->ImageHandle, > + RestExSb->ControllerHandle > + ); > + > + NetLibDestroyServiceChild ( > + RestExSb->ControllerHandle, > + RestExSb->ImageHandle, > + &gEfiHttpServiceBindingProtocolGuid, > + RestExSb->HttpChildHandle > + ); > + > + RestExSb->HttpChildHandle =3D NULL; > + } > + > + gBS->UninstallProtocolInterface ( > + RestExSb->ControllerHandle, > + &gEfiCallerIdGuid, > + &RestExSb->Id > + ); > + > + FreePool (RestExSb); > +} > + > +/** > + Check the NIC controller handle represents an in-band or out-of-band > Redfish host > + interface device. If not in-band, treat it as out-of-band interface de= vice. > + > + @param[in] Controller The NIC controller handle needs to be ch= ecked. > + > + @return EFI_REST_EX_SERVICE_ACCESS_MODE of the device. > + > +**/ > +EFI_REST_EX_SERVICE_ACCESS_MODE > +RestExServiceAccessMode ( > + IN EFI_HANDLE Controller > + ) > +{ > + // > + // This is EFI REST EX driver instance to connect > + // to Redfish service using HTTP in out of band. > + // > + if (FixedPcdGetBool (PcdRedfishRestExServiceAccessModeInBand)) { > + return EfiRestExServiceInBandAccess; > + } else { > + return EfiRestExServiceOutOfBandAccess; > + } > +} > + > +/** > + Create then initialize a RestEx service binding instance. > + > + @param[in] Controller The controller to install the RestEx ser= vice > + binding on. > + @param[in] Image The driver binding image of the RestEx d= river. > + @param[out] Service The variable to receive the created serv= ice > + binding instance. > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the > instance. > + @retval EFI_SUCCESS The service instance is created for the = controller. > + > +**/ > +EFI_STATUS > +RestExCreateService ( > + IN EFI_HANDLE Controller, > + IN EFI_HANDLE Image, > + OUT RESTEX_SERVICE **Service > + ) > +{ > + EFI_STATUS Status; > + RESTEX_SERVICE *RestExSb; > + > + Status =3D EFI_SUCCESS; > + RestExSb =3D NULL; > + > + *Service =3D NULL; > + > + RestExSb =3D AllocateZeroPool (sizeof (RESTEX_SERVICE)); > + if (RestExSb =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + RestExSb->Signature =3D RESTEX_SERVICE_SIGNATURE; > + > + RestExSb->ServiceBinding =3D mRedfishRestExServiceBinding; > + > + RestExSb->RestExChildrenNum =3D 0; > + InitializeListHead (&RestExSb->RestExChildrenList); > + > + RestExSb->ControllerHandle =3D Controller; > + RestExSb->ImageHandle =3D Image; > + > + RestExSb- > >RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.Len > gth =3D sizeof (EFI_REST_EX_SERVICE_INFO); > + RestExSb- > >RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.Res > tServiceInfoVer.Major =3D 1; > + RestExSb- > >RestExServiceInfo.EfiRestExServiceInfoV10.EfiRestExServiceInfoHeader.Res > tServiceInfoVer.Minor =3D 0; > + RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestServiceType =3D > EfiRestExServiceRedfish; > + RestExSb- > >RestExServiceInfo.EfiRestExServiceInfoV10.RestServiceAccessMode =3D > RestExServiceAccessMode (Controller); > + RestExSb->RestExServiceInfo.EfiRestExServiceInfoV10.RestExConfigType = =3D > EfiRestExConfigHttp; > + RestExSb- > >RestExServiceInfo.EfiRestExServiceInfoV10.RestExConfigDataLength =3D > sizeof (EFI_REST_EX_HTTP_CONFIG_DATA); > + > + Status =3D gBS->InstallProtocolInterface ( > + &Controller, > + &gEfiCallerIdGuid, > + EFI_NATIVE_INTERFACE, > + &RestExSb->Id > + ); > + if (EFI_ERROR (Status)) { > + FreePool (RestExSb); > + RestExSb =3D NULL; > + } > + > + *Service =3D RestExSb; > + return Status; > +} > + > +/** > + This is the declaration of an EFI image entry point. This entry point = is > + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers incl= uding > + both device drivers and bus drivers. > + > + @param[in] ImageHandle The firmware allocated handle for the UEFI > image. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval Others An unexpected error occurred. > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + > + Status =3D EFI_SUCCESS; > + > + // > + // Install the RestEx Driver Binding Protocol. > + // > + Status =3D EfiLibInstallDriverBindingComponentName2 ( > + ImageHandle, > + SystemTable, > + &gRedfishRestExDriverBinding, > + ImageHandle, > + &gRedfishRestExComponentName, > + &gRedfishRestExComponentName2 > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + return Status; > +} > + > +/** > + Tests to see if this driver supports a given controller. If a child de= vice is > provided, > + it further tests to see if this driver supports creating a handle for = the > specified child device. > + > + This function checks to see if the driver specified by This supports t= he > device specified by > + ControllerHandle. Drivers will typically use the device path attached = to > + ControllerHandle and/or the services from the bus I/O abstraction > attached to > + ControllerHandle to determine if the driver supports ControllerHandle. > This function > + may be called many times during platform initialization. In order to r= educe > boot times, the tests > + performed by this function must be very small, and take as little time= as > possible to execute. This > + function must not change the state of any hardware devices, and this > function must be aware that the > + device specified by ControllerHandle may already be managed by the > same driver or a > + different driver. This function must match its calls to AllocatePages(= ) with > FreePages(), > + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(= ). > + Because ControllerHandle may have been previously started by the same > driver, if a protocol is > + already in the opened state, then it must not be closed with > CloseProtocol(). This is required > + to guarantee the state of ControllerHandle is not modified by this fun= ction. > + > + @param[in] This A pointer to the > EFI_DRIVER_BINDING_PROTOCOL instance. > + @param[in] ControllerHandle The handle of the controller to test.= This > handle > + must support a protocol interface tha= t supplies > + an I/O abstraction to the driver. > + @param[in] RemainingDevicePath A pointer to the remaining portion of= a > device path. This > + parameter is ignored by device driver= s, and is optional for > bus > + drivers. For bus drivers, if this par= ameter is not NULL, then > + the bus driver must determine if the = bus controller > specified > + by ControllerHandle and the child con= troller specified > + by RemainingDevicePath are both suppo= rted by this > + bus driver. > + > + @retval EFI_SUCCESS The device specified by ControllerHan= dle and > + RemainingDevicePath is supported by t= he driver specified > by This. > + @retval EFI_ALREADY_STARTED The device specified by > ControllerHandle and > + RemainingDevicePath is already being = managed by the > driver > + specified by This. > + @retval EFI_ACCESS_DENIED The device specified by ControllerHan= dle > and > + RemainingDevicePath is already being = managed by a > different > + driver or an application that require= s exclusive access. > + Currently not implemented. > + @retval EFI_UNSUPPORTED The device specified by ControllerHan= dle > and > + RemainingDevicePath is not supported = by the driver > specified by This. > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverBindingSupported ( > + IN EFI_DRIVER_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL > + ) > +{ > + > + // > + // Test for the HttpServiceBinding Protocol. > + // > + return gBS->OpenProtocol ( > + ControllerHandle, > + &gEfiHttpServiceBindingProtocolGuid, > + NULL, > + This->DriverBindingHandle, > + ControllerHandle, > + EFI_OPEN_PROTOCOL_TEST_PROTOCOL > + ); > + > +} > + > +/** > + Starts a device controller or a bus controller. > + > + The Start() function is designed to be invoked from the EFI boot servi= ce > ConnectController(). > + As a result, much of the error checking on the parameters to Start() h= as > been moved into this > + common boot service. It is legal to call Start() from other locations, > + but the following calling restrictions must be followed, or the system > behavior will not be deterministic. > + 1. ControllerHandle must be a valid EFI_HANDLE. > + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a > naturally aligned > + EFI_DEVICE_PATH_PROTOCOL. > + 3. Prior to calling Start(), the Supported() function for the driver s= pecified > by This must > + have been called with the same calling parameters, and Supported() > must have returned EFI_SUCCESS. > + > + @param[in] This A pointer to the > EFI_DRIVER_BINDING_PROTOCOL instance. > + @param[in] ControllerHandle The handle of the controller to start= . This > handle > + must support a protocol interface tha= t supplies > + an I/O abstraction to the driver. > + @param[in] RemainingDevicePath A pointer to the remaining portion of= a > device path. This > + parameter is ignored by device driver= s, and is optional for > bus > + drivers. For a bus driver, if this pa= rameter is NULL, then > handles > + for all the children of Controller ar= e created by this driver. > + If this parameter is not NULL and the= first Device Path > Node is > + not the End of Device Path Node, then= only the handle for > the > + child device specified by the first D= evice Path Node of > + RemainingDevicePath is created by thi= s driver. > + If the first Device Path Node of Rema= iningDevicePath is > + the End of Device Path Node, no child= handle is created by > this > + driver. > + > + @retval EFI_SUCCESS The device was started. > + @retval EFI_DEVICE_ERROR The device could not be started due t= o a > device error.Currently not implemented. > + @retval EFI_OUT_OF_RESOURCES The request could not be completed > due to a lack of resources. > + @retval Others The driver failded to start the devic= e. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverBindingStart ( > + IN EFI_DRIVER_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL > + ) > +{ > + RESTEX_SERVICE *RestExSb; > + EFI_STATUS Status; > + UINT32 *Id; > + VOID *Interface; > + > + Status =3D gBS->OpenProtocol ( > + ControllerHandle, > + &gEfiCallerIdGuid, > + (VOID **) &Id, > + This->DriverBindingHandle, > + ControllerHandle, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + if (!EFI_ERROR (Status)) { > + return EFI_ALREADY_STARTED; > + } > + > + Status =3D RestExCreateService (ControllerHandle, This- > >DriverBindingHandle, &RestExSb); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + ASSERT (RestExSb !=3D NULL); > + > + // > + // Create a Http child instance, but do not configure it. > + // This will establish the parent-child relationship. > + // > + Status =3D NetLibCreateServiceChild ( > + ControllerHandle, > + This->DriverBindingHandle, > + &gEfiHttpServiceBindingProtocolGuid, > + &RestExSb->HttpChildHandle > + ); > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + Status =3D gBS->OpenProtocol ( > + RestExSb->HttpChildHandle, > + &gEfiHttpProtocolGuid, > + &Interface, > + This->DriverBindingHandle, > + ControllerHandle, > + EFI_OPEN_PROTOCOL_BY_DRIVER > + ); > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + // > + // Install the RestEx ServiceBinding Protocol onto ControllerHandle. > + // > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + &ControllerHandle, > + &gEfiRestExServiceBindingProtocolGuid, > + &RestExSb->ServiceBinding, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + return EFI_SUCCESS; > + > +ON_ERROR: > + RestExDestroyService (RestExSb); > + > + return Status; > +} > + > +/** > + Stops a device controller or a bus controller. > + > + The Stop() function is designed to be invoked from the EFI boot service > DisconnectController(). > + As a result, much of the error checking on the parameters to Stop() has > been moved > + into this common boot service. It is legal to call Stop() from other l= ocations, > + but the following calling restrictions must be followed, or the system > behavior will not be deterministic. > + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a > previous call to this > + same driver's Start() function. > + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be= a > valid > + EFI_HANDLE. In addition, all of these handles must have been create= d in > this driver's > + Start() function, and the Start() function must have called OpenPro= tocol() > on > + ControllerHandle with an Attribute of > EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. > + > + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROT= OCOL > instance. > + @param[in] ControllerHandle A handle to the device being stopped. The > handle must > + support a bus specific I/O protocol for = the driver > + to use to stop the device. > + @param[in] NumberOfChildren The number of child device handles in > ChildHandleBuffer. > + @param[in] ChildHandleBuffer An array of child handles to be freed. M= ay > be NULL > + if NumberOfChildren is 0. > + > + @retval EFI_SUCCESS The device was stopped. > + @retval EFI_DEVICE_ERROR The device could not be stopped due to a > device error. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverBindingStop ( > + IN EFI_DRIVER_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN UINTN NumberOfChildren, > + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL > + ) > +{ > + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; > + RESTEX_SERVICE *RestExSb; > + EFI_HANDLE NicHandle; > + EFI_STATUS Status; > + LIST_ENTRY *List; > + RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT Context; > + > + // > + // RestEx driver opens HTTP child, So, Controller is a HTTP > + // child handle. Locate the Nic handle first. Then get the > + // RestEx private data back. > + // > + NicHandle =3D NetLibGetNicHandle (ControllerHandle, > &gEfiHttpProtocolGuid); > + if (NicHandle =3D=3D NULL) { > + return EFI_SUCCESS; > + } > + > + Status =3D gBS->OpenProtocol ( > + NicHandle, > + &gEfiRestExServiceBindingProtocolGuid, > + (VOID **) &ServiceBinding, > + This->DriverBindingHandle, > + NicHandle, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + if (EFI_ERROR (Status)) { > + return EFI_DEVICE_ERROR; > + } > + > + RestExSb =3D RESTEX_SERVICE_FROM_THIS (ServiceBinding); > + > + if (!IsListEmpty (&RestExSb->RestExChildrenList)) { > + // > + // Destroy the RestEx child instance in ChildHandleBuffer. > + // > + List =3D &RestExSb->RestExChildrenList; > + Context.ServiceBinding =3D ServiceBinding; > + Context.NumberOfChildren =3D NumberOfChildren; > + Context.ChildHandleBuffer =3D ChildHandleBuffer; > + Status =3D NetDestroyLinkList ( > + List, > + RestExDestroyChildEntryInHandleBuffer, > + &Context, > + NULL > + ); > + } > + > + if (NumberOfChildren =3D=3D 0 && IsListEmpty (&RestExSb- > >RestExChildrenList)) { > + gBS->UninstallProtocolInterface ( > + NicHandle, > + &gEfiRestExServiceBindingProtocolGuid, > + ServiceBinding > + ); > + > + RestExDestroyService (RestExSb); > + > + if (gRedfishRestExControllerNameTable !=3D NULL) { > + FreeUnicodeStringTable (gRedfishRestExControllerNameTable); > + gRedfishRestExControllerNameTable =3D NULL; > + } > + > + Status =3D EFI_SUCCESS; > + } > + > + return Status; > +} > + > +/** > + Creates a child handle and installs a protocol. > + > + The CreateChild() function installs a protocol on ChildHandle. > + If ChildHandle is a pointer to NULL, then a new handle is created and > returned in ChildHandle. > + If ChildHandle is not a pointer to NULL, then the protocol installs on= the > existing ChildHandle. > + > + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param[in] ChildHandle Pointer to the handle of the child to create. I= f it is > NULL, > + then a new handle is created. If it is a pointe= r to an existing > UEFI handle, > + then the protocol is added to the existing UEFI= handle. > + > + @retval EFI_SUCCES The protocol was added to ChildHandle. > + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to create > + the child > + @retval other The child handle was not created > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExServiceBindingCreateChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE *ChildHandle > + ) > +{ > + RESTEX_SERVICE *RestExSb; > + RESTEX_INSTANCE *Instance; > + EFI_STATUS Status; > + EFI_TPL OldTpl; > + VOID *Http; > + > + if ((This =3D=3D NULL) || (ChildHandle =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + RestExSb =3D RESTEX_SERVICE_FROM_THIS (This); > + > + Status =3D RestExCreateInstance (RestExSb, &Instance); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + ASSERT (Instance !=3D NULL); > + > + // > + // Install the RestEx protocol onto ChildHandle > + // > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + ChildHandle, > + &gEfiRestExProtocolGuid, > + &Instance->RestEx, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + goto ON_ERROR; > + } > + > + Instance->ChildHandle =3D *ChildHandle; > + > + // > + // Open the Http protocol BY_CHILD. > + // > + Status =3D gBS->OpenProtocol ( > + RestExSb->HttpChildHandle, > + &gEfiHttpProtocolGuid, > + (VOID **) &Http, > + gRedfishRestExDriverBinding.DriverBindingHandle, > + Instance->ChildHandle, > + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER > + ); > + if (EFI_ERROR (Status)) { > + gBS->UninstallMultipleProtocolInterfaces ( > + Instance->ChildHandle, > + &gEfiRestExProtocolGuid, > + &Instance->RestEx, > + NULL > + ); > + > + goto ON_ERROR; > + } > + > + // > + // Open the Http protocol by child. > + // > + Status =3D gBS->OpenProtocol ( > + Instance->HttpIo.Handle, > + &gEfiHttpProtocolGuid, > + (VOID **) &Http, > + gRedfishRestExDriverBinding.DriverBindingHandle, > + Instance->ChildHandle, > + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER > + ); > + if (EFI_ERROR (Status)) { > + // > + // Close the Http protocol. > + // > + gBS->CloseProtocol ( > + RestExSb->HttpChildHandle, > + &gEfiHttpProtocolGuid, > + gRedfishRestExDriverBinding.DriverBindingHandle, > + ChildHandle > + ); > + > + gBS->UninstallMultipleProtocolInterfaces ( > + Instance->ChildHandle, > + &gEfiRestExProtocolGuid, > + &Instance->RestEx, > + NULL > + ); > + > + goto ON_ERROR; > + } > + > + // > + // Add it to the parent's child list. > + // > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + InsertTailList (&RestExSb->RestExChildrenList, &Instance->Link); > + RestExSb->RestExChildrenNum++; > + > + gBS->RestoreTPL (OldTpl); > + > + return EFI_SUCCESS; > + > +ON_ERROR: > + > + RestExDestroyInstance (Instance); > + return Status; > +} > + > +/** > + Destroys a child handle with a protocol installed on it. > + > + The DestroyChild() function does the opposite of CreateChild(). It rem= oves > a protocol > + that was installed by CreateChild() from ChildHandle. If the removed > protocol is the > + last protocol on ChildHandle, then ChildHandle is destroyed. > + > + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param[in] ChildHandle Handle of the child to destroy > + > + @retval EFI_SUCCES The protocol was removed from ChildHandl= e. > + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol > that is being removed. > + @retval EFI_INVALID_PARAMETER Child handle is NULL. > + @retval EFI_ACCESS_DENIED The protocol could not be removed from > the ChildHandle > + because its services are being used. > + @retval other The child handle was not destroyed > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExServiceBindingDestroyChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ChildHandle > + ) > +{ > + RESTEX_SERVICE *RestExSb; > + RESTEX_INSTANCE *Instance; > + > + EFI_REST_EX_PROTOCOL *RestEx; > + EFI_STATUS Status; > + EFI_TPL OldTpl; > + > + if ((This =3D=3D NULL) || (ChildHandle =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Retrieve the private context data structures > + // > + Status =3D gBS->OpenProtocol ( > + ChildHandle, > + &gEfiRestExProtocolGuid, > + (VOID **) &RestEx, > + NULL, > + NULL, > + EFI_OPEN_PROTOCOL_GET_PROTOCOL > + ); > + > + if (EFI_ERROR (Status)) { > + return EFI_UNSUPPORTED; > + } > + > + Instance =3D RESTEX_INSTANCE_FROM_THIS (RestEx); > + RestExSb =3D RESTEX_SERVICE_FROM_THIS (This); > + > + if (Instance->Service !=3D RestExSb) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (Instance->InDestroy) { > + return EFI_SUCCESS; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + Instance->InDestroy =3D TRUE; > + > + // > + // Close the Http protocol. > + // > + gBS->CloseProtocol ( > + RestExSb->HttpChildHandle, > + &gEfiHttpProtocolGuid, > + gRedfishRestExDriverBinding.DriverBindingHandle, > + ChildHandle > + ); > + > + gBS->CloseProtocol ( > + Instance->HttpIo.Handle, > + &gEfiHttpProtocolGuid, > + gRedfishRestExDriverBinding.DriverBindingHandle, > + ChildHandle > + ); > + > + > + gBS->RestoreTPL (OldTpl); > + > + // > + // Uninstall the RestEx protocol first to enable a top down destructio= n. > + // > + Status =3D gBS->UninstallProtocolInterface ( > + ChildHandle, > + &gEfiRestExProtocolGuid, > + RestEx > + ); > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + if (EFI_ERROR (Status)) { > + Instance->InDestroy =3D FALSE; > + gBS->RestoreTPL (OldTpl); > + return Status; > + } > + > + RemoveEntryList (&Instance->Link); > + RestExSb->RestExChildrenNum--; > + > + gBS->RestoreTPL (OldTpl); > + > + RestExDestroyInstance (Instance); > + return EFI_SUCCESS; > +} > + > diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.h > b/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.h > new file mode 100644 > index 0000000000..6743ced23c > --- /dev/null > +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExDriver.h > @@ -0,0 +1,650 @@ > +/** @file > + RedfishRestExDxe support functions definitions. > + > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef EFI_REDFISH_RESTEX_DRIVER_H_ > +#define EFI_REDFISH_RESTEX_DRIVER_H_ > + > +/// > +/// Libraries classes > +/// > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/// > +/// UEFI Driver Model Protocols > +/// > +#include > +#include > +#include > + > +/// > +/// Protocol instances > +/// > +extern EFI_COMPONENT_NAME_PROTOCOL > gRedfishRestExComponentName; > +extern EFI_COMPONENT_NAME2_PROTOCOL > gRedfishRestExComponentName2; > +extern EFI_UNICODE_STRING_TABLE > *gRedfishRestExControllerNameTable; > + > +extern EFI_DRIVER_BINDING_PROTOCOL gRedfishRestExDriverBinding; > +extern EFI_SERVICE_BINDING_PROTOCOL mRedfishRestExServiceBinding; > +extern EFI_REST_EX_PROTOCOL mRedfishRestExProtocol; > +/// > +/// RestEx service block > +/// > +typedef struct _RESTEX_SERVICE RESTEX_SERVICE; > + > +/// > +/// RestEx instance block > +/// > +typedef struct _RESTEX_INSTANCE RESTEX_INSTANCE; > + > +/// > +/// Driver Version > +/// > +#define REDFISH_RESTEX_DRIVER_VERSION 0x0100 > + > +#define RESTEX_SERVICE_SIGNATURE SIGNATURE_32 ('R', 'E', 'S', 'S') > +#define RESTEX_INSTANCE_SIGNATURE SIGNATURE_32 ('R', 'E', 'I', 'S') > + > +#define RESTEX_SERVICE_FROM_THIS(a) \ > + CR (a, RESTEX_SERVICE, ServiceBinding, RESTEX_SERVICE_SIGNATURE) > + > +#define RESTEX_INSTANCE_FROM_THIS(a) \ > + CR (a, RESTEX_INSTANCE, RestEx, RESTEX_INSTANCE_SIGNATURE) > + > + > +#define RESTEX_STATE_UNCONFIGED 0 > +#define RESTEX_STATE_CONFIGED 1 > + > +struct _RESTEX_SERVICE { > + UINT32 Signature; > + EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; > + > + UINT16 RestExChildrenNum; > + LIST_ENTRY RestExChildrenList; > + > + EFI_HANDLE ControllerHandle; > + EFI_HANDLE ImageHandle; > + > + // > + // Use to establish the parent-child relationship. > + // > + EFI_HANDLE HttpChildHandle; > + > + UINT32 Id; > + > + EFI_REST_EX_SERVICE_INFO RestExServiceInfo; > +}; > + > +#define RESTEX_INSTANCE_FLAGS_TLS_RETRY 0x00000001 > +#define RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY 0x00000002 > + > +struct _RESTEX_INSTANCE { > + UINT32 Signature; > + LIST_ENTRY Link; > + > + EFI_REST_EX_PROTOCOL RestEx; > + > + INTN State; > + BOOLEAN InDestroy; > + > + RESTEX_SERVICE *Service; > + EFI_HANDLE ChildHandle; > + > + EFI_REST_EX_CONFIG_DATA ConfigData; > + > + // > + // HTTP_IO to access the HTTP service > + // > + HTTP_IO HttpIo; > + > + UINT32 Flags; > +}; > + > +typedef struct { > + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; > + UINTN NumberOfChildren; > + EFI_HANDLE *ChildHandleBuffer; > +} RESTEX_DESTROY_CHILD_IN_HANDLE_BUF_CONTEXT; > + > +/** > + Provides a simple HTTP-like interface to send and receive resources fr= om a > REST service. > + > + The SendReceive() function sends an HTTP request to this REST service, > and returns a > + response when the data is retrieved from the service. RequestMessage > contains the HTTP > + request to the REST resource identified by RequestMessage.Request.Url. > The > + ResponseMessage is the returned HTTP response for that request, > including any HTTP > + status. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instan= ce for a > particular > + REST service. > + @param[in] RequestMessage Pointer to the HTTP request data for t= his > resource > + @param[out] ResponseMessage Pointer to the HTTP response data > obtained for this requested. > + > + @retval EFI_SUCCESS operation succeeded. > + @retval EFI_INVALID_PARAMETER This, RequestMessage, or > ResponseMessage are NULL. > + @retval EFI_DEVICE_ERROR An unexpected system or network error > occurred. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExSendReceive ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage, > + OUT EFI_HTTP_MESSAGE *ResponseMessage > + ); > + > +/** > + Obtain the current time from this REST service instance. > + > + The GetServiceTime() function is an optional interface to obtain the > current time from > + this REST service instance. If this REST service does not support to r= etrieve > the time, > + this function returns EFI_UNSUPPORTED. This function must returns > EFI_UNSUPPORTED if > + EFI_REST_EX_SERVICE_TYPE returned in EFI_REST_EX_SERVICE_INFO from > GetService() is > + EFI_REST_EX_SERVICE_UNSPECIFIC. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instan= ce for a > particular > + REST service. > + @param[out] Time A pointer to storage to receive a snap= shot of > the current time of > + the REST service. > + > + @retval EFI_SUCCESS operation succeeded. > + @retval EFI_INVALID_PARAMETER This or Time are NULL. > + @retval EFI_UNSUPPORTED The RESTful service does not support > returning the time. > + @retval EFI_DEVICE_ERROR An unexpected system or network error > occurred. > + @retval EFI_NOT_READY The configuration of this instance is = not set > yet. Configure() must > + be executed and returns successfully p= rior to invoke this > function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExGetServiceTime ( > + IN EFI_REST_EX_PROTOCOL *This, > + OUT EFI_TIME *Time > + ); > + > +/** > + This function returns the information of REST service provided by this= EFI > REST EX driver instance. > + > + The information such as the type of REST service and the access mode of > REST EX driver instance > + (In-band or Out-of-band) are described in EFI_REST_EX_SERVICE_INFO > structure. For the vendor-specific > + REST service, vendor-specific REST service information is returned in > VendorSpecifcData. > + REST EX driver designer is well know what REST service this REST EX dr= iver > instance intends to > + communicate with. The designer also well know this driver instance is = used > to talk to BMC through > + specific platform mechanism or talk to REST server through UEFI HTTP > protocol. REST EX driver is > + responsible to fill up the correct information in > EFI_REST_EX_SERVICE_INFO. EFI_REST_EX_SERVICE_INFO > + is referred by EFI REST clients to pickup the proper EFI REST EX driver > instance to get and set resource. > + GetService() is a basic and mandatory function which must be able to u= se > even Configure() is not invoked > + in previously. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instan= ce for a > particular > + REST service. > + @param[out] RestExServiceInfo Pointer to receive a pointer to > EFI_REST_EX_SERVICE_INFO structure. The > + format of EFI_REST_EX_SERVICE_INFO is = version > controlled for the future > + extension. The version of EFI_REST_EX_= SERVICE_INFO > structure is returned > + in the header within this structure. E= FI REST client refers to > the correct > + format of structure according to the v= ersion number. The > pointer to > + EFI_REST_EX_SERVICE_INFO is a memory b= lock allocated > by EFI REST EX driver > + instance. That is caller's responsibil= ity to free this memory > when this > + structure is no longer needed. Refer t= o Related Definitions > below for the > + definitions of EFI_REST_EX_SERVICE_INF= O structure. > + > + @retval EFI_SUCCESS EFI_REST_EX_SERVICE_INFO is returned in > RestExServiceInfo. This function > + is not supported in this REST EX Proto= col driver instance. > + @retval EFI_UNSUPPORTED This function is not supported in this= REST > EX Protocol driver instance. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExGetService ( > + IN EFI_REST_EX_PROTOCOL *This, > + OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo > + ); > + > +/** > + This function returns operational configuration of current EFI REST EX= child > instance. > + > + This function returns the current configuration of EFI REST EX child i= nstance. > The format of > + operational configuration depends on the implementation of EFI REST EX > driver instance. For > + example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol= as > the undying protocol > + to communicate with REST service. In this case, the type of configurat= ion is > + EFI_REST_EX_CONFIG_TYPE_HTTP returned from GetService(). > EFI_HTTP_CONFIG_DATA is used as EFI REST > + EX configuration format and returned to EFI REST client. User has to t= ype > cast RestExConfigData > + to EFI_HTTP_CONFIG_DATA. For those non HTTP-aware REST EX driver > instances, the type of configuration > + is EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC returned from GetService(). In > this case, the format of > + returning data could be non industrial. Instead, the format of configu= ration > data is system/platform > + specific definition such as BMC mechanism used in EFI REST EX driver > instance. EFI REST client and > + EFI REST EX driver instance have to refer to the specific system /plat= form > spec which is out of UEFI scope. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL insta= nce. > + @param[out] RestExConfigData Pointer to receive a pointer to > EFI_REST_EX_CONFIG_DATA. > + The memory allocated for configuration= data should be > freed > + by caller. See Related Definitions for= the details. > + > + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is returned in > successfully. > + @retval EFI_UNSUPPORTED This function is not supported in this= REST > EX Protocol driver instance. > + @retval EFI_NOT_READY The configuration of this instance is = not set > yet. Configure() must be > + executed and returns successfully prio= r to invoke this > function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExGetModeData ( > + IN EFI_REST_EX_PROTOCOL *This, > + OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData > + ); > + > +/** > + This function is used to configure EFI REST EX child instance. > + > + This function is used to configure the setting of underlying protocol = of REST > EX child > + instance. The type of configuration is according to the implementation= of > EFI REST EX > + driver instance. For example, HTTP-aware EFI REST EX driver instance u= ses > EFI HTTP protocol > + as the undying protocol to communicate with REST service. The type of > configuration is > + EFI_REST_EX_CONFIG_TYPE_HTTP and RestExConfigData is the same > format with EFI_HTTP_CONFIG_DATA. > + Akin to HTTP configuration, REST EX child instance can be configure to= use > different HTTP > + local access point for the data transmission. Multiple REST clients ma= y use > different > + configuration of HTTP to distinguish themselves, such as to use the > different TCP port. > + For those non HTTP-aware REST EX driver instance, the type of > configuration is > + EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC. RestExConfigData refers to the > non industrial standard. > + Instead, the format of configuration data is system/platform specific > definition such as BMC. > + In this case, EFI REST client and EFI REST EX driver instance have to = refer to > the specific > + system/platform spec which is out of the UEFI scope. Besides > GetService()function, no other > + EFI REST EX functions can be executed by this instance until Configure= ()is > executed and returns > + successfully. All other functions must returns EFI_NOT_READY if this > instance is not configured > + yet. Set RestExConfigData to NULL means to put EFI REST EX child insta= nce > into the unconfigured > + state. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL insta= nce. > + @param[in] RestExConfigData Pointer to EFI_REST_EX_CONFIG_DATA. > See Related Definitions in > + GetModeData() protocol interface. > + > + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is set in > successfully. > + @retval EFI_DEVICE_ERROR Configuration for this REST EX child > instance is failed with the given > + EFI_REST_EX_CONFIG_DATA. > + @retval EFI_UNSUPPORTED This function is not supported in this= REST > EX Protocol driver instance. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExConfigure ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_REST_EX_CONFIG_DATA RestExConfigData > + ); > + > +/** > + This function sends REST request to REST service and signal caller's e= vent > asynchronously when > + the final response is received by REST EX Protocol driver instance. > + > + The essential design of this function is to handle asynchronous > send/receive implicitly according > + to REST service asynchronous request mechanism. Caller will get the > notification once the response > + is returned from REST service. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL ins= tance. > + @param[in] RequestMessage This is the HTTP request message sent > to REST service. Set RequestMessage > + to NULL to cancel the previous async= hronous request > associated with the > + corresponding RestExToken. See descr= iptions for the > details. > + @param[in] RestExToken REST EX token which REST EX Protocol > instance uses to notify REST client > + the status of response of asynchrono= us REST request. See > related definition > + of EFI_REST_EX_TOKEN. > + @param[in] TimeOutInMilliSeconds The pointer to the timeout in > milliseconds which REST EX Protocol driver > + instance refers as the duration to d= rop asynchronous REST > request. NULL > + pointer means no timeout for this RE= ST request. REST EX > Protocol driver > + signals caller's event with EFI_STAT= US set to EFI_TIMEOUT > in RestExToken > + if REST EX Protocol can't get the re= sponse from REST > service within > + TimeOutInMilliSeconds. > + > + @retval EFI_SUCCESS Asynchronous REST request is establi= shed. > + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance > doesn't support asynchronous request. > + @retval EFI_TIMEOUT Asynchronous REST request is not > established and timeout is expired. > + @retval EFI_ABORT Previous asynchronous REST request h= as been > canceled. > + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR > for other errors according to HTTP Status Code. > + @retval EFI_NOT_READY The configuration of this instance i= s not set > yet. Configure() must be executed > + and returns successfully prior to in= voke this function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExAyncSendReceive ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, > + IN EFI_REST_EX_TOKEN *RestExToken, > + IN UINTN *TimeOutInMilliSeconds OPTIONAL > + ); > + > +/** > + This function sends REST request to a REST Event service and signals c= aller's > event > + token asynchronously when the URI resource change event is received by > REST EX > + Protocol driver instance. > + > + The essential design of this function is to monitor event implicitly a= ccording > to > + REST service event service mechanism. Caller will get the notification= if > certain > + resource is changed. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL ins= tance. > + @param[in] RequestMessage This is the HTTP request message sent > to REST service. Set RequestMessage > + to NULL to cancel the previous event= service associated > with the corresponding > + RestExToken. See descriptions for th= e details. > + @param[in] RestExToken REST EX token which REST EX Protocol > driver instance uses to notify REST client > + the URI resource which monitored by = REST client has > been changed. See the related > + definition of EFI_REST_EX_TOKEN in > EFI_REST_EX_PROTOCOL.AsyncSendReceive(). > + > + @retval EFI_SUCCESS Asynchronous REST request is establi= shed. > + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance > doesn't support asynchronous request. > + @retval EFI_ABORT Previous asynchronous REST request h= as been > canceled or event subscription has been > + delete from service. > + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR > for other errors according to HTTP Status Code. > + @retval EFI_NOT_READY The configuration of this instance i= s not set > yet. Configure() must be executed > + and returns successfully prior to in= voke this function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExEventService ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, > + IN EFI_REST_EX_TOKEN *RestExToken > + ); > +/** > + Create a new TLS session becuase the previous on is closed. > + status. > + > + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instan= ce > for a particular > + REST service. > + @retval EFI_SUCCESS operation succeeded. > + @retval EFI Errors Other errors. > + > +**/ > +EFI_STATUS > +ResetHttpTslSession ( > + IN RESTEX_INSTANCE *Instance > +); > + > + > +/** > + Callback function which provided by user to remove one node in > NetDestroyLinkList process. > + > + @param[in] Entry The entry to be removed. > + @param[in] Context Pointer to the callback context correspo= nds to > the Context in NetDestroyLinkList. > + > + @retval EFI_SUCCESS The entry has been removed successfully. > + @retval Others Fail to remove the entry. > + > +**/ > +EFI_STATUS > +EFIAPI > +RestExDestroyChildEntryInHandleBuffer ( > + IN LIST_ENTRY *Entry, > + IN VOID *Context > + ); > + > +/** > + Destroy the RestEx instance and recycle the resources. > + > + @param[in] Instance The pointer to the RestEx instance. > + > +**/ > +VOID > +RestExDestroyInstance ( > + IN RESTEX_INSTANCE *Instance > + ); > + > +/** > + Create the RestEx instance and initialize it. > + > + @param[in] Service The pointer to the RestEx service. > + @param[out] Instance The pointer to the RestEx instance. > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. > + @retval EFI_SUCCESS The RestEx instance is created. > + > +**/ > +EFI_STATUS > +RestExCreateInstance ( > + IN RESTEX_SERVICE *Service, > + OUT RESTEX_INSTANCE **Instance > + ); > + > + > +/** > + Release all the resource used the RestEx service binding instance. > + > + @param RestExSb The RestEx service binding instance. > + > +**/ > +VOID > +RestExDestroyService ( > + IN RESTEX_SERVICE *RestExSb > + ); > + > +/** > + Create then initialize a RestEx service binding instance. > + > + @param[in] Controller The controller to install the RestEx ser= vice > + binding on. > + @param[in] Image The driver binding image of the RestEx d= river. > + @param[out] Service The variable to receive the created serv= ice > + binding instance. > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create > the instance. > + @retval EFI_SUCCESS The service instance is created for the > controller. > + > +**/ > +EFI_STATUS > +RestExCreateService ( > + IN EFI_HANDLE Controller, > + IN EFI_HANDLE Image, > + OUT RESTEX_SERVICE **Service > + ); > + > +/** > + This is the declaration of an EFI image entry point. This entry point = is > + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers incl= uding > + both device drivers and bus drivers. > + > + @param[in] ImageHandle The firmware allocated handle for the UEFI > image. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval Others An unexpected error occurred. > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ); > + > +/** > + Tests to see if this driver supports a given controller. If a child de= vice is > provided, > + it further tests to see if this driver supports creating a handle for = the > specified child device. > + > + This function checks to see if the driver specified by This supports t= he > device specified by > + ControllerHandle. Drivers will typically use the device path attached = to > + ControllerHandle and/or the services from the bus I/O abstraction > attached to > + ControllerHandle to determine if the driver supports ControllerHandle. > This function > + may be called many times during platform initialization. In order to r= educe > boot times, the tests > + performed by this function must be very small, and take as little time= as > possible to execute. This > + function must not change the state of any hardware devices, and this > function must be aware that the > + device specified by ControllerHandle may already be managed by the > same driver or a > + different driver. This function must match its calls to AllocatePages(= ) with > FreePages(), > + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(= ). > + Because ControllerHandle may have been previously started by the same > driver, if a protocol is > + already in the opened state, then it must not be closed with > CloseProtocol(). This is required > + to guarantee the state of ControllerHandle is not modified by this fun= ction. > + > + @param[in] This A pointer to the > EFI_DRIVER_BINDING_PROTOCOL instance. > + @param[in] ControllerHandle The handle of the controller to test.= This > handle > + must support a protocol interface tha= t supplies > + an I/O abstraction to the driver. > + @param[in] RemainingDevicePath A pointer to the remaining portion of= a > device path. This > + parameter is ignored by device driver= s, and is optional for > bus > + drivers. For bus drivers, if this par= ameter is not NULL, then > + the bus driver must determine if the = bus controller > specified > + by ControllerHandle and the child con= troller specified > + by RemainingDevicePath are both suppo= rted by this > + bus driver. > + > + @retval EFI_SUCCESS The device specified by ControllerHan= dle and > + RemainingDevicePath is supported by t= he driver specified > by This. > + @retval EFI_ALREADY_STARTED The device specified by > ControllerHandle and > + RemainingDevicePath is already being = managed by the > driver > + specified by This. > + @retval EFI_ACCESS_DENIED The device specified by ControllerHan= dle > and > + RemainingDevicePath is already being = managed by a > different > + driver or an application that require= s exclusive access. > + Currently not implemented. > + @retval EFI_UNSUPPORTED The device specified by ControllerHan= dle > and > + RemainingDevicePath is not supported = by the driver > specified by This. > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverBindingSupported ( > + IN EFI_DRIVER_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL > + ); > + > +/** > + Starts a device controller or a bus controller. > + > + The Start() function is designed to be invoked from the EFI boot servi= ce > ConnectController(). > + As a result, much of the error checking on the parameters to Start() h= as > been moved into this > + common boot service. It is legal to call Start() from other locations, > + but the following calling restrictions must be followed, or the system > behavior will not be deterministic. > + 1. ControllerHandle must be a valid EFI_HANDLE. > + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a > naturally aligned > + EFI_DEVICE_PATH_PROTOCOL. > + 3. Prior to calling Start(), the Supported() function for the driver s= pecified > by This must > + have been called with the same calling parameters, and Supported() > must have returned EFI_SUCCESS. > + > + @param[in] This A pointer to the > EFI_DRIVER_BINDING_PROTOCOL instance. > + @param[in] ControllerHandle The handle of the controller to start= . This > handle > + must support a protocol interface tha= t supplies > + an I/O abstraction to the driver. > + @param[in] RemainingDevicePath A pointer to the remaining portion of= a > device path. This > + parameter is ignored by device driver= s, and is optional for > bus > + drivers. For a bus driver, if this pa= rameter is NULL, then > handles > + for all the children of Controller ar= e created by this driver. > + If this parameter is not NULL and the= first Device Path > Node is > + not the End of Device Path Node, then= only the handle for > the > + child device specified by the first D= evice Path Node of > + RemainingDevicePath is created by thi= s driver. > + If the first Device Path Node of Rema= iningDevicePath is > + the End of Device Path Node, no child= handle is created by > this > + driver. > + > + @retval EFI_SUCCESS The device was started. > + @retval EFI_DEVICE_ERROR The device could not be started due t= o a > device error.Currently not implemented. > + @retval EFI_OUT_OF_RESOURCES The request could not be completed > due to a lack of resources. > + @retval Others The driver failded to start the devic= e. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverBindingStart ( > + IN EFI_DRIVER_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL > + ); > + > +/** > + Stops a device controller or a bus controller. > + > + The Stop() function is designed to be invoked from the EFI boot service > DisconnectController(). > + As a result, much of the error checking on the parameters to Stop() has > been moved > + into this common boot service. It is legal to call Stop() from other l= ocations, > + but the following calling restrictions must be followed, or the system > behavior will not be deterministic. > + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a > previous call to this > + same driver's Start() function. > + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be= a > valid > + EFI_HANDLE. In addition, all of these handles must have been create= d in > this driver's > + Start() function, and the Start() function must have called OpenPro= tocol() > on > + ControllerHandle with an Attribute of > EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. > + > + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROT= OCOL > instance. > + @param[in] ControllerHandle A handle to the device being stopped. The > handle must > + support a bus specific I/O protocol for = the driver > + to use to stop the device. > + @param[in] NumberOfChildren The number of child device handles in > ChildHandleBuffer. > + @param[in] ChildHandleBuffer An array of child handles to be freed. M= ay > be NULL > + if NumberOfChildren is 0. > + > + @retval EFI_SUCCESS The device was stopped. > + @retval EFI_DEVICE_ERROR The device could not be stopped due to a > device error. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverBindingStop ( > + IN EFI_DRIVER_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN UINTN NumberOfChildren, > + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL > + ); > + > +/** > + Creates a child handle and installs a protocol. > + > + The CreateChild() function installs a protocol on ChildHandle. > + If ChildHandle is a pointer to NULL, then a new handle is created and > returned in ChildHandle. > + If ChildHandle is not a pointer to NULL, then the protocol installs on= the > existing ChildHandle. > + > + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param[in] ChildHandle Pointer to the handle of the child to create. I= f it is > NULL, > + then a new handle is created. If it is a pointe= r to an existing > UEFI handle, > + then the protocol is added to the existing UEFI= handle. > + > + @retval EFI_SUCCES The protocol was added to ChildHandle. > + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to create > + the child > + @retval other The child handle was not created > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExServiceBindingCreateChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE *ChildHandle > + ); > + > +/** > + Destroys a child handle with a protocol installed on it. > + > + The DestroyChild() function does the opposite of CreateChild(). It rem= oves > a protocol > + that was installed by CreateChild() from ChildHandle. If the removed > protocol is the > + last protocol on ChildHandle, then ChildHandle is destroyed. > + > + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param[in] ChildHandle Handle of the child to destroy > + > + @retval EFI_SUCCES The protocol was removed from ChildHandl= e. > + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol > that is being removed. > + @retval EFI_INVALID_PARAMETER Child handle is NULL. > + @retval EFI_ACCESS_DENIED The protocol could not be removed from > the ChildHandle > + because its services are being used. > + @retval other The child handle was not destroyed > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExServiceBindingDestroyChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ChildHandle > + ); > +#endif > diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf > b/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf > new file mode 100644 > index 0000000000..75437b086a > --- /dev/null > +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf > @@ -0,0 +1,63 @@ > +## @file > +# Implementation of Redfish EFI_REST_EX_PROTOCOL interfaces. > +# > +# Copyright (c) 2019, Intel Corporation. All rights reserved.
> +# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x0001001b > + BASE_NAME =3D RedfishRestExDxe > + FILE_GUID =3D B64702DA-E6B5-43c8-8CE8-D253071E9D6C > + MODULE_TYPE =3D UEFI_DRIVER > + VERSION_STRING =3D 1.0 > + ENTRY_POINT =3D RedfishRestExDriverEntryPoint > + UNLOAD_IMAGE =3D NetLibDefaultUnload > + MODULE_UNI_FILE =3D RedfishRestExDxe.uni > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + NetworkPkg/NetworkPkg.dec > + RedfishPkg/RedfishPkg.dec > + > +[Sources] > + ComponentName.c > + RedfishRestExDriver.c > + RedfishRestExDriver.h > + RedfishRestExImpl.c > + RedfishRestExProtocol.c > + RedfishRestExInternal.h > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + DebugLib > + DevicePathLib > + DpcLib > + HttpLib > + HttpIoLib > + PrintLib > + MemoryAllocationLib > + NetLib > + UefiLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + UefiRuntimeServicesTableLib > + > +[Protocols] > + gEfiRestExServiceBindingProtocolGuid ## BY_START > + gEfiRestExProtocolGuid ## BY_START > + gEfiHttpServiceBindingProtocolGuid ## TO_START > + gEfiHttpProtocolGuid ## TO_START > + gEfiDevicePathProtocolGuid ## TO_START > + > +[Pcd] > + > gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceAccessModeInBan > d ## CONSUMES > + > +[UserExtensions.TianoCore."ExtraFiles"] > + RedfishRestExDxeExtra.uni > + > diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.uni > b/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.uni > new file mode 100644 > index 0000000000..afa0c142a9 > --- /dev/null > +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.uni > @@ -0,0 +1,16 @@ > +// /** @file > +// Redfish UEFI RESTEX DXE Driver. > +// > +// This driver provides Redfish UEFI RESTEX protocols. > +// > +// Copyright (c) 2019, Intel Corporation. All rights reserved.
> +// (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> +// > +// SPDX-License-Identifier: BSD-2-Clause-Patent > +// > +// **/ > + > +#string STR_MODULE_ABSTRACT #language en-US "UEFI Redfish > RESTEX service" > + > +#string STR_MODULE_DESCRIPTION #language en-US "This driver > provides Redfish EFI RESTEX Protocol and Redfish EFI RESREX Service Bindi= ng > Protocol." > + > diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExDxeExtra.uni > b/RedfishPkg/RedfishRestExDxe/RedfishRestExDxeExtra.uni > new file mode 100644 > index 0000000000..a8ecf8aede > --- /dev/null > +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExDxeExtra.uni > @@ -0,0 +1,15 @@ > +// /** @file > +// RestExDxe Localized Strings and Content > +// > +// Copyright (c) 2019, Intel Corporation. All rights reserved.
> +// (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> +// > +// SPDX-License-Identifier: BSD-2-Clause-Patent > +// > +// **/ > + > +#string STR_PROPERTIES_MODULE_NAME > +#language en-US > +"Redfish UEFI RESTEX DXE" > + > + > diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c > b/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c > new file mode 100644 > index 0000000000..006b64adc0 > --- /dev/null > +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExImpl.c > @@ -0,0 +1,157 @@ > +/** @file > + RestExDxe support functions implementation. > + > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > +#include > +#include "RedfishRestExInternal.h" > + > +/** > + Create a new TLS session becuase the previous on is closed. > + status. > + > + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instan= ce > for a particular > + REST service. > + @retval EFI_SUCCESS operation succeeded. > + @retval EFI_ERROR Other errors. > + > +**/ > +EFI_STATUS > +ResetHttpTslSession ( > + IN RESTEX_INSTANCE *Instance > +) > +{ > + EFI_STATUS Status; > + > + DEBUG ((DEBUG_INFO, "%a: TCP connection is finished. Could be TSL > session closure, reset HTTP instance for the new TLS session.\n", > __FUNCTION__)); > + > + Status =3D Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, NU= LL); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Error to reset HTTP instance.\n", > __FUNCTION__)); > + return Status; > + } > + Status =3D Instance->HttpIo.Http->Configure(Instance->HttpIo.Http, > &((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)- > >HttpConfigData); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Error to re-initiate HTTP instance.\n", > __FUNCTION__)); > + } > + return Status; > +} > +/** > + This function check > + > + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL insta= nce > for a particular > + REST service. > + @param[in] HttpIoReceiveStatus This is the status return from > HttpIoRecvResponse > + > + @retval EFI_SUCCESS The payload receive from Redfish service= in > sucessfully. > + @retval EFI_NOT_READY May need to resend the HTTP request. > + @retval EFI_DEVICE_ERROR Something wrong and can't be resolved. > + @retval Others Other errors as indicated. > + > +**/ > +EFI_STATUS > +RedfishCheckHttpReceiveStatus ( > + IN RESTEX_INSTANCE *Instance, > + IN EFI_STATUS HttpIoReceiveStatus > + ) > +{ > + EFI_STATUS Status; > + EFI_STATUS ReturnStatus; > + > + if (!EFI_ERROR (HttpIoReceiveStatus)){ > + ReturnStatus =3D EFI_SUCCESS; > + } else if (EFI_ERROR (HttpIoReceiveStatus) && HttpIoReceiveStatus !=3D > EFI_CONNECTION_FIN) { > + if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY) =3D=3D > 0) { > + DEBUG ((DEBUG_ERROR, "%a: TCP error, reset HTTP session.\n", > __FUNCTION__)); > + Instance->Flags |=3D RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY; > + gBS->Stall (500); > + Status =3D ResetHttpTslSession (Instance); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", > __FUNCTION__)); > + ReturnStatus =3D EFI_DEVICE_ERROR; > + } else { > + return EFI_NOT_READY; > + } > + } else { > + ReturnStatus =3D EFI_DEVICE_ERROR; > + } > + } else { > + if (HttpIoReceiveStatus =3D=3D EFI_CONNECTION_FIN) { > + if ((Instance->Flags & RESTEX_INSTANCE_FLAGS_TLS_RETRY) !=3D 0) { > + DEBUG ((DEBUG_ERROR, "%a: REST_EX Send and receive fail even > with a new TLS session.\n", __FUNCTION__)); > + ReturnStatus =3D EFI_DEVICE_ERROR; > + } > + Instance->Flags |=3D RESTEX_INSTANCE_FLAGS_TLS_RETRY; > + Status =3D ResetHttpTslSession (Instance); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Reset HTTP instance fail.\n", > __FUNCTION__)); > + ReturnStatus =3D EFI_DEVICE_ERROR; > + } > + return EFI_NOT_READY; > + } > + } > + // > + // Clean TLS new session retry and error try flags. > + // > + Instance->Flags &=3D ~ (RESTEX_INSTANCE_FLAGS_TLS_RETRY | > RESTEX_INSTANCE_FLAGS_TCP_ERROR_RETRY); > + return ReturnStatus; > +} > + > +/** > + This function send the HTTP request without body to see > + if the write to URL is permitted by Redfish service. This function > + checks if the HTTP request has Content-length in HTTP header. If yes, > + set HTTP body to NULL and then send to service. Check the HTTP status > + for the firther actions. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL in= stance for > a particular > + REST service. > + @param[in] RequestMessage Pointer to the HTTP request data f= or > this resource > + @param[in] PreservedRequestHeaders The pointer to save the request > headers > + @param[in] ItsWrite This is write method to URL. > + > + @retval EFI_INVALID_PARAMETER Improper given parameters. > + @retval EFI_SUCCESS This HTTP request is free to send to Re= dfish > service. > + @retval EFI_OUT_OF_RESOURCES NOt enough memory to process. > + @retval EFI_ACCESS_DENIED Not allowed to write to this URL. > + > + @retval Others Other errors as indicated. > + > +**/ > +EFI_STATUS > +RedfishHttpAddExpectation ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage, > + IN EFI_HTTP_HEADER **PreservedRequestHeaders, > + IN BOOLEAN *ItsWrite > + ) > +{ > + EFI_HTTP_HEADER *NewHeaders; > + > + if (This =3D=3D NULL || RequestMessage =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + *ItsWrite =3D FALSE; > + if (PreservedRequestHeaders !=3D NULL) { > + *PreservedRequestHeaders =3D RequestMessage->Headers; > + } > + > + if ((RequestMessage->Data.Request->Method !=3D HttpMethodPut) && > (RequestMessage->Data.Request->Method !=3D HttpMethodPost) && > + (RequestMessage->Data.Request->Method !=3D HttpMethodPatch)) { > + return EFI_SUCCESS; > + } > + *ItsWrite =3D TRUE; > + > + NewHeaders =3D AllocateZeroPool((RequestMessage->HeaderCount + 1) * > sizeof(EFI_HTTP_HEADER)); > + CopyMem ((VOID*)NewHeaders, (VOID *)RequestMessage->Headers, > RequestMessage->HeaderCount * sizeof (EFI_HTTP_HEADER)); > + HttpSetFieldNameAndValue (NewHeaders + RequestMessage- > >HeaderCount, HTTP_HEADER_EXPECT, HTTP_EXPECT_100_CONTINUE); > + RequestMessage->HeaderCount ++; > + RequestMessage->Headers =3D NewHeaders; > + return EFI_SUCCESS; > +} > + > diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExInternal.h > b/RedfishPkg/RedfishRestExDxe/RedfishRestExInternal.h > new file mode 100644 > index 0000000000..a75985928c > --- /dev/null > +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExInternal.h > @@ -0,0 +1,611 @@ > +/** @file > + RedfishRestExDxe support functions definitions. > + > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> + (C) Copyright 2019-2020 Hewlett Packard Enterprise Development LP
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef EFI_REDFISH_RESTEX_INTERNAL_H_ > +#define EFI_REDFISH_RESTEX_INTERNAL_H_ > + > +/// > +/// Libraries classes > +/// > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/// > +/// UEFI Driver Model Protocols > +/// > +#include > +#include > +#include > + > +#include "RedfishRestExDriver.h" > + > +/** > + This function check > + > + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instance= for > a particular > + REST service. > + @param[in] HttpReceiveEfiStatus This is the status return from > HttpIoRecvResponse > + > + @retval EFI_SUCCESS The payload receive from Redfish service= in > sucessfully. > + @retval EFI_NOT_READY May need to resend the HTTP request. > + @retval EFI_DEVICE_ERROR Something wrong and can't be resolved. > + @retval Others Other errors as indicated. > + > +**/ > +EFI_STATUS > +RedfishCheckHttpReceiveStatus ( > + IN RESTEX_INSTANCE *Instance, > + IN EFI_STATUS HttpIoReceiveStatus > + ); > + > +/** > + This function send the HTTP request without body to see > + if the write to URL is permitted by Redfish service. This function > + checks if the HTTP request has Content-length in HTTP header. If yes, > + set HTTP body to NULL and then send to service. Check the HTTP status > + for the firther actions. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL in= stance for > a particular > + REST service. > + @param[in] RequestMessage Pointer to the HTTP request data f= or > this resource > + @param[in] PreservedRequestHeaders The pointer to save the request > headers > + @param[in] ItsWrite This is write method to URL. > + > + @retval EFI_INVALID_PARAMETER Improper given parameters. > + @retval EFI_SUCCESS This HTTP request is free to send to Re= dfish > service. > + @retval EFI_OUT_OF_RESOURCES NOt enough memory to process. > + @retval EFI_ACCESS_DENIED Not allowed to write to this URL. > + > + @retval Others Other errors as indicated. > + > +**/ > +EFI_STATUS > +RedfishHttpAddExpectation ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage, > + IN EFI_HTTP_HEADER **PreservedRequestHeaders, > + IN BOOLEAN *ItsWrite > + ); > + > +/** > + Provides a simple HTTP-like interface to send and receive resources fr= om a > REST service. > + > + The SendReceive() function sends an HTTP request to this REST service, > and returns a > + response when the data is retrieved from the service. RequestMessage > contains the HTTP > + request to the REST resource identified by RequestMessage.Request.Url. > The > + ResponseMessage is the returned HTTP response for that request, > including any HTTP > + status. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instan= ce for a > particular > + REST service. > + @param[in] RequestMessage Pointer to the HTTP request data for t= his > resource > + @param[out] ResponseMessage Pointer to the HTTP response data > obtained for this requested. > + > + @retval EFI_SUCCESS operation succeeded. > + @retval EFI_INVALID_PARAMETER This, RequestMessage, or > ResponseMessage are NULL. > + @retval EFI_DEVICE_ERROR An unexpected system or network error > occurred. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExSendReceive ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage, > + OUT EFI_HTTP_MESSAGE *ResponseMessage > + ); > + > +/** > + Obtain the current time from this REST service instance. > + > + The GetServiceTime() function is an optional interface to obtain the > current time from > + this REST service instance. If this REST service does not support to r= etrieve > the time, > + this function returns EFI_UNSUPPORTED. This function must returns > EFI_UNSUPPORTED if > + EFI_REST_EX_SERVICE_TYPE returned in EFI_REST_EX_SERVICE_INFO from > GetService() is > + EFI_REST_EX_SERVICE_UNSPECIFIC. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instan= ce for a > particular > + REST service. > + @param[out] Time A pointer to storage to receive a snap= shot of > the current time of > + the REST service. > + > + @retval EFI_SUCCESS operation succeeded. > + @retval EFI_INVALID_PARAMETER This or Time are NULL. > + @retval EFI_UNSUPPORTED The RESTful service does not support > returning the time. > + @retval EFI_DEVICE_ERROR An unexpected system or network error > occurred. > + @retval EFI_NOT_READY The configuration of this instance is = not set > yet. Configure() must > + be executed and returns successfully p= rior to invoke this > function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExGetServiceTime ( > + IN EFI_REST_EX_PROTOCOL *This, > + OUT EFI_TIME *Time > + ); > + > +/** > + This function returns the information of REST service provided by this= EFI > REST EX driver instance. > + > + The information such as the type of REST service and the access mode of > REST EX driver instance > + (In-band or Out-of-band) are described in EFI_REST_EX_SERVICE_INFO > structure. For the vendor-specific > + REST service, vendor-specific REST service information is returned in > VendorSpecifcData. > + REST EX driver designer is well know what REST service this REST EX dr= iver > instance intends to > + communicate with. The designer also well know this driver instance is = used > to talk to BMC through > + specific platform mechanism or talk to REST server through UEFI HTTP > protocol. REST EX driver is > + responsible to fill up the correct information in > EFI_REST_EX_SERVICE_INFO. EFI_REST_EX_SERVICE_INFO > + is referred by EFI REST clients to pickup the proper EFI REST EX driver > instance to get and set resource. > + GetService() is a basic and mandatory function which must be able to u= se > even Configure() is not invoked > + in previously. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instan= ce for a > particular > + REST service. > + @param[out] RestExServiceInfo Pointer to receive a pointer to > EFI_REST_EX_SERVICE_INFO structure. The > + format of EFI_REST_EX_SERVICE_INFO is = version > controlled for the future > + extension. The version of EFI_REST_EX_= SERVICE_INFO > structure is returned > + in the header within this structure. E= FI REST client refers to > the correct > + format of structure according to the v= ersion number. The > pointer to > + EFI_REST_EX_SERVICE_INFO is a memory b= lock allocated > by EFI REST EX driver > + instance. That is caller's responsibil= ity to free this memory > when this > + structure is no longer needed. Refer t= o Related Definitions > below for the > + definitions of EFI_REST_EX_SERVICE_INF= O structure. > + > + @retval EFI_SUCCESS EFI_REST_EX_SERVICE_INFO is returned in > RestExServiceInfo. This function > + is not supported in this REST EX Proto= col driver instance. > + @retval EFI_UNSUPPORTED This function is not supported in this= REST > EX Protocol driver instance. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExGetService ( > + IN EFI_REST_EX_PROTOCOL *This, > + OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo > + ); > + > +/** > + This function returns operational configuration of current EFI REST EX= child > instance. > + > + This function returns the current configuration of EFI REST EX child i= nstance. > The format of > + operational configuration depends on the implementation of EFI REST EX > driver instance. For > + example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol= as > the undying protocol > + to communicate with REST service. In this case, the type of configurat= ion is > + EFI_REST_EX_CONFIG_TYPE_HTTP returned from GetService(). > EFI_HTTP_CONFIG_DATA is used as EFI REST > + EX configuration format and returned to EFI REST client. User has to t= ype > cast RestExConfigData > + to EFI_HTTP_CONFIG_DATA. For those non HTTP-aware REST EX driver > instances, the type of configuration > + is EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC returned from GetService(). In > this case, the format of > + returning data could be non industrial. Instead, the format of configu= ration > data is system/platform > + specific definition such as BMC mechanism used in EFI REST EX driver > instance. EFI REST client and > + EFI REST EX driver instance have to refer to the specific system /plat= form > spec which is out of UEFI scope. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL insta= nce. > + @param[out] RestExConfigData Pointer to receive a pointer to > EFI_REST_EX_CONFIG_DATA. > + The memory allocated for configuration= data should be > freed > + by caller. See Related Definitions for= the details. > + > + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is returned in > successfully. > + @retval EFI_UNSUPPORTED This function is not supported in this= REST > EX Protocol driver instance. > + @retval EFI_NOT_READY The configuration of this instance is = not set > yet. Configure() must be > + executed and returns successfully prio= r to invoke this > function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExGetModeData ( > + IN EFI_REST_EX_PROTOCOL *This, > + OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData > + ); > + > +/** > + This function is used to configure EFI REST EX child instance. > + > + This function is used to configure the setting of underlying protocol = of REST > EX child > + instance. The type of configuration is according to the implementation= of > EFI REST EX > + driver instance. For example, HTTP-aware EFI REST EX driver instance u= ses > EFI HTTP protocol > + as the undying protocol to communicate with REST service. The type of > configuration is > + EFI_REST_EX_CONFIG_TYPE_HTTP and RestExConfigData is the same > format with EFI_HTTP_CONFIG_DATA. > + Akin to HTTP configuration, REST EX child instance can be configure to= use > different HTTP > + local access point for the data transmission. Multiple REST clients ma= y use > different > + configuration of HTTP to distinguish themselves, such as to use the > different TCP port. > + For those non HTTP-aware REST EX driver instance, the type of > configuration is > + EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC. RestExConfigData refers to the > non industrial standard. > + Instead, the format of configuration data is system/platform specific > definition such as BMC. > + In this case, EFI REST client and EFI REST EX driver instance have to = refer to > the specific > + system/platform spec which is out of the UEFI scope. Besides > GetService()function, no other > + EFI REST EX functions can be executed by this instance until Configure= ()is > executed and returns > + successfully. All other functions must returns EFI_NOT_READY if this > instance is not configured > + yet. Set RestExConfigData to NULL means to put EFI REST EX child insta= nce > into the unconfigured > + state. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL insta= nce. > + @param[in] RestExConfigData Pointer to EFI_REST_EX_CONFIG_DATA. > See Related Definitions in > + GetModeData() protocol interface. > + > + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is set in > successfully. > + @retval EFI_DEVICE_ERROR Configuration for this REST EX child > instance is failed with the given > + EFI_REST_EX_CONFIG_DATA. > + @retval EFI_UNSUPPORTED This function is not supported in this= REST > EX Protocol driver instance. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExConfigure ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_REST_EX_CONFIG_DATA RestExConfigData > + ); > + > +/** > + This function sends REST request to REST service and signal caller's e= vent > asynchronously when > + the final response is received by REST EX Protocol driver instance. > + > + The essential design of this function is to handle asynchronous > send/receive implicitly according > + to REST service asynchronous request mechanism. Caller will get the > notification once the response > + is returned from REST service. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL ins= tance. > + @param[in] RequestMessage This is the HTTP request message sent > to REST service. Set RequestMessage > + to NULL to cancel the previous async= hronous request > associated with the > + corresponding RestExToken. See descr= iptions for the > details. > + @param[in] RestExToken REST EX token which REST EX Protocol > instance uses to notify REST client > + the status of response of asynchrono= us REST request. See > related definition > + of EFI_REST_EX_TOKEN. > + @param[in] TimeOutInMilliSeconds The pointer to the timeout in > milliseconds which REST EX Protocol driver > + instance refers as the duration to d= rop asynchronous REST > request. NULL > + pointer means no timeout for this RE= ST request. REST EX > Protocol driver > + signals caller's event with EFI_STAT= US set to EFI_TIMEOUT > in RestExToken > + if REST EX Protocol can't get the re= sponse from REST > service within > + TimeOutInMilliSeconds. > + > + @retval EFI_SUCCESS Asynchronous REST request is establi= shed. > + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance > doesn't support asynchronous request. > + @retval EFI_TIMEOUT Asynchronous REST request is not > established and timeout is expired. > + @retval EFI_ABORT Previous asynchronous REST request h= as been > canceled. > + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR > for other errors according to HTTP Status Code. > + @retval EFI_NOT_READY The configuration of this instance i= s not set > yet. Configure() must be executed > + and returns successfully prior to in= voke this function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExAyncSendReceive ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, > + IN EFI_REST_EX_TOKEN *RestExToken, > + IN UINTN *TimeOutInMilliSeconds OPTIONAL > + ); > + > +/** > + This function sends REST request to a REST Event service and signals c= aller's > event > + token asynchronously when the URI resource change event is received by > REST EX > + Protocol driver instance. > + > + The essential design of this function is to monitor event implicitly a= ccording > to > + REST service event service mechanism. Caller will get the notification= if > certain > + resource is changed. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL ins= tance. > + @param[in] RequestMessage This is the HTTP request message sent > to REST service. Set RequestMessage > + to NULL to cancel the previous event= service associated > with the corresponding > + RestExToken. See descriptions for th= e details. > + @param[in] RestExToken REST EX token which REST EX Protocol > driver instance uses to notify REST client > + the URI resource which monitored by = REST client has > been changed. See the related > + definition of EFI_REST_EX_TOKEN in > EFI_REST_EX_PROTOCOL.AsyncSendReceive(). > + > + @retval EFI_SUCCESS Asynchronous REST request is establi= shed. > + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance > doesn't support asynchronous request. > + @retval EFI_ABORT Previous asynchronous REST request h= as been > canceled or event subscription has been > + delete from service. > + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR > for other errors according to HTTP Status Code. > + @retval EFI_NOT_READY The configuration of this instance i= s not set > yet. Configure() must be executed > + and returns successfully prior to in= voke this function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExEventService ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, > + IN EFI_REST_EX_TOKEN *RestExToken > + ); > +/** > + Create a new TLS session becuase the previous on is closed. > + status. > + > + @param[in] Instance Pointer to EFI_REST_EX_PROTOCOL instan= ce > for a particular > + REST service. > + @retval EFI_SUCCESS operation succeeded. > + @retval EFI Errors Other errors. > + > +**/ > +EFI_STATUS > +ResetHttpTslSession ( > + IN RESTEX_INSTANCE *Instance > +); > + > + > +/** > + Callback function which provided by user to remove one node in > NetDestroyLinkList process. > + > + @param[in] Entry The entry to be removed. > + @param[in] Context Pointer to the callback context correspo= nds to > the Context in NetDestroyLinkList. > + > + @retval EFI_SUCCESS The entry has been removed successfully. > + @retval Others Fail to remove the entry. > + > +**/ > +EFI_STATUS > +EFIAPI > +RestExDestroyChildEntryInHandleBuffer ( > + IN LIST_ENTRY *Entry, > + IN VOID *Context > + ); > + > +/** > + Destroy the RestEx instance and recycle the resources. > + > + @param[in] Instance The pointer to the RestEx instance. > + > +**/ > +VOID > +RestExDestroyInstance ( > + IN RESTEX_INSTANCE *Instance > + ); > + > +/** > + Create the RestEx instance and initialize it. > + > + @param[in] Service The pointer to the RestEx service. > + @param[out] Instance The pointer to the RestEx instance. > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. > + @retval EFI_SUCCESS The RestEx instance is created. > + > +**/ > +EFI_STATUS > +RestExCreateInstance ( > + IN RESTEX_SERVICE *Service, > + OUT RESTEX_INSTANCE **Instance > + ); > + > + > +/** > + Release all the resource used the RestEx service binding instance. > + > + @param[in] RestExSb The RestEx service binding instance. > + > +**/ > +VOID > +RestExDestroyService ( > + IN RESTEX_SERVICE *RestExSb > + ); > + > +/** > + Create then initialize a RestEx service binding instance. > + > + @param[in] Controller The controller to install the RestEx ser= vice > + binding on. > + @param[in] Image The driver binding image of the RestEx d= river. > + @param[out] Service The variable to receive the created serv= ice > + binding instance. > + > + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create > the instance. > + @retval EFI_SUCCESS The service instance is created for the > controller. > + > +**/ > +EFI_STATUS > +RestExCreateService ( > + IN EFI_HANDLE Controller, > + IN EFI_HANDLE Image, > + OUT RESTEX_SERVICE **Service > + ); > + > +/** > + This is the declaration of an EFI image entry point. This entry point = is > + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers incl= uding > + both device drivers and bus drivers. > + > + @param[in] ImageHandle The firmware allocated handle for the UEFI > image. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS The operation completed successfully. > + @retval Others An unexpected error occurred. > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverEntryPoint ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ); > + > +/** > + Tests to see if this driver supports a given controller. If a child de= vice is > provided, > + it further tests to see if this driver supports creating a handle for = the > specified child device. > + > + This function checks to see if the driver specified by This supports t= he > device specified by > + ControllerHandle. Drivers will typically use the device path attached = to > + ControllerHandle and/or the services from the bus I/O abstraction > attached to > + ControllerHandle to determine if the driver supports ControllerHandle. > This function > + may be called many times during platform initialization. In order to r= educe > boot times, the tests > + performed by this function must be very small, and take as little time= as > possible to execute. This > + function must not change the state of any hardware devices, and this > function must be aware that the > + device specified by ControllerHandle may already be managed by the > same driver or a > + different driver. This function must match its calls to AllocatePages(= ) with > FreePages(), > + AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol(= ). > + Because ControllerHandle may have been previously started by the same > driver, if a protocol is > + already in the opened state, then it must not be closed with > CloseProtocol(). This is required > + to guarantee the state of ControllerHandle is not modified by this fun= ction. > + > + @param[in] This A pointer to the > EFI_DRIVER_BINDING_PROTOCOL instance. > + @param[in] ControllerHandle The handle of the controller to test.= This > handle > + must support a protocol interface tha= t supplies > + an I/O abstraction to the driver. > + @param[in] RemainingDevicePath A pointer to the remaining portion of= a > device path. This > + parameter is ignored by device driver= s, and is optional for > bus > + drivers. For bus drivers, if this par= ameter is not NULL, then > + the bus driver must determine if the = bus controller > specified > + by ControllerHandle and the child con= troller specified > + by RemainingDevicePath are both suppo= rted by this > + bus driver. > + > + @retval EFI_SUCCESS The device specified by ControllerHan= dle and > + RemainingDevicePath is supported by t= he driver specified > by This. > + @retval EFI_ALREADY_STARTED The device specified by > ControllerHandle and > + RemainingDevicePath is already being = managed by the > driver > + specified by This. > + @retval EFI_ACCESS_DENIED The device specified by ControllerHan= dle > and > + RemainingDevicePath is already being = managed by a > different > + driver or an application that require= s exclusive access. > + Currently not implemented. > + @retval EFI_UNSUPPORTED The device specified by ControllerHan= dle > and > + RemainingDevicePath is not supported = by the driver > specified by This. > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverBindingSupported ( > + IN EFI_DRIVER_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL > + ); > + > +/** > + Starts a device controller or a bus controller. > + > + The Start() function is designed to be invoked from the EFI boot servi= ce > ConnectController(). > + As a result, much of the error checking on the parameters to Start() h= as > been moved into this > + common boot service. It is legal to call Start() from other locations, > + but the following calling restrictions must be followed, or the system > behavior will not be deterministic. > + 1. ControllerHandle must be a valid EFI_HANDLE. > + 2. If RemainingDevicePath is not NULL, then it must be a pointer to a > naturally aligned > + EFI_DEVICE_PATH_PROTOCOL. > + 3. Prior to calling Start(), the Supported() function for the driver s= pecified > by This must > + have been called with the same calling parameters, and Supported() > must have returned EFI_SUCCESS. > + > + @param[in] This A pointer to the > EFI_DRIVER_BINDING_PROTOCOL instance. > + @param[in] ControllerHandle The handle of the controller to start= . This > handle > + must support a protocol interface tha= t supplies > + an I/O abstraction to the driver. > + @param[in] RemainingDevicePath A pointer to the remaining portion of= a > device path. This > + parameter is ignored by device driver= s, and is optional for > bus > + drivers. For a bus driver, if this pa= rameter is NULL, then > handles > + for all the children of Controller ar= e created by this driver. > + If this parameter is not NULL and the= first Device Path > Node is > + not the End of Device Path Node, then= only the handle for > the > + child device specified by the first D= evice Path Node of > + RemainingDevicePath is created by thi= s driver. > + If the first Device Path Node of Rema= iningDevicePath is > + the End of Device Path Node, no child= handle is created by > this > + driver. > + > + @retval EFI_SUCCESS The device was started. > + @retval EFI_DEVICE_ERROR The device could not be started due t= o a > device error.Currently not implemented. > + @retval EFI_OUT_OF_RESOURCES The request could not be completed > due to a lack of resources. > + @retval Others The driver failded to start the devic= e. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverBindingStart ( > + IN EFI_DRIVER_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL > + ); > + > +/** > + Stops a device controller or a bus controller. > + > + The Stop() function is designed to be invoked from the EFI boot service > DisconnectController(). > + As a result, much of the error checking on the parameters to Stop() has > been moved > + into this common boot service. It is legal to call Stop() from other l= ocations, > + but the following calling restrictions must be followed, or the system > behavior will not be deterministic. > + 1. ControllerHandle must be a valid EFI_HANDLE that was used on a > previous call to this > + same driver's Start() function. > + 2. The first NumberOfChildren handles of ChildHandleBuffer must all be= a > valid > + EFI_HANDLE. In addition, all of these handles must have been create= d in > this driver's > + Start() function, and the Start() function must have called OpenPro= tocol() > on > + ControllerHandle with an Attribute of > EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER. > + > + @param[in] This A pointer to the EFI_DRIVER_BINDING_PROT= OCOL > instance. > + @param[in] ControllerHandle A handle to the device being stopped. The > handle must > + support a bus specific I/O protocol for = the driver > + to use to stop the device. > + @param[in] NumberOfChildren The number of child device handles in > ChildHandleBuffer. > + @param[in] ChildHandleBuffer An array of child handles to be freed. M= ay > be NULL > + if NumberOfChildren is 0. > + > + @retval EFI_SUCCESS The device was stopped. > + @retval EFI_DEVICE_ERROR The device could not be stopped due to a > device error. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExDriverBindingStop ( > + IN EFI_DRIVER_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ControllerHandle, > + IN UINTN NumberOfChildren, > + IN EFI_HANDLE *ChildHandleBuffer OPTIONAL > + ); > + > +/** > + Creates a child handle and installs a protocol. > + > + The CreateChild() function installs a protocol on ChildHandle. > + If ChildHandle is a pointer to NULL, then a new handle is created and > returned in ChildHandle. > + If ChildHandle is not a pointer to NULL, then the protocol installs on= the > existing ChildHandle. > + > + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param[in] ChildHandle Pointer to the handle of the child to create. I= f it is > NULL, > + then a new handle is created. If it is a pointe= r to an existing > UEFI handle, > + then the protocol is added to the existing UEFI= handle. > + > + @retval EFI_SUCCES The protocol was added to ChildHandle. > + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > available to create > + the child > + @retval other The child handle was not created > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExServiceBindingCreateChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE *ChildHandle > + ); > + > +/** > + Destroys a child handle with a protocol installed on it. > + > + The DestroyChild() function does the opposite of CreateChild(). It rem= oves > a protocol > + that was installed by CreateChild() from ChildHandle. If the removed > protocol is the > + last protocol on ChildHandle, then ChildHandle is destroyed. > + > + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL > instance. > + @param[in] ChildHandle Handle of the child to destroy > + > + @retval EFI_SUCCES The protocol was removed from ChildHandl= e. > + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol > that is being removed. > + @retval EFI_INVALID_PARAMETER Child handle is NULL. > + @retval EFI_ACCESS_DENIED The protocol could not be removed from > the ChildHandle > + because its services are being used. > + @retval other The child handle was not destroyed > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExServiceBindingDestroyChild ( > + IN EFI_SERVICE_BINDING_PROTOCOL *This, > + IN EFI_HANDLE ChildHandle > + ); > +#endif > diff --git a/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c > b/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c > new file mode 100644 > index 0000000000..65a5fe3713 > --- /dev/null > +++ b/RedfishPkg/RedfishRestExDxe/RedfishRestExProtocol.c > @@ -0,0 +1,735 @@ > +/** @file > + Implementation of Redfish EFI_REST_EX_PROTOCOL interfaces. > + > + Copyright (c) 2019, Intel Corporation. All rights reserved.
> + (C) Copyright 2020 Hewlett Packard Enterprise Development LP
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > +#include > +#include "RedfishRestExInternal.h" > + > +EFI_REST_EX_PROTOCOL mRedfishRestExProtocol =3D { > + RedfishRestExSendReceive, > + RedfishRestExGetServiceTime, > + RedfishRestExGetService, > + RedfishRestExGetModeData, > + RedfishRestExConfigure, > + RedfishRestExAyncSendReceive, > + RedfishRestExEventService > +}; > + > +/** > + Provides a simple HTTP-like interface to send and receive resources fr= om a > REST service. > + > + The SendReceive() function sends an HTTP request to this REST service, > and returns a > + response when the data is retrieved from the service. RequestMessage > contains the HTTP > + request to the REST resource identified by RequestMessage.Request.Url. > The > + ResponseMessage is the returned HTTP response for that request, > including any HTTP > + status. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instan= ce for a > particular > + REST service. > + @param[in] RequestMessage Pointer to the HTTP request data for t= his > resource > + @param[out] ResponseMessage Pointer to the HTTP response data > obtained for this requested. > + > + @retval EFI_SUCCESS operation succeeded. > + @retval EFI_INVALID_PARAMETER This, RequestMessage, or > ResponseMessage are NULL. > + @retval EFI_DEVICE_ERROR An unexpected system or network error > occurred. > + @retval EFI_ACCESS_DENIED HTTP method is not allowed on this URL. > + @retval EFI_BAD_BUFFER_SIZE The payload is to large to be handled = on > server side. > + @retval EFI_UNSUPPORTED Unsupported HTTP response. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExSendReceive ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage, > + OUT EFI_HTTP_MESSAGE *ResponseMessage > + ) > +{ > + EFI_STATUS Status; > + RESTEX_INSTANCE *Instance; > + HTTP_IO_RESPONSE_DATA *ResponseData; > + UINTN TotalReceivedSize; > + UINTN Index; > + LIST_ENTRY *ChunkListLink; > + HTTP_IO_CHUNKS *ThisChunk; > + BOOLEAN CopyChunkData; > + BOOLEAN MediaPresent; > + EFI_HTTP_HEADER *PreservedRequestHeaders; > + BOOLEAN ItsWrite; > + BOOLEAN IsGetChunkedTransfer; > + HTTP_IO_SEND_CHUNK_PROCESS SendChunkProcess; > + HTTP_IO_SEND_NON_CHUNK_PROCESS SendNonChunkProcess; > + EFI_HTTP_MESSAGE ChunkTransferRequestMessage; > + > + Status =3D EFI_SUCCESS; > + ResponseData =3D NULL; > + IsGetChunkedTransfer =3D FALSE; > + SendChunkProcess =3D HttpIoSendChunkNone; > + SendNonChunkProcess =3D HttpIoSendNonChunkNone; > + > + // > + // Validate the parameters > + // > + if ((This =3D=3D NULL) || (RequestMessage =3D=3D NULL) || ResponseMess= age =3D=3D > NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Instance =3D RESTEX_INSTANCE_FROM_THIS (This); > + > + // > + // Check Media Status. > + // > + MediaPresent =3D TRUE; > + NetLibDetectMedia (Instance->Service->ControllerHandle, > &MediaPresent); > + if (!MediaPresent) { > + DEBUG ((DEBUG_INFO, "RedfishRestExSendReceive(): No > MediaPresent.\n")); > + return EFI_NO_MEDIA; > + } > + > + DEBUG ((DEBUG_INFO, "\nRedfishRestExSendReceive():\n")); > + DEBUG ((DEBUG_INFO, "*** Perform HTTP Request Method - %d, URL: > %s\n", RequestMessage->Data.Request->Method, RequestMessage- > >Data.Request->Url)); > + > + // > + // Add header "Expect" to server, only for URL write. > + // > + Status =3D RedfishHttpAddExpectation (This, RequestMessage, > &PreservedRequestHeaders, &ItsWrite); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + if (ItsWrite =3D=3D TRUE) { > + if (RequestMessage->BodyLength > HTTP_IO_MAX_SEND_PAYLOAD) { > + // > + // Send chunked transfer. > + // > + SendChunkProcess ++; > + CopyMem ((VOID *)&ChunkTransferRequestMessage, (VOID > *)RequestMessage, sizeof (EFI_HTTP_MESSAGE)); > + } else { > + SendNonChunkProcess ++; > + } > + } > +ReSendRequest:; > + // > + // Send out the request to REST service. > + // > + if (ItsWrite =3D=3D TRUE) { > + // > + // This is write to URI > + // > + if (SendChunkProcess > HttpIoSendChunkNone) { > + // > + // This is chunk transfer for writing large payload. > + // Send request header first and then handle the > + // following request message body using chunk transfer. > + // > + do { > + Status =3D HttpIoSendChunkedTransfer( > + &(Instance->HttpIo), > + &SendChunkProcess, > + &ChunkTransferRequestMessage > + ); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + } while (SendChunkProcess =3D=3D HttpIoSendChunkContent || > SendChunkProcess =3D=3D HttpIoSendChunkEndChunk); > + } else { > + // > + // This is the non-chunk transfer, send request header first and t= hen > + // handle the following request message body using chunk transfer. > + // > + Status =3D HttpIoSendRequest( > + &(Instance->HttpIo), > + (SendNonChunkProcess =3D=3D HttpIoSendNonChunkContent)?= NULL: > RequestMessage->Data.Request, > + (SendNonChunkProcess =3D=3D HttpIoSendNonChunkContent)?= 0: > RequestMessage->HeaderCount, > + (SendNonChunkProcess =3D=3D HttpIoSendNonChunkContent)?= NULL: > RequestMessage->Headers, > + (SendNonChunkProcess =3D=3D > HttpIoSendNonChunkHeaderZeroContent)? 0: RequestMessage- > >BodyLength, > + (SendNonChunkProcess =3D=3D > HttpIoSendNonChunkHeaderZeroContent)? NULL: RequestMessage->Body > + ); > + } > + } else { > + // > + // This is read from URI. > + // > + Status =3D HttpIoSendRequest( > + &(Instance->HttpIo), > + RequestMessage->Data.Request, > + RequestMessage->HeaderCount, > + RequestMessage->Headers, > + RequestMessage->BodyLength, > + RequestMessage->Body > + ); > + } > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + // > + // ResponseMessage->Data.Response is to indicate whether to receive > the HTTP header or not. > + // ResponseMessage->BodyLength/ResponseMessage->Body are to > indicate whether to receive the response body or not. > + // Clean the previous buffers and all of them will be allocated later > according to the actual situation. > + // > + if (ResponseMessage->Data.Response !=3D NULL) { > + FreePool(ResponseMessage->Data.Response); > + ResponseMessage->Data.Response =3D NULL; > + } > + > + ResponseMessage->BodyLength =3D 0; > + if (ResponseMessage->Body !=3D NULL) { > + FreePool(ResponseMessage->Body); > + ResponseMessage->Body =3D NULL; > + } > + > + // > + // Use zero BodyLength to only receive the response headers. > + // > + ResponseData =3D AllocateZeroPool (sizeof(HTTP_IO_RESPONSE_DATA)); > + if (ResponseData =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + > + DEBUG ((DEBUG_INFO, "Receiving HTTP response and headers...\n")); > + Status =3D RedfishCheckHttpReceiveStatus ( > + Instance, > + HttpIoRecvResponse ( > + &(Instance->HttpIo), > + TRUE, > + ResponseData > + ) > + ); > + if (Status =3D=3D EFI_NOT_READY) { > + goto ReSendRequest; > + } else if (Status =3D=3D EFI_DEVICE_ERROR) { > + goto ON_EXIT; > + } > + // > + // Restore the headers if it ever changed in RedfishHttpAddExpectation= (). > + // > + if (RequestMessage->Headers !=3D PreservedRequestHeaders) { > + FreePool (RequestMessage->Headers); > + RequestMessage->Headers =3D PreservedRequestHeaders; // Restore > headers before we adding "Expect". > + RequestMessage->HeaderCount --; // Minus one head= er count > for "Expect". > + } > + > + DEBUG ((DEBUG_INFO, "HTTP Response StatusCode - %d:", > ResponseData->Response.StatusCode)); > + if (ResponseData->Response.StatusCode =3D=3D HTTP_STATUS_200_OK) { > + DEBUG ((DEBUG_INFO, "HTTP_STATUS_200_OK\n")); > + > + if (SendChunkProcess =3D=3D HttpIoSendChunkHeaderZeroContent) { > + DEBUG ((DEBUG_INFO, "This is chunk transfer, start to send all chu= nks.", > ResponseData->Response.StatusCode)); > + SendChunkProcess ++; > + goto ReSendRequest; > + } > + } else if (ResponseData->Response.StatusCode =3D=3D > HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE) { > + DEBUG ((DEBUG_INFO, > "HTTP_STATUS_413_REQUEST_ENTITY_TOO_LARGE\n")); > + > + Status =3D EFI_BAD_BUFFER_SIZE; > + goto ON_EXIT; > + } else if (ResponseData->Response.StatusCode =3D=3D > HTTP_STATUS_405_METHOD_NOT_ALLOWED){ > + DEBUG ((DEBUG_ERROR, > "HTTP_STATUS_405_METHOD_NOT_ALLOWED\n")); > + > + Status =3D EFI_ACCESS_DENIED; > + goto ON_EXIT; > + } else if (ResponseData->Response.StatusCode =3D=3D > HTTP_STATUS_400_BAD_REQUEST) { > + DEBUG ((DEBUG_INFO, "HTTP_STATUS_400_BAD_REQUEST\n")); > + if (SendChunkProcess =3D=3D HttpIoSendChunkHeaderZeroContent) { > + DEBUG ((DEBUG_INFO, "Bad request may caused by zero length chunk. > Try to send all chunks...\n")); > + SendChunkProcess ++; > + goto ReSendRequest; > + } > + } else if (ResponseData->Response.StatusCode =3D=3D > HTTP_STATUS_100_CONTINUE) { > + DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE\n")); > + if (SendChunkProcess =3D=3D HttpIoSendChunkHeaderZeroContent) { > + // > + // We get HTTP_STATUS_100_CONTINUE to send the body using chunk > transfer. > + // > + DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE for chunk > transfer...\n")); > + SendChunkProcess ++; > + goto ReSendRequest; > + } > + if (SendNonChunkProcess =3D=3D HttpIoSendNonChunkHeaderZeroContent) > { > + DEBUG ((DEBUG_INFO, "HTTP_STATUS_100_CONTINUE for non chunk > transfer...\n")); > + SendNonChunkProcess ++; > + goto ReSendRequest; > + } > + // > + // It's the REST protocol's responsibility to handle the interim HTTP > response (e.g. 100 Continue Informational), > + // and return the final response content to the caller. > + // > + if (ResponseData->Headers !=3D NULL && ResponseData->HeaderCount !=3D > 0) { > + FreePool (ResponseData->Headers); > + } > + ZeroMem (ResponseData, sizeof(HTTP_IO_RESPONSE_DATA)); > + Status =3D HttpIoRecvResponse ( > + &(Instance->HttpIo), > + TRUE, > + ResponseData > + ); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + } else { > + DEBUG ((DEBUG_ERROR, "This HTTP Status is not handled!\n")); > + Status =3D EFI_UNSUPPORTED; > + goto ON_EXIT; > + } > + > + // > + // Ready to return the StatusCode, Header info and BodyLength. > + // > + ResponseMessage->Data.Response =3D AllocateZeroPool (sizeof > (EFI_HTTP_RESPONSE_DATA)); > + if (ResponseMessage->Data.Response =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + > + ResponseMessage->Data.Response->StatusCode =3D ResponseData- > >Response.StatusCode; > + ResponseMessage->HeaderCount =3D ResponseData->HeaderCount; > + ResponseMessage->Headers =3D ResponseData->Headers; > + > + // > + // Get response message body. > + // > + if (ResponseMessage->HeaderCount > 0) { > + Status =3D HttpIoGetContentLength (ResponseMessage->HeaderCount, > ResponseMessage->Headers, &ResponseMessage->BodyLength); > + if (EFI_ERROR (Status) && Status !=3D EFI_NOT_FOUND) { > + goto ON_EXIT; > + } > + > + if (Status =3D=3D EFI_NOT_FOUND) { > + ASSERT (ResponseMessage->BodyLength =3D=3D 0); > + } > + > + if (ResponseMessage->BodyLength =3D=3D 0) { > + // > + // Check if Chunked Transfer Coding. > + // > + Status =3D HttpIoGetChunkedTransferContent ( > + &(Instance->HttpIo), > + ResponseMessage->HeaderCount, > + ResponseMessage->Headers, > + &ChunkListLink, > + &ResponseMessage->BodyLength > + ); > + if (EFI_ERROR (Status) && Status !=3D EFI_NOT_FOUND) { > + goto ON_EXIT; > + } > + if (Status =3D=3D EFI_SUCCESS && > + ChunkListLink !=3D NULL && > + !IsListEmpty(ChunkListLink) && > + ResponseMessage->BodyLength !=3D 0) { > + IsGetChunkedTransfer =3D TRUE; > + // > + // Copy data to Message body. > + // > + CopyChunkData =3D TRUE; > + ResponseMessage->Body =3D AllocateZeroPool (ResponseMessage- > >BodyLength); > + if (ResponseMessage->Body =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + CopyChunkData =3D FALSE; > + } > + Index =3D 0; > + while (!IsListEmpty(ChunkListLink)) { > + ThisChunk =3D (HTTP_IO_CHUNKS *)GetFirstNode (ChunkListLink); > + if (CopyChunkData) { > + CopyMem(((UINT8 *)ResponseMessage->Body + Index), (UINT8 > *)ThisChunk->Data, ThisChunk->Length); > + Index +=3D ThisChunk->Length; > + } > + RemoveEntryList (&ThisChunk->NextChunk); > + FreePool ((VOID *)ThisChunk->Data); > + FreePool ((VOID *)ThisChunk); > + }; > + FreePool ((VOID *)ChunkListLink); > + } > + } > + Status =3D EFI_SUCCESS; > + } > + > + // > + // Ready to return the Body from REST service if have any. > + // > + if (ResponseMessage->BodyLength > 0 && !IsGetChunkedTransfer) { > + ResponseData->HeaderCount =3D 0; > + ResponseData->Headers =3D NULL; > + > + ResponseMessage->Body =3D AllocateZeroPool (ResponseMessage- > >BodyLength); > + if (ResponseMessage->Body =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + > + // > + // Only receive the Body. > + // > + TotalReceivedSize =3D 0; > + while (TotalReceivedSize < ResponseMessage->BodyLength) { > + ResponseData->BodyLength =3D ResponseMessage->BodyLength - > TotalReceivedSize; > + ResponseData->Body =3D (CHAR8 *) ResponseMessage->Body + > TotalReceivedSize; > + Status =3D HttpIoRecvResponse ( > + &(Instance->HttpIo), > + FALSE, > + ResponseData > + ); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + > + TotalReceivedSize +=3D ResponseData->BodyLength; > + } > + DEBUG ((DEBUG_INFO, "Total of lengh of Response :%d\n", > TotalReceivedSize)); > + } > + DEBUG ((DEBUG_INFO, "RedfishRestExSendReceive()- EFI_STATUS: %r\n", > Status)); > + > +ON_EXIT: > + > + if (ResponseData !=3D NULL) { > + FreePool (ResponseData); > + } > + > + if (EFI_ERROR (Status)) { > + if (ResponseMessage->Data.Response !=3D NULL) { > + FreePool (ResponseMessage->Data.Response); > + ResponseMessage->Data.Response =3D NULL; > + } > + > + if (ResponseMessage->Body !=3D NULL) { > + FreePool (ResponseMessage->Body); > + ResponseMessage->Body =3D NULL; > + } > + } > + return Status; > +} > + > +/** > + Obtain the current time from this REST service instance. > + > + The GetServiceTime() function is an optional interface to obtain the > current time from > + this REST service instance. If this REST service does not support to r= etrieve > the time, > + this function returns EFI_UNSUPPORTED. This function must returns > EFI_UNSUPPORTED if > + EFI_REST_EX_SERVICE_TYPE returned in EFI_REST_EX_SERVICE_INFO from > GetService() is > + EFI_REST_EX_SERVICE_UNSPECIFIC. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instan= ce for a > particular > + REST service. > + @param[out] Time A pointer to storage to receive a snap= shot of > the current time of > + the REST service. > + > + @retval EFI_SUCCESS operation succeeded. > + @retval EFI_INVALID_PARAMETER This or Time are NULL. > + @retval EFI_UNSUPPORTED The RESTful service does not support > returning the time. > + @retval EFI_DEVICE_ERROR An unexpected system or network error > occurred. > + @retval EFI_NOT_READY The configuration of this instance is = not set > yet. Configure() must > + be executed and returns successfully p= rior to invoke this > function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExGetServiceTime ( > + IN EFI_REST_EX_PROTOCOL *This, > + OUT EFI_TIME *Time > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + This function returns the information of REST service provided by this= EFI > REST EX driver instance. > + > + The information such as the type of REST service and the access mode of > REST EX driver instance > + (In-band or Out-of-band) are described in EFI_REST_EX_SERVICE_INFO > structure. For the vendor-specific > + REST service, vendor-specific REST service information is returned in > VendorSpecifcData. > + REST EX driver designer is well know what REST service this REST EX dr= iver > instance intends to > + communicate with. The designer also well know this driver instance is = used > to talk to BMC through > + specific platform mechanism or talk to REST server through UEFI HTTP > protocol. REST EX driver is > + responsible to fill up the correct information in > EFI_REST_EX_SERVICE_INFO. EFI_REST_EX_SERVICE_INFO > + is referred by EFI REST clients to pickup the proper EFI REST EX driver > instance to get and set resource. > + GetService() is a basic and mandatory function which must be able to u= se > even Configure() is not invoked > + in previously. > + > + @param[in] This Pointer to EFI_REST_EX_PROTOCOL instan= ce for a > particular > + REST service. > + @param[out] RestExServiceInfo Pointer to receive a pointer to > EFI_REST_EX_SERVICE_INFO structure. The > + format of EFI_REST_EX_SERVICE_INFO is = version > controlled for the future > + extension. The version of EFI_REST_EX_= SERVICE_INFO > structure is returned > + in the header within this structure. E= FI REST client refers to > the correct > + format of structure according to the v= ersion number. The > pointer to > + EFI_REST_EX_SERVICE_INFO is a memory b= lock allocated > by EFI REST EX driver > + instance. That is caller's responsibil= ity to free this memory > when this > + structure is no longer needed. Refer t= o Related Definitions > below for the > + definitions of EFI_REST_EX_SERVICE_INF= O structure. > + > + @retval EFI_SUCCESS EFI_REST_EX_SERVICE_INFO is returned in > RestExServiceInfo. This function > + is not supported in this REST EX Proto= col driver instance. > + @retval EFI_UNSUPPORTED This function is not supported in this= REST > EX Protocol driver instance. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExGetService ( > + IN EFI_REST_EX_PROTOCOL *This, > + OUT EFI_REST_EX_SERVICE_INFO **RestExServiceInfo > + ) > +{ > + EFI_TPL OldTpl; > + RESTEX_INSTANCE *Instance; > + EFI_REST_EX_SERVICE_INFO *ServiceInfo; > + > + ServiceInfo =3D NULL; > + > + if (This =3D=3D NULL || RestExServiceInfo =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + Instance =3D RESTEX_INSTANCE_FROM_THIS (This); > + > + ServiceInfo =3D AllocateZeroPool (sizeof (EFI_REST_EX_SERVICE_INFO)); > + if (ServiceInfo =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + CopyMem (ServiceInfo, &(Instance->Service->RestExServiceInfo), sizeof > (EFI_REST_EX_SERVICE_INFO)); > + > + *RestExServiceInfo =3D ServiceInfo; > + > + gBS->RestoreTPL (OldTpl); > + > + return EFI_SUCCESS; > +} > + > +/** > + This function returns operational configuration of current EFI REST EX= child > instance. > + > + This function returns the current configuration of EFI REST EX child i= nstance. > The format of > + operational configuration depends on the implementation of EFI REST EX > driver instance. For > + example, HTTP-aware EFI REST EX driver instance uses EFI HTTP protocol= as > the undying protocol > + to communicate with REST service. In this case, the type of configurat= ion is > + EFI_REST_EX_CONFIG_TYPE_HTTP returned from GetService(). > EFI_HTTP_CONFIG_DATA is used as EFI REST > + EX configuration format and returned to EFI REST client. User has to t= ype > cast RestExConfigData > + to EFI_HTTP_CONFIG_DATA. For those non HTTP-aware REST EX driver > instances, the type of configuration > + is EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC returned from GetService(). In > this case, the format of > + returning data could be non industrial. Instead, the format of configu= ration > data is system/platform > + specific definition such as BMC mechanism used in EFI REST EX driver > instance. EFI REST client and > + EFI REST EX driver instance have to refer to the specific system /plat= form > spec which is out of UEFI scope. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL insta= nce. > + @param[out] RestExConfigData Pointer to receive a pointer to > EFI_REST_EX_CONFIG_DATA. > + The memory allocated for configuration= data should be > freed > + by caller. See Related Definitions for= the details. > + > + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is returned in > successfully. > + @retval EFI_UNSUPPORTED This function is not supported in this= REST > EX Protocol driver instance. > + @retval EFI_NOT_READY The configuration of this instance is = not set > yet. Configure() must be > + executed and returns successfully prio= r to invoke this > function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExGetModeData ( > + IN EFI_REST_EX_PROTOCOL *This, > + OUT EFI_REST_EX_CONFIG_DATA *RestExConfigData > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + This function is used to configure EFI REST EX child instance. > + > + This function is used to configure the setting of underlying protocol = of REST > EX child > + instance. The type of configuration is according to the implementation= of > EFI REST EX > + driver instance. For example, HTTP-aware EFI REST EX driver instance u= ses > EFI HTTP protocol > + as the undying protocol to communicate with REST service. The type of > configuration is > + EFI_REST_EX_CONFIG_TYPE_HTTP and RestExConfigData is the same > format with EFI_HTTP_CONFIG_DATA. > + Akin to HTTP configuration, REST EX child instance can be configure to= use > different HTTP > + local access point for the data transmission. Multiple REST clients ma= y use > different > + configuration of HTTP to distinguish themselves, such as to use the > different TCP port. > + For those non HTTP-aware REST EX driver instance, the type of > configuration is > + EFI_REST_EX_CONFIG_TYPE_UNSPECIFIC. RestExConfigData refers to the > non industrial standard. > + Instead, the format of configuration data is system/platform specific > definition such as BMC. > + In this case, EFI REST client and EFI REST EX driver instance have to = refer to > the specific > + system/platform spec which is out of the UEFI scope. Besides > GetService()function, no other > + EFI REST EX functions can be executed by this instance until Configure= ()is > executed and returns > + successfully. All other functions must returns EFI_NOT_READY if this > instance is not configured > + yet. Set RestExConfigData to NULL means to put EFI REST EX child insta= nce > into the unconfigured > + state. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL insta= nce. > + @param[in] RestExConfigData Pointer to EFI_REST_EX_CONFIG_DATA. > See Related Definitions in > + GetModeData() protocol interface. > + > + @retval EFI_SUCCESS EFI_REST_EX_CONFIG_DATA is set in > successfully. > + @retval EFI_DEVICE_ERROR Configuration for this REST EX child > instance is failed with the given > + EFI_REST_EX_CONFIG_DATA. > + @retval EFI_UNSUPPORTED This function is not supported in this= REST > EX Protocol driver instance. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExConfigure ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_REST_EX_CONFIG_DATA RestExConfigData > + ) > +{ > + EFI_STATUS Status; > + EFI_TPL OldTpl; > + RESTEX_INSTANCE *Instance; > + > + EFI_HTTP_CONFIG_DATA *HttpConfigData; > + > + Status =3D EFI_SUCCESS; > + HttpConfigData =3D NULL; > + > + if (This =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + OldTpl =3D gBS->RaiseTPL (TPL_CALLBACK); > + > + Instance =3D RESTEX_INSTANCE_FROM_THIS (This); > + > + if (RestExConfigData =3D=3D NULL) { > + // > + // Set RestExConfigData to NULL means to put EFI REST EX child insta= nce > into the unconfigured state. > + // > + HttpIoDestroyIo (&(Instance->HttpIo)); > + > + if (Instance->ConfigData !=3D NULL) { > + if (((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)- > >HttpConfigData.AccessPoint.IPv4Node !=3D NULL) { > + FreePool(((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance- > >ConfigData)->HttpConfigData.AccessPoint.IPv4Node); > + } > + FreePool(Instance->ConfigData); > + Instance->ConfigData =3D NULL; > + } > + > + Instance->State =3D RESTEX_STATE_UNCONFIGED; > + } else { > + HttpConfigData =3D &((EFI_REST_EX_HTTP_CONFIG_DATA > *)RestExConfigData)->HttpConfigData; > + Status =3D Instance->HttpIo.Http->Configure (Instance->HttpIo.Http, > HttpConfigData); > + if (EFI_ERROR (Status)) { > + goto ON_EXIT; > + } > + Instance->HttpIo.Timeout =3D ((EFI_REST_EX_HTTP_CONFIG_DATA > *)RestExConfigData)->SendReceiveTimeout; > + > + Instance->ConfigData =3D AllocateZeroPool (sizeof > (EFI_REST_EX_HTTP_CONFIG_DATA)); > + if (Instance->ConfigData =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + CopyMem (Instance->ConfigData, RestExConfigData, sizeof > (EFI_REST_EX_HTTP_CONFIG_DATA)); > + if (HttpConfigData->LocalAddressIsIPv6 =3D=3D TRUE) { > + ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)- > >HttpConfigData.AccessPoint.IPv6Node =3D AllocateZeroPool (sizeof > (EFI_HTTPv6_ACCESS_POINT)); > + if (((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)- > >HttpConfigData.AccessPoint.IPv6Node =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + CopyMem ( > + ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)- > >HttpConfigData.AccessPoint.IPv6Node, > + HttpConfigData->AccessPoint.IPv6Node, > + sizeof (EFI_HTTPv6_ACCESS_POINT) > + ); > + } else { > + ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)- > >HttpConfigData.AccessPoint.IPv4Node =3D AllocateZeroPool (sizeof > (EFI_HTTPv4_ACCESS_POINT)); > + if (((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)- > >HttpConfigData.AccessPoint.IPv4Node =3D=3D NULL) { > + Status =3D EFI_OUT_OF_RESOURCES; > + goto ON_EXIT; > + } > + CopyMem ( > + ((EFI_REST_EX_HTTP_CONFIG_DATA *)Instance->ConfigData)- > >HttpConfigData.AccessPoint.IPv4Node, > + HttpConfigData->AccessPoint.IPv4Node, > + sizeof (EFI_HTTPv4_ACCESS_POINT) > + ); > + } > + Instance->State =3D RESTEX_STATE_CONFIGED; > + } > + > +ON_EXIT: > + gBS->RestoreTPL (OldTpl); > + return Status; > +} > + > +/** > + This function sends REST request to REST service and signal caller's e= vent > asynchronously when > + the final response is received by REST EX Protocol driver instance. > + > + The essential design of this function is to handle asynchronous > send/receive implicitly according > + to REST service asynchronous request mechanism. Caller will get the > notification once the response > + is returned from REST service. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL ins= tance. > + @param[in] RequestMessage This is the HTTP request message sent > to REST service. Set RequestMessage > + to NULL to cancel the previous async= hronous request > associated with the > + corresponding RestExToken. See descr= iptions for the > details. > + @param[in] RestExToken REST EX token which REST EX Protocol > instance uses to notify REST client > + the status of response of asynchrono= us REST request. See > related definition > + of EFI_REST_EX_TOKEN. > + @param[in] TimeOutInMilliSeconds The pointer to the timeout in > milliseconds which REST EX Protocol driver > + instance refers as the duration to d= rop asynchronous REST > request. NULL > + pointer means no timeout for this RE= ST request. REST EX > Protocol driver > + signals caller's event with EFI_STAT= US set to EFI_TIMEOUT > in RestExToken > + if REST EX Protocol can't get the re= sponse from REST > service within > + TimeOutInMilliSeconds. > + > + @retval EFI_SUCCESS Asynchronous REST request is establi= shed. > + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance > doesn't support asynchronous request. > + @retval EFI_TIMEOUT Asynchronous REST request is not > established and timeout is expired. > + @retval EFI_ABORT Previous asynchronous REST request h= as been > canceled. > + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR > for other errors according to HTTP Status Code. > + @retval EFI_NOT_READY The configuration of this instance i= s not set > yet. Configure() must be executed > + and returns successfully prior to in= voke this function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExAyncSendReceive ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, > + IN EFI_REST_EX_TOKEN *RestExToken, > + IN UINTN *TimeOutInMilliSeconds OPTIONAL > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + This function sends REST request to a REST Event service and signals c= aller's > event > + token asynchronously when the URI resource change event is received by > REST EX > + Protocol driver instance. > + > + The essential design of this function is to monitor event implicitly a= ccording > to > + REST service event service mechanism. Caller will get the notification= if > certain > + resource is changed. > + > + @param[in] This This is the EFI_REST_EX_PROTOCOL ins= tance. > + @param[in] RequestMessage This is the HTTP request message sent > to REST service. Set RequestMessage > + to NULL to cancel the previous event= service associated > with the corresponding > + RestExToken. See descriptions for th= e details. > + @param[in] RestExToken REST EX token which REST EX Protocol > driver instance uses to notify REST client > + the URI resource which monitored by = REST client has > been changed. See the related > + definition of EFI_REST_EX_TOKEN in > EFI_REST_EX_PROTOCOL.AsyncSendReceive(). > + > + @retval EFI_SUCCESS Asynchronous REST request is establi= shed. > + @retval EFI_UNSUPPORTED This REST EX Protocol driver instance > doesn't support asynchronous request. > + @retval EFI_ABORT Previous asynchronous REST request h= as been > canceled or event subscription has been > + delete from service. > + @retval EFI_DEVICE_ERROR Otherwise, returns EFI_DEVICE_ERROR > for other errors according to HTTP Status Code. > + @retval EFI_NOT_READY The configuration of this instance i= s not set > yet. Configure() must be executed > + and returns successfully prior to in= voke this function. > + > +**/ > +EFI_STATUS > +EFIAPI > +RedfishRestExEventService ( > + IN EFI_REST_EX_PROTOCOL *This, > + IN EFI_HTTP_MESSAGE *RequestMessage OPTIONAL, > + IN EFI_REST_EX_TOKEN *RestExToken > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > -- > 2.17.1