2016年5月9日 星期一

使用byte矩陣傳輸資料到NFC Tag

這是在Safari的官網上找到關於NFC資料的技術文件。主要是讓使用者可以在Web中經由Safari瀏覽器啟動Android的NFC功能後,再用byte矩陣自組要傳輸到Tag、或Tag Reader中的資料。

當初研究它的目的是想要可以讓Android手機可以用NFC Beaming功能來隨意模仿成Tag、具有特定ID,讓其他Tag Reader可以感應。

但奮戰了整整一天......最後是徒勞無功。在這裡寫下我的心得。



用Android的NdefRecord中的public NdefRecord (short tnf, byte[] type, byte[] id, byte[] payload)函數,雖然很快有基本的Beaming功能,但送出去的訊息ID遲遲都是0...而且是一個0,而不是一串0!(一個長度只有1的byte[]。)

所以就異想天開用public NdefMessage (byte[] data)的方式來組看看,或許ID顯示為0是NdefRecord物件的問題。




NFC的每一筆資料,稱為Message,可以由多組Record組成。

每一組Record又由RecordHeader和RecordPayLoad組成。

每個RecordPayLoad資料長度上限為2的32次方。除此以外沒有限制。(但似乎也不能為0。)

「文件中」說Header由6~9個程度不等的Byte矩陣組成,為何會有6和9的差異?因為其中有所謂ShortRecord和Non-ShortRecord的差異。如果是ShortRecord,則為6,反之則為9。

(為何要強調「文件中」...等一下解釋。先聲明這是文件中非常不精準的地方。)

RecordHeader中的第一個Byte稱為TNF+Flag(Message Flags),我帶入的是217。

因為一個Byte由八個bit組成,在這個欄位中,每個bit都有自己獨特的意義。而我用的是11011001。每個數字代表著一個bite,所以內容只有0或一,換算成十進位後數值是217。

第四個bit正好決定了這筆Record為ShortRecord或Non-ShortRecord,而我帶入的是1,也就表示「True」,所以PayLoadLength的部分只有一個Byte。要等一下計算玩PlayLoad長度後決定數值。

但如果TNF+Flag(Message Flags)是11001001,就會佔去四個Byte,因為第四個數值是0,也就表示這筆資料不是ShortRecord。(Record的長度是四個Byte或一個Byte的差異。)



開頭是{1,1},因為我的Message中只有一組Record,所以都是Begin兼End,如果是Begin,就是10,如果是End就是01。(假設共有三組Record,則第一組10,第二組00,第三組01。)



第三個0/1是Chunk...還是搞不懂這是什麼東西。

第五個0/1是ID Length,如果0,就表示沒有ID,自然也不需要設定ID Length,RecordHead就少了兩個欄位-----設ID Length的欄位和ID本身。

所以上面要強調「文件中」,因為如果ShortRecord為false,而ID Length又為True,則Header的長度上限絕對不只9個Byte。

第六到第八個0/1是TypeNameFormat,是一組的。三個bit可以表示0~7,而Type剛好有八種組合,Empty/Well-Known/URI.......一般都是用WellKnown和URI。(我帶入其他的數值都失敗。)



到此為止,資料很成功送出去,Read很成功的讀取到了我用這方式所寫入的資料。



但Header除了第一個Byte為TNF+Flag(Message Flags)以外,接著還有Type Length(一個Byte),PayLoadLength,(一或四個Byte,視資料是否為ShortRecord而定,)還有IDLength(一個Byte)。

1.TNF+Flag。(長度1)
2.TypeLength。(長度1)
3.PayLoadLength。(長度1)
4.IDLength。(長度1)

這六個Byte之後是所謂的長度浮動的階段,第一個是PayLoadType,它是一個字串轉換成Byte矩陣形式後插入,長度必須要精準計算後寫入TypeLength欄位中,(所以長度大小自然不能超過255。)但PayLoadType的命名邏輯文件中的解釋很模糊,但始終是那八大類,這只是個用來顯示的字串罷了!

接著就是所謂的ID。不管是數值或字串,它一樣也是轉換成Byte矩陣後計算長度插入,長度要寫在IDLength欄位中。

沒有留言:

張貼留言