本示例使用设备 :
https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-21818769070.11.23eb789efg450Y&id=615391857885
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>15693卡读写DEMO</title>
<script language="javascript">
var iswsrun = false;
var ws;
var received_msg = "";
var mytimer;
var strls = "";
var errorno = "";
var wsUri = "ws://127.0.0.1:39189"; //端口号必须与RFIDWebServer端口一致
function isUIntNum(val) {
var testval = /^\d+$/; // 非负整数
return (testval.test(val));
}
function isHex(val) {
var testval = /^(\d|[A-F]|[a-f])+$/; // 十六进制数判断
return (testval.test(val));
}
function beep() { //驱动发卡器响声令
textarea.value = "";
WebSocketRun("pcdbeep,30");
}
function getdevicenumber() { //读取发卡器唯一出厂序号,可以当加密狗使用
textarea.value = "";
serialnumber.value="";
WebSocketRun("pcdgetdevicenumber");
}
function readcard_15693() {
textarea.value = "";
carduid.value="";
RWdata.value= "";
myctrlword = 0; //读任何卡,不需指定卡号,读完后不静止该卡,可赋值NEEDSERIAL及NEEDHALT的组合模式,或为0
mypiccserial = "0000000000000000"; //指定序列号,未知卡序列号时可指定为16个0,因为15693卡是8个字节的卡序列号
afi= textafi.value.trim(); ; //16进制,一般取00
if (!isHex(afi) || afi.length!=2) {
alert( "应用标识AFI输入错误,请输入2位16进制应用标识AFI!");
textafi.focus();
textafi.select();
return;
}
myblockaddr = startno.value.trim(); //本次写卡的开始块号
if (!isUIntNum(myblockaddr)) {
alert("读写起始页输入错误!");
startno.focus();
startno.select();
return;
}
myblocksize = pagenumber.value.trim(); //本次读写页数
if (!isUIntNum(myblocksize) || myblocksize<1 || myblocksize>12) {
alert("读写页数输入错误,读写页数需大于等于1,小于等于12!");
pagenumber.focus();
pagenumber.select();
return;
}
var Read15693Comm = "iso15693readex," + myctrlword + "," + afi + "," + myblockaddr + "," + myblocksize + "," + mypiccserial;
WebSocketRun(Read15693Comm);
}
function writecard_15693() {
textarea.value = "";
carduid.value="";
myctrlword = 0; //写任何卡,不需指定卡号,读完后不静止该卡,可赋值NEEDSERIAL及NEEDHALT的组合模式,或为0
mypiccserial = "0000000000000000"; //指定序列号,未知卡序列号时可指定为16个0,因为15693卡是8个字节的卡序列号
afi= textafi.value.trim(); ; //16进制,一般取00
if (!isHex(afi) || afi.length!=2) {
alert( "应用标识AFI输入错误,请输入2位16进制应用标识AFI!");
textafi.focus();
textafi.select();
return;
}
myblockaddr = startno.value.trim(); //本次写卡的开始块号
if (!isUIntNum(myblockaddr)) {
alert("读写起始页输入错误!");
startno.focus();
startno.select();
return;
}
myblocksize = pagenumber.value.trim(); //本次读写页数
if (!isUIntNum(myblocksize) || myblocksize<1 || myblocksize>12) {
alert("读写页数输入错误,读写页数需大于等于1,小于等于12!");
pagenumber.focus();
pagenumber.select();
return;
}
//数据
strls = RWdata.value.trim();
if (!isHex(strls) || strls.length<myblocksize*8) {
alert( "读写数据输入错误,请输入"+(myblocksize*8).toString()+"位16进制写卡数据!");
RWdata.focus();
RWdata.select();
return;
}
var WriteNtagComm = "iso15693writeex," + myctrlword + "," + afi + "," + myblockaddr + "," + myblocksize + "," + mypiccserial + "," + strls;
WebSocketRun(WriteNtagComm);
}
function Searchcards(){ //搜寻感应区内的多张15693卡
textarea.value = "";
finduid.value="";
clearlist();
textflag.value="16";
flag= "16" ; //16进制,固定的操作码16
afi= textafi.value.trim(); ; //16进制,一般取00
if (!isHex(afi) || afi.length!=2) {
alert( "应用标识AFI输入错误,请输入2位16进制应用标识AFI!");
textafi.focus();
textafi.select();
return;
}
MaskLen = textmasklen.value.trim(); //掩码长度
if (!isUIntNum(MaskLen)) {
alert("掩码长度输入错误,请输入正确的掩码长度!");
textmasklen.focus();
textmasklen.select();
return;
}
WebSocketRun("iso15693inventory16," + flag + "," + afi + "," + MaskLen );
}
function read15693block(){
textarea.value = "";
textarea2.value="";
textflag.value="22";
flag= "22" ; //16进制,固定的操作码22
myblockaddr = startblock.value.trim(); //本次写卡的开始块号
if (!isUIntNum(myblockaddr)) {
alert("读写起始页输入错误!");
startblock.focus();
startblock.select();
return;
}
myblocksize = rwblocks.value.trim(); //本次读写页数
if (!isUIntNum(myblocksize)) {
alert("读写页数输入错误!");
rwblocks.focus();
rwblocks.select();
return;
}
mypiccserial= finduid.value.trim(); ; //指定要读写卡的UID
if (!isHex(mypiccserial) || mypiccserial.length!=16) {
alert( "卡片UID输入错误,请输入16位16进制UID!");
finduid.focus();
finduid.select();
return;
}
WebSocketRun("iso15693readblock," + flag + "," + myblockaddr + "," + myblocksize + "," + mypiccserial);
}
function write15693block(){
textarea.value = "";
textflag.value="22";
flag= "22" ; //16进制,固定的操作码22
myblockaddr = startblock.value.trim(); //本次写卡的开始块号
if (!isUIntNum(myblockaddr)) {
alert("读写起始页输入错误!");
startblock.focus();
startblock.select();
return;
}
myblocksize = rwblocks.value.trim(); //本次读写页数
if (!isUIntNum(myblocksize)) {
alert("读写页数输入错误!");
rwblocks.focus();
rwblocks.select();
return;
}
//数据
strls = textarea2.value.trim();
if (!isHex(strls) || strls.length<myblocksize*8) {
alert( "读写数据输入错误,请输入"+(myblocksize*8).toString()+"位16进制写卡数据!");
textarea2.focus();
textarea2.select();
return;
}
mypiccserial= finduid.value.trim(); ; //指定要读写卡的UID
if (!isHex(mypiccserial) || mypiccserial.length!=16) {
alert( "卡片UID输入错误,请输入16位16进制UID!");
finduid.focus();
finduid.select();
return;
}
WebSocketRun("iso15693writeblock," + flag + "," + myblockaddr + "," + myblocksize + "," + mypiccserial+ "," + strls);
}
function write15693uid(){
textarea.value = "";
afi= textafi.value.trim(); ; //16进制,一般取00
if (!isHex(afi) || afi.length!=2) {
alert( "应用标识AFI输入错误,请输入2位16进制应用标识AFI!");
textafi.focus();
textafi.select();
return;
}
newuid= textnewuid.value.trim(); ; //16进制UID
if (!isHex(newuid) || newuid.length!=16) {
alert( "新UID输入错误,请输入16位16进制新UID!");
textnewuid.focus();
textnewuid.select();
return;
}
WebSocketRun("iso15693writeuid,"+afi+","+newuid)
}
function DispErrInfo(errcode){
var errstr = "";
switch (errcode) {
case "ReturnCode:008":
case "ReturnCode:009":
case "ReturnCode:010":
errstr = ",未寻到卡,请将卡放到发卡器的感应区!";
break;
case "ReturnCode:011":
case "ReturnCode:012":
errstr = ",卡密码认证失败!";
break;
case "ReturnCode:013":
errstr = ",读卡失败,可能需要验证密码!";
break;
case "ReturnCode:014":
errstr = ",写卡失败,可能需要验证密码!";
break;
case "ReturnCode:021":
errstr = ",没有动态库!";
break;
case "ReturnCode:022":
errstr = ",动态库或驱动程序异常!";
break;
case "ReturnCode:023":
errstr = ",驱动程序错误或发卡器未连接!";
break;
case "ReturnCode:024":
errstr = ",操作超时,一般是动态库没有反映!";
break;
case "ReturnCode:025":
errstr = ",发送字数不够!";
break;
case "ReturnCode:026":
errstr = ",发送的CRC错!";
break;
case "ReturnCode:027":
errstr = ",接收的字数不够!";
break;
case "ReturnCode:028":
errstr = ",接收的CRC错!";
break;
case "ReturnCode:029":
errstr = ",函数输入参数格式错误!";
break;
case "ReturnCode:040":
errstr = ",使卡进入静止(Quiet)状态失败!";
break;
case "ReturnCode:041":
errstr = ",选中卡操作失败!";
break;
case "ReturnCode:042":
errstr = ",让卡从静止中重起准备失败!";
break;
case "ReturnCode:044":
errstr = ",一次写块不能超过12块!";
break;
case "ReturnCode:045":
errstr = ",每块字节数选错!";
break;
case "ReturnCode:046":
errstr = ",本次读取的块数超过卡片允许的一次读取最多块数!";
break;
case "ReturnCode:444":
errstr = ",RFIDWebServer系统文件错误!";
break;
default:
errstr = ",未知的错误!";
}
return errstr;
}
window.onerror = function (e) {
alert("不好意思,出错了!");
return true;//屏蔽系统事件
}
function timeoutevent() {
ws.close();
textarea.value = "websockket返回超时";
}
//websockket数据处理
function WebSocketRev(evt) {
clearTimeout(mytimer);
received_msg = evt.data;
ws.close();
//在这里解析返回数据
var strlist = received_msg.split(",");
if (strlist.length > 1) {
var dispstr = "";
switch (strlist[0]) {
case "pcdbeep":
dispstr = "函数名称:" + strlist[0] + "\r\n";
if (strlist[1] == "ReturnCode:000") {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + ",已执行蜂鸣响声操作!\r\n";
} else {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + DispErrInfo(strlist[1]);
}
textarea.value = dispstr;
break;
case "pcdgetdevicenumber":
dispstr = "函数名称:" + strlist[0] + "\r\n";
if (strlist[1] == "ReturnCode:000") {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + ",已读取设备编号!\r\n";
serialnumber.value = strlist[2] ;
} else {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + DispErrInfo(strlist[1]);
}
textarea.value = dispstr;
break;
case "iso15693readex":
dispstr = "函数名称:" + strlist[0] + "\r\n";
if (strlist[1] == "ReturnCode:000") {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + ",已读取卡内数据!\r\n";
} else {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + DispErrInfo(strlist[1]);
}
if (strlist.length > 2) {
carduid.value=strlist[2];
finduid.value=strlist[2];
textnewuid.value=strlist[2];
}
if (strlist.length > 3) {
RWdata.value= strlist[3];
}
textarea.value = dispstr;
break;
case "iso15693writeuid": //写uid
case "iso15693writeblock": //写指定卡
case "iso15693writeex": //轻松写任意卡
dispstr = "函数名称:" + strlist[0] + "\r\n";
if (strlist[1] == "ReturnCode:000") {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + ",写卡成功!\r\n";
} else {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + DispErrInfo(strlist[1]);
}
if (strlist.length > 2) {
carduid.value=strlist[2];
finduid.value=strlist[2];
textnewuid.value=strlist[2];
}
textarea.value = dispstr;
break;
case "iso15693inventory16":
dispstr = "函数名称:" + strlist[0] + "\r\n";
if (strlist[1] == "ReturnCode:000") {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + ",搜寻卡片成功!\r\n";
} else {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + DispErrInfo(strlist[1]);
}
textarea.value = dispstr;
if (strlist.length > 2) {
carduid.value=strlist[2];
finduid.value=strlist[2];
textnewuid.value=strlist[2];
}
if (strlist.length > 3) {
addlist(strlist[3]);
}
if (strlist.length > 4) {
addlist(strlist[4]);
}
break;
case "iso15693readblock":
dispstr = "函数名称:" + strlist[0] + "\r\n";
if (strlist[1] == "ReturnCode:000") {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + ",已读取卡内数据!\r\n"
textarea2.value= strlist[2];
} else {
dispstr = dispstr + "操作结果:" + strlist[1];
dispstr = dispstr + DispErrInfo(strlist[1]);
}
textarea.value = dispstr;
break;
}
}
}
function addlist(itemstr){
const select = document.querySelector("#sel_finduid");
const option = document.createElement("option");
option.value = "value";
option.text = itemstr;
select.add(option);
}
function clearlist(){
obj = document.getElementById("sel_finduid"); ///drp是select控件的ID值
for(i=obj.options.length-1 ; i>= 0 ; i--)
obj.options[i] = null;
}
function seleotheruit(){
var myselect=document.getElementById("sel_finduid");
var index=myselect.selectedIndex ;
myselect.options[index].value;
seleudistr=myselect.options[index].text;
finduid.value=seleudistr.substr(seleudistr.length - 16, 16);
}
function WebSocketRun(sendinfo) {
iswsrun = false;
try {
if ("WebSocket" in window) {
ws = new WebSocket(wsUri);
}
else if ("MozWebSocket" in window) {
ws = new MozWebSocket(wsUri);
}
else {
received_msg = "您的浏览器不支持WebSocket,请选用支持WebSocket的浏览器!";
return;
}
clearTimeout(mytimer);
ws.onopen = function (evt) {
ws.send(sendinfo);
iswsrun = true;
mytimer = setTimeout("timeoutevent()", 3000); //如果一次读、写页数比较大,可适当延长通讯超时时间。
};
ws.onmessage = WebSocketRev;
ws.onerror = function (e) {
if (iswsrun != true) {
received_msg = "请先在当前电脑下载>安装>运行我们的服务程序......";
window.open("http://www.icmcu.com/ICID15693-02V2test/RFIDWebServerSetup.exe", "top");//打开新窗口
alert("请先下载>安装>运行我们的服务程序,再刷新本页面......");
}
};
}
catch (ex) {
if (iswsrun != true) {
received_msg = "请先在当前电脑下载>安装>运行我们的服务程序......";
window.open("http://www.icmcu.com/ICID15693-02V2test/RFIDWebServerSetup.exe", "top");//打开新窗口
alert("请先下载>安装>运行我们的服务程序,再刷新本页面......");
}
}
}
</script>
<style>
th {
background-color:#F5F5F5;
color: blue;
font-family:楷体;
}
td {
background-color:#F5F5F5;
font-family:楷体;
}
#carduid ,#finduid,#textnewuid{
text-align: center;
color: red;
}
</style>
</head>
<body>
<table width="866" height="526" border="1" align="center">
<tr>
<th width="124" height="45" scope="row"><input name="butt_beep" type="submit" id="butt_beep" onclick="beep()" value="驱动发卡器响声" /></th>
<td width="716"><input name="butt_getdevnum" type="submit" id="butt_getdevnum" onclick="getdevicenumber()" value="读取发卡器唯一出厂序列号" />
设备编号:
<input style="color:red;text-align:center;" name="serialnumber" type="text" id="serialnumber" size="8" maxlength="8" /></td>
</tr>
<tr>
<th height="45" scope="row"> </th>
<td>应用标识AFI:
<input style="color:blue;text-align:center;" name="textafi" type="text" id="textafi" value="00" size="2" maxlength="2" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/>
,操作标志FLAG:
<input style="color:blue;text-align:center;" name="textflag" type="text" id="textflag" value="00" size="2" maxlength="2" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/>
,数据存储格式标识DSFID:
<input style="color:blue;text-align:center;" name="textdsfid" type="text" id="textdsfid" value="00" size="2" maxlength="2" onkeyup="this.value=this.value.replace(/[^0-9a-fA-F]/g,'')"/></td>
</tr>
<tr>
<th height="103" scope="row"><p>
<input name="butt_readcard_15693" type="submit" id="butt_readcard_15693" onclick="readcard_15693()" value="轻松读15693卡" />
</p>
<p> </p>
<p>
<input name="butt_writecard_15693" type="submit" id="butt_writecard_15693" onclick="writecard_15693()" value="轻松写15693卡" />
</p></th>
<td><p>读写起始页:
<input style="color:blue;blue-align:center;" name="startno" type="text" id="startno" value="0" size="3" maxlength="3" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
,读写页数:
<input style="color:blue;text-align:center;" name="pagenumber" type="text" id="pagenumber" value="12" size="2" maxlength="2" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
,感应区内只能一张卡,每次最多读、写12页。</p>
<p>返回UID号:
<input name="carduid" type="text" id="carduid" size="16" maxlength="16" />
</p>
<p>
<textarea style="color:red;" name="RWdata" id="RWdata" cols="100" rows="3" ></textarea>
</p></td>
</tr>
<tr>
<th height="175" scope="row"><p>
<input name="butt_iso15693inventory16" type="submit" id="butt_iso15693inventory16" onclick="Searchcards()" value="寻找感应区内多张卡" />
</p>
<p> </p>
<p>
<input name="butt_readblock" type="submit" id="butt_readblock" onclick="read15693block()" value="读取指定UID卡数据" />
</p>
<p>
<input name="butt_writeblock" type="submit" id="butt_writeblock" onclick="write15693block()" value="写数据到指定UID卡" />
</p></th>
<td><p>掩码长度:
<input style="color:blue;text-align:center;" name="textmasklen" type="text" id="textmasklen" value="0" size="2" maxlength="2" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
,寻找到的卡片UID列表:
<select style="color:red;" name="sel_finduid" id="sel_finduid" onchange="seleotheruit()">
</select>
<input name="finduid" type="text" id="finduid" size="16" maxlength="16" />
</p>
<p>读写起始页:
<input style="color:blue;text-align:center;" name="startblock" type="text" id="startblock" value="0" size="3" maxlength="3" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
,读写页数:
<input style="color:blue;text-align:center;" name="rwblocks" type="text" id="rwblocks" value="28" size="3" maxlength="3" onkeyup="this.value=this.value.replace(/\D/g,'')"/>
,感应区内可以有多张卡,读写前必须指定卡片的UID。</p>
<p>
<textarea style="color:red;" name="textarea2" id="textarea2" cols="100" rows="5" ></textarea>
</p></td>
</tr>
<tr>
<th height="45" scope="row"><p>
<input name="butt_writeuid" type="submit" id="butt_writeuid" onclick="write15693uid()" value="1830卡写入新UID" />
</p></th>
<td>新UID:
<input name="textnewuid" type="text" id="textnewuid" size="16" maxlength="16" /></td>
</tr>
<tr>
<th height="78" scope="row"><p>操作提示</p></th>
<td><textarea style="color:blue;" name="textarea" id="textarea" cols="100" rows="5" ></textarea></td>
</tr>
</table>
</body>
</html>