예제 #1
0
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 );
}
예제 #2
0
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;
}