18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2007-2008 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sim_card.h"
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <assert.h>
15a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin#include <stdio.h>
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* set ENABLE_DYNAMIC_RECORDS to 1 to enable dynamic records
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * for now, this is an experimental feature that needs more testing
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  ENABLE_DYNAMIC_RECORDS  0
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  A_SIM_PIN_SIZE  4
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  A_SIM_PUK_SIZE  8
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct ASimCardRec_ {
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ASimStatus  status;
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char        pin[ A_SIM_PIN_SIZE+1 ];
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char        puk[ A_SIM_PUK_SIZE+1 ];
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int         pin_retries;
30a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin    int         port;
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char        out_buff[ 256 ];
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int         out_size;
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} ASimCardRec;
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic ASimCardRec  _s_card[1];
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectASimCard
40a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Hugueninasimcard_create(int port)
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ASimCard  card    = _s_card;
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    card->status      = A_SIM_STATUS_READY;
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    card->pin_retries = 0;
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strncpy( card->pin, "0000", sizeof(card->pin) );
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strncpy( card->puk, "12345678", sizeof(card->puk) );
47a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin    card->port = port;
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return card;
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_destroy( ASimCard  card )
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* nothing really */
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    card=card;
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic __inline__ int
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_ready( ASimCard  card )
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return card->status == A_SIM_STATUS_READY;
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectASimStatus
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_get_status( ASimCard  sim )
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return sim->status;
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_set_status( ASimCard  sim, ASimStatus  status )
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sim->status = status;
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_get_pin( ASimCard  sim )
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return sim->pin;
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_get_puk( ASimCard  sim )
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return sim->puk;
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_set_pin( ASimCard  sim, const char*  pin )
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strncpy( sim->pin, pin, A_SIM_PIN_SIZE );
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sim->pin_retries = 0;
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_set_puk( ASimCard  sim, const char*  puk )
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    strncpy( sim->puk, puk, A_SIM_PUK_SIZE );
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    sim->pin_retries = 0;
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_check_pin( ASimCard  sim, const char*  pin )
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sim->status != A_SIM_STATUS_PIN   &&
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sim->status != A_SIM_STATUS_READY )
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !strcmp( sim->pin, pin ) ) {
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sim->status      = A_SIM_STATUS_READY;
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sim->pin_retries = 0;
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sim->status != A_SIM_STATUS_READY) {
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (++sim->pin_retries == 3)
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sim->status = A_SIM_STATUS_PUK;
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_check_puk( ASimCard  sim, const char* puk, const char*  pin )
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (sim->status != A_SIM_STATUS_PUK)
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( !strcmp( sim->puk, puk ) ) {
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strncpy( sim->puk, puk, A_SIM_PUK_SIZE );
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        strncpy( sim->pin, pin, A_SIM_PIN_SIZE );
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sim->status      = A_SIM_STATUS_READY;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sim->pin_retries = 0;
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 1;
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( ++sim->pin_retries == 6 ) {
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        sim->status = A_SIM_STATUS_ABSENT;
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef enum {
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_DM = 0,
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_DF,
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_EF_DEDICATED,
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_EF_LINEAR,
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_EF_CYCLIC
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SimFileType;
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef enum {
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_READ_ONLY       = (1 << 0),
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_NEED_PIN = (1 << 1),
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SimFileFlags;
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* descriptor for a known SIM File */
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  SIM_FILE_HEAD       \
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SimFileType     type;    \
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned short  id;      \
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    unsigned short  flags;
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_HEAD
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SimFileAnyRec, *SimFileAny;
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_HEAD
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cbytes_t   data;
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int        length;
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SimFileEFDedicatedRec, *SimFileEFDedicated;
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct {
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SIM_FILE_HEAD
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    byte_t     rec_count;
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    byte_t     rec_len;
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    cbytes_t   records;
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SimFileEFLinearRec, *SimFileEFLinear;
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef SimFileEFLinearRec   SimFileEFCyclicRec;
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef SimFileEFCyclicRec*  SimFileEFCyclic;
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef union {
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SimFileAnyRec          any;
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SimFileEFDedicatedRec  dedicated;
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SimFileEFLinearRec     linear;
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SimFileEFCyclicRec     cyclic;
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} SimFileRec, *SimFile;
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if ENABLE_DYNAMIC_RECORDS
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* convert a SIM File descriptor into an ASCII string,
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   assumes 'dst' is NULL or properly sized.
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return the number of chars, or -1 on error */
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectsim_file_to_hex( SimFile  file, bytes_t  dst )
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    SimFileType  type   = file->any.type;
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int          result = 0;
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* see 9.2.1 in TS 51.011 */
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (type) {
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SIM_FILE_EF_DEDICATED:
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SIM_FILE_EF_LINEAR:
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case SIM_FILE_EF_CYCLIC:
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (dst) {
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    int  file_size, perm;
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    memcpy(dst, "0000", 4);  /* bytes 1-2 are RFU */
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst += 4;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* bytes 3-4 are the file size */
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (type == SIM_FILE_EF_DEDICATED)
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        file_size = file->dedicated.length;
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        file_size = file->linear.rec_count * file->linear.rec_len;
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    gsm_hex_from_short( dst, file_size );
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst += 4;
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* bytes 5-6 are the file id */
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    gsm_hex_from_short( dst, file->any.id );
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst += 4;
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* byte 7 is the file type - always EF, i.e. 0x04 */
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[0] = '0';
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[1] = '4';
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst   += 2;
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* byte 8 is RFU, except bit 7 for cyclic files, which indicates
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                       that INCREASE is allowed. Since we don't support this yet... */
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[0] = '0';
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[1] = '0';
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst   += 2;
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* byte 9-11 are access conditions */
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (file->any.flags & SIM_FILE_READ_ONLY) {
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (file->any.flags & SIM_FILE_NEED_PIN)
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            perm = 0x1a;
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        else
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            perm = 0x0a;
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    } else {
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (file->any.flags & SIM_FILE_NEED_PIN)
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            perm = 0x11;
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        else
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            perm = 0x00;
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    gsm_hex_from_byte(dst, perm);
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    memcpy( dst+2, "a0aa", 4 );
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst += 6;
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* byte 12 is file status, we don't support invalidation */
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[0] = '0';
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[1] = '0';
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst   += 2;
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* byte 13 is length of the following data, always 2 */
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[0] = '0';
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[1] = '2';
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst   += 2;
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* byte 14 is struct of EF */
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    dst[0] = '0';
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (type == SIM_FILE_EF_DEDICATED)
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dst[1] = '0';
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else if (type == SIM_FILE_EF_LINEAR)
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dst[1] = '1';
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    else
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dst[1] = '3';
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    /* byte 15 is lenght of record, or 0 */
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    if (type == SIM_FILE_EF_DEDICATED) {
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dst[0] = '0';
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dst[1] = '0';
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    } else
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        gsm_hex_from_byte( dst, file->linear.rec_len );
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                result = 30;
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            result = -1;
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return result;
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const byte_t  _const_spn_cphs[20] = {
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x41, 0x6e, 0x64, 0x72, 0x6f, 0x69, 0x64, 0xff, 0xff, 0xff,
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const byte_t  _const_voicemail_cphs[1] = {
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x55
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const byte_t  _const_iccid[10] = {
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x98, 0x10, 0x14, 0x30, 0x12, 0x11, 0x81, 0x15, 0x70, 0x02
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic const byte_t  _const_cff_cphs[1] = {
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    0x55
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic SimFileEFDedicatedRec  _const_files_dedicated[] =
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { SIM_FILE_EF_DEDICATED, 0x6f14, SIM_FILE_READ_ONLY | SIM_FILE_NEED_PIN,
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      _const_spn_cphs, sizeof(_const_spn_cphs) },
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { SIM_FILE_EF_DEDICATED, 0x6f11, SIM_FILE_NEED_PIN,
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      _const_voicemail_cphs, sizeof(_const_voicemail_cphs) },
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { SIM_FILE_EF_DEDICATED, 0x2fe2, SIM_FILE_READ_ONLY,
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      _const_iccid, sizeof(_const_iccid) },
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { SIM_FILE_EF_DEDICATED, 0x6f13, SIM_FILE_NEED_PIN,
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      _const_cff_cphs, sizeof(_const_cff_cphs) },
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    { 0, 0, 0, NULL, 0 }  /* end of list */
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* ENABLE_DYNAMIC_RECORDS */
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectconst char*
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectasimcard_io( ASimCard  sim, const char*  cmd )
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  nn;
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if ENABLE_DYNAMIC_RECORDS
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int  command, id, p1, p2, p3;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    static const struct { const char*  cmd; const char*  answer; } answers[] =
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28436,0,0,15", "+CRSM: 144,0,000000146f1404001aa0aa01020000" },
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=176,28436,0,0,20", "+CRSM: 144,0,416e64726f6964ffffffffffffffffffffffffff" },
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28433,0,0,15", "+CRSM: 144,0,000000016f11040011a0aa01020000" },
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=176,28433,0,0,1", "+CRSM: 144,0,55" },
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,12258,0,0,15", "+CRSM: 144,0,0000000a2fe204000fa0aa01020000" },
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=176,12258,0,0,10", "+CRSM: 144,0,98101430121181157002" },
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28435,0,0,15", "+CRSM: 144,0,000000016f13040011a0aa01020000" },
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=176,28435,0,0,1",  "+CRSM: 144,0,55" },
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28472,0,0,15", "+CRSM: 144,0,0000000f6f3804001aa0aa01020000" },
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=176,28472,0,0,15", "+CRSM: 144,0,ff30ffff3c003c03000c0000f03f00" },
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28617,0,0,15", "+CRSM: 144,0,000000086fc9040011a0aa01020104" },
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=178,28617,1,4,4",  "+CRSM: 144,0,01000000" },
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28618,0,0,15", "+CRSM: 144,0,0000000a6fca040011a0aa01020105" },
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=178,28618,1,4,5",  "+CRSM: 144,0,0000000000" },
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28589,0,0,15", "+CRSM: 144,0,000000046fad04000aa0aa01020000" },
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=176,28589,0,0,4",  "+CRSM: 144,0,00000003" },
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28438,0,0,15", "+CRSM: 144,0,000000026f1604001aa0aa01020000" },
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=176,28438,0,0,2",  "+CRSM: 144,0,0233" },
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28486,0,0,15", "+CRSM: 148,4" },
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28621,0,0,15", "+CRSM: 148,4" },
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28613,0,0,15", "+CRSM: 144,0,000000f06fc504000aa0aa01020118" },
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=178,28613,1,4,24", "+CRSM: 144,0,43058441aa890affffffffffffffffffffffffffffffffff" },
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28480,0,0,15", "+CRSM: 144,0,000000806f40040011a0aa01020120" },
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=178,28480,1,4,32", "+CRSM: 144,0,ffffffffffffffffffffffffffffffffffff07815155258131f5ffffffffffff" },
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=192,28615,0,0,15", "+CRSM: 144,0,000000406fc7040011a0aa01020120" },
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { "+CRSM=178,28615,1,4,32", "+CRSM: 144,0,566f6963656d61696cffffffffffffffffff07915155125740f9ffffffffffff" },
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        { NULL, NULL }
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    };
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    assert( memcmp( cmd, "+CRSM=", 6 ) == 0 );
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if ENABLE_DYNAMIC_RECORDS
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if ( sscanf(cmd, "+CRSM=%d,%d,%d,%d,%d", &command, &id, &p1, &p2, &p3) == 5 ) {
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (command) {
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case A_SIM_CMD_GET_RESPONSE:
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    const SimFileEFDedicatedRec*  file = _const_files_dedicated;
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    assert(p1 == 0 && p2 == 0 && p3 == 15);
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for ( ; file->id != 0; file++ ) {
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (file->id == id) {
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            int    count;
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            char*  out = sim->out_buff;
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            strcpy( out, "+CRSM: 144,0," );
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            out  += strlen(out);
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            count = sim_file_to_hex( (SimFile) file, out );
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (count < 0)
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                return "ERROR: INTERNAL SIM ERROR";
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            out[count] = 0;
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            return sim->out_buff;
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case A_SIM_CMD_READ_BINARY:
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                {
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    const SimFileEFDedicatedRec*  file = _const_files_dedicated;
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    assert(p1 == 0 && p2 == 0);
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    for ( ; file->id != 0; file++ ) {
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (file->id == id) {
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            char*  out = sim->out_buff;
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            if (p3 > file->length)
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                return "ERROR: BINARY LENGTH IS TOO LONG";
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            strcpy( out, "+CRSM: 144,0," );
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            out  += strlen(out);
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            gsm_hex_from_bytes( out, file->data, p3 );
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            out[p3*2] = 0;
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                            return sim->out_buff;
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    }
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    break;
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                }
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case A_SIM_CMD_READ_RECORD:
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return "ERROR: UNSUPPORTED SIM COMMAND";
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
435a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin    if (!strcmp("+CRSM=178,28480,1,4,32", cmd)) {
436a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin        snprintf( sim->out_buff, sizeof(sim->out_buff), "+CRSM: 144,0,ffffffffffffffffffffffffffffffffffff0781515525%d1%d%df%dffffffffffff", (sim->port / 1000) % 10, (sim->port / 10) % 10, (sim->port / 100) % 10, sim->port % 10);
437a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin        return sim->out_buff;
438a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin        }
439a1b379c65f787fc85bd9c6f4a6d14d8a2bebc9d5Marc Petit-Huguenin
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (nn = 0; answers[nn].cmd != NULL; nn++) {
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if ( !strcmp( answers[nn].cmd, cmd ) ) {
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return answers[nn].answer;
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return "ERROR: BAD COMMAND";
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
448