SMBIOS Library
TokenDA.cpp
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
3  *
4  * Copyright (C) 2005 Dell Inc.
5  * by Michael Brown <Michael_E_Brown@dell.com>
6  * Licensed under the Open Software License version 2.1
7  *
8  * Alternatively, you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published
10  * by the Free Software Foundation; either version 2 of the License,
11  * or (at your option) any later version.
12 
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU General Public License for more details.
17  */
18 
19 // compat header should always be first header if including system headers
20 #define LIBSMBIOS_SOURCE
21 #include "smbios/compat.h"
22 
23 #include <iomanip>
24 #include <string.h>
25 
26 #include "TokenImpl.h"
27 
28 #include "smbios/ISmi.h"
29 
30 #define TODO do { throw NotImplementedImpl(); } while(0)
31 
32 using namespace std;
33 
34 #if defined(DEBUG_TOKEN_DA)
35 # define DCOUT(line) do { cout << line; } while(0)
36 # define DCERR(line) do { cerr << line; } while(0)
37 #else
38 # define DCOUT(line) do {} while(0)
39 # define DCERR(line) do {} while(0)
40 #endif
41 
42 namespace smbios
43 {
44  SmiTokenDA::SmiTokenDA( const smbios::ISmbiosItem &initItem, const calling_interface_token *initToken )
45  : IToken(), ISmiToken(), IProtectedToken(), item(initItem.clone()), password("")
46  {
47  memcpy( const_cast<calling_interface_token *>(&token), initToken, sizeof(token) );
48 
49  size_t size;
50  const u8 *ptr = item->getBufferCopy(size) ; // MUST DELETE[]!
51  memcpy( const_cast<calling_interface_structure*>(&structure), ptr, sizeof(structure) );
52  delete [] const_cast<u8 *>(ptr); //const_cast to fix msvc++
53  }
54 
55  // no dynamically allocated memory, yay!
57  {}
58 
60  {
61  return "TokenDA";
62  }
63 
65  {
66  return 0xFFFFFFFF;
67  }
68 
69  bool SmiTokenDA::tryPassword(std::string pw) const
70  {
71  // can't really validate password without retrying operation
72  password = pw;
73  return true;
74  }
75 
77  {
78  return *item;
79  }
80 
81  void SmiTokenDA::getSmiDetails( u16 *cmdIOAddress, u8 *cmdIOCode, u8 *location ) const
82  {
83  if (cmdIOAddress)
84  *cmdIOAddress = structure.cmdIOAddress;
85  if (cmdIOCode)
86  *cmdIOCode = structure.cmdIOCode;
87  if (location)
88  *location = token.location;
89  }
90 
92  {
93  return token.tokenId;
94  }
95 
96  bool SmiTokenDA::isActive() const
97  {
98  bool ret = false;
99 
100  DCERR("reading token: " << static_cast<u32>(token.location) << " compare with value: " << static_cast<u32>(token.value) << " actual: " << smi::readNVStorage(token.location, 0, 0) << endl);
102  ret = true;
103 
104  return ret;
105  }
106 
107  static void executeWithPassword(smi::IDellCallingInterfaceSmi *ci, u8 arg, string password)
108  {
109  for(int i=0; i<2; i++)
110  {
111  try
112  {
113  ci->execute();
114  break;
115  }
116  catch(const smi::SmiExecutedWithError &)
117  {
118  // on second time through, just pass exception upwards.
119  if(i==1)
120  throw;
121 
122  //cout << "Caught error. Might be bad password. Trying password: " << password << endl;
123  ci->setArg( arg, smi::getAuthenticationKey(password));
124  }
125  }
126  }
127 
128  void SmiTokenDA::activate() const
129  {
130  DCERR("trying to activate token: " << static_cast<u32>(token.location) << " with value: " << static_cast<u32>(token.value) << endl);
132  }
133 
134  bool SmiTokenDA::isString() const
135  {
136  return true;
137  }
138 
139  bool SmiTokenDA::isBool() const
140  {
141  return true;
142  }
143 
144  const string SmiTokenDA::getString(u8 *byteArray, unsigned int size ) const
145  {
146  std::auto_ptr<smi::IDellCallingInterfaceSmi> smi = smi::SmiFactory::getFactory()->makeNew(smi::SmiFactory::DELL_CALLING_INTERFACE_SMI);
147 
148  smi::IDellCallingInterfaceSmi *ci = dynamic_cast<smi::IDellCallingInterfaceSmi *>(smi.get());
149  ci->setClass( 0x0 ); /* Read Non-Volatile Storage class code */
150  ci->setSelect( 0x0 ); /* Read Non-Volatile Storage select code */
151  ci->setArg( 0, token.location );
152  ci->execute();
153 
154  // first word is data. ignore high bits.
155  u16 word = static_cast<u16>(ci->getRes(1));
156 
157  if(byteArray && size >= 2)
158  {
159  memset(byteArray, 0, size);
160  memcpy(byteArray, &word, sizeof(u16));
161  }
162 
163  char ret[3]={0};
164  memcpy(ret, &word, sizeof(u16));
165 
166  return ret; //automatically converted to std::string
167  }
168 
169  void SmiTokenDA::setString( const u8 *byteArray, size_t size ) const
170  {
171  if( size < 2 )
172  return;
173 
174  std::auto_ptr<smi::IDellCallingInterfaceSmi> smi = smi::SmiFactory::getFactory()->makeNew(smi::SmiFactory::DELL_CALLING_INTERFACE_SMI);
175 
176  smi::IDellCallingInterfaceSmi *ci = dynamic_cast<smi::IDellCallingInterfaceSmi *>(smi.get());
177  ci->setClass( 0x1 ); /* Read Non-Volatile Storage class code */
178  ci->setSelect( 0x0 ); /* Read Non-Volatile Storage select code */
179  ci->setArg( 0, token.location );
180  ci->setArg( 1, *reinterpret_cast<const u16 *>(byteArray) );
182  }
183 
184  unsigned int SmiTokenDA::getStringLength() const
185  {
186  // pretend all SMI tokens are one word
187  return 2;
188  }
189 
190  std::ostream & SmiTokenDA::streamify( std::ostream & cout ) const
191  {
192  std::ios::fmtflags old_opts = cout.flags ();
193 
194  cout << hex << setfill('0');
195  cout << "DMI type 0x" << setw(2) << static_cast<int>(structure.type);
196  cout << " Handle 0x" << setw(4) << static_cast<int>(structure.handle);
197  cout << " CmdIO Port 0x" << setw(4) << static_cast<int>(structure.cmdIOAddress);
198  cout << " CmdIO Code 0x" << setw(2) << static_cast<int>(structure.cmdIOCode);
199  cout << " Type 0x" << setw(4) << static_cast<int>(getType());
200  cout << " Location 0x" << setw(4) << static_cast<int>(token.location);
201  cout << " value " << setw(4) << static_cast<int>(token.value);
202 
203  cout.flags (old_opts);
204 
205  return cout;
206  }
207 
208 }