2 This file contains an 'Intel UEFI Application' and is
3 licensed for Intel CPUs and chipsets under the terms of your
4 license agreement with Intel or your vendor. This file may
5 be modified by the user, subject to additional terms of the
10 Copyright (c) 2011 Intel Corporation. All rights reserved
11 This software and associated documentation (if any) is furnished
12 under a license and may only be used or copied in accordance
13 with the terms of the license. Except as permitted by such
14 license, no part of this software or documentation may be
15 reproduced, stored in a retrieval system, or transmitted in any
16 form or by any means without the express written consent of
22 HTTP processing for the web server.
26 #include <WebServer.h>
29 Get a UTF-8 character from the buffer
31 @param [in] pData The address of the buffer containing the character
32 @param [out] ppData The address to receive the next character address
34 @return The character value
49 // Verify that there is some data left
51 if ( NULL
== pData
) {
60 // Get the first portion of the character
67 // Append the rest of the character
69 if ( 0 != ( Control
& 0x80 )) {
70 while ( 0 != ( Control
& 0x40 )) {
75 Data
= *pData
++ & 0x3f;
76 if ( 0x80 != ( Data
& 0xc0 )) {
84 Character
|= Data
& 0x3f;
90 // Return the next character location and the character
98 Transmit a portion of the HTTP response
100 @param [in] SocketFD The socket's file descriptor to add to the list.
101 @param [in] pPort The WSDT_PORT structure address
103 @retval EFI_SUCCESS The request was successfully processed
121 Status
= EFI_SUCCESS
;
122 pBuffer
= &pPort
->TxBuffer
[0];
125 // Attempt to send the data
127 LengthInBytes
= send ( SocketFD
,
131 if ( -1 != LengthInBytes
) {
133 // Account for the data sent
135 pBuffer
+= LengthInBytes
;
136 pPort
->TxBytes
-= LengthInBytes
;
142 Status
= EFI_DEVICE_ERROR
;
145 } while ( 0 < pPort
->TxBytes
);
148 // Return the operation status
150 DBG_EXIT_STATUS ( Status
);
156 Convert the ANSI character to lower case
158 @param [in] Character The character to convert to lower case.
160 @return The lower case character
169 // Determine if the character is upper case
171 if (( 'A' <= Character
) && ( 'Z' >= Character
)) {
172 Character
+= 'a' - 'A';
176 // Return the lower case value of the character
183 Match a Unicode string against a UTF-8 string
185 @param [in] pString A zero terminated Unicode string
186 @param [in] pData A zero terminated UTF-8 string
187 @param [in] bIgnoreCase TRUE if case is to be ignored
189 @return The difference between the last two characters tested.
190 Returns -1 for error.
197 IN BOOLEAN bIgnoreCase
206 // Get the character from the comparison string
208 Character1
= *pString
++;
211 // Convert the character to lower case
214 Character1
= HttpLowerCase ( Character1
);
218 // Get the character from the request
220 Character2
= HttpCharGet ( pData
, &pData
);
221 if ( NULL
== pData
) {
223 // Error getting character
230 // Convert the character to lower case
233 Character2
= HttpLowerCase ( Character2
);
237 // Compare the characters
239 Difference
= Character1
- Character2
;
240 if ( 0 != Difference
) {
243 } while ( 0 != Character1
);
246 // Return the difference
253 Buffer the HTTP page header
255 @param [in] SocketFD The socket's file descriptor to add to the list.
256 @param [in] pPort The WSDT_PORT structure address
257 @param [in] pTitle A zero terminated Unicode title string
259 @retval EFI_SUCCESS The request was successfully processed
265 IN WSDT_PORT
* pPort
,
266 IN CONST CHAR16
* pTitle
274 // Build the page header
277 Status
= HttpSendAnsiString ( SocketFD
,
282 "\"-//W3C//DTD HTML 4.01 Transitional//EN\" "
283 "\"http://www.w3.org/TR/html4/loose.dtd\">\r\n" );
284 if ( EFI_ERROR ( Status
)) {
287 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "<html lang=\"en-US\">\r\n" );
288 if ( EFI_ERROR ( Status
)) {
291 if ( NULL
!= pTitle
) {
292 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <head>\r\n" );
293 if ( EFI_ERROR ( Status
)) {
296 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <title>" );
297 if ( EFI_ERROR ( Status
)) {
300 Status
= HttpSendUnicodeString ( SocketFD
, pPort
, pTitle
);
301 if ( EFI_ERROR ( Status
)) {
304 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "</title>\r\n" );
305 if ( EFI_ERROR ( Status
)) {
308 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </head>\r\n" );
309 if ( EFI_ERROR ( Status
)) {
313 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <body>\r\n" );
318 // Return the operation status
320 DBG_EXIT_STATUS ( Status
);
326 Respond with an error indicating that the page was not found
328 @param [in] SocketFD The socket's file descriptor to add to the list.
329 @param [in] pPort The WSDT_PORT structure address
330 @param [out] pbDone Address to receive the request completion status
332 @retval EFI_SUCCESS The request was successfully processed
338 IN WSDT_PORT
* pPort
,
347 // Send the page not found
351 // Send the page header
353 Status
= HttpPageHeader ( SocketFD
, pPort
, L
"404 Not found" );
354 if ( EFI_ERROR ( Status
)) {
359 // Send the page body
361 Status
= HttpSendAnsiString ( SocketFD
,
363 "ERROR <b>404</b><br />"
364 "Requested page is not available\r\n" );
365 if ( EFI_ERROR ( Status
)) {
370 // Send the page trailer
372 Status
= HttpPageTrailer ( SocketFD
, pPort
, pbDone
);
377 // Return the operation status
379 DBG_EXIT_STATUS ( Status
);
385 Buffer and send the HTTP page trailer
387 @param [in] SocketFD The socket's file descriptor to add to the list.
388 @param [in] pPort The WSDT_PORT structure address
389 @param [out] pbDone Address to receive the request completion status
391 @retval EFI_SUCCESS The request was successfully processed
397 IN WSDT_PORT
* pPort
,
403 socklen_t LengthInBytes
;
404 struct sockaddr_in6 LocalAddress
;
405 struct sockaddr_in6 RemoteAddress
;
410 // Build the page header
413 LengthInBytes
= sizeof ( LocalAddress
);
414 RetVal
= getsockname ( SocketFD
, (struct sockaddr
*)&LocalAddress
, &LengthInBytes
);
416 LengthInBytes
= sizeof ( LocalAddress
);
417 RetVal
= getpeername ( SocketFD
, (struct sockaddr
*)&RemoteAddress
, &LengthInBytes
);
420 // Seperate the body from the trailer
422 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <hr>\r\n<code>" );
423 if ( EFI_ERROR ( Status
)) {
428 // Display the system addresses and the page transfer direction
430 Status
= HttpSendIpAddress ( SocketFD
, pPort
, &LocalAddress
);
431 if ( EFI_ERROR ( Status
)) {
434 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " --> " );
435 if ( EFI_ERROR ( Status
)) {
438 Status
= HttpSendIpAddress ( SocketFD
, pPort
, &RemoteAddress
);
439 if ( EFI_ERROR ( Status
)) {
442 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "</code>\r\n" );
443 if ( EFI_ERROR ( Status
)) {
450 // Terminate the page
452 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </body>\r\n" );
453 if ( EFI_ERROR ( Status
)) {
456 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </html>\r\n" );
457 if ( EFI_ERROR ( Status
)) {
462 // Send the page trailer
464 Status
= HttpFlush ( SocketFD
, pPort
);
465 if ( EFI_ERROR ( Status
)) {
470 // Mark the page as complete
477 // Return the operation status
479 DBG_EXIT_STATUS ( Status
);
485 Replace a space with a zero
487 @param [in] pData The request buffer address
488 @param [in] pEnd End of buffer address
490 @return The next character location
503 while ( pEnd
> pData
) {
505 // Get the character from the request
507 Character
= HttpCharGet ( pData
, &pData
);
508 if ( ' ' == Character
) {
515 // Replace the space character with zero
517 ZeroMem ( pSpace
, pData
- pSpace
);
520 // Return the next character location
527 Process an HTTP request
529 @param [in] SocketFD The socket's file descriptor to add to the list.
530 @param [in] pPort The WSDT_PORT structure address
531 @param [out] pbDone Address to receive the request completion status
533 @retval EFI_SUCCESS The request was successfully processed
539 IN WSDT_PORT
* pPort
,
545 CONST DT_PAGE
* pPage
;
546 CONST DT_PAGE
* pPageEnd
;
555 // Assume the request is not finished
558 Status
= EFI_SUCCESS
;
562 // Attempt to parse the command
564 pData
= &pPort
->Request
[0];
565 pEnd
= &pData
[ pPort
->RequestLength
];
567 pWebPage
= HttpReplaceSpace ( pVerb
, pEnd
);
568 if ( pEnd
<= pWebPage
) {
571 pVersion
= HttpReplaceSpace ( pWebPage
, pEnd
);
572 if ( pEnd
<= pVersion
) {
577 // Validate the request
579 if ( 0 != HttpMatch ( L
"GET", pVerb
, TRUE
)) {
581 // Invalid request type
583 DEBUG (( DEBUG_REQUEST
,
584 "HTTP: Invalid verb\r\n" ));
585 Status
= EFI_NOT_FOUND
;
590 // Walk the page table
592 pPage
= &mPageList
[0];
593 pPageEnd
= &pPage
[ mPageCount
];
594 while ( pPageEnd
> pPage
) {
596 // Determine if the page was located
598 if ( 0 == HttpMatch ( pPage
->pPageName
, pWebPage
, FALSE
)) {
607 if ( pPageEnd
<= pPage
) {
609 // The page was not found
611 DEBUG (( DEBUG_REQUEST
,
612 "HTTP: Page not found in page table\r\n" ));
613 Status
= EFI_NOT_FOUND
;
618 // Respond with the page contents
620 Status
= pPage
->pfnResponse ( SocketFD
, pPort
, pbDone
);
625 // Return page not found if necessary
627 if ( EFI_NOT_FOUND
== Status
) {
628 Status
= HttpPageNotFound ( SocketFD
, pPort
, pbDone
);
632 // Return the operation status
634 DBG_EXIT_STATUS ( Status
);
640 Buffer data for sending
642 @param [in] SocketFD The socket's file descriptor to add to the list.
643 @param [in] pPort The WSDT_PORT structure address
644 @param [in] LengthInBytes Length of valid data in the buffer
645 @param [in] pBuffer Buffer of data to send
647 @retval EFI_SUCCESS The request was successfully processed
653 IN WSDT_PORT
* pPort
,
654 IN
size_t LengthInBytes
,
655 IN CONST UINT8
* pBuffer
665 Status
= EFI_SUCCESS
;
668 // Determine how much data fits into the buffer
670 MaxBytes
= sizeof ( pPort
->TxBuffer
);
671 DataBytes
= MaxBytes
- pPort
->TxBytes
;
672 if ( DataBytes
> LengthInBytes
) {
673 DataBytes
= LengthInBytes
;
677 // Copy the data into the buffer
679 CopyMem ( &pPort
->TxBuffer
[ pPort
->TxBytes
],
684 // Account for the data copied
686 pPort
->TxBytes
+= DataBytes
;
687 LengthInBytes
-= DataBytes
;
690 // Transmit the buffer if it is full
692 if ( MaxBytes
<= pPort
->TxBytes
) {
693 Status
= HttpFlush ( SocketFD
, pPort
);
695 } while (( EFI_SUCCESS
== Status
) && ( 0 < LengthInBytes
));
698 // Return the operation status
707 @param [in] SocketFD The socket's file descriptor to add to the list.
708 @param [in] pPort The WSDT_PORT structure address
709 @param [in] pString A zero terminated Unicode string
711 @retval EFI_SUCCESS The request was successfully processed
717 IN WSDT_PORT
* pPort
,
718 IN CONST
char * pString
727 Status
= EFI_SUCCESS
;
730 // Walk the characters in he string
733 while ( 0 != *pData
) {
740 Status
= HttpSend ( SocketFD
,
743 (CONST UINT8
*)pString
);
746 // Return the operation status
755 @param [in] SocketFD The socket's file descriptor to add to the list.
756 @param [in] pPort The WSDT_PORT structure address
757 @param [in] Data The data byte to send
759 @retval EFI_SUCCESS The request was successfully processed
765 IN WSDT_PORT
* pPort
,
772 // Send the data byte
774 Status
= HttpSend ( SocketFD
,
780 // Return the operation status
789 @param [in] SocketFD The socket's file descriptor to add to the list.
790 @param [in] pPort The WSDT_PORT structure address
791 @param [in] Character Character to display
792 @param [in] pReplacement Replacement character string
794 @retval EFI_SUCCESS The request was successfully processed
800 IN WSDT_PORT
* pPort
,
802 IN CHAR8
* pReplacement
808 // Determine if this is a printable character
810 if (( 0x20 <= Character
) && ( 0x7f > Character
)) {
811 if ( '<' == Character
) {
813 // Replace with HTML equivalent
815 Status
= HttpSendAnsiString ( SocketFD
,
819 else if ( '>' == Character
) {
821 // Replace with HTML equivalent
823 Status
= HttpSendAnsiString ( SocketFD
,
827 else if ( '&' == Character
) {
829 // Replace with HTML equivalent
831 Status
= HttpSendAnsiString ( SocketFD
,
835 else if ( '\"' == Character
) {
837 // Replace with HTML equivalent
839 Status
= HttpSendAnsiString ( SocketFD
,
845 // Display the character
847 Status
= HttpSendByte ( SocketFD
,
854 // Not a displayable character
856 Status
= HttpSendAnsiString ( SocketFD
,
862 // Return the operation status
871 @param [in] SocketFD The socket's file descriptor to add to the list.
872 @param [in] pPort The WSDT_PORT structure address
873 @param [in] ByteCount The number of bytes to display
874 @param [in] pData Address of the byte array
876 @retval EFI_SUCCESS The request was successfully processed
882 IN WSDT_PORT
* pPort
,
884 IN CONST UINT8
* pData
891 CONST UINT8
* pDataEnd
;
897 // Use for/break instead of goto
901 // Start the field value
903 Status
= HttpSendAnsiString ( SocketFD
,
906 if ( EFI_ERROR ( Status
)) {
911 // Walk the bytes to be displayed
913 pEnd
= &pData
[ ByteCount
];
914 while ( pEnd
> pData
) {
916 // Display the address
918 Status
= HttpSendHexBits ( SocketFD
,
920 sizeof ( pData
) * 8,
922 if ( EFI_ERROR ( Status
)) {
927 // Separate the address and data
929 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
930 if ( EFI_ERROR ( Status
)) {
935 // Position the starting data correctly
937 InitialSpaces
= (UINTN
)pData
;
938 InitialSpaces
&= BYTES_ON_A_LINE
- 1;
939 for ( Index
= SPACES_ADDRESS_TO_DATA
940 + (( 2 + SPACES_BETWEEN_BYTES
)
942 0 < Index
; Index
-- ) {
943 Status
= HttpSendAnsiString ( SocketFD
,
946 if ( EFI_ERROR ( Status
)) {
950 if ( EFI_ERROR ( Status
)) {
957 BytesToDisplay
= pEnd
- pData
;
958 if (( BYTES_ON_A_LINE
- InitialSpaces
) < BytesToDisplay
) {
959 BytesToDisplay
= BYTES_ON_A_LINE
- InitialSpaces
;
961 pDataEnd
= &pData
[ BytesToDisplay
];
963 while ( pDataEnd
> pTemp
) {
964 Status
= HttpSendHexBits ( SocketFD
,
968 if ( EFI_ERROR ( Status
)) {
973 // Separate the data bytes
975 for ( Index
= SPACES_BETWEEN_BYTES
; 0 < Index
; Index
-- ) {
976 Status
= HttpSendAnsiString ( SocketFD
,
979 if ( EFI_ERROR ( Status
)) {
983 if ( EFI_ERROR ( Status
)) {
987 if ( EFI_ERROR ( Status
)) {
992 // Separate the data from the ASCII display
994 for ( Index
= (( 2 + SPACES_BETWEEN_BYTES
)
995 * ( BYTES_ON_A_LINE
- BytesToDisplay
- InitialSpaces
))
996 - SPACES_BETWEEN_BYTES
997 + SPACES_DATA_TO_ASCII
999 0 < Index
; Index
-- ) {
1000 Status
= HttpSendAnsiString ( SocketFD
,
1003 if ( EFI_ERROR ( Status
)) {
1007 if ( EFI_ERROR ( Status
)) {
1012 // Display the ASCII data
1014 while ( pDataEnd
> pData
) {
1015 Character
= *pData
++;
1016 Status
= HttpSendCharacter ( SocketFD
,
1020 if ( EFI_ERROR ( Status
)) {
1024 if ( EFI_ERROR ( Status
)) {
1029 // Terminate the line
1031 Status
= HttpSendAnsiString ( SocketFD
,
1034 if ( EFI_ERROR ( Status
)) {
1040 // Terminate the field value and row
1042 Status
= HttpSendAnsiString ( SocketFD
,
1049 // Return the operation status
1056 Display a row containing a GUID value
1058 @param [in] SocketFD The socket's file descriptor to add to the list.
1059 @param [in] pPort The WSDT_PORT structure address
1060 @param [in] pGuid Address of the GUID to display
1062 @retval EFI_SUCCESS The request was successfully processed
1068 IN WSDT_PORT
* pPort
,
1069 IN CONST EFI_GUID
* pGuid
1078 // Use for/break instead of goto
1082 // Display the GUID in a form found in the code
1084 // E.g. 0xca16005f, 0x11ec, 0x4bdc, { 0x99, 0x97, 0x27, 0x2c, 0xa9, 0xba, 0x15, 0xe5 }
1088 // Display the first 32 bits
1090 Status
= HttpSendAnsiString ( SocketFD
,
1093 if ( EFI_ERROR ( Status
)) {
1096 Status
= HttpSendHexBits ( SocketFD
,
1100 if ( EFI_ERROR ( Status
)) {
1105 // Display the second 16 bits
1107 Status
= HttpSendAnsiString ( SocketFD
,
1110 if ( EFI_ERROR ( Status
)) {
1113 Status
= HttpSendHexBits ( SocketFD
,
1117 if ( EFI_ERROR ( Status
)) {
1122 // Display the thrid 16 bits
1124 Status
= HttpSendAnsiString ( SocketFD
,
1127 if ( EFI_ERROR ( Status
)) {
1130 Status
= HttpSendHexBits ( SocketFD
,
1134 if ( EFI_ERROR ( Status
)) {
1139 // Place the last 64 bits in braces
1141 Status
= HttpSendAnsiString ( SocketFD
,
1144 if ( EFI_ERROR ( Status
)) {
1147 for ( Index
= 0; 7 >= Index
; Index
++ ) {
1149 // Display the next 8 bits
1151 Status
= HttpSendHexBits ( SocketFD
,
1154 pGuid
->Data4
[ Index
]);
1155 if ( EFI_ERROR ( Status
)) {
1160 // Separate the bytes
1162 Status
= HttpSendAnsiString ( SocketFD
,
1164 ( 7 != Index
) ? ", 0x" : " }" );
1165 if ( EFI_ERROR ( Status
)) {
1173 // Return the operation status
1175 DBG_EXIT_STATUS ( Status
);
1181 Output a hex value to the HTML page
1183 @param [in] SocketFD Socket file descriptor
1184 @param [in] pPort The WSDT_PORT structure address
1185 @param [in] Bits Number of bits to display
1186 @param [in] Value Value to display
1188 @retval EFI_SUCCESS Successfully displayed the address
1193 IN WSDT_PORT
* pPort
,
1205 Status
= EFI_SUCCESS
;
1208 // Walk the list of divisors
1210 Shift
= (( Bits
+ 3 ) & ( ~3 )) - 4;
1211 while ( 0 <= Shift
) {
1213 // Determine the next digit
1215 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1216 if ( 10 <= Digit
) {
1217 Digit
+= 'a' - '0' - 10;
1221 // Display the digit
1223 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1224 if ( EFI_ERROR ( Status
)) {
1229 // Set the next shift
1235 // Return the operation status
1242 Output a hex value to the HTML page
1244 @param [in] SocketFD Socket file descriptor
1245 @param [in] pPort The WSDT_PORT structure address
1246 @param [in] Value Value to display
1248 @retval EFI_SUCCESS Successfully displayed the address
1253 IN WSDT_PORT
* pPort
,
1257 BOOLEAN bDisplayZeros
;
1265 Status
= EFI_SUCCESS
;
1268 // Walk the list of divisors
1270 bDisplayZeros
= FALSE
;
1274 // Determine the next digit
1276 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1277 if ( 10 <= Digit
) {
1278 Digit
+= 'a' - '0' - 10;
1282 // Suppress leading zeros
1284 if (( 0 != Digit
) || bDisplayZeros
|| ( 0 == Shift
)) {
1285 bDisplayZeros
= TRUE
;
1288 // Display the digit
1290 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1291 if ( EFI_ERROR ( Status
)) {
1297 // Set the next shift
1300 } while ( 0 <= Shift
);
1303 // Return the operation status
1310 Output an IP6 address value to the HTML page
1312 @param [in] SocketFD Socket file descriptor
1313 @param [in] pPort The WSDT_PORT structure address
1314 @param [in] Value Value to display
1315 @param [in] bFirstValue TRUE if first value
1316 @param [in] bLastValue TRUE if last value
1317 @param [in] bZeroSuppression TRUE while zeros are being suppressed
1318 @param [in] pbZeroSuppression Address to receive TRUE when zero suppression
1319 has started, use NULL if next colon value not
1322 @retval EFI_SUCCESS Successfully displayed the address
1327 IN WSDT_PORT
* pPort
,
1329 IN BOOLEAN bFirstValue
,
1330 IN BOOLEAN bLastValue
,
1331 IN BOOLEAN bZeroSuppression
,
1332 IN BOOLEAN
* pbZeroSuppression
1335 BOOLEAN bZeroSuppressionStarting
;
1340 // Use break instead of goto
1342 bZeroSuppressionStarting
= FALSE
;
1343 Status
= EFI_SUCCESS
;
1346 // Display the leading colon if necessary
1348 if ( bZeroSuppression
&& ( bLastValue
|| ( 0 != Value
))) {
1349 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1350 if ( EFI_ERROR ( Status
)) {
1356 // Skip over a series of zero values
1358 bZeroSuppressionStarting
= (BOOLEAN
)( 0 == Value
);
1359 if ( !bZeroSuppressionStarting
) {
1361 // Display the value
1363 Digit
= ( Value
>> 4 ) & 0xf;
1364 Status
= HttpSendHexValue ( SocketFD
,
1367 if ( EFI_ERROR ( Status
)) {
1370 Digit
= Value
& 0xf;
1371 Status
= HttpSendHexValue ( SocketFD
,
1374 if ( EFI_ERROR ( Status
)) {
1377 Digit
= ( Value
>> 12 ) & 0xf;
1378 Status
= HttpSendHexValue ( SocketFD
,
1381 if ( EFI_ERROR ( Status
)) {
1384 Digit
= ( Value
>> 8 ) & 0xf;
1385 Status
= HttpSendHexValue ( SocketFD
,
1388 if ( EFI_ERROR ( Status
)) {
1394 // Display the trailing colon if necessary
1396 if (( !bLastValue
) && ( bFirstValue
|| ( 0 != Value
))) {
1397 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1403 // Return the next colon display
1404 if ( NULL
!= pbZeroSuppression
) {
1405 *pbZeroSuppression
= bZeroSuppressionStarting
;
1409 // Return the operation status
1416 Output an IP address to the HTML page
1418 @param [in] SocketFD Socket file descriptor
1419 @param [in] pPort The WSDT_PORT structure address
1420 @param [in] pAddress Address of the socket address
1422 @retval EFI_SUCCESS Successfully displayed the address
1427 IN WSDT_PORT
* pPort
,
1428 IN
struct sockaddr_in6
* pAddress
1431 BOOLEAN bZeroSuppression
;
1433 struct sockaddr_in
* pIpv4
;
1434 struct sockaddr_in6
* pIpv6
;
1439 // Use break instead of goto
1443 // Determine the type of address
1445 if ( AF_INET6
== pAddress
->sin6_family
) {
1449 // Display the address in RFC2732 format
1451 bZeroSuppression
= FALSE
;
1452 Status
= HttpSendByte ( SocketFD
, pPort
, '[' );
1453 if ( EFI_ERROR ( Status
)) {
1456 for ( Index
= 0; 8 > Index
; Index
++ ) {
1457 Status
= HttpSendIp6Value ( SocketFD
,
1459 pIpv6
->sin6_addr
.__u6_addr
.__u6_addr16
[ Index
],
1460 (BOOLEAN
)( 0 == Index
),
1461 (BOOLEAN
)( 7 == Index
),
1463 &bZeroSuppression
);
1464 if ( EFI_ERROR ( Status
)) {
1468 if ( EFI_ERROR ( Status
)) {
1473 // Separate the port number
1475 Status
= HttpSendByte ( SocketFD
, pPort
, ']' );
1478 // Get the port number
1480 PortNumber
= pIpv6
->sin6_port
;
1484 // Output the IPv4 address
1486 pIpv4
= (struct sockaddr_in
*)pAddress
;
1487 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)pIpv4
->sin_addr
.s_addr
);
1488 if ( EFI_ERROR ( Status
)) {
1491 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1492 if ( EFI_ERROR ( Status
)) {
1495 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pIpv4
->sin_addr
.s_addr
>> 8 ));
1496 if ( EFI_ERROR ( Status
)) {
1499 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1500 if ( EFI_ERROR ( Status
)) {
1503 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pIpv4
->sin_addr
.s_addr
>> 16 ));
1504 if ( EFI_ERROR ( Status
)) {
1507 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1508 if ( EFI_ERROR ( Status
)) {
1511 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pIpv4
->sin_addr
.s_addr
>> 24 ));
1514 // Get the port number
1516 PortNumber
= pIpv4
->sin_port
;
1518 if ( EFI_ERROR ( Status
)) {
1523 // Display the port number
1525 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1526 if ( EFI_ERROR ( Status
)) {
1529 Status
= HttpSendValue ( SocketFD
, pPort
, htons ( PortNumber
));
1534 // Return the operation status
1541 Send a Unicode string
1543 @param [in] SocketFD The socket's file descriptor to add to the list.
1544 @param [in] pPort The WSDT_PORT structure address
1545 @param [in] pString A zero terminated Unicode string
1547 @retval EFI_SUCCESS The request was successfully processed
1551 HttpSendUnicodeString (
1553 IN WSDT_PORT
* pPort
,
1554 IN CONST UINT16
* pString
1564 Status
= EFI_SUCCESS
;
1567 // Walk the characters in he string
1569 while ( 0 != ( Character
= *pString
++ )) {
1571 // Convert the character to UTF-8
1573 if ( 0 != ( Character
& 0xf800 )) {
1575 // Send the upper 4 bits
1577 Data
= (UINT8
)(( Character
>> 12 ) & 0xf );
1579 Status
= HttpSendByte ( SocketFD
,
1582 if ( EFI_ERROR ( Status
)) {
1587 // Send the next 6 bits
1589 Data
= (UINT8
)(( Character
>> 6 ) & 0x3f );
1591 Status
= HttpSendByte ( SocketFD
,
1594 if ( EFI_ERROR ( Status
)) {
1599 // Send the last 6 bits
1601 Data
= (UINT8
)( Character
& 0x3f );
1604 else if ( 0 != ( Character
& 0x0780 )) {
1606 // Send the upper 5 bits
1608 Data
= (UINT8
)(( Character
>> 6 ) & 0x1f );
1610 Status
= HttpSendByte ( SocketFD
,
1613 if ( EFI_ERROR ( Status
)) {
1618 // Send the last 6 bits
1620 Data
= (UINT8
)( Character
& 0x3f );
1624 Data
= (UINT8
)( Character
& 0x7f );
1628 // Send the last data byte
1630 Status
= HttpSendByte ( SocketFD
,
1633 if ( EFI_ERROR ( Status
)) {
1639 // Return the operation status
1646 Output a value to the HTML page
1648 @param [in] SocketFD Socket file descriptor
1649 @param [in] pPort The WSDT_PORT structure address
1650 @param [in] Value Value to display
1652 @retval EFI_SUCCESS Successfully displayed the address
1657 IN WSDT_PORT
* pPort
,
1661 BOOLEAN bDisplayZeros
;
1663 CONST UINT64
* pEnd
;
1664 CONST UINT64
* pDivisor
;
1665 CONST UINT64 pDivisors
[ ] = {
1666 10000000000000000000L,
1667 1000000000000000000L,
1668 100000000000000000L,
1692 Status
= EFI_SUCCESS
;
1695 // Walk the list of divisors
1697 bDisplayZeros
= FALSE
;
1698 pDivisor
= &pDivisors
[0];
1699 pEnd
= &pDivisor
[ sizeof ( pDivisors
) / sizeof ( pDivisors
[0])];
1700 while ( pEnd
> pDivisor
) {
1702 // Determine the next digit
1704 Digit
= Value
/ *pDivisor
;
1707 // Suppress leading zeros
1709 if (( 0 != Digit
) || bDisplayZeros
) {
1710 bDisplayZeros
= TRUE
;
1713 // Display the digit
1715 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1716 if ( EFI_ERROR ( Status
)) {
1721 // Determine the remainder
1723 Temp
= *pDivisor
* Digit
;
1728 // Set the next divisor
1734 // Display the final digit
1736 if ( !EFI_ERROR ( Status
)) {
1737 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Value
));
1741 // Return the operation status