1dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff/** @file
2f737cfb953905f42f3324e8e53ec324a15314210jgong  Support routines for PxeBc.
3e285199897e538523f762cb5b3900e81f872035avanjeff
4206b5f51beb15a22417c42e846678425de60c556Zhang LuboCopyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
5e5eed7d3641d71d7ea539e5379ea9c6a5cd97004hhtianThis program and the accompanying materials
6dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffare licensed and made available under the terms and conditions of the BSD License
7dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffwhich accompanies this distribution.  The full text of the license may be found at
8dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffhttp://opensource.org/licenses/bsd-license.php
9dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
10dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
13dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/
14dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
15dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
16dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff#include "PxeBcImpl.h"
17dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
18dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
19dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff/**
20e285199897e538523f762cb5b3900e81f872035avanjeff  The common notify function associated with various PxeBc events.
21dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
22f737cfb953905f42f3324e8e53ec324a15314210jgong  @param  Event     The event signaled.
23f737cfb953905f42f3324e8e53ec324a15314210jgong  @param  Context   The context.
24dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
25dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/
26dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffVOID
276d3ea23f1183f3378a53e44d34c0a27aebec7d9ajljustenEFIAPI
28dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffPxeBcCommonNotify (
29dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  IN EFI_EVENT           Event,
30dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  IN VOID                *Context
31dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  )
32dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{
33dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  *((BOOLEAN *) Context) = TRUE;
34dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff}
35dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
36f737cfb953905f42f3324e8e53ec324a15314210jgong
37f737cfb953905f42f3324e8e53ec324a15314210jgong/**
38f737cfb953905f42f3324e8e53ec324a15314210jgong  This function initialize(or configure) the Udp4Write instance.
39e285199897e538523f762cb5b3900e81f872035avanjeff
40f737cfb953905f42f3324e8e53ec324a15314210jgong  @param  Udp4       Pointer to the EFI_UDP4_PROTOCOL instance.
41f737cfb953905f42f3324e8e53ec324a15314210jgong  @param  StationIp  Pointer to the station ip address.
42f737cfb953905f42f3324e8e53ec324a15314210jgong  @param  SubnetMask Pointer to the subnetmask of the station ip address.
43f737cfb953905f42f3324e8e53ec324a15314210jgong  @param  Gateway    Pointer to the gateway ip address.
44f737cfb953905f42f3324e8e53ec324a15314210jgong  @param  SrcPort    Pointer to the srouce port of the station.
45e285199897e538523f762cb5b3900e81f872035avanjeff
46f737cfb953905f42f3324e8e53ec324a15314210jgong  @retval EFI_SUCCESS           The configuration settings were set, changed, or reset successfully.
47f737cfb953905f42f3324e8e53ec324a15314210jgong  @retval EFI_NO_MAPPING        When using a default address, configuration (DHCP, BOOTP,
48f737cfb953905f42f3324e8e53ec324a15314210jgong                                RARP, etc.) is not finished yet.
49f737cfb953905f42f3324e8e53ec324a15314210jgong  @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:
50f737cfb953905f42f3324e8e53ec324a15314210jgong  @retval EFI_ALREADY_STARTED   The EFI UDPv4 Protocol instance is already started/configured
51f737cfb953905f42f3324e8e53ec324a15314210jgong                                and must be stopped/reset before it can be reconfigured.
52f737cfb953905f42f3324e8e53ec324a15314210jgong  @retval EFI_ACCESS_DENIED     UdpConfigData. AllowDuplicatePort is FALSE
53f737cfb953905f42f3324e8e53ec324a15314210jgong                                and UdpConfigData.StationPort is already used by
54f737cfb953905f42f3324e8e53ec324a15314210jgong                                other instance.
55f737cfb953905f42f3324e8e53ec324a15314210jgong  @retval EFI_OUT_OF_RESOURCES  The EFI UDPv4 Protocol driver cannot allocate memory for this
56f737cfb953905f42f3324e8e53ec324a15314210jgong                                EFI UDPv4 Protocol instance.
57f737cfb953905f42f3324e8e53ec324a15314210jgong  @retval EFI_DEVICE_ERROR      An unexpected network or system error occurred and this instance
58f737cfb953905f42f3324e8e53ec324a15314210jgong                                was not opened.
59f737cfb953905f42f3324e8e53ec324a15314210jgong  @retval Others                Please examine the function Udp4->Routes(Udp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, Gateway) returns.
60e285199897e538523f762cb5b3900e81f872035avanjeff
61f737cfb953905f42f3324e8e53ec324a15314210jgong**/
628792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeffEFI_STATUS
638792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeffPxeBcConfigureUdpWriteInstance (
648792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  IN EFI_UDP4_PROTOCOL  *Udp4,
658792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  IN EFI_IPv4_ADDRESS   *StationIp,
668792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  IN EFI_IPv4_ADDRESS   *SubnetMask,
678792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  IN EFI_IPv4_ADDRESS   *Gateway,
688792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  IN OUT UINT16         *SrcPort
698792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  )
708792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff{
718792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  EFI_UDP4_CONFIG_DATA  Udp4CfgData;
728792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  EFI_STATUS            Status;
738792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff
748792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  ZeroMem (&Udp4CfgData, sizeof (Udp4CfgData));
758792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff
767bc01e86d9955cc3d43c02adfe5e67a321ebe7davanjeff  Udp4CfgData.ReceiveTimeout = PXEBC_DEFAULT_LIFETIME;
778792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  Udp4CfgData.TypeOfService  = DEFAULT_ToS;
788792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  Udp4CfgData.TimeToLive     = DEFAULT_TTL;
79319075ff6e1d1fb470667453ec24a2ba685f60a0vanjeff  Udp4CfgData.AllowDuplicatePort = TRUE;
808792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff
818792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  CopyMem (&Udp4CfgData.StationAddress, StationIp, sizeof (*StationIp));
828792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  CopyMem (&Udp4CfgData.SubnetMask, SubnetMask, sizeof (*SubnetMask));
838792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff
848792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  Udp4CfgData.StationPort    = *SrcPort;
858792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff
868792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  //
878792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  // Reset the instance.
888792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  //
898792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  Udp4->Configure (Udp4, NULL);
908792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff
918792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  Status = Udp4->Configure (Udp4, &Udp4CfgData);
928792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  if (!EFI_ERROR (Status) && (Gateway->Addr[0] != 0)) {
938792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff    //
948792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff    // basic configuration OK, need to add the default route entry
958792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff    //
968792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff    Status = Udp4->Routes (Udp4, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, Gateway);
978792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff    if (EFI_ERROR (Status)) {
988792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff      //
998792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff      // roll back
1008792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff      //
1018792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff      Udp4->Configure (Udp4, NULL);
1028792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff    }
1038792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  }
1048792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff
1058792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  if (!EFI_ERROR (Status) && (*SrcPort == 0)) {
1068792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff    Udp4->GetModeData (Udp4, &Udp4CfgData, NULL, NULL, NULL);
1078792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff    *SrcPort = Udp4CfgData.StationPort;
1088792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  }
1098792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff
1108792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff  return Status;
1118792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff}
1128792362f22e4fac66aeec04b13b7a6b70cb571e9vanjeff
113dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
114dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff/**
115f737cfb953905f42f3324e8e53ec324a15314210jgong  Convert number to ASCII value.
116dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
117dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  @param  Number              Numeric value to convert to decimal ASCII value.
118f737cfb953905f42f3324e8e53ec324a15314210jgong  @param  Buffer              Buffer to place ASCII version of the Number.
119dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  @param  Length              Length of Buffer.
120dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
121dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/
122dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffVOID
123dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffCvtNum (
124dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  IN UINTN  Number,
125dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  IN UINT8  *Buffer,
126f737cfb953905f42f3324e8e53ec324a15314210jgong  IN UINTN   Length
127dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  )
128dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{
129dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  UINTN Remainder;
130dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
131894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff  while (Length > 0) {
132dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff    Remainder = Number % 10;
133dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff    Number /= 10;
134894d038a8d0e99d456042e2b6d1554c4a406ea70vanjeff    Length--;
135dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff    Buffer[Length] = (UINT8) ('0' + Remainder);
136dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  }
137dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff}
138dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
139dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
140dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff/**
141f737cfb953905f42f3324e8e53ec324a15314210jgong  Convert unsigned int number to decimal number.
142dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
143206b5f51beb15a22417c42e846678425de60c556Zhang Lubo  @param      Number         The unsigned int number will be converted.
144206b5f51beb15a22417c42e846678425de60c556Zhang Lubo  @param      Buffer         Pointer to the buffer to store the decimal number after transform.
145206b5f51beb15a22417c42e846678425de60c556Zhang Lubo  @param[in]  BufferSize     The maxsize of the buffer.
146206b5f51beb15a22417c42e846678425de60c556Zhang Lubo
147f737cfb953905f42f3324e8e53ec324a15314210jgong  @return the length of the number after transform.
148dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
149dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/
150dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffUINTN
151dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffUtoA10 (
152dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  IN UINTN Number,
153206b5f51beb15a22417c42e846678425de60c556Zhang Lubo  IN CHAR8 *Buffer,
154206b5f51beb15a22417c42e846678425de60c556Zhang Lubo  IN UINTN BufferSize
155dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  )
156dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{
157dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  UINTN Index;
158dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  CHAR8 TempStr[64];
159dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
160dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  Index           = 63;
161dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  TempStr[Index]  = 0;
162dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
163dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  do {
164dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff    Index--;
165dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff    TempStr[Index]  = (CHAR8) ('0' + (Number % 10));
166dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff    Number          = Number / 10;
167dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  } while (Number != 0);
168dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
169206b5f51beb15a22417c42e846678425de60c556Zhang Lubo  AsciiStrCpyS (Buffer, BufferSize, &TempStr[Index]);
170dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
171dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  return AsciiStrLen (Buffer);
172dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff}
173dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
174dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
175dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff/**
176f737cfb953905f42f3324e8e53ec324a15314210jgong  Convert ASCII numeric string to a UINTN value.
177dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
178f737cfb953905f42f3324e8e53ec324a15314210jgong  @param  Buffer  Pointer to the 8-byte unsigned int value.
179dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
180f737cfb953905f42f3324e8e53ec324a15314210jgong  @return UINTN value of the ASCII string.
181dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
182dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff**/
183dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffUINT64
184dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeffAtoU64 (
185dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  IN UINT8 *Buffer
186dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  )
187dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff{
188dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  UINT64  Value;
189dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  UINT8   Character;
190dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
191dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  Value = 0;
192dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  while ((Character = *Buffer++) != '\0') {
193dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff    Value = MultU64x32 (Value, 10) + (Character - '0');
194dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  }
195dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
196dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff  return Value;
197dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff}
198dc361cc5a04657ddc8c74bd8f044f7ad30c4118avanjeff
199