SHEL23
[efi/shell/.git] / sermode / sermode.c
1 /*++
2
3 Copyright (c) 2005 - 2006, Intel Corporation                                                         
4 All rights reserved. This program and the accompanying materials                          
5 are licensed and made available under the terms and conditions of the BSD License         
6 which accompanies this distribution. The full text of the license may be found at         
7 http://opensource.org/licenses/bsd-license.php                                            
8                                                                                           
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
11
12 Module Name:
13
14   sermode.c
15   
16 Abstract:
17
18   Shell app "sermode"
19
20
21
22 Revision History
23
24 --*/
25
26 #include "EfiShellLib.h"
27 #include "sermode.h"
28
29 extern UINT8    STRING_ARRAY_NAME[];
30
31 //
32 // This is the generated header file which includes whatever needs to be exported (strings + IFR)
33 //
34 #include STRING_DEFINES_FILE
35
36 #include EFI_PROTOCOL_DEFINITION (SerialIo)
37
38 EFI_HII_HANDLE  HiiHandle;
39 EFI_GUID        EfiSermodeGuid = EFI_SERMODEB_GUID;
40 SHELL_VAR_CHECK_ITEM    SermodeCheckList[] = {
41   {
42     L"-b",
43     0x01,
44     0,
45     FlagTypeSingle
46   },
47   {
48     L"-?",
49     0x02,
50     0,
51     FlagTypeSingle
52   },
53   {
54     NULL,
55     0,
56     0,
57     0
58   }
59 };
60
61 //
62 //
63 //
64 EFI_STATUS
65 InitializeSerialMode (
66   IN EFI_HANDLE         ImageHandle,
67   IN EFI_SYSTEM_TABLE   *SystemTable
68   );
69
70 //
71 //
72 //
73 STATIC
74 EFI_STATUS
75 iDisplaySettings (
76   IN UINTN                   HandleIdx,
77   IN BOOLEAN                 HandleValid
78
79   )
80 {
81   EFI_SERIAL_IO_PROTOCOL  *SerialIo;
82   UINTN                   NoHandles;
83   EFI_HANDLE              *Handles;
84   EFI_STATUS              Status;
85   UINTN                   Index;
86   CHAR16                  *StopBits;
87   CHAR16                  Parity;
88
89   Handles   = NULL;
90   StopBits  = NULL;
91
92   Status    = LibLocateHandle (ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles);
93   if (EFI_ERROR (Status)) {
94     PrintToken (STRING_TOKEN (STR_SERMODE_NO_SERIAL_PORTS), HiiHandle);
95     return EFI_INVALID_PARAMETER;
96   }
97
98   for (Index = 0; Index < NoHandles; Index++) {
99     if (HandleValid) {
100       if (ShellHandleFromIndex (HandleIdx) != Handles[Index]) {
101         continue;
102
103       }
104
105     }
106
107     Status = BS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, &SerialIo);
108     if (!EFI_ERROR (Status)) {
109       switch (SerialIo->Mode->Parity) {
110       case DefaultParity:
111
112         Parity = 'D';
113         break;
114
115       case NoParity:
116
117         Parity = 'N';
118         break;
119
120       case EvenParity:
121
122         Parity = 'E';
123         break;
124
125       case OddParity:
126
127         Parity = 'O';
128         break;
129
130       case MarkParity:
131
132         Parity = 'M';
133         break;
134
135       case SpaceParity:
136
137         Parity = 'S';
138         break;
139
140       default:
141
142         Parity = 'U';
143       }
144
145       switch (SerialIo->Mode->StopBits) {
146       case DefaultStopBits:
147
148         StopBits = L"Default";
149         break;
150
151       case OneStopBit:
152
153         StopBits = L"1";
154         break;
155
156       case TwoStopBits:
157
158         StopBits = L"2";
159         break;
160
161       case OneFiveStopBits:
162
163         StopBits = L"1.5";
164         break;
165
166       default:
167
168         StopBits = L"Unknown";
169       }
170
171       PrintToken (
172         STRING_TOKEN (STR_SERMODE_DISPLAY),
173         HiiHandle,
174         ShellHandleToIndex (Handles[Index]),
175         Handles[Index],
176         SerialIo->Mode->BaudRate,
177         Parity,
178         SerialIo->Mode->DataBits,
179         StopBits
180         );
181     } else {
182       PrintToken (STRING_TOKEN (STR_SERMODE_NO_SERIAL_PORTS), HiiHandle);
183       break;
184     }
185
186     if (HandleValid) {
187       break;
188     }
189   }
190
191   if (Index == NoHandles) {
192     if ((NoHandles && HandleValid) || 0 == NoHandles) {
193       PrintToken (STRING_TOKEN (STR_SERMODE_NOT_FOUND), HiiHandle);
194     }
195   }
196
197   return Status;
198 }
199
200 EFI_BOOTSHELL_CODE(
201   EFI_APPLICATION_ENTRY_POINT(InitializeSerialMode)
202 )
203
204 EFI_STATUS
205 InitializeSerialMode (
206   IN EFI_HANDLE         ImageHandle,
207   IN EFI_SYSTEM_TABLE   *SystemTable
208   )
209 /*++
210
211 Routine Description:
212
213   Command entry point
214
215 Arguments:
216
217   ImageHandle - The image handle
218   SystemTable - The system table
219
220 Returns:
221
222   EFI_SUCCESS - Success
223
224 --*/
225 {
226   EFI_STATUS              Status;
227   UINTN                   Index;
228   UINTN                   NoHandles;
229   EFI_HANDLE              *Handles;
230   EFI_PARITY_TYPE         Parity;
231   EFI_STOP_BITS_TYPE      StopBits;
232   UINTN                   HandleIdx;
233   UINTN                   BaudRate;
234   UINTN                   DataBits;
235   UINTN                   Value;
236   EFI_SERIAL_IO_PROTOCOL  *SerialIo;
237   CHAR16                  *Useful;
238   SHELL_ARG_LIST          *Item;
239   SHELL_VAR_CHECK_CODE    RetCode;
240   SHELL_VAR_CHECK_PACKAGE ChkPck;
241
242   //
243   // Initialize app
244   //
245   EFI_SHELL_APP_INIT (ImageHandle, SystemTable);
246   
247   //
248   // Enable tab key which can pause the output
249   //
250   EnableOutputTabPause();
251
252   EFI_SHELL_STR_INIT (HiiHandle, STRING_ARRAY_NAME, EfiSermodeGuid);
253
254   Handles = NULL;
255   ZeroMem (&ChkPck, sizeof (SHELL_VAR_CHECK_PACKAGE));
256
257   RetCode = LibCheckVariables (SI, SermodeCheckList, &ChkPck, &Useful);
258   if (VarCheckOk != RetCode) {
259     switch (RetCode) {
260     case VarCheckDuplicate:
261       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_DUP_FLAG), HiiHandle, L"sermode", Useful);
262       break;
263
264     case VarCheckUnknown:
265       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_UNKNOWN_FLAG), HiiHandle, L"sermode", Useful);
266       break;
267
268     default:
269       break;
270     }
271
272     Status = EFI_INVALID_PARAMETER;
273     goto Done;
274   }
275   //
276   // Out put help.
277   //
278   if (LibCheckVarGetFlag (&ChkPck, L"-b") != NULL) {
279     EnablePageBreak (DEFAULT_INIT_ROW, DEFAULT_AUTO_LF);
280   }
281
282   if (LibCheckVarGetFlag (&ChkPck, L"-?") != NULL) {
283     if (ChkPck.ValueCount > 0 ||
284         ChkPck.FlagCount > 2 ||
285         (2 == ChkPck.FlagCount && !LibCheckVarGetFlag (&ChkPck, L"-b"))
286         ) {
287       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiHandle, L"sermode");
288       Status = EFI_INVALID_PARAMETER;
289     } else {
290       PrintToken (STRING_TOKEN (STR_SERMODE_VERBOSE_HELP), HiiHandle);
291       Status = EFI_SUCCESS;
292     }
293
294     goto Done;
295   }
296
297   if (ChkPck.ValueCount < 5 && ChkPck.ValueCount > 1) {
298     PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_FEW), HiiHandle, L"sermode");
299     Status = EFI_INVALID_PARAMETER;
300     goto Done;
301   }
302
303   if (ChkPck.ValueCount > 5) {
304     PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_TOO_MANY), HiiHandle, L"sermode");
305     Status = EFI_INVALID_PARAMETER;
306     goto Done;
307   }
308
309   ShellInitHandleEnumerator ();
310   Item = ChkPck.VarList;
311   if (Item) {
312     HandleIdx = (UINTN) StrToUIntegerBase (Item->VarStr, 16, &Status) - 1;
313     if (EFI_ERROR (Status) || HandleIdx >= ShellGetHandleNum ()) {
314       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"sermode", Item->VarStr);
315       goto Done;
316     }
317
318     Item = GetNextArg (Item);
319     if (NULL == Item) {
320       Status = iDisplaySettings (HandleIdx, TRUE);
321       goto Done;
322     }
323   } else {
324     Status = iDisplaySettings (0, FALSE);
325     goto Done;
326   }
327
328   BaudRate = (UINTN) StrToUInteger (Item->VarStr, &Status);
329   if (EFI_ERROR (Status)) {
330     PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"sermode", Item->VarStr);
331     goto Done;
332   }
333
334   Item = GetNextArg (Item);
335
336   ASSERT (Item);
337   if (StrLen (Item->VarStr) > 1) {
338     PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"sermode", Item->VarStr);
339     Status = EFI_INVALID_PARAMETER;
340     goto Done;
341   } else {
342     switch ((CHAR8) Item->VarStr[0]) {
343     case 'd':
344     case 'D':
345
346       Parity = DefaultParity;
347       break;
348
349     case 'n':
350     case 'N':
351
352       Parity = NoParity;
353       break;
354
355     case 'e':
356     case 'E':
357
358       Parity = EvenParity;
359       break;
360
361     case 'o':
362     case 'O':
363
364       Parity = OddParity;
365       break;
366
367     case 'm':
368     case 'M':
369
370       Parity = MarkParity;
371       break;
372
373     case 's':
374     case 'S':
375
376       Parity = SpaceParity;
377       break;
378
379     default:
380
381       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"sermode", Item->VarStr);
382       Status = EFI_INVALID_PARAMETER;
383       goto Done;
384     }
385   }
386
387   Item = GetNextArg (Item);
388
389   ASSERT (Item);
390   DataBits = (UINTN) StrToUInteger (Item->VarStr, &Status);
391   if (EFI_ERROR (Status)) {
392     PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"sermode", Item->VarStr);
393     goto Done;
394   } else {
395     switch (DataBits) {
396     case 4:
397     case 7:
398     case 8:
399
400       break;
401
402     default:
403
404       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"sermode", Item->VarStr);
405       goto Done;
406     }
407   }
408
409   Item = GetNextArg (Item);
410
411   ASSERT (Item);
412   Value = (UINTN) StrToUInteger (Item->VarStr, &Status);
413   if (EFI_ERROR (Status)) {
414     PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, L"sermode", Item->VarStr);
415     goto Done;
416   } else {
417     switch (Value) {
418     case 0:
419       StopBits = DefaultStopBits;
420       break;
421
422     case 1:
423       StopBits = OneStopBit;
424       break;
425
426     case 2:
427       StopBits = TwoStopBits;
428       break;
429
430     case 15:
431       StopBits = OneFiveStopBits;
432       break;
433
434     default:
435       PrintToken (STRING_TOKEN (STR_SHELLENV_GNC_INVALID_ARG), HiiHandle, Item->VarStr);
436       Status = EFI_INVALID_PARAMETER;
437       goto Done;
438     }
439   }
440   //
441   //
442   //
443   Status = LibLocateHandle (ByProtocol, &gEfiSerialIoProtocolGuid, NULL, &NoHandles, &Handles);
444   if (EFI_ERROR (Status)) {
445     PrintToken (STRING_TOKEN (STR_SERMODE_NO_SERIAL_PORTS), HiiHandle);
446     Status = EFI_INVALID_PARAMETER;
447     goto Done;
448   }
449   //
450   //
451   //
452   for (Index = 0; Index < NoHandles; Index++) {
453     if (ShellHandleFromIndex (HandleIdx) != Handles[Index]) {
454       continue;
455     }
456
457     Status = BS->HandleProtocol (Handles[Index], &gEfiSerialIoProtocolGuid, &SerialIo);
458     if (!EFI_ERROR (Status)) {
459       Status = SerialIo->SetAttributes (
460                           SerialIo,
461                           (UINT64) BaudRate,
462                           SerialIo->Mode->ReceiveFifoDepth,
463                           SerialIo->Mode->Timeout,
464                           Parity,
465                           (UINT8) DataBits,
466                           StopBits
467                           );
468       if (EFI_ERROR (Status)) {
469         PrintToken (STRING_TOKEN (STR_SERMODE_CANNOT_SET_ATTR), HiiHandle, Status, Handles[Index]);
470       } else {
471         PrintToken (STRING_TOKEN (STR_SERMODE_MODE_SET_ON_HANDLE), HiiHandle, Handles[Index]);
472       }
473       break;
474     }
475   }
476
477   if (Index == NoHandles) {
478     PrintToken (STRING_TOKEN (STR_SERMODE__NOT_SER_HANDLE), HiiHandle, HandleIdx + 1);
479     Status = EFI_INVALID_PARAMETER;
480   }
481
482 Done:
483   if (Handles) {
484     FreePool (Handles);
485   }
486
487   LibCheckVarFreeVarList (&ChkPck);
488   ShellCloseHandleEnumerator ();
489   LibUnInitializeStrings ();
490   return Status;
491 }
492
493 EFI_STATUS
494 InitializeSerialModeGetLineHelp (
495   OUT CHAR16              **Str
496   )
497 /*++
498
499 Routine Description:
500
501   Get this command's line help
502
503 Arguments:
504
505   Str - The line help
506
507 Returns:
508
509   EFI_SUCCESS   - Success
510
511 --*/
512 {
513   return LibCmdGetStringByToken (STRING_ARRAY_NAME, &EfiSermodeGuid, STRING_TOKEN (STR_SERMODE_LINE_HELP), Str);
514 }