// simcmd_readrecord struc_simcmd <0A0h, 0B2h, 0, 2, 0B0h, 0> // simcmd_verifypin struc_simcmd <0A0h, 20h, 0, 1, 8, 0> // simcmd_getresponse struc_simcmd <0A0h, 0C0h, 0, 0, 0Fh, 0> // simcmd_select_file_EFSMS_6f02 struc_simcmd <0A0h, 0A4h, 0, 0, 02h, 6F3Ch> // simcmd_select_DF_TELECOM_7f02 struc_simcmd <0A0h, 0A4h, 0, 0, 02h, 7F10h> #include #include "RilMonitor.h" #include "RilExceptions.h" #include "debug.h" // see ts 102 221 and 51.011 // ~/docs/umts/ts_102221v070300p-smartcard-terminalinterface.pdf // ~/docs/gsm-specs/51.011.pdf enum CardCommand { DEACTIVATE_FILE=0x04, TERMINAL_PROFILE=0x10, FETCH=0x12, TERMINAL_RESPONSE=0x14, VERIFY_CHV=0x20, CHANGE_PIN=0x24, DISABLE_PIN=0x26, ENABLE_PIN=0x28, UNBLOCK_PIN=0x2C, INCREASE=0x32, ACTIVATE_FILE=0x44, MANAGE_CHANNEL=0x70, GET_CHALLENGE=0x84, AUTHENTICATE=0x88, // used to calc the Kc from the Ki // A088000010FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF SELECT_FILE=0xA4, SEEK=0xA2, READ_BINARY=0xB0, READ_RECORD=0xB2, GET_RESPONSE=0xC0, ENVELOPE=0xC2, RETRIEVE_DATA=0xCB, UPDATE_BINARY=0xD6, SET_DATA=0xDB, UPDATE_RECORD=0xDC, STATUS=0xF2, }; // see 11.1.1 enum SelectType { BYFILEID= 0x00, CHILDDF= 0x01, PARENTDF= 0x03, DFBYNAME= 0x04, ABSPATH= 0x08, RELPATH= 0x09, }; enum ReadMode { READNEXTREC= 0x02, READPREVREC= 0x03, READABSOLUTE= 0x04, }; enum { NOSIZE=-1, EXPECTMAXREPLY= 0, }; // see ISO/IEC 7816-4 [1] subclause 5.4.1. enum { GSMSIM_CLASS= 0xa0, USIM_CLASS= 0x00, }; bool selectbyfileid(rilmonitor& m, int fileid, int& sw1, int& sw2) { ByteVector reply; requesthandler_ptr rs= m.SendSimCmd(GSMSIM_CLASS, SELECT_FILE, BYFILEID, 0, bufpack("n", fileid), NOSIZE, reply); rs->wait(); if (rs->errorcode()) { //debug("file %04x : ril-ERROR %s\n", fileid, RilResultString(rs->errorcode()).c_str()); return false; } //debug("SELECT(%04x): %s\n", fileid, vhexdump(reply).c_str()); reply.resize(reply.size()+2); int code= wcstol((const wchar_t*)&reply[0], 0, 16); sw1= code>>8; sw2= code&0xff; return true; } bool getresponse(rilmonitor& m, int sw2, ByteVector& reply) { requesthandler_ptr rs= m.SendSimCmd(GSMSIM_CLASS, GET_RESPONSE, 0, 0, ByteVector(), sw2, reply); rs->wait(); if (rs->errorcode()) { debug("response(%02x) : ril-ERROR %s\n", sw2, RilResultString(rs->errorcode()).c_str()); return false; } debug("RESPONSE(%02x): %s\n", sw2, vhexdump(reply).c_str()); return true; } bool dumprecord(rilmonitor& m, size_t recsize, size_t nrecords) { for (int recnum= 0 ; recnumwait(); if (rs->errorcode()) { debug("recnum %04x : ril-ERROR %s\n", recnum, RilResultString(rs->errorcode()).c_str()); return false; } debug("READREC(%04x): %s\n", recnum, vhexdump(reply).c_str()); } return true; } void dumpsimfile(rilmonitor& m, int fileid) { try { int type=0; size_t itemcount=0, itemsize=0; int sw1, sw2; selectbyfileid(m, fileid, sw1, sw2); // if response: 9404 : file not found -> next // 9fxx -> getresponse(m, xx) if (sw1!=0x9f) { debug("file %04x: %02x %02x\n", fileid, sw1, sw2); return; } ByteVector fileinfo; getresponse(m,sw2, fileinfo); debug("file %04x: info= %s\n", fileid, vhexdump(fileinfo).c_str()); // todo: process fileinfo response /* 00000000 7F10 0200000000030A93000C0400838A808A00 00000000 7F20 0200000000030A9300160400838A808A00 00000000 7F21 0200000000030A9300160400838A808A00 00000002 2F54 040004007701010000 0000000A 2FE2 040004004401010000 00000024 6F51 040044004401020109 00000050 2F53 040014004401020128 0000005B 3F00 0100000000030A9304090400838A808A00 00000096 2F16 04000400440102011E */ } catch(ril_error& e) { debug("rilerr: %08lx: %s\n", e.err, e.name.c_str()); } catch(ril_structsize_error& e) { debug("rilsize: got %d, expected %d\n", e.got, e.expect); } catch(...) { debug("unknown exception\n"); } } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { DebugSetLogfile("readsim.log"); rilmonitor m; StringList args; if (!SplitString(ToString(lpCmdLine), args, false)) { error("Error in commandline"); return false; } std::vector reqfile; bool bFullRange= false; for (StringList::iterator i= args.begin() ; i!=args.end() ; ++i) { std::string& arg= *i; if (arg[0]=='-') switch(arg[1]) { case 'f': bFullRange=true; break; } else reqfile.push_back(strtoul(arg.c_str(), 0, 0)); } m.DumpDriverInfo(); long siglevel; requesthandler_ptr rl= m.GetSignalQuality(siglevel); rl->wait(); if (!rl->errorcode()) debug("signallevel: %d\n", siglevel); #if 0 eventqueue signal; m.SignalQualityEvent(signal); #endif int sw1, sw2; if (bFullRange) { for (int fileid=0x2000 ; fileid<0x10000 ; fileid++) { dumpsimfile(m, fileid); } } else if (reqfile.empty()) { // 2000-3fff // 5000-7fff for (int fileid=0x2f00 ; fileid<0x8000 ; fileid+=((fileid&0xfff)==0)?0xf00:1) { dumpsimfile(m, fileid); } } else { for (unsigned i=0 ; i