3 HTTP processing for the web server.
5 Copyright (c) 2011-2012, Intel Corporation
6 All rights reserved. This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <WebServer.h>
20 Get a UTF-8 character from the buffer
22 @param [in] pData The address of the buffer containing the character
23 @param [out] ppData The address to receive the next character address
25 @return The character value
40 // Verify that there is some data left
42 if ( NULL
== pData
) {
51 // Get the first portion of the character
58 // Append the rest of the character
60 if ( 0 != ( Control
& 0x80 )) {
61 while ( 0 != ( Control
& 0x40 )) {
66 Data
= *pData
++ & 0x3f;
67 if ( 0x80 != ( Data
& 0xc0 )) {
75 Character
|= Data
& 0x3f;
81 // Return the next character location and the character
89 Transmit a portion of the HTTP response
91 @param [in] SocketFD The socket's file descriptor to add to the list.
92 @param [in] pPort The WSDT_PORT structure address
94 @retval EFI_SUCCESS The request was successfully processed
112 Status
= EFI_SUCCESS
;
113 pBuffer
= &pPort
->TxBuffer
[0];
116 // Attempt to send the data
118 LengthInBytes
= send ( SocketFD
,
122 if ( -1 != LengthInBytes
) {
124 // Account for the data sent
126 pBuffer
+= LengthInBytes
;
127 pPort
->TxBytes
-= LengthInBytes
;
133 Status
= EFI_DEVICE_ERROR
;
136 } while ( 0 < pPort
->TxBytes
);
139 // Return the operation status
141 DBG_EXIT_STATUS ( Status
);
147 Convert the ANSI character to lower case
149 @param [in] Character The character to convert to lower case.
151 @return The lower case character
160 // Determine if the character is upper case
162 if (( 'A' <= Character
) && ( 'Z' >= Character
)) {
163 Character
+= 'a' - 'A';
167 // Return the lower case value of the character
174 Match a Unicode string against a UTF-8 string
176 @param [in] pString A zero terminated Unicode string
177 @param [in] pData A zero terminated UTF-8 string
178 @param [in] bIgnoreCase TRUE if case is to be ignored
180 @return The difference between the last two characters tested.
181 Returns -1 for error.
188 IN BOOLEAN bIgnoreCase
197 // Get the character from the comparison string
199 Character1
= *pString
++;
202 // Convert the character to lower case
205 Character1
= HttpLowerCase ( Character1
);
209 // Get the character from the request
211 Character2
= HttpCharGet ( pData
, &pData
);
212 if ( NULL
== pData
) {
214 // Error getting character
221 // Convert the character to lower case
224 Character2
= HttpLowerCase ( Character2
);
228 // Compare the characters
230 Difference
= Character1
- Character2
;
231 if ( 0 != Difference
) {
234 } while ( 0 != Character1
);
237 // Return the difference
244 Buffer the HTTP page header
246 @param [in] SocketFD The socket's file descriptor to add to the list.
247 @param [in] pPort The WSDT_PORT structure address
248 @param [in] pTitle A zero terminated Unicode title string
250 @retval EFI_SUCCESS The request was successfully processed
256 IN WSDT_PORT
* pPort
,
257 IN CONST CHAR16
* pTitle
265 // Build the page header
268 Status
= HttpSendAnsiString ( SocketFD
,
273 "\"-//W3C//DTD HTML 4.01 Transitional//EN\" "
274 "\"http://www.w3.org/TR/html4/loose.dtd\">\r\n" );
275 if ( EFI_ERROR ( Status
)) {
278 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "<html lang=\"en-US\">\r\n" );
279 if ( EFI_ERROR ( Status
)) {
282 if ( NULL
!= pTitle
) {
283 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <head>\r\n" );
284 if ( EFI_ERROR ( Status
)) {
287 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <title>" );
288 if ( EFI_ERROR ( Status
)) {
291 Status
= HttpSendUnicodeString ( SocketFD
, pPort
, pTitle
);
292 if ( EFI_ERROR ( Status
)) {
295 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "</title>\r\n" );
296 if ( EFI_ERROR ( Status
)) {
299 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </head>\r\n" );
300 if ( EFI_ERROR ( Status
)) {
304 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <body>\r\n" );
309 // Return the operation status
311 DBG_EXIT_STATUS ( Status
);
317 Respond with an error indicating that the page was not found
319 @param [in] SocketFD The socket's file descriptor to add to the list.
320 @param [in] pPort The WSDT_PORT structure address
321 @param [out] pbDone Address to receive the request completion status
323 @retval EFI_SUCCESS The request was successfully processed
329 IN WSDT_PORT
* pPort
,
338 // Send the page not found
342 // Send the page header
344 Status
= HttpPageHeader ( SocketFD
, pPort
, L
"404 Not found" );
345 if ( EFI_ERROR ( Status
)) {
350 // Send the page body
352 Status
= HttpSendAnsiString ( SocketFD
,
354 "ERROR <b>404</b><br />"
355 "Requested page is not available\r\n" );
356 if ( EFI_ERROR ( Status
)) {
361 // Send the page trailer
363 Status
= HttpPageTrailer ( SocketFD
, pPort
, pbDone
);
368 // Return the operation status
370 DBG_EXIT_STATUS ( Status
);
376 Buffer and send the HTTP page trailer
378 @param [in] SocketFD The socket's file descriptor to add to the list.
379 @param [in] pPort The WSDT_PORT structure address
380 @param [out] pbDone Address to receive the request completion status
382 @retval EFI_SUCCESS The request was successfully processed
388 IN WSDT_PORT
* pPort
,
394 socklen_t LengthInBytes
;
395 struct sockaddr_in6 LocalAddress
;
396 struct sockaddr_in6 RemoteAddress
;
401 // Build the page header
404 LengthInBytes
= sizeof ( LocalAddress
);
405 RetVal
= getsockname ( SocketFD
, (struct sockaddr
*)&LocalAddress
, &LengthInBytes
);
407 LengthInBytes
= sizeof ( LocalAddress
);
408 RetVal
= getpeername ( SocketFD
, (struct sockaddr
*)&RemoteAddress
, &LengthInBytes
);
411 // Seperate the body from the trailer
413 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " <hr>\r\n<code>" );
414 if ( EFI_ERROR ( Status
)) {
419 // Display the system addresses and the page transfer direction
421 Status
= HttpSendIpAddress ( SocketFD
, pPort
, &LocalAddress
);
422 if ( EFI_ERROR ( Status
)) {
425 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " --> " );
426 if ( EFI_ERROR ( Status
)) {
429 Status
= HttpSendIpAddress ( SocketFD
, pPort
, &RemoteAddress
);
430 if ( EFI_ERROR ( Status
)) {
433 Status
= HttpSendAnsiString ( SocketFD
, pPort
, "</code>\r\n" );
434 if ( EFI_ERROR ( Status
)) {
441 // Terminate the page
443 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </body>\r\n" );
444 if ( EFI_ERROR ( Status
)) {
447 Status
= HttpSendAnsiString ( SocketFD
, pPort
, " </html>\r\n" );
448 if ( EFI_ERROR ( Status
)) {
453 // Send the page trailer
455 Status
= HttpFlush ( SocketFD
, pPort
);
456 if ( EFI_ERROR ( Status
)) {
461 // Mark the page as complete
468 // Return the operation status
470 DBG_EXIT_STATUS ( Status
);
476 Replace a space with a zero
478 @param [in] pData The request buffer address
479 @param [in] pEnd End of buffer address
481 @return The next character location
494 while ( pEnd
> pData
) {
496 // Get the character from the request
498 Character
= HttpCharGet ( pData
, &pData
);
499 if ( ' ' == Character
) {
506 // Replace the space character with zero
508 ZeroMem ( pSpace
, pData
- pSpace
);
511 // Return the next character location
518 Process an HTTP request
520 @param [in] SocketFD The socket's file descriptor to add to the list.
521 @param [in] pPort The WSDT_PORT structure address
522 @param [out] pbDone Address to receive the request completion status
524 @retval EFI_SUCCESS The request was successfully processed
530 IN WSDT_PORT
* pPort
,
536 CONST DT_PAGE
* pPage
;
537 CONST DT_PAGE
* pPageEnd
;
546 // Assume the request is not finished
549 Status
= EFI_SUCCESS
;
553 // Attempt to parse the command
555 pData
= &pPort
->Request
[0];
556 pEnd
= &pData
[ pPort
->RequestLength
];
558 pWebPage
= HttpReplaceSpace ( pVerb
, pEnd
);
559 if ( pEnd
<= pWebPage
) {
562 pVersion
= HttpReplaceSpace ( pWebPage
, pEnd
);
563 if ( pEnd
<= pVersion
) {
568 // Validate the request
570 if ( 0 != HttpMatch ( L
"GET", pVerb
, TRUE
)) {
572 // Invalid request type
574 DEBUG (( DEBUG_REQUEST
,
575 "HTTP: Invalid verb\r\n" ));
576 Status
= EFI_NOT_FOUND
;
581 // Walk the page table
583 pPage
= &mPageList
[0];
584 pPageEnd
= &pPage
[ mPageCount
];
585 while ( pPageEnd
> pPage
) {
587 // Determine if the page was located
589 if ( 0 == HttpMatch ( pPage
->pPageName
, pWebPage
, FALSE
)) {
598 if ( pPageEnd
<= pPage
) {
600 // The page was not found
602 DEBUG (( DEBUG_REQUEST
,
603 "HTTP: Page not found in page table\r\n" ));
604 Status
= EFI_NOT_FOUND
;
609 // Respond with the page contents
611 Status
= pPage
->pfnResponse ( SocketFD
, pPort
, pbDone
);
616 // Return page not found if necessary
618 if ( EFI_NOT_FOUND
== Status
) {
619 Status
= HttpPageNotFound ( SocketFD
, pPort
, pbDone
);
623 // Return the operation status
625 DBG_EXIT_STATUS ( Status
);
631 Buffer data for sending
633 @param [in] SocketFD The socket's file descriptor to add to the list.
634 @param [in] pPort The WSDT_PORT structure address
635 @param [in] LengthInBytes Length of valid data in the buffer
636 @param [in] pBuffer Buffer of data to send
638 @retval EFI_SUCCESS The request was successfully processed
644 IN WSDT_PORT
* pPort
,
645 IN
size_t LengthInBytes
,
646 IN CONST UINT8
* pBuffer
656 Status
= EFI_SUCCESS
;
659 // Determine how much data fits into the buffer
661 MaxBytes
= sizeof ( pPort
->TxBuffer
);
662 DataBytes
= MaxBytes
- pPort
->TxBytes
;
663 if ( DataBytes
> LengthInBytes
) {
664 DataBytes
= LengthInBytes
;
668 // Copy the data into the buffer
670 CopyMem ( &pPort
->TxBuffer
[ pPort
->TxBytes
],
675 // Account for the data copied
677 pPort
->TxBytes
+= DataBytes
;
678 LengthInBytes
-= DataBytes
;
681 // Transmit the buffer if it is full
683 if ( MaxBytes
<= pPort
->TxBytes
) {
684 Status
= HttpFlush ( SocketFD
, pPort
);
686 } while (( EFI_SUCCESS
== Status
) && ( 0 < LengthInBytes
));
689 // Return the operation status
698 @param [in] SocketFD The socket's file descriptor to add to the list.
699 @param [in] pPort The WSDT_PORT structure address
700 @param [in] pString A zero terminated Unicode string
702 @retval EFI_SUCCESS The request was successfully processed
708 IN WSDT_PORT
* pPort
,
709 IN CONST
char * pString
718 Status
= EFI_SUCCESS
;
721 // Walk the characters in he string
724 while ( 0 != *pData
) {
731 Status
= HttpSend ( SocketFD
,
734 (CONST UINT8
*)pString
);
737 // Return the operation status
746 @param [in] SocketFD The socket's file descriptor to add to the list.
747 @param [in] pPort The WSDT_PORT structure address
748 @param [in] Data The data byte to send
750 @retval EFI_SUCCESS The request was successfully processed
756 IN WSDT_PORT
* pPort
,
763 // Send the data byte
765 Status
= HttpSend ( SocketFD
,
771 // Return the operation status
780 @param [in] SocketFD The socket's file descriptor to add to the list.
781 @param [in] pPort The WSDT_PORT structure address
782 @param [in] Character Character to display
783 @param [in] pReplacement Replacement character string
785 @retval EFI_SUCCESS The request was successfully processed
791 IN WSDT_PORT
* pPort
,
793 IN CHAR8
* pReplacement
799 // Determine if this is a printable character
801 if (( 0x20 <= Character
) && ( 0x7f > Character
)) {
802 if ( '<' == Character
) {
804 // Replace with HTML equivalent
806 Status
= HttpSendAnsiString ( SocketFD
,
810 else if ( '>' == Character
) {
812 // Replace with HTML equivalent
814 Status
= HttpSendAnsiString ( SocketFD
,
818 else if ( '&' == Character
) {
820 // Replace with HTML equivalent
822 Status
= HttpSendAnsiString ( SocketFD
,
826 else if ( '\"' == Character
) {
828 // Replace with HTML equivalent
830 Status
= HttpSendAnsiString ( SocketFD
,
836 // Display the character
838 Status
= HttpSendByte ( SocketFD
,
845 // Not a displayable character
847 Status
= HttpSendAnsiString ( SocketFD
,
853 // Return the operation status
862 @param [in] SocketFD The socket's file descriptor to add to the list.
863 @param [in] pPort The WSDT_PORT structure address
864 @param [in] ByteCount The number of bytes to display
865 @param [in] pData Address of the byte array
867 @retval EFI_SUCCESS The request was successfully processed
873 IN WSDT_PORT
* pPort
,
875 IN CONST UINT8
* pData
882 CONST UINT8
* pDataEnd
;
888 // Use for/break instead of goto
892 // Start the field value
894 Status
= HttpSendAnsiString ( SocketFD
,
897 if ( EFI_ERROR ( Status
)) {
902 // Walk the bytes to be displayed
904 pEnd
= &pData
[ ByteCount
];
905 while ( pEnd
> pData
) {
907 // Display the address
909 Status
= HttpSendHexBits ( SocketFD
,
911 sizeof ( pData
) * 8,
912 (UINT64
)(UINTN
)pData
);
913 if ( EFI_ERROR ( Status
)) {
918 // Separate the address and data
920 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
921 if ( EFI_ERROR ( Status
)) {
926 // Position the starting data correctly
928 InitialSpaces
= (UINTN
)pData
;
929 InitialSpaces
&= BYTES_ON_A_LINE
- 1;
930 for ( Index
= SPACES_ADDRESS_TO_DATA
931 + (( 2 + SPACES_BETWEEN_BYTES
)
933 0 < Index
; Index
-- ) {
934 Status
= HttpSendAnsiString ( SocketFD
,
937 if ( EFI_ERROR ( Status
)) {
941 if ( EFI_ERROR ( Status
)) {
948 BytesToDisplay
= pEnd
- pData
;
949 if (( BYTES_ON_A_LINE
- InitialSpaces
) < BytesToDisplay
) {
950 BytesToDisplay
= BYTES_ON_A_LINE
- InitialSpaces
;
952 pDataEnd
= &pData
[ BytesToDisplay
];
954 while ( pDataEnd
> pTemp
) {
955 Status
= HttpSendHexBits ( SocketFD
,
959 if ( EFI_ERROR ( Status
)) {
964 // Separate the data bytes
966 for ( Index
= SPACES_BETWEEN_BYTES
; 0 < Index
; Index
-- ) {
967 Status
= HttpSendAnsiString ( SocketFD
,
970 if ( EFI_ERROR ( Status
)) {
974 if ( EFI_ERROR ( Status
)) {
978 if ( EFI_ERROR ( Status
)) {
983 // Separate the data from the ASCII display
985 for ( Index
= (( 2 + SPACES_BETWEEN_BYTES
)
986 * ( BYTES_ON_A_LINE
- BytesToDisplay
- InitialSpaces
))
987 - SPACES_BETWEEN_BYTES
988 + SPACES_DATA_TO_ASCII
990 0 < Index
; Index
-- ) {
991 Status
= HttpSendAnsiString ( SocketFD
,
994 if ( EFI_ERROR ( Status
)) {
998 if ( EFI_ERROR ( Status
)) {
1003 // Display the ASCII data
1005 while ( pDataEnd
> pData
) {
1006 Character
= *pData
++;
1007 Status
= HttpSendCharacter ( SocketFD
,
1011 if ( EFI_ERROR ( Status
)) {
1015 if ( EFI_ERROR ( Status
)) {
1020 // Terminate the line
1022 Status
= HttpSendAnsiString ( SocketFD
,
1025 if ( EFI_ERROR ( Status
)) {
1031 // Terminate the field value and row
1033 Status
= HttpSendAnsiString ( SocketFD
,
1040 // Return the operation status
1047 Display a row containing a GUID value
1049 @param [in] SocketFD The socket's file descriptor to add to the list.
1050 @param [in] pPort The WSDT_PORT structure address
1051 @param [in] pGuid Address of the GUID to display
1053 @retval EFI_SUCCESS The request was successfully processed
1059 IN WSDT_PORT
* pPort
,
1060 IN CONST EFI_GUID
* pGuid
1069 // Use for/break instead of goto
1073 // Display the GUID in a form found in the code
1075 // E.g. 0xca16005f, 0x11ec, 0x4bdc, { 0x99, 0x97, 0x27, 0x2c, 0xa9, 0xba, 0x15, 0xe5 }
1079 // Display the first 32 bits
1081 Status
= HttpSendAnsiString ( SocketFD
,
1084 if ( EFI_ERROR ( Status
)) {
1087 Status
= HttpSendHexBits ( SocketFD
,
1091 if ( EFI_ERROR ( Status
)) {
1096 // Display the second 16 bits
1098 Status
= HttpSendAnsiString ( SocketFD
,
1101 if ( EFI_ERROR ( Status
)) {
1104 Status
= HttpSendHexBits ( SocketFD
,
1108 if ( EFI_ERROR ( Status
)) {
1113 // Display the thrid 16 bits
1115 Status
= HttpSendAnsiString ( SocketFD
,
1118 if ( EFI_ERROR ( Status
)) {
1121 Status
= HttpSendHexBits ( SocketFD
,
1125 if ( EFI_ERROR ( Status
)) {
1130 // Place the last 64 bits in braces
1132 Status
= HttpSendAnsiString ( SocketFD
,
1135 if ( EFI_ERROR ( Status
)) {
1138 for ( Index
= 0; 7 >= Index
; Index
++ ) {
1140 // Display the next 8 bits
1142 Status
= HttpSendHexBits ( SocketFD
,
1145 pGuid
->Data4
[ Index
]);
1146 if ( EFI_ERROR ( Status
)) {
1151 // Separate the bytes
1153 Status
= HttpSendAnsiString ( SocketFD
,
1155 ( 7 != Index
) ? ", 0x" : " }" );
1156 if ( EFI_ERROR ( Status
)) {
1164 // Return the operation status
1166 DBG_EXIT_STATUS ( Status
);
1172 Output a hex value to the HTML page
1174 @param [in] SocketFD Socket file descriptor
1175 @param [in] pPort The WSDT_PORT structure address
1176 @param [in] Bits Number of bits to display
1177 @param [in] Value Value to display
1179 @retval EFI_SUCCESS Successfully displayed the address
1184 IN WSDT_PORT
* pPort
,
1196 Status
= EFI_SUCCESS
;
1199 // Walk the list of divisors
1201 Shift
= (( Bits
+ 3 ) & ( ~3 )) - 4;
1202 while ( 0 <= Shift
) {
1204 // Determine the next digit
1206 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1207 if ( 10 <= Digit
) {
1208 Digit
+= 'a' - '0' - 10;
1212 // Display the digit
1214 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1215 if ( EFI_ERROR ( Status
)) {
1220 // Set the next shift
1226 // Return the operation status
1233 Output a hex value to the HTML page
1235 @param [in] SocketFD Socket file descriptor
1236 @param [in] pPort The WSDT_PORT structure address
1237 @param [in] Value Value to display
1239 @retval EFI_SUCCESS Successfully displayed the address
1244 IN WSDT_PORT
* pPort
,
1248 BOOLEAN bDisplayZeros
;
1256 Status
= EFI_SUCCESS
;
1259 // Walk the list of divisors
1261 bDisplayZeros
= FALSE
;
1265 // Determine the next digit
1267 Digit
= (UINT32
)(( Value
>> Shift
) & 0xf );
1268 if ( 10 <= Digit
) {
1269 Digit
+= 'a' - '0' - 10;
1273 // Suppress leading zeros
1275 if (( 0 != Digit
) || bDisplayZeros
|| ( 0 == Shift
)) {
1276 bDisplayZeros
= TRUE
;
1279 // Display the digit
1281 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1282 if ( EFI_ERROR ( Status
)) {
1288 // Set the next shift
1291 } while ( 0 <= Shift
);
1294 // Return the operation status
1301 Output an IP6 address value to the HTML page
1303 @param [in] SocketFD Socket file descriptor
1304 @param [in] pPort The WSDT_PORT structure address
1305 @param [in] Value Value to display
1306 @param [in] bFirstValue TRUE if first value
1307 @param [in] bLastValue TRUE if last value
1308 @param [in] bZeroSuppression TRUE while zeros are being suppressed
1309 @param [in] pbZeroSuppression Address to receive TRUE when zero suppression
1310 has started, use NULL if next colon value not
1313 @retval EFI_SUCCESS Successfully displayed the address
1318 IN WSDT_PORT
* pPort
,
1320 IN BOOLEAN bFirstValue
,
1321 IN BOOLEAN bLastValue
,
1322 IN BOOLEAN bZeroSuppression
,
1323 IN BOOLEAN
* pbZeroSuppression
1326 BOOLEAN bZeroSuppressionStarting
;
1331 // Use break instead of goto
1333 bZeroSuppressionStarting
= FALSE
;
1334 Status
= EFI_SUCCESS
;
1337 // Display the leading colon if necessary
1339 if ( bZeroSuppression
&& ( bLastValue
|| ( 0 != Value
))) {
1340 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1341 if ( EFI_ERROR ( Status
)) {
1347 // Skip over a series of zero values
1349 bZeroSuppressionStarting
= (BOOLEAN
)( 0 == Value
);
1350 if ( !bZeroSuppressionStarting
) {
1352 // Display the value
1354 Digit
= ( Value
>> 4 ) & 0xf;
1355 Status
= HttpSendHexValue ( SocketFD
,
1358 if ( EFI_ERROR ( Status
)) {
1361 Digit
= Value
& 0xf;
1362 Status
= HttpSendHexValue ( SocketFD
,
1365 if ( EFI_ERROR ( Status
)) {
1368 Digit
= ( Value
>> 12 ) & 0xf;
1369 Status
= HttpSendHexValue ( SocketFD
,
1372 if ( EFI_ERROR ( Status
)) {
1375 Digit
= ( Value
>> 8 ) & 0xf;
1376 Status
= HttpSendHexValue ( SocketFD
,
1379 if ( EFI_ERROR ( Status
)) {
1385 // Display the trailing colon if necessary
1387 if (( !bLastValue
) && ( bFirstValue
|| ( 0 != Value
))) {
1388 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1394 // Return the next colon display
1395 if ( NULL
!= pbZeroSuppression
) {
1396 *pbZeroSuppression
= bZeroSuppressionStarting
;
1400 // Return the operation status
1407 Output an IP address to the HTML page
1409 @param [in] SocketFD Socket file descriptor
1410 @param [in] pPort The WSDT_PORT structure address
1411 @param [in] pAddress Address of the socket address
1413 @retval EFI_SUCCESS Successfully displayed the address
1418 IN WSDT_PORT
* pPort
,
1419 IN
struct sockaddr_in6
* pAddress
1422 BOOLEAN bZeroSuppression
;
1424 struct sockaddr_in
* pIpv4
;
1425 struct sockaddr_in6
* pIpv6
;
1430 // Use break instead of goto
1434 // Determine the type of address
1436 if ( AF_INET6
== pAddress
->sin6_family
) {
1440 // Display the address in RFC2732 format
1442 bZeroSuppression
= FALSE
;
1443 Status
= HttpSendByte ( SocketFD
, pPort
, '[' );
1444 if ( EFI_ERROR ( Status
)) {
1447 for ( Index
= 0; 8 > Index
; Index
++ ) {
1448 Status
= HttpSendIp6Value ( SocketFD
,
1450 pIpv6
->sin6_addr
.__u6_addr
.__u6_addr16
[ Index
],
1451 (BOOLEAN
)( 0 == Index
),
1452 (BOOLEAN
)( 7 == Index
),
1454 &bZeroSuppression
);
1455 if ( EFI_ERROR ( Status
)) {
1459 if ( EFI_ERROR ( Status
)) {
1464 // Separate the port number
1466 Status
= HttpSendByte ( SocketFD
, pPort
, ']' );
1469 // Get the port number
1471 PortNumber
= pIpv6
->sin6_port
;
1475 // Output the IPv4 address
1477 pIpv4
= (struct sockaddr_in
*)pAddress
;
1478 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)pIpv4
->sin_addr
.s_addr
);
1479 if ( EFI_ERROR ( Status
)) {
1482 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1483 if ( EFI_ERROR ( Status
)) {
1486 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pIpv4
->sin_addr
.s_addr
>> 8 ));
1487 if ( EFI_ERROR ( Status
)) {
1490 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1491 if ( EFI_ERROR ( Status
)) {
1494 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pIpv4
->sin_addr
.s_addr
>> 16 ));
1495 if ( EFI_ERROR ( Status
)) {
1498 Status
= HttpSendByte ( SocketFD
, pPort
, '.' );
1499 if ( EFI_ERROR ( Status
)) {
1502 Status
= HttpSendValue ( SocketFD
, pPort
, (UINT8
)( pIpv4
->sin_addr
.s_addr
>> 24 ));
1505 // Get the port number
1507 PortNumber
= pIpv4
->sin_port
;
1509 if ( EFI_ERROR ( Status
)) {
1514 // Display the port number
1516 Status
= HttpSendByte ( SocketFD
, pPort
, ':' );
1517 if ( EFI_ERROR ( Status
)) {
1520 Status
= HttpSendValue ( SocketFD
, pPort
, htons ( PortNumber
));
1525 // Return the operation status
1532 Send a Unicode string
1534 @param [in] SocketFD The socket's file descriptor to add to the list.
1535 @param [in] pPort The WSDT_PORT structure address
1536 @param [in] pString A zero terminated Unicode string
1538 @retval EFI_SUCCESS The request was successfully processed
1542 HttpSendUnicodeString (
1544 IN WSDT_PORT
* pPort
,
1545 IN CONST UINT16
* pString
1555 Status
= EFI_SUCCESS
;
1558 // Walk the characters in he string
1560 while ( 0 != ( Character
= *pString
++ )) {
1562 // Convert the character to UTF-8
1564 if ( 0 != ( Character
& 0xf800 )) {
1566 // Send the upper 4 bits
1568 Data
= (UINT8
)(( Character
>> 12 ) & 0xf );
1570 Status
= HttpSendByte ( SocketFD
,
1573 if ( EFI_ERROR ( Status
)) {
1578 // Send the next 6 bits
1580 Data
= (UINT8
)(( Character
>> 6 ) & 0x3f );
1582 Status
= HttpSendByte ( SocketFD
,
1585 if ( EFI_ERROR ( Status
)) {
1590 // Send the last 6 bits
1592 Data
= (UINT8
)( Character
& 0x3f );
1595 else if ( 0 != ( Character
& 0x0780 )) {
1597 // Send the upper 5 bits
1599 Data
= (UINT8
)(( Character
>> 6 ) & 0x1f );
1601 Status
= HttpSendByte ( SocketFD
,
1604 if ( EFI_ERROR ( Status
)) {
1609 // Send the last 6 bits
1611 Data
= (UINT8
)( Character
& 0x3f );
1615 Data
= (UINT8
)( Character
& 0x7f );
1619 // Send the last data byte
1621 Status
= HttpSendByte ( SocketFD
,
1624 if ( EFI_ERROR ( Status
)) {
1630 // Return the operation status
1637 Output a value to the HTML page
1639 @param [in] SocketFD Socket file descriptor
1640 @param [in] pPort The WSDT_PORT structure address
1641 @param [in] Value Value to display
1643 @retval EFI_SUCCESS Successfully displayed the address
1648 IN WSDT_PORT
* pPort
,
1652 BOOLEAN bDisplayZeros
;
1654 CONST UINT64
* pEnd
;
1655 CONST UINT64
* pDivisor
;
1656 CONST UINT64 pDivisors
[ ] = {
1657 10000000000000000000ULL,
1658 1000000000000000000ULL,
1659 100000000000000000ULL,
1660 10000000000000000ULL,
1661 1000000000000000ULL,
1683 Status
= EFI_SUCCESS
;
1686 // Walk the list of divisors
1688 bDisplayZeros
= FALSE
;
1689 pDivisor
= &pDivisors
[0];
1690 pEnd
= &pDivisor
[ sizeof ( pDivisors
) / sizeof ( pDivisors
[0])];
1691 while ( pEnd
> pDivisor
) {
1693 // Determine the next digit
1695 Digit
= Value
/ *pDivisor
;
1698 // Suppress leading zeros
1700 if (( 0 != Digit
) || bDisplayZeros
) {
1701 bDisplayZeros
= TRUE
;
1704 // Display the digit
1706 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Digit
));
1707 if ( EFI_ERROR ( Status
)) {
1712 // Determine the remainder
1714 Temp
= *pDivisor
* Digit
;
1719 // Set the next divisor
1725 // Display the final digit
1727 if ( !EFI_ERROR ( Status
)) {
1728 Status
= HttpSendByte ( SocketFD
, pPort
, (UINT8
)( '0' + Value
));
1732 // Return the operation status