aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Prestwood <james.prestwood@linux.intel.com>2017-11-08 09:23:51 -0800
committerDenis Kenzior <denkenz@gmail.com>2017-11-08 20:57:15 -0600
commit7bfcff17deef45f887b4eff188a97d9f73482479 (patch)
tree0aaf52f0eb8d22fc8b8cdfdb4e218632332a8457
parent11aee794f17584b1e2d3744b823776fea8b72624 (diff)
downloadphonesim-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.cpp276
-rw-r--r--src/aidapplication.h88
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