00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #define LIBSMBIOS_SOURCE
00021 #include "smbios/compat.h"
00022
00023 #include <iomanip>
00024
00025 #include "TokenImpl.h"
00026
00027 #include "smbios/ISmi.h"
00028
00029 #define TODO do { throw NotImplementedImpl(); } while(0)
00030
00031 using namespace std;
00032
00033 #if defined(DEBUG_TOKEN_DA)
00034 # define DCOUT(line) do { cout << line; } while(0)
00035 # define DCERR(line) do { cerr << line; } while(0)
00036 #else
00037 # define DCOUT(line) do {} while(0)
00038 # define DCERR(line) do {} while(0)
00039 #endif
00040
00041 namespace smbios
00042 {
00043 SmiTokenDA::SmiTokenDA( const smbios::ISmbiosItem &initItem, const calling_interface_token *initToken )
00044 : IToken(), ISmiToken(), IProtectedToken(), item(initItem.clone()), password("")
00045 {
00046 memcpy( const_cast<calling_interface_token *>(&token), initToken, sizeof(token) );
00047
00048 size_t size;
00049 const u8 *ptr = item->getBufferCopy(size) ;
00050 memcpy( const_cast<calling_interface_structure*>(&structure), ptr, sizeof(structure) );
00051 delete [] const_cast<u8 *>(ptr);
00052 }
00053
00054
00055 SmiTokenDA::~SmiTokenDA() throw()
00056 {}
00057
00058 string SmiTokenDA::getTokenClass() const
00059 {
00060 return "TokenDA";
00061 }
00062
00063 u32 SmiTokenDA::getValueFormat() const
00064 {
00065 return 0xFFFFFFFF;
00066 }
00067
00068 bool SmiTokenDA::tryPassword(std::string pw) const
00069 {
00070
00071 password = pw;
00072 return true;
00073 }
00074
00075 const ISmbiosItem &SmiTokenDA::getItemRef() const
00076 {
00077 return *item;
00078 }
00079
00080 void SmiTokenDA::getSmiDetails( u16 *cmdIOAddress, u8 *cmdIOCode, u8 *location ) const
00081 {
00082 if (cmdIOAddress)
00083 *cmdIOAddress = structure.cmdIOAddress;
00084 if (cmdIOCode)
00085 *cmdIOCode = structure.cmdIOCode;
00086 if (location)
00087 *location = token.location;
00088 }
00089
00090 u32 SmiTokenDA::getType() const
00091 {
00092 return token.tokenId;
00093 }
00094
00095 bool SmiTokenDA::isActive() const
00096 {
00097 bool ret = false;
00098
00099 DCERR("reading token: " << static_cast<u32>(token.location) << " compare with value: " << static_cast<u32>(token.value) << " actual: " << smi::readNVStorage(token.location, 0, 0) << endl);
00100 if (token.value == smi::readNVStorage(token.location, 0, 0))
00101 ret = true;
00102
00103 return ret;
00104 }
00105
00106 static void executeWithPassword(smi::IDellCallingInterfaceSmi *ci, u8 arg, string password)
00107 {
00108 for(int i=0; i<2; i++)
00109 {
00110 try
00111 {
00112 ci->execute();
00113 break;
00114 }
00115 catch(const smi::SmiExecutedWithError &)
00116 {
00117
00118 if(i==1)
00119 throw;
00120
00121
00122 ci->setArg( arg, smi::getAuthenticationKey(password));
00123 }
00124 }
00125 }
00126
00127 void SmiTokenDA::activate() const
00128 {
00129 DCERR("trying to activate token: " << static_cast<u32>(token.location) << " with value: " << static_cast<u32>(token.value) << endl);
00130 smi::writeNVStorage(password, token.location, token.value, 0, 0);
00131 }
00132
00133 bool SmiTokenDA::isString() const
00134 {
00135 return true;
00136 }
00137
00138 bool SmiTokenDA::isBool() const
00139 {
00140 return true;
00141 }
00142
00143 const string SmiTokenDA::getString(u8 *byteArray, unsigned int size ) const
00144 {
00145 std::auto_ptr<smi::ISmi> smi = smi::SmiFactory::getFactory()->makeNew(smi::SmiFactory::DELL_CALLING_INTERFACE_SMI_RAW);
00146 smi->setCommandIOMagic( structure.cmdIOAddress, structure.cmdIOCode );
00147
00148 smi::IDellCallingInterfaceSmi *ci = dynamic_cast<smi::IDellCallingInterfaceSmi *>(smi.get());
00149 ci->setClass( 0x0 );
00150 ci->setSelect( 0x0 );
00151 ci->setArg( 0, token.location );
00152 ci->execute();
00153
00154
00155 u16 word = static_cast<u16>(ci->getRes(1));
00156
00157 if(byteArray && size >= 2)
00158 {
00159 memset(byteArray, 0, size);
00160 memcpy(byteArray, &word, sizeof(u16));
00161 }
00162
00163 char ret[3]={0};
00164 memcpy(ret, &word, sizeof(u16));
00165
00166 return ret;
00167 }
00168
00169 void SmiTokenDA::setString( const u8 *byteArray, size_t size ) const
00170 {
00171 if( size < 2 )
00172 return;
00173
00174 std::auto_ptr<smi::ISmi> smi = smi::SmiFactory::getFactory()->makeNew(smi::SmiFactory::DELL_CALLING_INTERFACE_SMI_RAW);
00175 smi->setCommandIOMagic( structure.cmdIOAddress, structure.cmdIOCode );
00176
00177 smi::IDellCallingInterfaceSmi *ci = dynamic_cast<smi::IDellCallingInterfaceSmi *>(smi.get());
00178 ci->setClass( 0x1 );
00179 ci->setSelect( 0x0 );
00180 ci->setArg( 0, token.location );
00181 ci->setArg( 1, *reinterpret_cast<const u16 *>(byteArray) );
00182 executeWithPassword(ci, 2, password);
00183 }
00184
00185 unsigned int SmiTokenDA::getStringLength() const
00186 {
00187
00188 return 2;
00189 }
00190
00191 std::ostream & SmiTokenDA::streamify( std::ostream & cout ) const
00192 {
00193 std::ios::fmtflags old_opts = cout.flags ();
00194
00195 cout << hex << setfill('0');
00196 cout << "DMI type 0x" << setw(2) << static_cast<int>(structure.type);
00197 cout << " Handle 0x" << setw(4) << static_cast<int>(structure.handle);
00198 cout << " CmdIO Port 0x" << setw(4) << static_cast<int>(structure.cmdIOAddress);
00199 cout << " CmdIO Code 0x" << setw(2) << static_cast<int>(structure.cmdIOCode);
00200 cout << " Type 0x" << setw(4) << static_cast<int>(getType());
00201 cout << " Location 0x" << setw(4) << static_cast<int>(token.location);
00202 cout << " value " << setw(4) << static_cast<int>(token.value);
00203
00204 cout.flags (old_opts);
00205
00206 return cout;
00207 }
00208
00209 }