ByteString VsbDevice::doQuery(uint8_t cmdId, ByteString data) { ByteString cmdBuf(18, 0); cmdBuf[0] = cmdId; std::copy(data.begin(), data.end(), cmdBuf.begin()+2); sendFeatureReport(VSB_REPORTID, cmdBuf); bool dataOk = false; ByteString resp; for(int i = 0; i < NUM_READ_TRIES; ++i) { try { resp = getFeatureReport(VSB_REPORTID); } catch(HidDeviceError err) { if(i < NUM_READ_TRIES-1) continue; throw VsbError(std::string("HID subsystem error: ") + err.what()); } if(resp.size() < 2) continue; //Probably shouldn't ever happen, but let's not crash if it does if(!resp[0]) continue; //This also shouldn't happen... //FIXME: Implement a proper exception class to use here if(resp[0] != cmdId) throw std::runtime_error(boost::str(boost::format("Got the wrong command ID back! (%d)") % (int)resp[1])); if(resp[1] == VSB_RESP_BUSY) { //TODO: Insert a small time delay continue; } else if(resp[1] == VSB_RESP_NULL) throw VsbError("Null response code?"); else if(resp[1] == VSB_RESP_BADCMD) throw VsbError("Device reported bad command ID"); else if(resp[1] == VSB_RESP_BADCS) throw VsbError("Device reported stored configuration is corrupt/invalid"); else if(resp[1] == VSB_RESP_BADIDX) throw VsbError("Device reported bad keyseq page number"); else if(resp[1] == VSB_RESP_ERR) throw VsbError("Device reported general error"); else if(resp[1] == VSB_RESP_OK) { dataOk = true; break; } else throw VsbError("Got invalid response code"); } if(!dataOk) throw VsbError("Device failed to respond in time"); return ByteString(resp, 2); }
// Analyse an incoming message so that it can be checked against SXE policies. QString QCopRequestAnalyzer::analyze( QByteArray *msgQueue ) { dataSize = 0; moreData = false; QBuffer cmdBuf( msgQueue ); cmdBuf.open( QIODevice::ReadOnly | QIODevice::Unbuffered ); // Bail out if we don't have enough bytes for a complete packet. int size = read_int( &cmdBuf ); if ( size < (int)sizeof(qint32) ) { moreData = true; return QString(); } if ( size < QCopX11Client::minPacketSize ) size = QCopX11Client::minPacketSize; if ( size > ( msgQueue->size() - cmdBuf.pos() + sizeof(qint32) ) ) { moreData = true; return QString(); } // Read the command code and map it to a string. int cmd = read_int( &cmdBuf ); QString request; bool needChannel = false; bool needMessage = false; switch ( cmd ) { case QCopCmd_RegisterChannel: request = "QCopRegisterChannel/QCop/RegisterChannel/"; needChannel = true; break; case QCopCmd_Send: request = "QCopSend/QCop/"; needChannel = true; needMessage = true; break; case QCopCmd_DetachChannel: request = "QCopSend/QCop//detach()"; break; case QCopCmd_RequestRegistered: request = "QCopSend/QCop//isRegistered()"; break; default: return QString(); // Shouldn't happen in the server. } // Read the rest of the packet header. int chLength = read_int( &cmdBuf ); int msgLength = read_int( &cmdBuf ); read_int( &cmdBuf ); // forwardToLength - don't need this read_int( &cmdBuf ); // dataLength - don't need this // Add the channel and message names if necessary. if ( needChannel ) request += read_string( &cmdBuf, chLength ); if ( needMessage ) request += "/" + read_string( &cmdBuf, msgLength ); // Remove the packet we just processed from the queue. dataSize = size; // Return the policy string to the caller. return request; }