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