TianoCore EDK2 master
Loading...
Searching...
No Matches
RedfishHttpDxe.c
Go to the documentation of this file.
1
11#include "RedfishHttpDxe.h"
12#include "RedfishHttpData.h"
14
15REDFISH_HTTP_CACHE_PRIVATE *mRedfishHttpCachePrivate = NULL;
16
30 IN CONST CHAR8 *Msg,
31 IN UINTN ErrorLevel,
33 )
34{
35 LIST_ENTRY *List;
37 UINTN Index;
38
39 if (CacheList == NULL) {
40 return EFI_INVALID_PARAMETER;
41 }
42
43 if (!IS_EMPTY_STRING (Msg)) {
44 DEBUG ((ErrorLevel, "%a\n", Msg));
45 }
46
47 if (IsListEmpty (&CacheList->Head)) {
48 DEBUG ((ErrorLevel, "list is empty\n"));
49 return EFI_NOT_FOUND;
50 }
51
52 DEBUG ((ErrorLevel, "list count: %d capacity: %d\n", CacheList->Count, CacheList->Capacity));
53 Data = NULL;
54 Index = 0;
55 List = GetFirstNode (&CacheList->Head);
56 while (!IsNull (&CacheList->Head, List)) {
57 Data = REDFISH_HTTP_CACHE_FROM_LIST (List);
58
59 DEBUG ((ErrorLevel, "%d) Uri: %s Hit: %d\n", ++Index, Data->Uri, Data->HitCount));
60
61 List = GetNextNode (&CacheList->Head, List);
62 }
63
64 return EFI_SUCCESS;
65}
66
77BOOLEAN
79 IN EFI_HTTP_STATUS_CODE *StatusCode
80 )
81{
82 if (StatusCode == NULL) {
83 return TRUE;
84 }
85
86 if ((*StatusCode == HTTP_STATUS_500_INTERNAL_SERVER_ERROR) ||
87 (*StatusCode == HTTP_STATUS_UNSUPPORTED_STATUS))
88 {
89 return TRUE;
90 }
91
92 return FALSE;
93}
94
110BOOLEAN
112 IN EFI_HTTP_METHOD Method,
113 IN EFI_HTTP_STATUS_CODE *StatusCode
114 )
115{
116 BOOLEAN SuccessResponse;
117
118 if (StatusCode == NULL) {
119 return TRUE;
120 }
121
122 SuccessResponse = FALSE;
123 switch (Method) {
124 case HttpMethodPost:
125 if ((*StatusCode == HTTP_STATUS_200_OK) ||
126 (*StatusCode == HTTP_STATUS_201_CREATED) ||
127 (*StatusCode == HTTP_STATUS_202_ACCEPTED) ||
128 (*StatusCode == HTTP_STATUS_204_NO_CONTENT))
129 {
130 SuccessResponse = TRUE;
131 }
132
133 break;
134 case HttpMethodPatch:
135 case HttpMethodPut:
136 case HttpMethodDelete:
137 if ((*StatusCode == HTTP_STATUS_200_OK) ||
138 (*StatusCode == HTTP_STATUS_202_ACCEPTED) ||
139 (*StatusCode == HTTP_STATUS_204_NO_CONTENT))
140 {
141 SuccessResponse = TRUE;
142 }
143
144 break;
145 default:
146 //
147 // Return true for unsupported method to prevent false alarm.
148 //
149 SuccessResponse = TRUE;
150 break;
151 }
152
153 return SuccessResponse;
154}
155
166CHAR8 *
168 IN EFI_STRING UnicodeStr
169 )
170{
171 CHAR8 *AsciiStr;
173 EFI_STATUS Status;
174
175 if (IS_EMPTY_STRING (UnicodeStr)) {
176 return NULL;
177 }
178
179 AsciiStrSize = StrLen (UnicodeStr) + 1;
180 AsciiStr = AllocateZeroPool (AsciiStrSize);
181 if (AsciiStr == NULL) {
182 return NULL;
183 }
184
185 Status = UnicodeStrToAsciiStrS (UnicodeStr, AsciiStr, AsciiStrSize);
186 if (EFI_ERROR (Status)) {
187 DEBUG ((DEBUG_ERROR, "UnicodeStrToAsciiStrS failed: %r\n", Status));
188 FreePool (AsciiStr);
189 return NULL;
190 }
191
192 return AsciiStr;
193}
194
203CHAR8 *
205 IN EFI_HTTP_METHOD Method
206 )
207{
208 switch (Method) {
209 case HttpMethodGet:
210 return HTTP_METHOD_GET;
211 break;
212 case HttpMethodPost:
213 return HTTP_METHOD_POST;
214 break;
215 case HttpMethodPatch:
216 return HTTP_METHOD_PATCH;
217 break;
218 case HttpMethodPut:
219 return HTTP_METHOD_PUT;
220 break;
221 case HttpMethodDelete:
222 return HTTP_METHOD_DELETE;
223 break;
224 default:
225 break;
226 }
227
228 return "Unknown";
229}
230
239VOID
241 IN EFI_HTTP_METHOD Method,
242 IN EFI_STRING Uri,
243 IN EFI_HTTP_STATUS_CODE *HttpStatusCode OPTIONAL
244 )
245{
246 CHAR8 ErrorMsg[REDFISH_ERROR_MSG_MAX];
247
248 if (IS_EMPTY_STRING (Uri)) {
249 DEBUG ((DEBUG_ERROR, "%a: no URI to report error status\n", __func__));
250 return;
251 }
252
253 //
254 // Report failure of URI and HTTP status code.
255 //
256 AsciiSPrint (ErrorMsg, sizeof (ErrorMsg), REDFISH_HTTP_ERROR_REPORT, HttpMethodToString (Method), (HttpStatusCode == NULL ? HTTP_STATUS_UNSUPPORTED_STATUS : *HttpStatusCode), Uri);
257 DEBUG ((DEBUG_ERROR, "%a\n", ErrorMsg));
258 //
259 // TODO:
260 // Below PI status code is approved by PIWG and wait for specification published.
261 // We will uncomment below report status code after PI status code get published.
262 // REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4483
263 //
264 // REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
265 // EFI_ERROR_CODE | EFI_ERROR_MAJOR,
266 // EFI_COMPUTING_UNIT_MANAGEABILITY | EFI_MANAGEABILITY_EC_REDFISH_COMMUNICATION_ERROR,
267 // ErrorMsg,
268 // AsciiStrSize (ErrorMsg)
269 // );
270}
271
283REDFISH_SERVICE
284EFIAPI
287 IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo
288 )
289{
290 EFI_STATUS Status;
292 REDFISH_SERVICE_PRIVATE *NewService;
293 CHAR8 *AsciiLocation;
294 CHAR8 *Host;
295 CHAR8 *BasicAuthString;
296 UINTN BasicAuthStrSize;
297 CHAR8 *EncodedAuthString;
298 UINTN EncodedAuthStrSize;
299 EDKII_REDFISH_AUTH_METHOD AuthMethod;
300 CHAR8 *Username;
301 CHAR8 *Password;
302 UINTN UsernameSize;
303 UINTN PasswordSize;
304 EFI_REST_EX_PROTOCOL *RestEx;
305
306 if ((This == NULL) || (RedfishConfigServiceInfo == NULL)) {
307 return NULL;
308 }
309
310 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: service location: %s\n", __func__, RedfishConfigServiceInfo->RedfishServiceLocation));
311
312 Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
313 BasicAuthString = NULL;
314 EncodedAuthString = NULL;
315 Username = NULL;
316 Password = NULL;
317 NewService = NULL;
318 AsciiLocation = NULL;
319 Host = NULL;
320 BasicAuthStrSize = 0;
321 EncodedAuthStrSize = 0;
322 UsernameSize = 0;
323 PasswordSize = 0;
324
325 //
326 // Build host and host name from service location
327 //
328 if (!IS_EMPTY_STRING (RedfishConfigServiceInfo->RedfishServiceLocation)) {
329 AsciiLocation = StringUnicodeToAscii (RedfishConfigServiceInfo->RedfishServiceLocation);
330 if (AsciiLocation == NULL) {
331 goto ON_RELEASE;
332 }
333
334 Host = AllocateZeroPool (REDFISH_HOST_NAME_MAX);
335 if (AsciiLocation == NULL) {
336 goto ON_RELEASE;
337 }
338
339 if (RedfishConfigServiceInfo->RedfishServiceUseHttps) {
340 AsciiSPrint (Host, REDFISH_HOST_NAME_MAX, "https://%a", AsciiLocation);
341 } else {
342 AsciiSPrint (Host, REDFISH_HOST_NAME_MAX, "http://%a", AsciiLocation);
343 }
344
345 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Host: %a\n", __func__, Host));
346 }
347
348 //
349 // Find Rest Ex protocol
350 //
351 if (RedfishConfigServiceInfo->RedfishServiceRestExHandle != NULL) {
352 Status = gBS->HandleProtocol (
353 RedfishConfigServiceInfo->RedfishServiceRestExHandle,
354 &gEfiRestExProtocolGuid,
355 (VOID **)&RestEx
356 );
357 } else {
358 DEBUG ((DEBUG_ERROR, "%a: Rest Ex protocol is not available\n", __func__));
359 goto ON_RELEASE;
360 }
361
362 //
363 // Get credential
364 //
365 if (Private->CredentialProtocol == NULL) {
366 //
367 // No credential available on this system.
368 //
369 DEBUG ((DEBUG_WARN, "%a: no credential protocol available\n", __func__));
370 } else {
371 Status = Private->CredentialProtocol->GetAuthInfo (
372 Private->CredentialProtocol,
373 &AuthMethod,
374 &Username,
375 &Password
376 );
377 if (EFI_ERROR (Status) || ((AuthMethod != AuthMethodNone) && (IS_EMPTY_STRING (Username) || IS_EMPTY_STRING (Password)))) {
378 DEBUG ((DEBUG_ERROR, "%a: cannot get authentication information: %r\n", __func__, Status));
379 goto ON_RELEASE;
380 } else if (AuthMethod != AuthMethodNone) {
381 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Auth method: 0x%x username: %a password: %a\n", __func__, AuthMethod, Username, Password));
382
383 //
384 // Perform base64 encoding (RFC 7617)
385 //
386 UsernameSize = AsciiStrSize (Username);
387 PasswordSize = AsciiStrSize (Password);
388 BasicAuthStrSize = UsernameSize + PasswordSize; // one byte taken from null-terminator for ':'
389 BasicAuthString = AllocateZeroPool (BasicAuthStrSize);
390 if (BasicAuthString == NULL) {
391 goto ON_RELEASE;
392 }
393
395 BasicAuthString,
396 BasicAuthStrSize,
397 "%a:%a",
398 Username,
399 Password
400 );
401
402 Status = Base64Encode (
403 (CONST UINT8 *)BasicAuthString,
404 BasicAuthStrSize,
405 EncodedAuthString,
406 &EncodedAuthStrSize
407 );
408 if ((Status == EFI_BUFFER_TOO_SMALL) && (EncodedAuthStrSize > 0)) {
409 EncodedAuthString = AllocateZeroPool (EncodedAuthStrSize);
410 if (EncodedAuthString == NULL) {
411 goto ON_RELEASE;
412 }
413
414 Status = Base64Encode (
415 (CONST UINT8 *)BasicAuthString,
416 BasicAuthStrSize,
417 EncodedAuthString,
418 &EncodedAuthStrSize
419 );
420 if (EFI_ERROR (Status)) {
421 DEBUG ((DEBUG_ERROR, "%a: Base64Encode failure: %r\n", __func__, Status));
422 }
423
424 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Basic authorization: %a\n", __func__, EncodedAuthString));
425 } else {
426 DEBUG ((DEBUG_ERROR, "%a: Base64Encode failure: %r\n", __func__, Status));
427 goto ON_RELEASE;
428 }
429 }
430 }
431
432 NewService = CreateRedfishService (Host, AsciiLocation, EncodedAuthString, NULL, RestEx);
433 if (NewService == NULL) {
434 DEBUG ((DEBUG_ERROR, "%a: CreateRedfishService\n", __func__));
435 goto ON_RELEASE;
436 }
437
438 if (Private->CredentialProtocol != NULL) {
439 Status = Private->CredentialProtocol->RegisterRedfishService (Private->CredentialProtocol, NewService);
440 if (EFI_ERROR (Status)) {
441 DEBUG ((DEBUG_ERROR, "%a: Failed to register Redfish service - %r\n", __func__, Status));
442 }
443 }
444
445ON_RELEASE:
446
447 if (BasicAuthString != NULL) {
448 ZeroMem (BasicAuthString, BasicAuthStrSize);
449 FreePool (BasicAuthString);
450 }
451
452 if (EncodedAuthString != NULL) {
453 ZeroMem (BasicAuthString, EncodedAuthStrSize);
454 FreePool (EncodedAuthString);
455 }
456
457 if (Username != NULL) {
458 ZeroMem (Username, UsernameSize);
459 FreePool (Username);
460 }
461
462 if (Password != NULL) {
463 ZeroMem (Password, PasswordSize);
464 FreePool (Password);
465 }
466
467 if (AsciiLocation != NULL) {
468 FreePool (AsciiLocation);
469 }
470
471 if (Host != NULL) {
472 FreePool (Host);
473 }
474
475 return NewService;
476}
477
490EFIAPI
493 IN REDFISH_SERVICE RedfishService
494 )
495{
496 EFI_STATUS Status;
499
500 if ((This == NULL) || (RedfishService == NULL)) {
501 return EFI_INVALID_PARAMETER;
502 }
503
504 Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
505
506 Service = (REDFISH_SERVICE_PRIVATE *)RedfishService;
507 if (Service->Signature != REDFISH_HTTP_SERVICE_SIGNATURE) {
508 DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
509 }
510
511 if (Private->CredentialProtocol != NULL) {
512 Status = Private->CredentialProtocol->UnregisterRedfishService (Private->CredentialProtocol, RedfishService);
513 if (EFI_ERROR (Status)) {
514 DEBUG ((DEBUG_ERROR, "%a: Failed to unregister Redfish service - %r\n", __func__, Status));
515 } else {
516 if (Service->RestEx != NULL) {
517 Status = Service->RestEx->Configure (Service->RestEx, NULL);
518 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: release RestEx instance: %r\n", __func__, Status));
519 }
520 }
521 }
522
523 return ReleaseRedfishService (Service);
524}
525
538EDKII_JSON_VALUE
539EFIAPI
542 IN REDFISH_PAYLOAD RedfishPayload
543 )
544{
546
547 if ((This == NULL) || (RedfishPayload == NULL)) {
548 return NULL;
549 }
550
551 Payload = (REDFISH_PAYLOAD_PRIVATE *)RedfishPayload;
552 if (Payload->Signature != REDFISH_HTTP_PAYLOAD_SIGNATURE) {
553 DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
554 }
555
556 return Payload->JsonValue;
557}
558
578EFIAPI
581 IN REDFISH_SERVICE Service,
582 IN EFI_STRING Uri,
583 IN REDFISH_REQUEST *Request OPTIONAL,
584 OUT REDFISH_RESPONSE *Response,
585 IN BOOLEAN UseCache
586 )
587{
588 EFI_STATUS Status;
589 REDFISH_HTTP_CACHE_DATA *CacheData;
590 UINTN RetryCount;
592
593 if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri)) {
594 return EFI_INVALID_PARAMETER;
595 }
596
597 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Get URI: %s cache: %a\n", __func__, Uri, (UseCache ? "true" : "false")));
598
599 Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
600 CacheData = NULL;
601 RetryCount = 0;
602 ZeroMem (Response, sizeof (REDFISH_RESPONSE));
603
604 if (Private->CacheDisabled) {
605 UseCache = FALSE;
606 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: cache is disabled by PCD!\n", __func__));
607 }
608
609 //
610 // Search for cache list.
611 //
612 if (UseCache) {
613 CacheData = FindHttpCacheData (&Private->CacheList.Head, Uri);
614 if (CacheData != NULL) {
615 DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: cache hit! %s\n", __func__, Uri));
616
617 //
618 // Copy cached response to caller's buffer.
619 //
620 Status = CopyRedfishResponse (CacheData->Response, Response);
621 CacheData->HitCount += 1;
622 return Status;
623 }
624 }
625
626 //
627 // Get resource from redfish service.
628 //
629 do {
630 RetryCount += 1;
631 Status = HttpSendReceive (
632 Service,
633 Uri,
634 HttpMethodGet,
635 Request,
636 Response
637 );
638 DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
639 if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryGet)) {
640 break;
641 }
642
643 //
644 // Retry when BMC is not ready.
645 //
646 if ((Response->StatusCode != NULL)) {
647 DEBUG_CODE (
648 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
649 );
650
651 if (!RedfishRetryRequired (Response->StatusCode)) {
652 break;
653 }
654
655 //
656 // Release response for next round of request.
657 //
658 This->FreeResponse (This, Response);
659 }
660
661 DEBUG ((DEBUG_WARN, "%a: RedfishGetByUriEx failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryGet));
662 if (Private->RetrySetting.RetryWait > 0) {
663 gBS->Stall (Private->RetrySetting.RetryWait);
664 }
665 } while (TRUE);
666
667 if (EFI_ERROR (Status)) {
668 DEBUG_CODE (
669 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
670 );
671 //
672 // Report status code for Redfish failure
673 //
674 ReportHttpError (HttpMethodGet, Uri, Response->StatusCode);
675 DEBUG ((DEBUG_ERROR, "%a: get %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryGet, Status));
676 goto ON_RELEASE;
677 }
678
679 if (!Private->CacheDisabled) {
680 //
681 // Keep response in cache list
682 //
683 Status = AddHttpCacheData (&Private->CacheList, Uri, Response);
684 if (EFI_ERROR (Status)) {
685 DEBUG ((DEBUG_ERROR, "%a: failed to cache %s: %r\n", __func__, Uri, Status));
686 goto ON_RELEASE;
687 }
688
689 DEBUG_CODE (
690 DebugPrintHttpCacheList (__func__, REDFISH_HTTP_CACHE_DEBUG_DUMP, &Private->CacheList);
691 );
692 }
693
694ON_RELEASE:
695
696 return Status;
697}
698
711EFIAPI
714 IN REDFISH_REQUEST *Request
715 )
716{
717 if ((This == NULL) || (Request == NULL)) {
718 return EFI_INVALID_PARAMETER;
719 }
720
721 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: entry\n", __func__));
722
723 return ReleaseRedfishRequest (Request);
724}
725
737EFIAPI
740 IN REDFISH_RESPONSE *Response
741 )
742{
743 if ((This == NULL) || (Response == NULL)) {
744 return EFI_INVALID_PARAMETER;
745 }
746
747 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: entry\n", __func__));
748
749 return ReleaseRedfishResponse (Response);
750}
751
763EFIAPI
766 IN EFI_STRING Uri
767 )
768{
770 REDFISH_HTTP_CACHE_DATA *CacheData;
771
772 if ((This == NULL) || IS_EMPTY_STRING (Uri)) {
773 return EFI_INVALID_PARAMETER;
774 }
775
776 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: expire URI: %s\n", __func__, Uri));
777
778 Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
779
780 CacheData = FindHttpCacheData (&Private->CacheList.Head, Uri);
781 if (CacheData == NULL) {
782 return EFI_NOT_FOUND;
783 }
784
785 return DeleteHttpCacheData (&Private->CacheList, CacheData);
786}
787
809EFIAPI
812 IN REDFISH_SERVICE Service,
813 IN EFI_STRING Uri,
814 IN CHAR8 *Content,
815 IN UINTN ContentSize OPTIONAL,
816 IN CHAR8 *ContentType OPTIONAL,
817 OUT REDFISH_RESPONSE *Response
818 )
819{
820 EFI_STATUS Status;
821 UINTN RetryCount;
822 REDFISH_REQUEST Request;
824
825 if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Content)) {
826 return EFI_INVALID_PARAMETER;
827 }
828
829 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Patch URI: %s\n", __func__, Uri));
830
831 Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
832 RetryCount = 0;
833 ZeroMem (Response, sizeof (REDFISH_RESPONSE));
834 ZeroMem (&Request, sizeof (REDFISH_REQUEST));
835
836 Request.Content = Content;
837 Request.ContentLength = ContentSize;
838 Request.ContentType = ContentType;
839
840 //
841 // Patch resource to redfish service.
842 //
843 do {
844 RetryCount += 1;
845 Status = HttpSendReceive (
846 Service,
847 Uri,
848 HttpMethodPatch,
849 &Request,
850 Response
851 );
852 DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
853 if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryPatch)) {
854 break;
855 }
856
857 //
858 // Retry when BMC is not ready.
859 //
860 if ((Response->StatusCode != NULL)) {
861 DEBUG_CODE (
862 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
863 );
864
865 if (!RedfishRetryRequired (Response->StatusCode)) {
866 break;
867 }
868
869 //
870 // Release response for next round of request.
871 //
872 This->FreeResponse (This, Response);
873 }
874
875 DEBUG ((DEBUG_WARN, "%a: RedfishPatchToUriEx failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryPatch));
876 if (Private->RetrySetting.RetryWait > 0) {
877 gBS->Stall (Private->RetrySetting.RetryWait);
878 }
879 } while (TRUE);
880
881 //
882 // Redfish resource is updated. Automatically expire the cached response
883 // so application can directly get resource from Redfish service again.
884 //
885 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
886 RedfishExpireResponse (This, Uri);
887
888 if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodPatch, Response->StatusCode)) {
889 DEBUG_CODE (
890 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
891 );
892 //
893 // Report status code for Redfish failure
894 //
895 ReportHttpError (HttpMethodPatch, Uri, Response->StatusCode);
896 DEBUG ((DEBUG_ERROR, "%a: patch %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryPatch, Status));
897 goto ON_RELEASE;
898 }
899
900ON_RELEASE:
901
902 return Status;
903}
904
926EFIAPI
929 IN REDFISH_SERVICE Service,
930 IN EFI_STRING Uri,
931 IN CHAR8 *Content,
932 IN UINTN ContentSize OPTIONAL,
933 IN CHAR8 *ContentType OPTIONAL,
934 OUT REDFISH_RESPONSE *Response
935 )
936{
937 EFI_STATUS Status;
938 UINTN RetryCount;
939 REDFISH_REQUEST Request;
941
942 if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Content)) {
943 return EFI_INVALID_PARAMETER;
944 }
945
946 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Put URI: %s\n", __func__, Uri));
947
948 Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
949 RetryCount = 0;
950 ZeroMem (Response, sizeof (REDFISH_RESPONSE));
951 ZeroMem (&Request, sizeof (REDFISH_REQUEST));
952
953 Request.Content = Content;
954 Request.ContentLength = ContentSize;
955 Request.ContentType = ContentType;
956
957 //
958 // Patch resource to redfish service.
959 //
960 do {
961 RetryCount += 1;
962 Status = HttpSendReceive (
963 Service,
964 Uri,
965 HttpMethodPut,
966 &Request,
967 Response
968 );
969 DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
970 if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryPut)) {
971 break;
972 }
973
974 //
975 // Retry when BMC is not ready.
976 //
977 if ((Response->StatusCode != NULL)) {
978 DEBUG_CODE (
979 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
980 );
981
982 if (!RedfishRetryRequired (Response->StatusCode)) {
983 break;
984 }
985
986 //
987 // Release response for next round of request.
988 //
989 This->FreeResponse (This, Response);
990 }
991
992 DEBUG ((DEBUG_WARN, "%a: RedfishPutToUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryPut));
993 if (Private->RetrySetting.RetryWait > 0) {
994 gBS->Stall (Private->RetrySetting.RetryWait);
995 }
996 } while (TRUE);
997
998 //
999 // Redfish resource is updated. Automatically expire the cached response
1000 // so application can directly get resource from Redfish service again.
1001 //
1002 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
1003 RedfishExpireResponse (This, Uri);
1004
1005 if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodPut, Response->StatusCode)) {
1006 DEBUG_CODE (
1007 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
1008 );
1009 //
1010 // Report status code for Redfish failure
1011 //
1012 ReportHttpError (HttpMethodPut, Uri, Response->StatusCode);
1013 DEBUG ((DEBUG_ERROR, "%a: put %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryPut, Status));
1014 goto ON_RELEASE;
1015 }
1016
1017ON_RELEASE:
1018
1019 return Status;
1020}
1021
1043EFIAPI
1046 IN REDFISH_SERVICE Service,
1047 IN EFI_STRING Uri,
1048 IN CHAR8 *Content,
1049 IN UINTN ContentSize OPTIONAL,
1050 IN CHAR8 *ContentType OPTIONAL,
1051 OUT REDFISH_RESPONSE *Response
1052 )
1053{
1054 EFI_STATUS Status;
1055 UINTN RetryCount;
1056 REDFISH_REQUEST Request;
1058
1059 if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri) || IS_EMPTY_STRING (Content)) {
1060 return EFI_INVALID_PARAMETER;
1061 }
1062
1063 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Post URI: %s\n", __func__, Uri));
1064
1065 Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
1066 RetryCount = 0;
1067 ZeroMem (Response, sizeof (REDFISH_RESPONSE));
1068 ZeroMem (&Request, sizeof (REDFISH_REQUEST));
1069
1070 Request.Content = Content;
1071 Request.ContentLength = ContentSize;
1072 Request.ContentType = ContentType;
1073
1074 //
1075 // Patch resource to redfish service.
1076 //
1077 do {
1078 RetryCount += 1;
1079 Status = HttpSendReceive (
1080 Service,
1081 Uri,
1082 HttpMethodPost,
1083 &Request,
1084 Response
1085 );
1086 DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
1087 if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryPost)) {
1088 break;
1089 }
1090
1091 //
1092 // Retry when BMC is not ready.
1093 //
1094 if ((Response->StatusCode != NULL)) {
1095 DEBUG_CODE (
1096 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
1097 );
1098
1099 if (!RedfishRetryRequired (Response->StatusCode)) {
1100 break;
1101 }
1102
1103 //
1104 // Release response for next round of request.
1105 //
1106 This->FreeResponse (This, Response);
1107 }
1108
1109 DEBUG ((DEBUG_WARN, "%a: RedfishPostToUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryPost));
1110 if (Private->RetrySetting.RetryWait > 0) {
1111 gBS->Stall (Private->RetrySetting.RetryWait);
1112 }
1113 } while (TRUE);
1114
1115 //
1116 // Redfish resource is updated. Automatically expire the cached response
1117 // so application can directly get resource from Redfish service again.
1118 //
1119 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
1120 RedfishExpireResponse (This, Uri);
1121
1122 if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodPost, Response->StatusCode)) {
1123 DEBUG_CODE (
1124 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
1125 );
1126 //
1127 // Report status code for Redfish failure
1128 //
1129 ReportHttpError (HttpMethodPost, Uri, Response->StatusCode);
1130 DEBUG ((DEBUG_ERROR, "%a: post %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryPost, Status));
1131 goto ON_RELEASE;
1132 }
1133
1134ON_RELEASE:
1135
1136 return Status;
1137}
1138
1162EFIAPI
1165 IN REDFISH_SERVICE Service,
1166 IN EFI_STRING Uri,
1167 IN CHAR8 *Content OPTIONAL,
1168 IN UINTN ContentSize OPTIONAL,
1169 IN CHAR8 *ContentType OPTIONAL,
1170 OUT REDFISH_RESPONSE *Response
1171 )
1172{
1173 EFI_STATUS Status;
1174 UINTN RetryCount;
1175 REDFISH_REQUEST Request;
1177
1178 if ((This == NULL) || (Service == NULL) || (Response == NULL) || IS_EMPTY_STRING (Uri)) {
1179 return EFI_INVALID_PARAMETER;
1180 }
1181
1182 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Delete URI: %s\n", __func__, Uri));
1183
1184 Private = REDFISH_HTTP_CACHE_PRIVATE_FROM_THIS (This);
1185 RetryCount = 0;
1186 ZeroMem (Response, sizeof (REDFISH_RESPONSE));
1187 ZeroMem (&Request, sizeof (REDFISH_REQUEST));
1188
1189 Request.Content = Content;
1190 Request.ContentLength = ContentSize;
1191 Request.ContentType = ContentType;
1192
1193 //
1194 // Patch resource to redfish service.
1195 //
1196 do {
1197 RetryCount += 1;
1198 Status = HttpSendReceive (
1199 Service,
1200 Uri,
1201 HttpMethodDelete,
1202 &Request,
1203 Response
1204 );
1205 DEBUG ((REDFISH_HTTP_CACHE_DEBUG_REQUEST, "%a: HTTP request: %s :%r\n", __func__, Uri, Status));
1206 if (!EFI_ERROR (Status) || (RetryCount >= Private->RetrySetting.MaximumRetryDelete)) {
1207 break;
1208 }
1209
1210 //
1211 // Retry when BMC is not ready.
1212 //
1213 if ((Response->StatusCode != NULL)) {
1214 DEBUG_CODE (
1215 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
1216 );
1217
1218 if (!RedfishRetryRequired (Response->StatusCode)) {
1219 break;
1220 }
1221
1222 //
1223 // Release response for next round of request.
1224 //
1225 This->FreeResponse (This, Response);
1226 }
1227
1228 DEBUG ((DEBUG_WARN, "%a: RedfishDeleteByUri failed, retry (%d/%d)\n", __func__, RetryCount, Private->RetrySetting.MaximumRetryDelete));
1229 if (Private->RetrySetting.RetryWait > 0) {
1230 gBS->Stall (Private->RetrySetting.RetryWait);
1231 }
1232 } while (TRUE);
1233
1234 //
1235 // Redfish resource is updated. Automatically expire the cached response
1236 // so application can directly get resource from Redfish service again.
1237 //
1238 DEBUG ((REDFISH_HTTP_CACHE_DEBUG, "%a: Resource is updated, expire URI: %s\n", __func__, Uri));
1239 RedfishExpireResponse (This, Uri);
1240
1241 if (EFI_ERROR (Status) || !RedfishSuccessResponse (HttpMethodDelete, Response->StatusCode)) {
1242 DEBUG_CODE (
1243 DumpRedfishResponse (NULL, DEBUG_ERROR, Response);
1244 );
1245 //
1246 // Report status code for Redfish failure
1247 //
1248 ReportHttpError (HttpMethodDelete, Uri, Response->StatusCode);
1249 DEBUG ((DEBUG_ERROR, "%a: delete %s failed (%d/%d): %r\n", __func__, Uri, RetryCount, Private->RetrySetting.MaximumRetryDelete, Status));
1250 goto ON_RELEASE;
1251 }
1252
1253ON_RELEASE:
1254
1255 return Status;
1256}
1257
1258EDKII_REDFISH_HTTP_PROTOCOL mEdkIIRedfishHttpProtocol = {
1259 EDKII_REDFISH_HTTP_PROTOCOL_REVISION,
1271};
1272
1283EFIAPI
1285 IN EFI_HANDLE ImageHandle
1286 )
1287{
1288 if (mRedfishHttpCachePrivate == NULL) {
1289 return EFI_SUCCESS;
1290 }
1291
1292 if (!IsListEmpty (&mRedfishHttpCachePrivate->CacheList.Head)) {
1293 ReleaseCacheList (&mRedfishHttpCachePrivate->CacheList);
1294 }
1295
1296 gBS->UninstallMultipleProtocolInterfaces (
1297 ImageHandle,
1298 &gEdkIIRedfishHttpProtocolGuid,
1299 &mRedfishHttpCachePrivate->Protocol,
1300 NULL
1301 );
1302
1303 FreePool (mRedfishHttpCachePrivate);
1304 mRedfishHttpCachePrivate = NULL;
1305
1306 return EFI_SUCCESS;
1307}
1308
1316VOID
1317EFIAPI
1319 IN EFI_EVENT Event,
1320 IN VOID *Context
1321 )
1322{
1323 EFI_STATUS Status;
1325
1326 Private = (REDFISH_HTTP_CACHE_PRIVATE *)Context;
1327 if (Private->Signature != REDFISH_HTTP_DRIVER_SIGNATURE) {
1328 DEBUG ((DEBUG_ERROR, "%a: signature check failure\n", __func__));
1329 return;
1330 }
1331
1332 //
1333 // Locate HII credential protocol.
1334 //
1335 Status = gBS->LocateProtocol (
1336 &gEdkIIRedfishCredential2ProtocolGuid,
1337 NULL,
1338 (VOID **)&Private->CredentialProtocol
1339 );
1340 if (EFI_ERROR (Status)) {
1341 return;
1342 }
1343
1344 gBS->CloseEvent (Event);
1345}
1346
1357EFIAPI
1359 IN EFI_HANDLE ImageHandle,
1360 IN EFI_SYSTEM_TABLE *SystemTable
1361 )
1362{
1363 EFI_STATUS Status;
1364 VOID *Registration;
1365
1366 if (mRedfishHttpCachePrivate != NULL) {
1367 return EFI_ALREADY_STARTED;
1368 }
1369
1370 mRedfishHttpCachePrivate = AllocateZeroPool (sizeof (REDFISH_HTTP_CACHE_PRIVATE));
1371 if (mRedfishHttpCachePrivate == NULL) {
1372 return EFI_OUT_OF_RESOURCES;
1373 }
1374
1375 //
1376 // Initial cache list and protocol instance.
1377 //
1378 mRedfishHttpCachePrivate->Signature = REDFISH_HTTP_DRIVER_SIGNATURE;
1379 mRedfishHttpCachePrivate->ImageHandle = ImageHandle;
1380 CopyMem (&mRedfishHttpCachePrivate->Protocol, &mEdkIIRedfishHttpProtocol, sizeof (EDKII_REDFISH_HTTP_PROTOCOL));
1381 mRedfishHttpCachePrivate->CacheList.Capacity = REDFISH_HTTP_CACHE_LIST_SIZE;
1382 mRedfishHttpCachePrivate->CacheList.Count = 0x00;
1383 mRedfishHttpCachePrivate->CacheDisabled = PcdGetBool (PcdHttpCacheDisabled);
1384 InitializeListHead (&mRedfishHttpCachePrivate->CacheList.Head);
1385
1386 //
1387 // Get retry settings
1388 //
1389 mRedfishHttpCachePrivate->RetrySetting.MaximumRetryGet = PcdGet16 (PcdHttpGetRetry);
1390 mRedfishHttpCachePrivate->RetrySetting.MaximumRetryPut = PcdGet16 (PcdHttpPutRetry);
1391 mRedfishHttpCachePrivate->RetrySetting.MaximumRetryPatch = PcdGet16 (PcdHttpPatchRetry);
1392 mRedfishHttpCachePrivate->RetrySetting.MaximumRetryPost = PcdGet16 (PcdHttpPostRetry);
1393 mRedfishHttpCachePrivate->RetrySetting.MaximumRetryDelete = PcdGet16 (PcdHttpDeleteRetry);
1394 mRedfishHttpCachePrivate->RetrySetting.RetryWait = PcdGet16 (PcdHttpRetryWaitInSecond) * 1000000U;
1395
1396 //
1397 // Install the gEdkIIRedfishHttpProtocolGuid onto Handle.
1398 //
1399 Status = gBS->InstallMultipleProtocolInterfaces (
1400 &mRedfishHttpCachePrivate->ImageHandle,
1401 &gEdkIIRedfishHttpProtocolGuid,
1402 &mRedfishHttpCachePrivate->Protocol,
1403 NULL
1404 );
1405 if (EFI_ERROR (Status)) {
1406 DEBUG ((DEBUG_ERROR, "%a: cannot install Redfish http protocol: %r\n", __func__, Status));
1407 RedfishHttpDriverUnload (ImageHandle);
1408 return Status;
1409 }
1410
1411 //
1412 // Install protocol notification if credential protocol is installed.
1413 //
1414 mRedfishHttpCachePrivate->NotifyEvent = EfiCreateProtocolNotifyEvent (
1415 &gEdkIIRedfishCredential2ProtocolGuid,
1416 TPL_CALLBACK,
1418 mRedfishHttpCachePrivate,
1419 &Registration
1420 );
1421 if (mRedfishHttpCachePrivate->NotifyEvent == NULL) {
1422 DEBUG ((DEBUG_ERROR, "%a: failed to create protocol notification for gEdkIIRedfishCredential2ProtocolGuid\n", __func__));
1423 ASSERT (FALSE);
1424 RedfishHttpDriverUnload (ImageHandle);
1425 return Status;
1426 }
1427
1428 return EFI_SUCCESS;
1429}
UINT64 UINTN
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
Definition: LinkedList.c:403
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
RETURN_STATUS EFIAPI UnicodeStrToAsciiStrS(IN CONST CHAR16 *Source, OUT CHAR8 *Destination, IN UINTN DestMax)
Definition: SafeString.c:2650
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
UINTN EFIAPI AsciiStrSize(IN CONST CHAR8 *String)
Definition: String.c:681
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
RETURN_STATUS EFIAPI Base64Encode(IN CONST UINT8 *Source, IN UINTN SourceLength, OUT CHAR8 *Destination OPTIONAL, IN OUT UINTN *DestinationSize)
Definition: String.c:1195
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EDKII_REDFISH_AUTH_METHOD
@ AuthMethodNone
No authentication is required.
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define DEBUG_CODE(Expression)
Definition: DebugLib.h:590
EFI_HTTP_METHOD
Definition: Http.h:43
EFI_HTTP_STATUS_CODE
Definition: Http.h:59
#define PcdGet16(TokenName)
Definition: PcdLib.h:349
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
EFI_STATUS DumpRedfishResponse(IN CONST CHAR8 *Message, IN UINTN ErrorLevel, IN REDFISH_RESPONSE *Response)
EFI_STATUS AddHttpCacheData(IN REDFISH_HTTP_CACHE_LIST *List, IN EFI_STRING Uri, IN REDFISH_RESPONSE *Response)
REDFISH_SERVICE_PRIVATE * CreateRedfishService(IN CHAR8 *Host, IN CHAR8 *HostName, IN CHAR8 *BasicAuth OPTIONAL, IN CHAR8 *SessionToken OPTIONAL, IN EFI_REST_EX_PROTOCOL *RestEx)
EFI_STATUS CopyRedfishResponse(IN REDFISH_RESPONSE *SrcResponse, OUT REDFISH_RESPONSE *DstResponse)
EFI_STATUS ReleaseRedfishService(IN REDFISH_SERVICE_PRIVATE *Service)
EFI_STATUS ReleaseCacheList(IN REDFISH_HTTP_CACHE_LIST *CacheList)
EFI_STATUS DeleteHttpCacheData(IN REDFISH_HTTP_CACHE_LIST *List, IN REDFISH_HTTP_CACHE_DATA *Data)
REDFISH_HTTP_CACHE_DATA * FindHttpCacheData(IN LIST_ENTRY *ListHeader, IN EFI_STRING Uri)
EFI_STATUS EFIAPI RedfishExpireResponse(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN EFI_STRING Uri)
EFI_STATUS EFIAPI RedfishGetResource(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_SERVICE Service, IN EFI_STRING Uri, IN REDFISH_REQUEST *Request OPTIONAL, OUT REDFISH_RESPONSE *Response, IN BOOLEAN UseCache)
EFI_STATUS EFIAPI RedfishPutResource(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_SERVICE Service, IN EFI_STRING Uri, IN CHAR8 *Content, IN UINTN ContentSize OPTIONAL, IN CHAR8 *ContentType OPTIONAL, OUT REDFISH_RESPONSE *Response)
BOOLEAN RedfishSuccessResponse(IN EFI_HTTP_METHOD Method, IN EFI_HTTP_STATUS_CODE *StatusCode)
EFI_STATUS EFIAPI RedfishFreeResponse(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_RESPONSE *Response)
BOOLEAN RedfishRetryRequired(IN EFI_HTTP_STATUS_CODE *StatusCode)
EFI_STATUS DebugPrintHttpCacheList(IN CONST CHAR8 *Msg, IN UINTN ErrorLevel, IN REDFISH_HTTP_CACHE_LIST *CacheList)
EFI_STATUS EFIAPI RedfishPatchResource(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_SERVICE Service, IN EFI_STRING Uri, IN CHAR8 *Content, IN UINTN ContentSize OPTIONAL, IN CHAR8 *ContentType OPTIONAL, OUT REDFISH_RESPONSE *Response)
EFI_STATUS EFIAPI RedfishDeleteResource(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_SERVICE Service, IN EFI_STRING Uri, IN CHAR8 *Content OPTIONAL, IN UINTN ContentSize OPTIONAL, IN CHAR8 *ContentType OPTIONAL, OUT REDFISH_RESPONSE *Response)
EFI_STATUS EFIAPI RedfishHttpDriverUnload(IN EFI_HANDLE ImageHandle)
EDKII_JSON_VALUE EFIAPI RedfishJsonInRedfishPayload(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_PAYLOAD RedfishPayload)
EFI_STATUS EFIAPI RedfishFreeRedfishService(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_SERVICE RedfishService)
CHAR8 * HttpMethodToString(IN EFI_HTTP_METHOD Method)
EFI_STATUS EFIAPI RedfishHttpEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI RedfishFreeRequest(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_REQUEST *Request)
VOID ReportHttpError(IN EFI_HTTP_METHOD Method, IN EFI_STRING Uri, IN EFI_HTTP_STATUS_CODE *HttpStatusCode OPTIONAL)
EFI_STATUS EFIAPI RedfishPostResource(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_SERVICE Service, IN EFI_STRING Uri, IN CHAR8 *Content, IN UINTN ContentSize OPTIONAL, IN CHAR8 *ContentType OPTIONAL, OUT REDFISH_RESPONSE *Response)
VOID EFIAPI CredentialProtocolInstalled(IN EFI_EVENT Event, IN VOID *Context)
CHAR8 * StringUnicodeToAscii(IN EFI_STRING UnicodeStr)
REDFISH_SERVICE EFIAPI RedfishCreateRedfishService(IN EDKII_REDFISH_HTTP_PROTOCOL *This, IN REDFISH_CONFIG_SERVICE_INFORMATION *RedfishConfigServiceInfo)
EFI_STATUS ReleaseRedfishRequest(IN REDFISH_REQUEST *Request)
EFI_STATUS ReleaseRedfishResponse(IN REDFISH_RESPONSE *Response)
EFI_STATUS HttpSendReceive(IN REDFISH_SERVICE Service, IN EFI_STRING Uri, IN EFI_HTTP_METHOD Method, IN REDFISH_REQUEST *Request OPTIONAL, OUT REDFISH_RESPONSE *Response)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
Definition: UefiLib.c:134