| 1 |
using System; |
| 2 |
using System.Collections.Generic; |
| 3 |
using System.Text; |
| 4 |
using System.Runtime.InteropServices; |
| 5 |
|
| 6 |
namespace FelicaLib |
| 7 |
{ |
| 8 |
// システムコード |
| 9 |
public enum SystemCode : int |
| 10 |
{ |
| 11 |
Any = 0xffff, // ANY |
| 12 |
Common = 0xfe00, // 共通領域 |
| 13 |
Cyberne = 0x0003, // サイバネ領域 |
| 14 |
|
| 15 |
Edy = 0xfe00, // Edy (=共通領域) |
| 16 |
Suica = 0x0003, // Suica (=サイバネ領域) |
| 17 |
} |
| 18 |
|
| 19 |
public interface IFelica : IDisposable |
| 20 |
{ |
| 21 |
void Polling(int systemcode); |
| 22 |
byte[] IDm(); |
| 23 |
byte[] PMm(); |
| 24 |
byte[] ReadWithoutEncryption(int servicecode, int addr); |
| 25 |
} |
| 26 |
|
| 27 |
public class Felica : IFelica |
| 28 |
{ |
| 29 |
[DllImport("felicalib.dll")] |
| 30 |
private extern static IntPtr pasori_open(String dummy); |
| 31 |
[DllImport("felicalib.dll")] |
| 32 |
private extern static void pasori_close(IntPtr p); |
| 33 |
[DllImport("felicalib.dll")] |
| 34 |
private extern static int pasori_init(IntPtr p); |
| 35 |
[DllImport("felicalib.dll")] |
| 36 |
private extern static IntPtr felica_polling(IntPtr p, ushort systemcode, byte rfu, byte time_slot); |
| 37 |
[DllImport("felicalib.dll")] |
| 38 |
private extern static void felica_free(IntPtr f); |
| 39 |
[DllImport("felicalib.dll")] |
| 40 |
private extern static void felica_getidm(IntPtr f, byte[] data); |
| 41 |
[DllImport("felicalib.dll")] |
| 42 |
private extern static void felica_getpmm(IntPtr f, byte[] data); |
| 43 |
[DllImport("felicalib.dll")] |
| 44 |
private extern static int felica_read_without_encryption02(IntPtr f, int servicecode, int mode, byte addr, byte[] data); |
| 45 |
|
| 46 |
private IntPtr pasorip = IntPtr.Zero; |
| 47 |
private IntPtr felicap = IntPtr.Zero; |
| 48 |
|
| 49 |
public Felica() |
| 50 |
{ |
| 51 |
pasorip = pasori_open(null); |
| 52 |
if (pasorip == IntPtr.Zero) |
| 53 |
{ |
| 54 |
throw new Exception("felicalib.dll を開けません"); |
| 55 |
} |
| 56 |
if (pasori_init(pasorip) != 0) |
| 57 |
{ |
| 58 |
throw new Exception("PaSoRi に接続できません"); |
| 59 |
} |
| 60 |
} |
| 61 |
|
| 62 |
public void Dispose() |
| 63 |
{ |
| 64 |
if (pasorip != IntPtr.Zero) |
| 65 |
{ |
| 66 |
pasori_close(pasorip); |
| 67 |
pasorip = IntPtr.Zero; |
| 68 |
} |
| 69 |
} |
| 70 |
|
| 71 |
~Felica() |
| 72 |
{ |
| 73 |
Dispose(); |
| 74 |
} |
| 75 |
|
| 76 |
public void Polling(int systemcode) |
| 77 |
{ |
| 78 |
felica_free(felicap); |
| 79 |
|
| 80 |
felicap = felica_polling(pasorip, (ushort)systemcode, 0, 0); |
| 81 |
if (felicap == IntPtr.Zero) |
| 82 |
{ |
| 83 |
throw new Exception("カード読み取り失敗"); |
| 84 |
} |
| 85 |
} |
| 86 |
|
| 87 |
public byte[] IDm() |
| 88 |
{ |
| 89 |
if (felicap == IntPtr.Zero) |
| 90 |
{ |
| 91 |
throw new Exception("no polling executed."); |
| 92 |
} |
| 93 |
|
| 94 |
byte[] buf = new byte[8]; |
| 95 |
felica_getidm(felicap, buf); |
| 96 |
return buf; |
| 97 |
} |
| 98 |
|
| 99 |
public byte[] PMm() |
| 100 |
{ |
| 101 |
if (felicap == IntPtr.Zero) |
| 102 |
{ |
| 103 |
throw new Exception("no polling executed."); |
| 104 |
} |
| 105 |
|
| 106 |
byte[] buf = new byte[8]; |
| 107 |
felica_getpmm(felicap, buf); |
| 108 |
return buf; |
| 109 |
} |
| 110 |
|
| 111 |
public byte[] ReadWithoutEncryption(int servicecode, int addr) |
| 112 |
{ |
| 113 |
if (felicap == IntPtr.Zero) |
| 114 |
{ |
| 115 |
throw new Exception("no polling executed."); |
| 116 |
} |
| 117 |
|
| 118 |
byte[] data = new byte[16]; |
| 119 |
int ret = felica_read_without_encryption02(felicap, servicecode, 0, (byte)addr, data); |
| 120 |
if (ret != 0) |
| 121 |
{ |
| 122 |
return null; |
| 123 |
} |
| 124 |
return data; |
| 125 |
} |
| 126 |
} |
| 127 |
} |