Release 4.0.0-preview1-00051
[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         /// <privilege>http://tizen.org/privilege/nfc</privilege>
141         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
142         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
143         public IEnumerable<NfcTagInformation> ForeachInformation()
144         {
145             List<NfcTagInformation> infoList = new List<NfcTagInformation>();
146             Interop.Nfc.TagInformationCallback callback = (IntPtr key, IntPtr infoValue, int valueSize, IntPtr userData) =>
147             {
148                 if (key != IntPtr.Zero && infoValue != IntPtr.Zero)
149                 {
150                     NfcTagInformation tagInfo = new NfcTagInformation(Marshal.PtrToStringAnsi(key), new byte[valueSize]);
151
152                     Marshal.Copy(infoValue, tagInfo.InformationValue, 0, valueSize);
153
154                     infoList.Add(tagInfo);
155
156                     return true;
157                 }
158                 return false;
159             };
160
161             int ret = Interop.Nfc.Tag.ForeachInformation(_tagHandle, callback, IntPtr.Zero);
162             if (ret != (int)NfcError.None)
163             {
164                 Log.Error(Globals.LogTag, "Failed to get all Tag information, Error - " + (NfcError)ret);
165                 NfcErrorFactory.ThrowNfcException(ret);
166             }
167
168             return infoList;
169         }
170
171         /// <summary>
172         /// Transceives the data of the raw format card.
173         /// </summary>
174         /// <since_tizen> 3 </since_tizen>
175         /// <param name="buffer">The binary data for parameter or additional commands.</param>
176         /// <privilege>http://tizen.org/privilege/nfc</privilege>
177         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
178         /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
179         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
180         public Task<byte[]> TransceiveAsync(byte[] buffer)
181         {
182             var task = new TaskCompletionSource<byte[]>();
183
184             byte[] resultBuffer = null;
185             Interop.Nfc.TagTransceiveCompletedCallback callback = (int result, IntPtr resultData, int dataSize, IntPtr userData) =>
186             {
187                 if (result == (int)NfcError.None)
188                 {
189                     resultBuffer = new byte[dataSize];
190                     Marshal.Copy(resultData, resultBuffer, 0, dataSize);
191                     task.SetResult(resultBuffer);
192                 }
193                 return;
194             };
195
196             int ret = Interop.Nfc.Tag.Transceive(_tagHandle, buffer, buffer.Length, callback, IntPtr.Zero);
197             if (ret != (int)NfcError.None)
198             {
199                 Log.Error(Globals.LogTag, "Failed to transceive data, Error - " + (NfcError)ret);
200                 NfcErrorFactory.ThrowNfcException(ret);
201             }
202
203             return task.Task;
204         }
205
206         /// <summary>
207         /// Reads NDEF formatted data from NFC tag.
208         /// </summary>
209         /// <since_tizen> 3 </since_tizen>
210         /// <privilege>http://tizen.org/privilege/nfc</privilege>
211         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
212         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
213         public Task<NfcNdefMessage> ReadNdefMessageAsync()
214         {
215             var task = new TaskCompletionSource<NfcNdefMessage>();
216
217             NfcNdefMessage ndefMsg = null;
218             Interop.Nfc.TagReadCompletedCallback callback = (int result, IntPtr ndefMessage, IntPtr userData) =>
219             {
220                 if (result == (int)NfcError.None)
221                 {
222                     ndefMsg = new NfcNdefMessage(ndefMessage);
223                     task.SetResult(ndefMsg);
224
225                     return true;
226                 }
227                 return false;
228             };
229
230             int ret = Interop.Nfc.Tag.ReadNdef(_tagHandle, callback, IntPtr.Zero);
231             if (ret != (int)NfcError.None)
232             {
233                 Log.Error(Globals.LogTag, "Failed to read ndef message, Error - " + (NfcError)ret);
234                 NfcErrorFactory.ThrowNfcException(ret);
235             }
236
237             return task.Task;
238         }
239
240         /// <summary>
241         /// Writes NDEF formatted data.
242         /// </summary>
243         /// <since_tizen> 3 </since_tizen>
244         /// <param name="ndefMessage">The NfcNdefMessage object.</param>
245         /// <privilege>http://tizen.org/privilege/nfc</privilege>
246         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
247         /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
248         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
249         public Task<NfcError> WriteNdefMessageAsync(NfcNdefMessage ndefMessage)
250         {
251             var task = new TaskCompletionSource<NfcError>();
252
253             Interop.Nfc.VoidCallback callback = (int result, IntPtr userData) =>
254             {
255                 task.SetResult((NfcError)result);
256                 return;
257             };
258
259             int ret = Interop.Nfc.Tag.WriteNdef(_tagHandle, ndefMessage.GetHandle(), callback, IntPtr.Zero);
260             if (ret != (int)NfcError.None)
261             {
262                 Log.Error(Globals.LogTag, "Failed to write ndef message, Error - " + (NfcError)ret);
263                 NfcErrorFactory.ThrowNfcException(ret);
264             }
265
266             return task.Task;
267         }
268
269         /// <summary>
270         /// Formats the detected tag that can store NDEF message.
271         /// </summary>
272         /// <since_tizen> 3 </since_tizen>
273         /// <param name="keyValue">The key value that may need to format the tag.</param>
274         /// <privilege>http://tizen.org/privilege/nfc</privilege>
275         /// <exception cref="NotSupportedException">Thrown when Nfc is not supported.</exception>
276         /// <exception cref="ArgumentException">Thrown when method is failed due to an invalid parameter.</exception>
277         /// <exception cref="InvalidOperationException">Thrown when the method failed due to invalid operation.</exception>
278         public Task<NfcError> FormatNdefMessageAsync(byte[] keyValue)
279         {
280             var task = new TaskCompletionSource<NfcError>();
281
282             Interop.Nfc.VoidCallback callback = (int result, IntPtr userData) =>
283             {
284                 task.SetResult((NfcError)result);
285                 return;
286             };
287
288             int ret = Interop.Nfc.Tag.FormatNdef(_tagHandle, keyValue, keyValue.Length, callback, IntPtr.Zero);
289             if (ret != (int)NfcError.None)
290             {
291                 Log.Error(Globals.LogTag, "Failed to format ndef message, Error - " + (NfcError)ret);
292                 NfcErrorFactory.ThrowNfcException(ret);
293             }
294
295             return task.Task;
296         }
297     }
298 }