Version up : 1.0.3 to 1.0.4
[platform/core/csapi/tizenfx.git] / src / Tizen.Network.Nfc / Tizen.Network.Nfc / NfcTag.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Runtime.InteropServices;
19 using System.Collections.Generic;
20 using System.Threading.Tasks;
21
22 namespace Tizen.Network.Nfc
23 {
24     /// <summary>
25     /// A class for managing the Tag information.
26     /// </summary>
27     public class NfcTag : IDisposable
28     {
29         private bool disposed = false;
30         private IntPtr _tagHandle = IntPtr.Zero;
31
32         /// <summary>
33         /// The type of NFC tag.
34         /// </summary>
35         public NfcTagType Type
36         {
37             get
38             {
39                 int type;
40                 int ret = Interop.Nfc.Tag.GetType(_tagHandle, out type);
41                 if (ret != (int)NfcError.None)
42                 {
43                     Log.Error(Globals.LogTag, "Failed to get tag type, Error - " + (NfcError)ret);
44                 }
45                 return (NfcTagType)type;
46             }
47         }
48
49         /// <summary>
50         /// Whether the given NFC tag supports NDEF messages.
51         /// </summary>
52         public bool IsSupportNdef
53         {
54             get
55             {
56                 bool isSupport;
57                 int ret = Interop.Nfc.Tag.IsSupportNdef(_tagHandle, out isSupport);
58                 if (ret != (int)NfcError.None)
59                 {
60                     Log.Error(Globals.LogTag, "Failed to get support state, Error - " + (NfcError)ret);
61                 }
62                 return isSupport;
63
64             }
65         }
66
67         /// <summary>
68         /// The maximum NDEF message size that can be stored in NFC tag.
69         /// </summary>
70         public uint MaximumNdefSize
71         {
72             get
73             {
74                 uint maxSize;
75                 int ret = Interop.Nfc.Tag.GetMaximumNdefSize(_tagHandle, out maxSize);
76                 if (ret != (int)NfcError.None)
77                 {
78                     Log.Error(Globals.LogTag, "Failed to get max ndef size, Error - " + (NfcError)ret);
79                 }
80                 return maxSize;
81             }
82         }
83
84         /// <summary>
85         /// The size of NDEF message that stored in the tag.
86         /// </summary>
87         public uint NdefSize
88         {
89             get
90             {
91                 uint ndefSize;
92                 int ret = Interop.Nfc.Tag.GetNdefSize(_tagHandle, out ndefSize);
93                 if (ret != (int)NfcError.None)
94                 {
95                     Log.Error(Globals.LogTag, "Failed to get ndef size, Error - " + (NfcError)ret);
96                 }
97                 return ndefSize;
98             }
99         }
100
101         internal NfcTag(IntPtr handle)
102         {
103             _tagHandle = handle;
104         }
105
106         ~NfcTag()
107         {
108             Dispose(false);
109         }
110
111         public void Dispose()
112         {
113             Dispose(true);
114             GC.SuppressFinalize(this);
115         }
116
117         private void Dispose(bool disposing)
118         {
119             if (disposed)
120                 return;
121
122             if (disposing)
123             {
124                 // Free managed objects.
125             }
126             //Free unmanaged objects
127             disposed = true;
128         }
129
130         /// <summary>
131         /// Retrieves all tag information.
132         /// </summary>
133         /// <returns>List of NfcTagInformation objects.</returns>
134         public IEnumerable<NfcTagInformation> ForeachInformation()
135         {
136             List<NfcTagInformation> infoList = new List<NfcTagInformation>();
137             Interop.Nfc.TagInformationCallback callback = (IntPtr key, IntPtr infoValue, int valueSize, IntPtr userData) =>
138             {
139                 if (key != IntPtr.Zero && infoValue != IntPtr.Zero)
140                 {
141                     NfcTagInformation tagInfo = new NfcTagInformation(Marshal.PtrToStringAnsi(key), new byte[valueSize]);
142
143                     Marshal.Copy(infoValue, tagInfo.InformationValue, 0, valueSize);
144
145                     infoList.Add(tagInfo);
146
147                     return true;
148                 }
149                 return false;
150             };
151
152             int ret = Interop.Nfc.Tag.ForeachInformation(_tagHandle, callback, IntPtr.Zero);
153             if (ret != (int)NfcError.None)
154             {
155                 Log.Error(Globals.LogTag, "Failed to get all Tag information, Error - " + (NfcError)ret);
156                 NfcErrorFactory.ThrowNfcException(ret);
157             }
158
159             return infoList;
160         }
161
162         /// <summary>
163         /// Transceives the data of the raw format card.
164         /// </summary>
165         /// <param name="buffer">The binary data for parameter or additional commands.</param>
166         public Task<byte[]> TransceiveAsync(byte[] buffer)
167         {
168             var task = new TaskCompletionSource<byte[]>();
169             
170             byte[] resultBuffer = null;
171             Interop.Nfc.TagTransceiveCompletedCallback callback = (int result, IntPtr resultData, int dataSize, IntPtr userData) =>
172             {
173                 if (result == (int)NfcError.None)
174                 {
175                     resultBuffer = new byte[dataSize];
176                     Marshal.Copy(resultData, resultBuffer, 0, dataSize);
177                     task.SetResult(resultBuffer);
178                 }
179                 return;
180             };
181
182             int ret = Interop.Nfc.Tag.Transceive(_tagHandle, buffer, buffer.Length, callback, IntPtr.Zero);
183             if (ret != (int)NfcError.None)
184             {
185                 Log.Error(Globals.LogTag, "Failed to transceive data, Error - " + (NfcError)ret);
186                 NfcErrorFactory.ThrowNfcException(ret);
187             }
188
189             return task.Task;
190         }
191
192         /// <summary>
193         /// Reads NDEF formatted data from NFC tag.
194         /// </summary>
195         public Task<NfcNdefMessage> ReadNdefMessageAsync()
196         {
197             var task = new TaskCompletionSource<NfcNdefMessage>();
198
199             NfcNdefMessage ndefMsg = null;
200             Interop.Nfc.TagReadCompletedCallback callback = (int result, IntPtr ndefMessage, IntPtr userData) =>
201             {
202                 if (result == (int)NfcError.None)
203                 {
204                     ndefMsg = new NfcNdefMessage(ndefMessage);
205                     task.SetResult(ndefMsg);
206
207                     return true;
208                 }
209                 return false;
210             };
211
212             int ret = Interop.Nfc.Tag.ReadNdef(_tagHandle, callback, IntPtr.Zero);
213             if (ret != (int)NfcError.None)
214             {
215                 Log.Error(Globals.LogTag, "Failed to read ndef message, Error - " + (NfcError)ret);
216                 NfcErrorFactory.ThrowNfcException(ret);
217             }
218
219             return task.Task;
220         }
221
222         /// <summary>
223         /// Writes NDEF formatted data.
224         /// </summary>
225         /// <param name="ndefMessage">The NfcNdefMessage object.</param>
226         public Task<NfcError> WriteNdefMessageAsync(NfcNdefMessage ndefMessage)
227         {
228             var task = new TaskCompletionSource<NfcError>();
229
230             Interop.Nfc.VoidCallback callback = (int result, IntPtr userData) =>
231             {
232                 task.SetResult((NfcError)result);
233                 return;
234             };
235
236             int ret = Interop.Nfc.Tag.WriteNdef(_tagHandle, ndefMessage.GetHandle(), callback, IntPtr.Zero);
237             if (ret != (int)NfcError.None)
238             {
239                 Log.Error(Globals.LogTag, "Failed to write ndef message, Error - " + (NfcError)ret);
240                 NfcErrorFactory.ThrowNfcException(ret);
241             }
242
243             return task.Task;
244         }
245
246         /// <summary>
247         /// Formats the detected tag that can store NDEF message.
248         /// </summary>
249         /// <param name="keyValue">The key value that may need to format the tag.</param>
250         public Task<NfcError> FormatNdefMessageAsync(byte[] keyValue)
251         {
252             var task = new TaskCompletionSource<NfcError>();
253
254             Interop.Nfc.VoidCallback callback = (int result, IntPtr userData) =>
255             {
256                 task.SetResult((NfcError)result);
257                 return;
258             };
259
260             int ret = Interop.Nfc.Tag.FormatNdef(_tagHandle, keyValue, keyValue.Length, callback, IntPtr.Zero);
261             if (ret != (int)NfcError.None)
262             {
263                 Log.Error(Globals.LogTag, "Failed to format ndef message, Error - " + (NfcError)ret);
264                 NfcErrorFactory.ThrowNfcException(ret);
265             }
266
267             return task.Task;
268         }
269     }
270 }