Ejemplo n.º 1
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;
}