00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "m_desktop.h"
00023 #include "data.h"
00024 #include "protocol.h"
00025 #include "protostructs.h"
00026 #include "packet.h"
00027 #include "endian.h"
00028 #include "error.h"
00029 #include "usbwrap.h"
00030 #include "controller.h"
00031 #include <stdexcept>
00032 #include <sstream>
00033
00034 #include "debug.h"
00035
00036 namespace Barry { namespace Mode {
00037
00038
00039
00040
00041
00042 Desktop::Desktop(Controller &con)
00043 : Mode(con, Controller::Desktop)
00044 , m_ic(0)
00045 {
00046 }
00047
00048 Desktop::Desktop(Controller &con, const IConverter &ic)
00049 : Mode(con, Controller::Desktop)
00050 , m_ic(&ic)
00051 {
00052 }
00053
00054 Desktop::~Desktop()
00055 {
00056 }
00057
00058
00059
00060
00061 void Desktop::LoadCommandTable()
00062 {
00063 char rawCommand[] = { 6, 0, 0x0a, 0, 0x40, 0, 0, 1, 0, 0 };
00064 *((uint16_t*) rawCommand) = htobs(m_socket->GetSocket());
00065
00066 Data command(rawCommand, sizeof(rawCommand));
00067 Data response;
00068
00069 try {
00070 m_socket->Packet(command, response);
00071
00072 MAKE_PACKET(rpack, response);
00073 while( rpack->command != SB_COMMAND_DB_DONE ) {
00074 m_socket->NextRecord(response);
00075
00076 rpack = (const Protocol::Packet *) response.GetData();
00077 if( rpack->command == SB_COMMAND_DB_DATA && btohs(rpack->size) > 10 ) {
00078
00079
00080 m_commandTable.Clear();
00081 m_commandTable.Parse(response, 6);
00082 }
00083 }
00084
00085 ddout(m_commandTable);
00086
00087 }
00088 catch( Usb::Error & ) {
00089 eout("Desktop: error getting command table");
00090 eeout(command, response);
00091 throw;
00092 }
00093 }
00094
00095 void Desktop::LoadDBDB()
00096 {
00097 Data command, response;
00098 DBPacket packet(*this, command, response);
00099 packet.GetDBDB();
00100
00101 m_socket->Packet(packet);
00102
00103 while( packet.Command() != SB_COMMAND_DB_DONE ) {
00104 if( packet.Command() == SB_COMMAND_DB_DATA ) {
00105 m_dbdb.Clear();
00106 m_dbdb.Parse(response);
00107 }
00108
00109
00110 m_socket->NextRecord(response);
00111 }
00112 }
00113
00114 void Desktop::OnOpen()
00115 {
00116
00117 LoadCommandTable();
00118 LoadDBDB();
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 unsigned int Desktop::GetDBID(const std::string &name) const
00136 {
00137 unsigned int ID = 0;
00138
00139 if( !m_dbdb.GetDBNumber(name, ID) ) {
00140 throw Error("Desktop: database name not found: " + name);
00141 }
00142 return ID;
00143 }
00144
00145
00146
00147
00148
00149
00150
00151 unsigned int Desktop::GetDBCommand(CommandType ct)
00152 {
00153 unsigned int cmd = 0;
00154 const char *cmdName = "Unknown";
00155
00156 switch( ct )
00157 {
00158 case DatabaseAccess:
00159 cmdName = "Database Access";
00160 cmd = m_commandTable.GetCommand(cmdName);
00161 break;
00162 default:
00163 throw std::logic_error("Desktop: unknown command type");
00164 }
00165
00166 if( cmd == 0 ) {
00167 std::ostringstream oss;
00168 oss << "Desktop: unable to get command code: " << cmdName;
00169 throw Error(oss.str());
00170 }
00171
00172 return cmd;
00173 }
00174
00175 void Desktop::SetIConverter(const IConverter &ic)
00176 {
00177 m_ic = ⁣
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187 void Desktop::GetRecordStateTable(unsigned int dbId, RecordStateTable &result)
00188 {
00189 dout("Database ID: " << dbId);
00190
00191
00192 result.Clear();
00193
00194 Data command, response;
00195 DBPacket packet(*this, command, response);
00196 packet.GetRecordStateTable(dbId);
00197
00198 m_socket->Packet(packet);
00199 result.Parse(response);
00200
00201
00202 while( packet.Command() != SB_COMMAND_DB_DONE )
00203 m_socket->NextRecord(response);
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 void Desktop::AddRecord(unsigned int dbId, Builder &build)
00215 {
00216 dout("Database ID: " << dbId);
00217
00218 Data command, response;
00219 DBPacket packet(*this, command, response);
00220
00221 if( packet.SetRecord(dbId, build, m_ic) ) {
00222
00223 std::ostringstream oss;
00224
00225 m_socket->Packet(packet);
00226
00227
00228 if( packet.Command() != SB_COMMAND_DB_DONE ) {
00229 oss << "Desktop: device responded with unexpected packet command code: "
00230 << "0x" << std::hex << packet.Command();
00231 throw Error(oss.str());
00232 }
00233
00234 if( packet.ReturnCode() != 0 ) {
00235 oss << "Desktop: device responded with error code (command: "
00236 << packet.Command() << ", code: "
00237 << packet.ReturnCode() << ")";
00238 throw Error(oss.str());
00239 }
00240 }
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250 void Desktop::GetRecord(unsigned int dbId,
00251 unsigned int stateTableIndex,
00252 Parser &parser)
00253 {
00254 dout("Database ID: " << dbId);
00255
00256 Data command, response;
00257 DBPacket packet(*this, command, response);
00258 packet.GetRecordByIndex(dbId, stateTableIndex);
00259
00260 m_socket->Packet(packet);
00261
00262
00263 if( response.GetSize() < SB_PACKET_RESPONSE_HEADER_SIZE ) {
00264 eeout(command, response);
00265
00266 std::ostringstream oss;
00267 oss << "Desktop: invalid response packet size of "
00268 << std::dec << response.GetSize();
00269 eout(oss.str());
00270 throw Error(oss.str());
00271 }
00272 if( packet.Command() != SB_COMMAND_DB_DATA ) {
00273 eeout(command, response);
00274
00275 std::ostringstream oss;
00276 oss << "Desktop: unexpected command of 0x"
00277 << std::setbase(16) << packet.Command()
00278 << " instead of expected 0x"
00279 << std::setbase(16) << (unsigned int)SB_COMMAND_DB_DATA;
00280 eout(oss.str());
00281 throw Error(oss.str());
00282 }
00283
00284
00285 packet.Parse(parser, m_ic);
00286
00287
00288 while( packet.Command() != SB_COMMAND_DB_DONE )
00289 m_socket->NextRecord(response);
00290 }
00291
00292
00293
00294
00295
00296
00297
00298 void Desktop::SetRecord(unsigned int dbId, unsigned int stateTableIndex,
00299 Builder &build)
00300 {
00301 dout("Database ID: " << dbId << " Index: " << stateTableIndex);
00302
00303 Data command, response;
00304 DBPacket packet(*this, command, response);
00305
00306
00307 if( !packet.SetRecordByIndex(dbId, stateTableIndex, build, m_ic) ) {
00308 throw std::logic_error("Desktop: no data available in SetRecord");
00309 }
00310
00311 m_socket->Packet(packet);
00312
00313 std::ostringstream oss;
00314
00315
00316 if( packet.Command() != SB_COMMAND_DB_DONE ) {
00317 oss << "Desktop: device responded with unexpected packet command code: "
00318 << "0x" << std::hex << packet.Command();
00319 throw Error(oss.str());
00320 }
00321
00322 if( packet.ReturnCode() != 0 ) {
00323 oss << "Desktop: device responded with error code (command: "
00324 << packet.Command() << ", code: "
00325 << packet.ReturnCode() << ")";
00326 throw Error(oss.str());
00327 }
00328 }
00329
00330
00331
00332
00333
00334
00335 void Desktop::ClearDirty(unsigned int dbId, unsigned int stateTableIndex)
00336 {
00337 dout("Database ID: " << dbId);
00338
00339 Data command, response;
00340 DBPacket packet(*this, command, response);
00341 packet.SetRecordFlags(dbId, stateTableIndex, 0);
00342
00343 m_socket->Packet(packet);
00344
00345
00346 while( packet.Command() != SB_COMMAND_DB_DONE )
00347 m_socket->NextRecord(response);
00348 }
00349
00350
00351
00352
00353
00354
00355 void Desktop::DeleteRecord(unsigned int dbId, unsigned int stateTableIndex)
00356 {
00357 dout("Database ID: " << dbId);
00358
00359 Data command, response;
00360 DBPacket packet(*this, command, response);
00361 packet.DeleteRecordByIndex(dbId, stateTableIndex);
00362
00363 m_socket->Packet(packet);
00364
00365
00366 while( packet.Command() != SB_COMMAND_DB_DONE )
00367 m_socket->NextRecord(response);
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 void Desktop::LoadDatabase(unsigned int dbId, Parser &parser)
00394 {
00395 dout("Database ID: " << dbId);
00396
00397 Data command, response;
00398 DBPacket packet(*this, command, response);
00399 packet.GetRecords(dbId);
00400
00401 m_socket->Packet(packet);
00402
00403 while( packet.Command() != SB_COMMAND_DB_DONE ) {
00404 if( packet.Command() == SB_COMMAND_DB_DATA ) {
00405
00406
00407 packet.Parse(parser, m_ic);
00408 }
00409
00410
00411 m_socket->NextRecord(response);
00412 }
00413 }
00414
00415 void Desktop::ClearDatabase(unsigned int dbId)
00416 {
00417 dout("Database ID: " << dbId);
00418
00419 Data command, response;
00420 DBPacket packet(*this, command, response);
00421 packet.ClearDatabase(dbId);
00422
00423
00424 m_socket->Packet(packet, 60000);
00425 if( packet.ReturnCode() != 0 ) {
00426 std::ostringstream oss;
00427 oss << "Desktop: could not clear database: (command: "
00428 << "0x" << std::hex << packet.Command() << ", code: "
00429 << "0x" << std::hex << packet.ReturnCode() << ")";
00430 throw Error(oss.str());
00431 }
00432
00433
00434 if( packet.Command() != SB_COMMAND_DB_DONE ) {
00435 eeout(command, response);
00436 throw Error("Desktop: error clearing database, bad response");
00437 }
00438 }
00439
00440 void Desktop::SaveDatabase(unsigned int dbId, Builder &builder)
00441 {
00442 dout("Database ID: " << dbId);
00443
00444
00445
00446
00447
00448
00449
00450
00451 ClearDatabase(dbId);
00452
00453 Data command, response;
00454 DBPacket packet(*this, command, response);
00455
00456
00457 bool first = true;
00458 while( packet.SetRecord(dbId, builder, m_ic) ) {
00459 dout("Database ID: " << dbId);
00460
00461 m_socket->Packet(packet, first ? 60000 : -1);
00462 first = false;
00463
00464 std::ostringstream oss;
00465
00466 if( packet.Command() != SB_COMMAND_DB_DONE ) {
00467 oss << "Desktop: device responded with unexpected packet command code: "
00468 << "0x" << std::hex << packet.Command();
00469 throw Error(oss.str());
00470 }
00471
00472 if( packet.ReturnCode() != 0 ) {
00473 oss << "Desktop: device responded with error code (command: "
00474 << packet.Command() << ", code: "
00475 << packet.ReturnCode() << ")";
00476 throw Error(oss.str());
00477 }
00478 }
00479 }
00480
00481 }}
00482