Add since_tizen Tag
[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     /// <since_tizen> 3 </since_tizen>
28     public class NfcTag : IDisposable
29     {
30         private bool disposed = false;
31         private IntPtr _tagHandle = IntPtr.Zero;
32
33         /// <summary>
34         /// The type of NFC tag.
35         /// </summary>
36         /// <since_tizen> 3 </since_tizen>
37         public NfcTagType Type
38         {
39             get
40             {
41                 int type;
42                 int ret = Interop.Nfc.Tag.GetType(_tagHandle, out type);
43                 if (ret != (int)NfcError.None)
44                 {
45                     Log.Error(Globals.LogTag, "Failed to get tag type, Error - " + (NfcError)ret);
46                 }
47                 return (NfcTagType)type;
48             }
49         }
50
51         /// <summary>
52         /// Whether the given NFC tag supports NDEF messages.
53         /// </summary>
54         /// <since_tizen> 3 </since_tizen>
55         public bool IsSupportNdef
56         {
57             get
58             {
59                 bool isSupport;
60                 int ret = Interop.Nfc.Tag.IsSupportNdef(_tagHandle, out isSupport);
61                 if (ret != (int)NfcError.None)
62                 {
63                     Log.Error(Globals.LogTag, "Failed to get support state, Error - " + (NfcError)ret);
64                 }
65                 return isSupport;
66
67             }
68         }
69
70         /// <summary>
71         /// The maximum NDEF message size that can be stored in NFC tag.
72         /// </summary>
73         /// <since_tizen> 3 </since_tizen>
74         public uint MaximumNdefSize
75         {
76             get
77             {
78                 uint maxSize;
79                 int ret = Interop.Nfc.Tag.GetMaximumNdefSize(_tagHandle, out maxSize);
80                 if (ret != (int)NfcError.None)
81                 {
82                     Log.Error(Globals.LogTag, "Failed to get max ndef size, Error - " + (NfcError)ret);
83                 }
84                 return maxSize;
85             }
86         }
87
88         /// <summary>
89         /// The size of NDEF message that stored in the tag.
90         /// </summary>
91         /// <since_tizen> 3 </since_tizen>
92         public uint NdefSize
93         {
94             get
95             {
96                 uint ndefSize;
97                 int ret = Interop.Nfc.Tag.GetNdefSize(_tagHandle, out ndefSize);
98                 if (ret != (int)NfcError.None)
99                 {
100                     Log.Error(Globals.LogTag, "Failed to get ndef size, Error - " + (NfcError)ret);
101                 }
102                 return ndefSize;
103             }
104         }
105
106         internal NfcTag(IntPtr handle)
107         {
108             _tagHandle = handle;
109         }
110
111         ~NfcTag()
112         {
113             Dispose(false);
114         }
115
116         public void Dispose()
117         {
118             Dispose(true);
119             GC.SuppressFinalize(this);
120         }
121
122         private void Dispose(bool disposing)
123         {
124             if (disposed)
125                 return;
126
127             if (disposing)
128             {
129                 // Free managed objects.
130             }
131             //Free unmanaged objects
132             disposed = true;
133         }
134
135         /// <summary>
136         /// Retrieves all tag information.
137         /// </summary>
138         /// <since_tizen> 3 </since_tizen>
139         /// <returns>List of NfcTagInformation objects.</returns>
140         public IEnumerable<NfcTagInformation> ForeachInformation()
141         {
142             List<NfcTagInformation> infoList = new List<NfcTagInformation>();
143             Interop.Nfc.TagInformationCallback callback = (IntPtr key, IntPtr infoValue, int valueSize, IntPtr userData) =>
144             {
145                 if (key != IntPtr.Zero && infoValue != IntPtr.Zero)
146                 {
147                     NfcTagInformation tagInfo = new NfcTagInformation(Marshal.PtrToStringAnsi(key), new byte[valueSize]);
148
149                     Marshal.Copy(infoValue, tagInfo.InformationValue, 0, valueSize);
150
151                     infoList.Add(tagInfo);
152
153                     return true;
154                 }
155                 return false;
156             };
157
158             int ret = Interop.Nfc.Tag.ForeachInformation(_tagHandle, callback, IntPtr.Zero);
159             if (ret != (int)NfcError.None)
160             {
161                 Log.Error(Globals.LogTag, "Failed to get all Tag information, Error - " + (NfcError)ret);
162                 NfcErrorFactory.ThrowNfcException(ret);
163             }
164
165             return infoList;
166         }
167
168         /// <summary>
169         /// Transceives the data of the raw format card.
170         /// </summary>
171         /// <since_tizen> 3 </since_tizen>
172         /// <param name="buffer">The binary data for parameter or additional commands.</param>
173         public Task<byte[]> TransceiveAsync(byte[] buffer)
174         {
175             var task = new TaskCompletionSource<byte[]>();
176             
177             byte[] resultBuffer = null;
178             Interop.Nfc.TagTransceiveCompletedCallback callback = (int result, IntPtr resultData, int dataSize, IntPtr userData) =>
179             {
180                 if (result == (int)NfcError.None)
181                 {
182                     resultBuffer = new byte[dataSize];
183                     Marshal.Copy(resultData, resultBuffer, 0, dataSize);
184                     task.SetResult(resultBuffer);
185                 }
186                 return;
187             };
188
189             int ret = Interop.Nfc.Tag.Transceive(_tagHandle, buffer, buffer.Length, callback, IntPtr.Zero);
190             if (ret != (int)NfcError.None)
191             {
192                 Log.Error(Globals.LogTag, "Failed to transceive data, Error - " + (NfcError)ret);
193                 NfcErrorFactory.ThrowNfcException(ret);
194             }
195
196             return task.Task;
197         }
198
199         /// <summary>
200         /// Reads NDEF formatted data from NFC tag.
201         /// </summary>
202         /// <since_tizen> 3 </since_tizen>
203         public Task<NfcNdefMessage> ReadNdefMessageAsync()
204         {
205             var task = new TaskCompletionSource<NfcNdefMessage>();
206
207             NfcNdefMessage ndefMsg = null;
208             Interop.Nfc.TagReadCompletedCallback callback = (int result, IntPtr ndefMessage, IntPtr userData) =>
209             {
210                 if (result == (int)NfcError.None)
211                 {
212                     ndefMsg = new NfcNdefMessage(ndefMessage);
213                     task.SetResult(ndefMsg);
214
215                     return true;
216                 }
217                 return false;
218             };
219
220             int ret = Interop.Nfc.Tag.ReadNdef(_tagHandle, callback, IntPtr.Zero);
221             if (ret != (int)NfcError.None)
222             {
223                 Log.Error(Globals.LogTag, "Failed to read ndef message, Error - " + (NfcError)ret);
224                 NfcErrorFactory.ThrowNfcException(ret);
225             }
226
227             return task.Task;
228         }
229
230         /// <summary>
231         /// Writes NDEF formatted data.
232         /// </summary>
233         /// <since_tizen> 3 </since_tizen>
234         /// <param name="ndefMessage">The NfcNdefMessage object.</param>
235         public Task<NfcError> WriteNdefMessageAsync(NfcNdefMessage ndefMessage)
236         {
237             var task = new TaskCompletionSource<NfcError>();
238
239             Interop.Nfc.VoidCallback callback = (int result, IntPtr userData) =>
240             {
241                 task.SetResult((NfcError)result);
242                 return;
243             };
244
245             int ret = Interop.Nfc.Tag.WriteNdef(_tagHandle, ndefMessage.GetHandle(), callback, IntPtr.Zero);
246             if (ret != (int)NfcError.None)
247             {
248                 Log.Error(Globals.LogTag, "Failed to write ndef message, Error - " + (NfcError)ret);
249                 NfcErrorFactory.ThrowNfcException(ret);
250             }
251
252             return task.Task;
253         }
254
255         /// <summary>
256         /// Formats the detected tag that can store NDEF message.
257         /// </summary>
258         /// <since_tizen> 3 </since_tizen>
259         /// <param name="keyValue">The key value that may need to format the tag.</param>
260         public Task<NfcError> FormatNdefMessageAsync(byte[] keyValue)
261         {
262             var task = new TaskCompletionSource<NfcError>();
263
264             Interop.Nfc.VoidCallback callback = (int result, IntPtr userData) =>
265             {
266                 task.SetResult((NfcError)result);
267                 return;
268             };
269
270             int ret = Interop.Nfc.Tag.FormatNdef(_tagHandle, keyValue, keyValue.Length, callback, IntPtr.Zero);
271             if (ret != (int)NfcError.None)
272             {
273                 Log.Error(Globals.LogTag, "Failed to format ndef message, Error - " + (NfcError)ret);
274                 NfcErrorFactory.ThrowNfcException(ret);
275             }
276
277             return task.Task;
278         }
279     }
280 }