首页 > 其他分享 >Delphi轻松读写NDEF文本、智能海报、应用控制等NFC标签

Delphi轻松读写NDEF文本、智能海报、应用控制等NFC标签

时间:2023-07-30 10:05:00浏览次数:44  
标签:status begin NFC 标签 Delphi NDEF cardno myctrlword


        NDEF 全称 NFC data exchange format 即 nfc 数据交换格式,是一种标准化的数据格式,可用于在任何兼容的NFC设备与另一个NFC设备或标签之间交换信息。数据格式由NDEF消息和NDEF记录组成。

       NDEF信息可以写到不同类型的NFC芯片中,如NFC_Forum_Type2类的Ntag2x、FM11NTx系列芯片、NFC_Forum_Type4标签、NFC_Forum_Type5类的15693系列芯片、MifareClassic系列芯片等,不同类型的芯片NDEF信息的存储方式也略有不同,这就大大增加了NDEF信息写入、读取的难度。

        广州荣士电子将各种不同类型的NDEF记录类型的写入、读取方式都函数化,开发人员不需再了解复杂的NDEF记录格式,只需调用相应的函数就可快速写入正确的NDEF信息。

Delphi轻松读写NDEF文本、智能海报、应用控制等NFC标签_NDEF标签

Delphi轻松读写NDEF文本、智能海报、应用控制等NFC标签_Delphi智能海报_02

 本说明使用的发卡器:Android Linux RFID读写器NFC发卡器WEB可编程NDEF文本/智能海报/-淘宝网 (taobao.com)

写入NDEF纯文本 
var
  status:byte;
  languagecodestr:string;
  languagecodestrlen:integer;
  textstr:string;
  textstrlen:integer;
begin
     languagecodestr:='en';    //语言编码,英文为en,中文为zh
     languagecodestrlen:=length(languagecodestr);   //语言编码长度
     textstr:=trim(Memo1.Text);         //NDEF文本
     textstrlen:= length(textstr);      //文本长度

     tagbuf_forumtype4_clear();     //清空NDEF数据缓冲
     tagbuf_clear();
     status := tagbuf_addtext(languagecodestr, languagecodestrlen, textstr, textstrlen);  //生成NDEF纯文本标签数据缓冲
     if status=0 then
         WriteTag(1)  //将NDEF缓冲数据写入各种不同类型的NFC标签
     else
         Application.MessageBox('生成NDEF纯文本数据缓冲失败!', '提示', MB_OK+MB_ICONINFORMATION);
 写入NDEF智能海报
var
  status:byte;
  languagecodestr:string;
  languagecodestrlen:integer;
  titlestr:string;
  titlestrlen:integer;
  uriheaderindex:integer;
  uristr:string;
  uristrlen:integer;
begin
     languagecodestr:='en';    //语言编码,英文为en,中文为zh
     languagecodestrlen:=length(languagecodestr);   //语言编码长度
     titlestr:=trim(Edit1.Text);           //标题
     titlestrlen:= length(titlestr);       //标题长度
     uriheaderindex:=ComboBox1.ItemIndex ; //前缀
     uristr:=trim(Edit2.Text);             //URI
     uristrlen:= length(uristr);           //URI长度

     tagbuf_forumtype4_clear();            //清空NDEF数据缓冲
     tagbuf_clear();
     status := tagbuf_adduri(languagecodestr, languagecodestrlen, titlestr, titlestrlen, uriheaderindex, uristr, uristrlen);  //生成NDEF URI标签数据缓冲
     if status=0 then
         WriteTag(2)  //将NDEF缓冲数据写入各种不同类型的NFC标签
     else
         Application.MessageBox('生成NDEF URI数据缓冲失败!', '提示', MB_OK+MB_ICONINFORMATION);
写NDEF地图坐标
var
  status:byte;
  languagecodestr:string;
  languagecodestrlen:integer;
  titlestr:string;
  titlestrlen:integer;
  uriheaderindex:integer;
  uristr:string;
  uristrlen:integer;
begin
     languagecodestr:='en';    //语言编码,英文为en,中文为zh
     languagecodestrlen:=length(languagecodestr);   //语言编码长度
     titlestr:=trim(Edit3.Text);           //标题,地点名称
     titlestrlen:= length(titlestr);       //标题长度
     uriheaderindex:=0 ;                   //前缀,地图坐标取0
     uristr:='geo:'+trim(Edit4.Text)+','+trim(Edit5.Text);    //URI,纬度,经度
     uristrlen:= length(uristr);           //URI长度

     tagbuf_forumtype4_clear();            //清空NDEF数据缓冲
     tagbuf_clear();
     status := tagbuf_adduri(languagecodestr, languagecodestrlen, titlestr, titlestrlen, uriheaderindex, uristr, uristrlen);  //生成NDEF地图坐标标签数据缓冲
     if status=0 then
         WriteTag(3)  //将NDEF缓冲数据写入各种不同类型的NFC标签
     else
         Application.MessageBox('生成NDEF地图坐标数据缓冲失败!', '提示', MB_OK+MB_ICONINFORMATION);
写NDEF电子名片
var
  status:byte;
  infostr:string;
  infostrlen:integer;
begin
     infostr:='BEGIN:VCARD'+chr(10);                           //名片信息
     infostr:=infostr+'VERSION:3.0'+chr(10);
     infostr:=infostr+'FN:'+trim(Edit7.Text)+chr(10);          //姓名
     infostr:=infostr+'TEL:'+trim(Edit8.Text)+chr(10);         //电话
     infostr:=infostr+'ORG:'+trim(Edit9.Text)+chr(10);         //单位名称
     infostr:=infostr+'ADR:'+trim(Edit12.Text)+chr(10);        //地址
     infostr:=infostr+'EMAIL:'+trim(Edit10.Text)+chr(10);      //邮箱
     infostr:=infostr+'URL:'+trim(Edit11.Text)+chr(10);        //官网
     infostr:=infostr+'END:VCARD' +chr(10);

     infostrlen:=length(infostr);     //名片信息长度

     tagbuf_forumtype4_clear();       //清空NDEF数据缓冲
     tagbuf_clear();
     status := tagbuf_addbusinesscard(infostr, infostrlen);  //生成NDEF电子名片标签数据缓冲
     if status=0 then
         WriteTag(5)  //将NDEF缓冲数据写入各种不同类型的NFC标签
     else
         Application.MessageBox('生成NDEF电子名片数据缓冲失败!', '提示', MB_OK+MB_ICONINFORMATION);
写NDEF控制标签WIFI连接
var
  status:byte;
  ssidstr:string;
  ssidstrlen:integer;
  keystr:string;
  keystrlen:integer;
  authtype:integer;
  crypttype:integer;
begin
     ssidstr:=trim(Edit13.Text);           //WIFI热点名称
     ssidstrlen:=length(ssidstr);          //热点名称长度
     authtype:=ComboBox2.ItemIndex ;       //认证方式
     crypttype:=ComboBox3.ItemIndex ;      //加密算法
     keystr:=trim(Edit14.Text);            //密码
     keystrlen:= length(keystr);           //密码长度

     tagbuf_forumtype4_clear();            //清空NDEF数据缓冲
     tagbuf_clear();
     status := tagbuf_addwifi(ssidstr, ssidstrlen, authtype, crypttype, keystr, keystrlen);  //生成NDEF控制标签WIFI连接数据缓冲
     if status=0 then
         WriteTag(6)  //将NDEF缓冲数据写入各种不同类型的NFC标签
     else
         Application.MessageBox('生成NDEF控制标签WIFI连接数据缓冲失败!', '提示', MB_OK+MB_ICONINFORMATION);
写NDEF控制标签蓝牙连接 
var
  status:byte;
  blenamestr:string;
  blenamestrlen:integer;
  macstr:string;
  macbuf:array[0..5] of byte;
  AStrings: TStringList;
  i:integer;
begin
     blenamestr:=trim(Edit15.Text);           //蓝牙设备名称
     blenamestrlen:=length(blenamestr);       //蓝牙设备名称长度
     macstr:=trim(Edit16.Text);               //蓝牙设备MAC

     try
         AStrings := TStringList.Create;
         ExtractStrings([':'],[],Pchar(macstr),AStrings);
         if AStrings.Count =6 then
         begin
             for i:=0 to 5 do  macbuf[i]:=strtoint('$'+AStrings.Strings[i]);
         end
         else
         begin
              Application.MessageBox(PAnsiChar('MAC地址输入错误!'), '提示', MB_OK+MB_ICONSTOP);
              Edit16.SetFocus ;
              exit;
         end;
     except
         Application.MessageBox(PAnsiChar('MAC地址输入错误!'), '提示', MB_OK+MB_ICONSTOP);
         Edit16.SetFocus ;
         exit;
     end;

     tagbuf_forumtype4_clear();            //清空NDEF数据缓冲
     tagbuf_clear();
     status := tagbuf_addbluetooth(blenamestr, blenamestrlen, @macbuf);  //生成NDEF控制标签蓝牙连接数据缓冲
     if status=0 then
         WriteTag(7)  //将NDEF缓冲数据写入各种不同类型的NFC标签
     else
         Application.MessageBox('生成NDEF控制标签蓝牙连接数据缓冲失败!', '提示', MB_OK+MB_ICONINFORMATION);
将NDEF信息写入不同类型的NFC标签
var
  cardtyep:integer;
  status:byte;
  afi:byte;
  myctrlword:byte;
  mypiccserial:array[0..7] of byte;
  mypiccseriallen:array[0..0] of byte;
  dispinf:string;
  cardno:string;
  i:integer;
begin
     case NdefType of
          1:
            dispinf:=',写NDEF纯文本标签';
          2:
            dispinf:=',写NDEF URI标签';
          3:
            dispinf:=',写NDEF地图坐标标签';
          4:
            dispinf:=',写NDEF呼叫电话标签';
          5:
            dispinf:=',写NDEF电子名片标签';
          6:
            dispinf:=',写NDEF控制标签WIFI连接';
          7:
            dispinf:=',写NDEF控制标签蓝牙连接';
          8:
            dispinf:=',写NDEF控制标签启动应用';
          9:
            dispinf:=',写NDEF数据类型标签';
          44:
            dispinf:=',清除标签内NDEF信息';
     end;

     cardtyep:=checkcardtype;//判断发卡器上标签类型

     case  cardtyep of
          1:
          begin //写forumtype2 Ntag2标签
              if CheckBox1.Checked then myctrlword:=$10 else myctrlword:=0;
              status:= forumtype2_write_ndeftag(myctrlword, @mypiccserial, @oldpicckey);
              if  status=0 then
              begin
                  if (CheckBox1.Checked and CheckBox2.Checked=false) or (CheckBox1.Checked=false and CheckBox2.Checked) then  NtagKeyEn;   //开启或关闭密码保护

                  pcdbeep(38);
                  cardno:='ForumType2Uid:' ;
                  for i:=0 to 6 do cardno:=cardno+inttohex(mypiccserial[i],2);
                  Application.MessageBox(PAnsiChar(cardno+dispinf+'成功!'), '提示', MB_OK+MB_ICONINFORMATION);
              end
              else
                  disperrinf(status);
          end;
          2:
          begin  //写forumtype5 15693标签
              myctrlword:=0;
              afi:=0;
              status := forumtype5_write_ndeftag(myctrlword, afi, @mypiccserial);
              if  status=0 then
              begin
                  //if CheckBox2.Checked then status := iso15693lockblock(34, 1, @mypiccserial);    //警告:forumtype5、15693卡锁定块数据后只能读取不可再修改,为防止卡片锁死,仅在确定需要才开启此段代码。

                  pcdbeep(38);
                  cardno:='ForumType5Uid:' ;
                  for i:=0 to 7 do cardno:=cardno+inttohex(mypiccserial[7-i],2);
                  Application.MessageBox(PAnsiChar(cardno+dispinf+'成功!'), '提示', MB_OK+MB_ICONINFORMATION);
              end
              else
                  disperrinf(status);
          end;
          3:
          begin  //写MifareClassic标签
              if NdefType=44 then  //清空MifareClassic内NDEF信息并恢复到出厂状态
              begin
                  if CheckBox1.Checked then myctrlword:=$80+$40+$10+$2 else myctrlword:=$80+$10+$2;
                  status:= piccclear_ndeftag(myctrlword, @mypiccserial, @oldpicckey);
              end
              else
              begin     //写NDEF信息 到 MifareClassic标签内
                  if CheckBox1.Checked then myctrlword:=$80+$40+$10 else myctrlword:=$80+$10;
                  if CheckBox2.Checked then myctrlword:=myctrlword+$04;
                  status:= piccwrite_ndeftag(myctrlword, @mypiccserial, @oldpicckey,@newpicckey);
              end;
              if  status=0 then
              begin
                  pcdbeep(38);
                  cardno:='MifareClassUid:' ;
                  for i:=0 to 3 do cardno:=cardno+inttohex(mypiccserial[i],2);
                  Application.MessageBox(PAnsiChar(cardno+dispinf+'成功!'), '提示', MB_OK+MB_ICONINFORMATION);
              end
              else
                  disperrinf(status);
          end;
          4:
          begin  //写forumtype4 标签
              if CheckBox1.Checked then myctrlword:=$40 else myctrlword:=0;
              status := forumtype4_write_ndeftag(myctrlword, @mypiccserial, @mypiccseriallen, @newpicckey);
              if  status=0 then
              begin
                  pcdbeep(38);
                  cardno:='ForumType4Uid:' ;
                  for i:=0 to mypiccseriallen[0]-1 do cardno:=cardno+inttohex(mypiccserial[i],2);
                  Application.MessageBox(PAnsiChar(cardno+dispinf+'成功!'), '提示', MB_OK+MB_ICONINFORMATION);
              end
              else
                  disperrinf(status);
          end;
     end;
 读取不同类型芯片内的NDEF信息
var
  status: Byte;
  afi: Byte;
  cardtype: Integer;
  myctrlword: Byte;
  revstrlen: Integer;
  recordnumber: Integer;
  mypiccserial: array[0..7] of Byte;
  mypiccseriallen:array[0..0] of Byte;
  mypiccdata: array[0..2048] of Byte;
  cardno: string;
  ndefstr:string;
  ndefchr: PChar;
  ndefchr1:Pchar;
  i: Integer;
begin
     status:=255;
     memo2.Text :='';
     tagbuf_forumtype4_clear();            //清空NDEF数据缓冲
     tagbuf_clear();
     
     cardtype:=checkcardtype;//判断发卡器上标签类型

     case  cardtype of
          1:      //读forumtype2 Ntag2标签
          begin
              if CheckBox1.Checked then myctrlword:=$10 else myctrlword:=0;
              status := forumtype2_read_ndeftag(myctrlword, @mypiccserial, @oldpicckey);
              if status=0 then
              begin
                  cardno:='ForumType2Uid:' ;
                  for i:=0 to 6 do cardno:=cardno+inttohex(mypiccserial[i],2);
              end;
          end;
          2:     //读forumtype5 15693标签
          begin
              myctrlword:=0;
              afi:=0;
              status := forumtype5_read_ndeftag(myctrlword, afi, @mypiccserial);
              if status=0 then
              begin
                  cardno:='ForumType5Uid:' ;
                  for i:=0 to 7 do cardno:=cardno+inttohex(mypiccserial[7-i],2);
              end;
          end;
          3:      //读MifareClassic标签
          begin
              if CheckBox1.Checked then myctrlword:=$80+$40+$10 else myctrlword:=$80+$10;
              status := piccread_ndeftag(myctrlword, @mypiccserial, @oldpicckey);
              if status=0 then
              begin
                  cardno:='MifareClassUid:' ;
                  for i:=0 to 3 do cardno:=cardno+inttohex(mypiccserial[i],2);
              end;
          end;
          4:      //读forumtype4 标签
          begin
              if CheckBox1.Checked then myctrlword:=$40 else myctrlword:=0;
              status := forumtype4_read_ndeftag(myctrlword, @mypiccserial,@mypiccseriallen, @oldpicckey);
              if status=0 then
              begin
                  cardno:='ForumType4Uid:' ;
                  for i:=0 to mypiccseriallen[0]-1 do cardno:=cardno+inttohex(mypiccserial[i],2);
              end;
          end;
     end;

     if status=0 then
     begin
          pcdbeep(38);
          tagbuf_read(@mypiccdata, @revstrlen, @recordnumber);
          ndefstr:=cardno+chr(13)+chr(10);
          for i:=0 to revstrlen-1 do  ndefstr:=ndefstr+chr(mypiccdata[i]);
          Memo2.Text := ndefstr;
     end;

标签:status,begin,NFC,标签,Delphi,NDEF,cardno,myctrlword
From: https://blog.51cto.com/RongShi/6898594

相关文章

  • 使用Delphi编写DLL劫持内存补丁
    在有些破解程序时,不能暴力修改程序,修改后,程序就不能正常运行,因为很多程序启动时有自我的校验,但是当程序加载到内存后,在内存中修改相应的地方就可以达到破解的效果。那么怎样在不破坏程序的前提下,达到修改程序呢?当一个可执行文件运行时,Windows加载器将可执行模块映射到进程的地址......
  • Android NFC简介
    目录:AndroidNFC1 简介1.1 什么是 NFC1.2Android 上的 NFC1.3Android 中的 NFC 通讯机制2 用法2.1 读取 tag2.2 发送消息2.2.1 发送过程2.2.2NDEF 消息格式1 简介1.1 什么是 NFC近场通讯 (NearFiledCommunication) 技术是一种近距离的高频无线......
  • org.springframework.beans.factory.parsing.BeanDefinitionParsingException
    org.springframework.beans.factory.parsing.BeanDefinitionParsingException:Configurationproblem:Failedtoimportbeandefinitionsfromrelativelocation[spring-controller.xml]Offendingresource:classpathresource[applicationContext.xml];nestedexcep......
  • Delphi 的 DBGrid 中的下拉列表和查找字段编程方法
    数据网格是非常流行的数据输入和显示形式,像大家熟悉的Excel、VFP 中的功能强大的BROWS 等,为广大程序员乐于采用。在用 Delphi 开发数据库应用系统时,利用数据网格DBGrid 输入数据时,有些字段只允许某几个固定的字符串,像档案案卷的保管期限,只有“永久”、“长期”和“短期”三种......
  • Delphi中的Sender:TObject对象解析
     Delphi中的Sender:TObject1、Sender介绍Sender的类型是Tobject,是Tobject的派生类。Sender是一个TObject类型的参数,它告诉Delphi哪个控件接收这个事件并调用相应的处理过程。例如:procedureTForm1.Button1Click(Sender:TObject);begin//end;当点击BUTTON1时,会......
  • Keil5报错Error: L6218E: Undefined symbol assert_param (referred from misc.o)
    该函数定义在stm32f10x_conf.h里,在C\C++设置一栏中定义USE_STDPERIPH_DRIVER,STM32F10X_HD使宏生效即可解决问题。   ......
  • Delphi中URL的编码与解码;即urlencode的使用
    一、URL简介   URL是网页的地址,比如 ​​ ​http://www.shanhaiMy.com​​​。Web浏览器通过URL从web服务器请求页面。   由于URL字符串常常会包含非ASCII字符,URL在传输过程中,往往出现错误。因此,可以将非字符串字符,让一些特殊ASCII字符组合,代替非ASCII字符。这就......
  • Cannot read properties of undefined (reading 'state') 或者 Cannot read propertie
     第一步,先检查是否在main.js中引入store.js 如果检查完都引入了,且还是存在报错,第二步:在package.json将vuex的版本更换为其它版本,并从新yarn安装,建议vuex版本为3.0然后从新启动项目即可解决......
  • Delphi7 TClientDataSet作为内存数据集合使用
    IDE:Delphi7使用TClientDataSet控件在Delphi中保存内存数据集合(相当于Java中的List<Map>),代码片段:procedureTMainForm.btnExportClick(Sender:TObject);tmpCds:TClientDataSet;tmpStr:string;begin//TClientDataSet作为内存数据集合使用//*********************......
  • #pragma once 指令和 #ifndef 指令
    #pragmaonce指令和#ifndef指令都是用于避免头文件的重复包含,但它们有一些区别和注意事项。1.功能区别:-#pragmaonce:这是一个非标准的预处理指令,它告诉编译器只包含一次当前的头文件。这是一种简单方便的方式,可以避免头文件的多次包含。大多数编译器都支持这个指令,但并非所......