void tst_QSimToolkit::testEncodeEventDownload() { QFETCH( QByteArray, data ); QFETCH( QByteArray, payload ); QFETCH( int, event ); QFETCH( int, sourceDevice ); // Output a dummy line to give some indication of which test we are currently running. qDebug() << ""; // Check that the envelope PDU can be parsed correctly. QSimEnvelope decodedEnv = QSimEnvelope::fromPdu(data); QVERIFY( decodedEnv.type() == QSimEnvelope::EventDownload ); QVERIFY( decodedEnv.sourceDevice() == (QSimCommand::Device)sourceDevice ); QCOMPARE( (int)decodedEnv.event(), event ); QCOMPARE( decodedEnv.extensionData(), payload ); // Check that the original envelope PDU can be reconstructed correctly. QByteArray pdu = decodedEnv.toPdu(); pdu[2] = data[2]; // Handle 0x19 vs 0x99 discrepancy. QCOMPARE( pdu, data ); }
bool SimApplication::execute( const QString& cmd ) { // Process SIM toolkit begin and end commands by forcing the app back to the main menu. if ( cmd == "AT*TSTB" || cmd == "AT*TSTE") { d->rules->respond( "OK" ); abort(); return true; } // If not AT+CSIM, then this is not a SIM toolkit command. if ( !cmd.startsWith( "AT+CSIM=" ) ) return false; // Extract the binary payload of the AT+CSIM command. int comma = cmd.indexOf( QChar(',') ); if ( comma < 0 ) return false; QByteArray param = QAtUtils::fromHex( cmd.mid(comma + 1) ); if ( param.length() < 5 || param[0] != (char)0xA0 ) return false; // Check for TERMINAL PROFILE, FETCH, TERMINAL RESPONSE, // and ENVELOPE packets. if ( param[1] == (char)0x10 ) { // Download of a TERMINAL PROFILE. We respond with a simple OK, // on the assumption that what we were sent was valid. d->rules->respond( "+CSIM: 4,9000\nOK" ); // Abort the SIM application and force it to return to the main menu. abort(); } else if ( param[1] == (char)0x12 ) { // Fetch the current command contents. QByteArray resp = d->currentCommand; if ( resp.isEmpty() ) { // We weren't expecting a FETCH. d->rules->respond( "+CSIM: 4,6F00\nOK" ); return true; } resp += (char)0x90; resp += (char)0x00; d->rules->respond( "+CSIM: " + QString::number( resp.size() * 2 ) + "," + QAtUtils::toHex( resp ) + "\nOK" ); } else if ( param[1] == (char)0x14 ) { // Process a TERMINAL RESPONSE message. QSimTerminalResponse resp; resp = QSimTerminalResponse::fromPdu( param.mid(5) ); if ( resp.command().type() != QSimCommand::NoCommand && resp.command().type() != d->expectedType ) { // Response to the wrong type of command. d->rules->respond( "+CSIM: 4,6F00\nOK" ); return true; } response( resp ); } else if ( param[1] == (char)0xC2 ) { // Process a menu selection ENVELOPE message. We turn it into a // QSimTerminalResponse to make it easier to process. QSimEnvelope env; env = QSimEnvelope::fromPdu( param.mid(5) ); if ( env.type() == QSimEnvelope::EventDownload ) { d->rules->respond( "+CSIM: 4,9000\nOK" ); return true; } if ( env.type() != QSimEnvelope::MenuSelection ) return false; if ( d->expectedType != QSimCommand::SetupMenu ) { // Envelope sent for the wrong type of command. d->rules->respond( "+CSIM: 4,6F00\nOK" ); return true; } d->rules->respond( "+CSIM: 4,9000\nOK" ); d->expectedType = QSimCommand::NoCommand; d->currentCommand = QByteArray(); d->target = 0; d->slot = 0; if ( env.requestHelp() ) mainMenuHelpRequest( env.menuItem() ); else mainMenuSelection( env.menuItem() ); } else { // This SIM command is not related to SIM toolkit - ignore it. return false; } return true; }