高分SIM卡 C#开发求助

ga3ga3 2011-04-13 10:29:48
读取SIM卡电话本的指令可以参考 http://blog.csdn.net/jennyvenus/archive/2008/04/01/2238743.aspx
我精简了一下,主要指令如下:
3B7B112233000102030405060708090A //reset
A0A40000023F00 //SELECT
A0A40000027F10 //SELECT
A0A40000026F3A //SELECT
A0C000000F //GET RESPONSE
A0B201041C //READ RECORD


通过VC的样例,pcscSIMPLE.EXE 执行上述指令,全部OK ,没有问题。

但我通过调用c#,pcscCSharp,就报错。

我的代码如下:

//上下文句柄
int pcscContext = 0;

//建立API
Int32 ret = PCSCCSharp.SCardEstablishContext(0, 0, 0,out pcscContext);

//列出读卡机
List<string> list = new List<string>();
list = PCSCCSharp.SCardListReaders(pcscContext);

//连接

int phCard = 0;
int pdwActiveProtocol = 0;

ret = PCSCCSharp.SCardConnect(pcscContext, list[0], 2, 1, ref phCard, ref pdwActiveProtocol);

PCSC.SCARD_IO_REQUEST SendPci, RecvPci;

SendPci.dwProtocol = pdwActiveProtocol;
SendPci.cbPciLength = 8;

RecvPci.dwProtocol = pdwActiveProtocol;
RecvPci.cbPciLength = 8;

byte[] SelectRecvBytes = new byte[20];//应回 90 00
int SelectRecvLength = 2000;

//提交指令
// ret = PCSCCSharp.SCardBeginTransaction(phCard);


byte[] byInBuffer;
byte[] byOutBuffer;


//下达Select Profile的ADPU
ret = PCSCCSharp.SCardTransmit(phCard, ref SendPci, SelectAPDU, SelectAPDU.Length, ref RecvPci, ref SelectRecvBytes[0], ref SelectRecvLength);




byInBuffer = new byte[] { 0x3B, 0x7B, 0x11, 0x22, 0x33, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A };
SelectRecvBytes = new byte[20];
ret = PCSCCSharp.SCardTransmit(phCard, ref SendPci, byInBuffer, byInBuffer.Length, ref RecvPci, ref SelectRecvBytes[0], ref SelectRecvLength);


byInBuffer = new byte[] { 0xA0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00 };
SelectRecvBytes = new byte[20];
ret = PCSCCSharp.SCardTransmit(phCard, ref SendPci, byInBuffer, byInBuffer.Length, ref RecvPci, ref SelectRecvBytes[0], ref SelectRecvLength);

byInBuffer = new byte[] { 0xA0, 0xA4, 0x00, 0x00, 0x02, 0x7F, 0x10 };
SelectRecvBytes = new byte[20];
ret = PCSCCSharp.SCardTransmit(phCard, ref SendPci, byInBuffer, byInBuffer.Length, ref RecvPci, ref SelectRecvBytes[0], ref SelectRecvLength);


byInBuffer = new byte[] { 0xA0, 0xA4, 0x00, 0x00, 0x02, 0x6F, 0x3A };
SelectRecvBytes = new byte[20];
ret = PCSCCSharp.SCardTransmit(phCard, ref SendPci, byInBuffer, byInBuffer.Length, ref RecvPci, ref SelectRecvBytes[0], ref SelectRecvLength);


//没有读取出来 A0C000000F <-------------------------
byInBuffer = new byte[] { 0xA0, 0xC0, 0x00, 0x00, 0x0F };
SelectRecvBytes = new byte[20];
ret = PCSCCSharp.SCardTransmit(phCard, ref SendPci, byInBuffer, byInBuffer.Length, ref RecvPci, ref SelectRecvBytes[0], ref SelectRecvLength);

//没有读取出来 <-------------------------

byInBuffer = new byte[] { 0xA0, 0xB2, 0x01, 0x04, 0x1C };
SelectRecvBytes = new byte[20];
ret = PCSCCSharp.SCardTransmit(phCard, ref SendPci, byInBuffer, byInBuffer.Length, ref RecvPci, ref SelectRecvBytes[0], ref SelectRecvLength);


//ret = PCSCCSharp.SCardEndTransaction(pcscContext, 1);

ret = PCSCCSharp.SCardDisconnect(pcscContext, 1);

ret = PCSCCSharp.SCardReleaseContext(pcscContext);






请大家帮我看看有什么问题!!最好能够给个样例参考一下,谢谢!!如果解决了,分数可以再加
...全文
268 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
用户 昵称 2011-04-14
  • 打赏
  • 举报
回复
文件大小 / 记录长度,就是记录个数了,返回的数据中没有个数,必须自己算,sim卡的东西俺现在已经忘光了。
ga3ga3 2011-04-14
  • 打赏
  • 举报
回复
to:jennyvenus

兄弟,你对读取IMSI,以及短信、电话本这些,应该很熟悉了。
snooper我也在用,很不错。

就在你的记录
http://blog.csdn.net/jennyvenus/archive/2008/04/01/2238743.aspx


GET RESPONSE

A0 C0 00 00 0F

00 00 1B 58 6F 3A 04 00 11 FF 22 01 02 01 1C

最后的1C表示长度,但不知道哪个能够表示电话本记录总数的。


我不太清楚有没有读取短消息、电话本记录总数的指令。我去翻翻GSM11.11



ga3ga3 2011-04-14
  • 打赏
  • 举报
回复
呵呵,测试通过了。上来一看,发现兄弟已经又回复 真是感谢啊:)

用户 昵称 2011-04-14
  • 打赏
  • 举报
回复
俺脚着就是SelectRecvLength 的值越来越小了。

最开始是2000
A0A40000023F00 //SELECT,这句后,返回9fxx,SelectRecvLength 值为2
A0A40000027F10 //SELECT,这句后,返回9fxx,SelectRecvLength 值为2
A0A40000026F3A //SELECT,这句后,返回9fxx,SelectRecvLength 值为2
A0C000000F //GET RESPONSE,这句后,返回xx xx xx.... xx 90 00,SelectRecvLength 值为2,装不下0x0f + 2 = 0x11个数据了。
A0B201041C //READ RECORD
ga3ga3 2011-04-14
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 doubleu2005 的回复:]
你去掉前四步,直接到第五步试试,如果能读出就证明还是程序设置问题
[/Quote]

可以考虑下,不过按照规范,直接读取,肯定是读不到的,呵呵。
没有前面的SELECT等选择指令,是无法直接读取到标准文件的。就像选择文件,你没有选择其相对应的路径,直接选文件,是选不到的。
ga3ga3 2011-04-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 tsapi 的回复:]
C# code
Code Snippet
[DllImport("sms.dll")]

private static extern IntPtr SmsGetPhoneNumber(IntPtr psmsaAddress);

[DllImport("cellcore.dll")]

private static extern IntPtr SimInitialize(IntPt……
[/Quote]

to:Tsapi
这个是嵌入式开发吧,在windows xp 下能用么?
zhlbgo 2011-04-14
  • 打赏
  • 举报
回复
哦,原来如此,又学到了一点,谢谢呀~!
[Quote=引用 5 楼 ga3ga3 的回复:]
通过GSM模块来实现的,所以用AT指令。
PCSC通过直接调用wincard.DLL实。现直接对智能卡读写,所以指令用十六进制的,可以看规范GSM11.11。
我也刚学,不是很熟悉。呵呵
[/Quote]
ga3ga3 2011-04-13
  • 打赏
  • 举报
回复
通过GSM模块来实现的,所以用AT指令。
PCSC通过直接调用wincard.DLL实。现直接对智能卡读写,所以指令用十六进制的,可以看规范GSM11.11。
我也刚学,不是很熟悉。呵呵
zhlbgo 2011-04-13
  • 打赏
  • 举报
回复
恕我水平有限,对与您使用的技术理解有限,所以有点疑问。我听说是用AT指令的,怎么您的代码没有AT呢?
ga3ga3 2011-04-13
  • 打赏
  • 举报
回复
是呀,不过有c#的成功样例也行哦。。。
qldsrx 2011-04-13
  • 打赏
  • 举报
回复
你这个程序是否要读卡器才能测试?貌似我没硬件条件,帮不了忙。
ga3ga3 2011-04-13
  • 打赏
  • 举报
回复
" <-------------------------" 表示开始出现的问题,前面步骤的返回值都是正常的。
doubleu2005 2011-04-13
  • 打赏
  • 举报
回复
你去掉前四步,直接到第五步试试,如果能读出就证明还是程序设置问题
  • 打赏
  • 举报
回复
路过,学习了。。。
ga3ga3 2011-04-13
  • 打赏
  • 举报
回复
谢谢楼上各位,我明天try again
用户 昵称 2011-04-13
  • 打赏
  • 举报
回复
在每条 SCardTransmit之前都执行一下

SelectRecvLength = 2000;

试试

用户 昵称 2011-04-13
  • 打赏
  • 举报
回复
0xA0, 0xC0, 0x00, 0x00, 0x0F

这个0f是怎么得到的?
Daqing 2011-04-13
  • 打赏
  • 举报
回复
Code Snippet
[DllImport("sms.dll")]

private static extern IntPtr SmsGetPhoneNumber(IntPtr psmsaAddress);

[DllImport("cellcore.dll")]

private static extern IntPtr SimInitialize(IntPtr dwFlags, IntPtr lpfnCallBack, IntPtr dwParam, out IntPtr lphSim);

[DllImport("cellcore.dll")]

private static extern IntPtr SimGetRecordInfo(IntPtr hSim, IntPtr dwAddress, ref SimRecord lpSimRecordInfo);

[DllImport("cellcore.dll")]

private static extern IntPtr SimReadRecord(IntPtr hSim, IntPtr dwAddress, IntPtr dwRecordType, IntPtr dwIndex, byte[] lpData, IntPtr dwBufferSize, ref IntPtr lpdwBytesRead);

[DllImport("cellcore.dll")]

private static extern IntPtr SimDeinitialize(IntPtr hSim );



public static string GetServiceProvider()

{

IntPtr hSim, res;

res = SimInitialize(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out hSim);

if (res != IntPtr.Zero)

throw new Exception("Could not initialize SIM");

SimRecord rec = new SimRecord();

rec.cbSize = (IntPtr)Marshal.SizeOf(rec);

res = SimGetRecordInfo(hSim, (IntPtr)SERVICE_PROVIDER, ref rec);

if (res != IntPtr.Zero)

throw new Exception("Could not read the service provider information from the SIM");

byte[] bData = new byte[(int)rec.dwSize + 1];

IntPtr dwBytesRead = IntPtr.Zero;

res = SimReadRecord(hSim, (IntPtr)SERVICE_PROVIDER, rec.dwRecordType, IntPtr.Zero, bData, (IntPtr)bData.Length, ref dwBytesRead);

if (res != IntPtr.Zero)

throw new Exception("Could not read the service provider from the SIM");

byte[] bScrubbed = new byte[(int)dwBytesRead];

int nPos = 0;

// Scrub the non-ascii characters

for (int i = 0; i < (int)dwBytesRead; i ++)

{

if (((int)bData[i] > 19) && ((int)bData[i] < 125))

{

bScrubbed[nPos] = bData[i];

nPos++;

}

}

SimDeinitialize(hSim);

return Encoding.ASCII.GetString(bScrubbed, 0, bScrubbed.Length);

}



http://msdn.microsoft.com/en-us/library/aa446543.aspx
下载一下这个api就可
ga3ga3 2011-04-13
  • 打赏
  • 举报
回复
" <-------------------------" 第五步 返回的错误是 SCARD_F_INTERNAL_ERROR 0x80100001
而在VC中,没有错误,返回了具体的内容。我不太清楚错在哪,没开发过。哎
ga3ga3 2011-04-13
  • 打赏
  • 举报
回复
啊,竟然没有人啊。。。纳闷

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧