diff options
author | James Prestwood <james.prestwood@linux.intel.com> | 2017-11-08 09:23:51 -0800 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2017-11-08 20:57:15 -0600 |
commit | 7bfcff17deef45f887b4eff188a97d9f73482479 (patch) | |
tree | 0aaf52f0eb8d22fc8b8cdfdb4e218632332a8457 | |
parent | 11aee794f17584b1e2d3744b823776fea8b72624 (diff) | |
download | phonesim-7bfcff17deef45f887b4eff188a97d9f73482479.tar.gz |
aidapplications: new class for AID applications
New AID applications can be created using the XML
<application> tag. Inside this tag a file system
can be created which is accessable via session
based file access.
-rw-r--r-- | src/aidapplication.cpp | 276 | ||||
-rw-r--r-- | src/aidapplication.h | 88 |
2 files changed, 364 insertions, 0 deletions
diff --git a/src/aidapplication.cpp b/src/aidapplication.cpp new file mode 100644 index 0000000..e255145 --- /dev/null +++ b/src/aidapplication.cpp @@ -0,0 +1,276 @@ +#include "aidapplication.h" +#include "simfilesystem.h" +#include "simauth.h" + +#include <qatutils.h> +#include <qsimcontrolevent.h> + +AidApplication::AidApplication( QObject *parent, SimXmlNode& n ) + : QObject( parent ) +{ + SimXmlNode *child = n.children; + + type = n.getAttribute( "type" ); + aid = n.getAttribute( "id" ); + + while (child) { + if ( child->tag == "filesystem" ) + fs = new SimFileSystem( (SimRules *)parent, *child, FILE_SYSTEM_TYPE_ISIM ); + + child = child->next; + } +} + +AidApplication::~AidApplication() +{ +} + +AidAppWrapper::AidAppWrapper( SimRules *r, QList<AidApplication *> apps, SimAuth *sa ) : QObject( r ) +{ + applications = apps; + session_start = 257; + rules = r; + auth = sa; +} + +AidAppWrapper::~AidAppWrapper() +{ +} + +bool AidAppWrapper::command( const QString& cmd ) +{ + if ( cmd.startsWith( "AT+CUAD") ) { + QString response( "+CUAD: " ); + + if ( cmd.contains("=?") ) { + rules->respond( "OK" ); + return true; + } + + foreach ( AidApplication* app, applications ) + response += app->getAid(); + + response.append( "\n\nOK" ); + + rules->respond( response ); + + return true; + } else if ( cmd.startsWith( "AT+CCHO" ) ) { + QString aid; + int session_id = -1; + + if ( !cmd.contains("=") ) { + rules->respond( "ERROR" ); + return true; + } + + if ( cmd.contains("=?") ) { + rules->respond( "OK" ); + return true; + } + + aid = cmd.split('=')[1]; + aid = aid.replace("\"", ""); + + foreach ( AidApplication* app, applications ) { + if ( app->getAid().contains( aid ) ) { + if ( sessions.size() >= MAX_LOGICAL_CHANNELS ) + break; + + sessions.insert( session_start, app ); + session_id = session_start; + session_start++; + break; + } + } + + if ( session_id == -1 ) { + rules->respond( "ERROR" ); + return true; + } + + rules->respond( QString( "+CCHO: %1\n\nOK" ).arg(session_id, 0, 10) ); + return true; + } else if ( cmd.startsWith( "AT+CCHC" ) ) { + int session_id = -1; + + if ( !cmd.contains("=") ) { + rules->respond( "ERROR" ); + return true; + } + + if ( cmd.contains("=?") ) { + rules->respond( "OK" ); + return true; + } + + session_id = cmd.split('=')[1].toInt(); + + sessions.remove( session_id ); + + rules->respond( "OK" ); + return true; + } else if ( cmd.startsWith( "AT+CRLA" ) ) { + QString resp; + AidApplication *app; + QStringList params = cmd.split('=')[1].split(','); + + int session_id = params[0].toInt(); + + if ( !sessions.contains( session_id ) ) { + rules->respond( "ERROR" ); + return true; + } + + app = sessions[session_id]; + if (!app) { + rules->respond( "ERROR" ); + return true; + } + + QString file_cmd; + QString response = "+CRLA: "; + + for (int i = 1; i < params.length(); i++) { + file_cmd += params[i]; + + if (i != params.length() - 1) + file_cmd += ","; + } + + bool ok = app->fs->fileAccess( file_cmd, resp ); + + if (!ok) { + rules->respond( "OK" ); + return true; + } + + response += resp; + + rules->respond( response ); + rules->respond( "OK" ); + + return true; + } else if ( cmd.startsWith( "AT+CGLA" ) ) { + QString auth_data; + QString command; + QString resp; + AidApplication *app; + QStringList params = cmd.split('=')[1].split(','); + + int session_id = params[0].toInt(); + + if ( !sessions.contains( session_id ) ) { + rules->respond( "ERROR" ); + return true; + } + + app = sessions[session_id]; + if (!app) { + rules->respond( "ERROR" ); + return true; + } + + command = params[2].replace("\"", ""); + auth_data = command.mid(10); + + switch (checkCommand(app, command)) { + case CMD_TYPE_GSM_AUTH: + { + QString sres, kc; + QString rand = auth_data.mid(2, 32); + auth->gsmAuthenticate(rand, sres, kc); + + resp = QString( "+CGLA: 32,\"04 %1 08 %2 \"" ) + .arg( sres, kc ); + resp.replace( " ", ""); + + rules->respond( resp ); + rules->respond( "OK" ); + + return true; + } + break; + case CMD_TYPE_UMTS_AUTH: + { + enum UmtsStatus status; + QString res, ck, ik, auts; + QString rand = auth_data.mid(2, 32); + QString autn = auth_data.mid(36, 32); + + status = auth->umtsAuthenticate( rand, autn, res, ck, ik, auts ); + resp = QString("+CGLA: "); + + QString test; + + switch (status) { + case UMTS_OK: + resp += QString( "88,\"DB08 %1 10 %2 10 %3\"" ) + .arg( res, ck, ik ); + resp.replace( " ", "" ); + + break; + case UMTS_INVALID_MAC: + resp += QString( "4,\"%1\"") + .arg( CMD_TYPE_APP_ERROR, 0, 16 ); + + break; + case UMTS_SYNC_FAILURE: + resp += QString( "34,\"DC0E %1 \"" ).arg( auts ); + resp.replace( " ", "" ); + + break; + case UMTS_ERROR: + rules->respond( "ERROR" ); + return true; + } + + rules->respond( resp ); + rules->respond( "OK" ); + } + break; + default: + return false; + } + } + + return false; +} + +enum CmdType AidAppWrapper::checkCommand( AidApplication *app, QString command) +{ + QString cls = command.mid(0, 2); + QString ins = command.mid(2, 2); + QString p1 = command.mid(4, 2); + QString p2 = command.mid(6, 2); + QString lc = command.mid(8, 2); + + if ( cls != "00" ) + return CMD_TYPE_UNSUPPORTED_CLS; + + if ( ins != "88" ) + return CMD_TYPE_UNSUPPORTED_INS; + + if ( p1 != "00" ) + return CMD_TYPE_INCORRECT_P2_P1; + + if ( p2 == "80" ) { + if ( lc != "11" ) + return CMD_TYPE_WRONG_LENGTH; + + if ( !(app->getType() == "USim" || app->getType() == "ISim") ) + return CMD_TYPE_APP_ERROR; + + return CMD_TYPE_GSM_AUTH; + } else if ( p2 == "81" ) { + if ( lc != "22" ) + return CMD_TYPE_WRONG_LENGTH; + + if ( app->getType() != "ISim" ) + return CMD_TYPE_APP_ERROR; + + return CMD_TYPE_UMTS_AUTH; + } else { + return CMD_TYPE_UNKNOWN; + } +} diff --git a/src/aidapplication.h b/src/aidapplication.h new file mode 100644 index 0000000..6a2f4d9 --- /dev/null +++ b/src/aidapplication.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** This file is part of the Qt Extended Opensource Package. +** +** Copyright (C) 2017 Intel Corporation. All rights reserved. +** +** This file may be used under the terms of the GNU General Public License +** version 2.0 as published by the Free Software Foundation and appearing +** in the file LICENSE.GPL included in the packaging of this file. +** +** Please review the following information to ensure GNU General Public +** Licensing requirements will be met: +** http://www.fsf.org/licensing/licenses/info/GPLv2.html. +** +** +****************************************************************************/ + +#ifndef AIDAPPLICATION_H +#define AIDAPPLICATION_H + +#include "phonesim.h" + +#define MAX_LOGICAL_CHANNELS 4 + +/* + * Some common errors + */ +enum CmdType { + CMD_TYPE_GSM_AUTH = 0, + CMD_TYPE_UMTS_AUTH = 1, + CMD_TYPE_UNSUPPORTED_CLS = 0x6E00, + CMD_TYPE_UNSUPPORTED_INS = 0x6D00, + CMD_TYPE_INCORRECT_P2_P1 = 0x6A86, + CMD_TYPE_WRONG_LENGTH = 0x6700, + CMD_TYPE_APP_ERROR = 0x9862, + CMD_TYPE_UNKNOWN = 0xFFFF +}; + +/* + * Class for representing a single AID + */ +class AidApplication : public QObject +{ + Q_OBJECT +public: + AidApplication( QObject *parent, SimXmlNode& n ); + ~AidApplication(); + + QString getAid() { return aid; }; + QString getType() { return type; }; + SimFileSystem *fs; + +signals: + // Send a response to a command. + void send( const QString& line ); + +private: + QString aid; + QString type; +}; + +/* + * Wrapper for containing all AIDs on the SIM + */ +class AidAppWrapper : public QObject +{ + Q_OBJECT +public: + AidAppWrapper( SimRules *r, QList<AidApplication *> apps, SimAuth *auth = NULL ); + ~AidAppWrapper(); + + bool command( const QString& cmd ); + +//signals: + // Send a response to a command. +// void send( const QString& line ); +private: + QList<AidApplication *> applications; + QMap<int, AidApplication*> sessions; + int session_start; + SimRules *rules; + SimAuth *auth; + + enum CmdType checkCommand( AidApplication *app, QString command); + +}; + +#endif |