wrt-plugins-tizen_0.4.23
[framework/web/wrt-plugins-tizen.git] / src / NFC / NFCTag.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include <Commons/Exception.h>
19 #include <JSTizenException.h>
20
21 #include "NFCTag.h"
22 #include "NFCUtil.h"
23 #include <Logger.h>
24
25 namespace DeviceAPI {
26 namespace NFC {
27
28 namespace
29 {
30         /**
31         * Callback method called by platform as interval time.
32         * @param event_type Platform magnetic evet type
33         * @param event Platform sensor event data
34         * @param this_ User data pointer.
35         */
36         static bool TagInformationCallback(const char *key, const unsigned char *value, int value_size, void *user_data) {
37                 LoggerD("Callback TagInformationCallback.");
38                 if (user_data) {
39                         NFCUtil util;
40                         std::vector<unsigned char> tagInfo = util.toVector(value, value_size);
41                         (static_cast<NFCTag*>(user_data))->makeTagProperties(key, tagInfo);
42                         return TRUE;
43                 }
44                 LoggerD("Error! TagInformationCallback is Null.");
45                 return false;
46         }
47
48         static void TagReadCallback(nfc_error_e result , nfc_ndef_message_h message , void * data) {
49                 LoggerD("Callback TagReadCallback.");
50                 if (data) {
51                         NFCTag *tagPtr = (NFCTag *)((EventNFCPtrs<EventTagActionRead> *)data)->getThisPtr();
52                         if (tagPtr) {
53                                 EventTagActionReadPtr event = ((EventNFCPtrs<EventTagActionRead> *)data)->getEventPtrs();
54                                 LoggerD("message handler :" << message);
55
56                                 unsigned char *rawdata = NULL;
57                                 int size;
58                                 if (nfc_ndef_message_get_rawdata(message, &rawdata, &size) != NFC_ERROR_NONE) {
59                                         LoggerE("Can't get record's rawdata");
60                                         if (rawdata)
61                                                 free(rawdata);
62                                         return;
63                                 }
64
65                                 NFCUtil util;
66                                 std::vector<unsigned char> readData = util.toVector(rawdata, size);
67                                 if (rawdata)
68                                         free(rawdata);
69                                 tagPtr->readNdefManualAnswer((int)result, readData, event);
70                         }
71                 
72                 } else {
73                         LoggerD("Error! TagReadCallback is Null.");
74                 }
75         }
76
77         static void TagWriteCallback(nfc_error_e result, void *data) {
78                 LoggerD("Callback TagWriteCallback.");
79                 if (data) {
80                         ((NFCTag *)data)->writeNdefManualAnswer((int)result);
81                 } else {
82                         LoggerD("Error! TagWriteCallback is Null.");
83                 }               
84         }
85
86         static void TagTransceiveCallback(nfc_error_e result, unsigned char *buffer, int buffer_size,  void *data) {
87                 LoggerD("Callback TagTransceiveCallback.");
88                 if (data) {
89                         NFCUtil util;
90                         std::vector<unsigned char> responseData = util.toVector(buffer, buffer_size)    ;
91                         ((NFCTag *)data)->transceiveManualAnswer((int)result, responseData);
92                 } else {
93                         LoggerD("Error! TagTransceiveCallback is Null.");
94                 }               
95         }
96
97         static void TagFormatCallback(nfc_error_e result, void *data) {
98                 LoggerD("Callback TagFormatCallback.");
99                 if (data) {
100                         ((NFCTag *)data)->formatManualAnswer((int)result);              
101                 } else {
102                         LoggerD("Error! TagFormatCallback is Null.");
103                 }               
104         }
105 }//private namespace
106
107 NFCTag::NFCTag(void *tagHandle)
108 {
109         LoggerD("entered");
110
111         handle = (nfc_tag_h)tagHandle;
112
113         m_EventTagActionWritePtr.Reset();
114         m_EventTagActionTransceivePtr.Reset();
115         m_EventTagActionFormatPtr.Reset();
116 }
117
118 NFCTag::~NFCTag()
119 {
120         LoggerD("entered");
121         handle = NULL;
122 }
123
124 bool NFCTag::isConnected() {
125         nfc_tag_h curHandle = NULL;
126         if (nfc_manager_get_connected_tag(&curHandle) == NFC_ERROR_NONE) {
127                 if (curHandle == handle)
128                         return true;
129         }
130         return false;
131 }
132
133 nfcTagType NFCTag::getTagType() {
134         nfc_tag_type_e type = NFC_UNKNOWN_TARGET;
135         int result = nfc_tag_get_type(handle, &type);
136
137         NFCUtil util;
138         if (result != NFC_ERROR_NONE)
139                 util.throwNFCException(result, "Can't get tag Type");
140
141         return util.convertTonfcTagType(type);
142 }
143
144 bool NFCTag::isNDEFSupport() {
145         bool isNDEF = FALSE;
146         int result = nfc_tag_is_support_ndef(handle, &isNDEF);
147
148         NFCUtil util;
149         if (result != NFC_ERROR_NONE)
150                 util.throwNFCException(result, "Can't get if Ndef is supported");
151
152         return isNDEF;
153 }
154 long NFCTag::getNdefSize(){
155         unsigned int ndefSize;
156         int result = nfc_tag_get_ndef_size(handle, &ndefSize);
157
158         NFCUtil util;
159         if (result != NFC_ERROR_NONE)
160                 util.throwNFCException(result, "Can't get Ndef size");
161
162         return static_cast<long>(ndefSize);
163 }
164 std::vector<NFCTagProperties> NFCTag::getProperties() {
165         LoggerD("Enter");
166         props.clear();
167         int result = nfc_tag_foreach_information(handle, TagInformationCallback, this);
168
169         NFCUtil util;
170         if (result != NFC_ERROR_NONE)
171                 util.throwNFCException(result, "Can't get Ndef Properties");
172
173         return props;
174 }
175
176 void NFCTag::makeTagProperties(const char *key, std::vector<unsigned char> &value) {
177         NFCTagProperties newProp;
178         newProp.key = key;
179         newProp.value = value;
180         props.push_back(newProp);
181 }
182
183 void NFCTag::readNdef(const EventTagActionReadPtr& event) {
184         LoggerD("Enter");
185         if (!isNDEFSupport())
186                 ThrowMsg(WrtDeviceApis::Commons::UnsupportedException, "Not Support NDEF");
187
188         EventRequestReceiver<EventTagActionRead>::PostRequest(event);
189 }
190
191 void NFCTag::writeNdef(const EventTagActionWritePtr& event) {
192         LoggerD("Enter");
193         if (!isNDEFSupport())
194                 ThrowMsg(WrtDeviceApis::Commons::UnsupportedException, "Not Support NDEF");
195
196         if (m_EventTagActionWritePtr.Get() != NULL)
197                 EventTagActionWrites.push_back(event);
198         else
199                 EventRequestReceiver<EventTagActionWrite>::PostRequest(event);
200
201         return;
202 }
203
204 void NFCTag::transceive(const EventTagActionTransceivePtr& event) {
205         LoggerD("Enter");
206
207         if (m_EventTagActionTransceivePtr.Get() != NULL)
208                 EventTagActionTransceives.push_back(event);
209         else
210                 EventRequestReceiver<EventTagActionTransceive>::PostRequest(event);
211 }
212
213 void NFCTag::format(const EventTagActionFormatPtr& event) {
214         LoggerD("Enter");
215         EventRequestReceiver<EventTagActionFormat>::PostRequest(event);
216 }
217
218 void NFCTag::readNdefManualAnswer(int result, std::vector<unsigned char> &data, const EventTagActionReadPtr &event)
219 {
220         LoggerD("Enter");
221         if ((nfc_error_e)result == NFC_ERROR_NONE) {
222                 event->setResult(TRUE);
223                 event->setReadNdefResult(data);
224         } else {
225                 NFCUtil util;
226                 event->setResult(FALSE);
227                 event->setError(util.getNFCErrorString(result));
228                 event->setErrorMessage(util.getNFCErrorMessage(result));
229         }
230         EventRequestReceiver<EventTagActionRead>::ManualAnswer(event);
231
232         std::vector<TagReadDataPtr>::iterator it;
233         for (it = EventTagActionsReads.begin(); it != EventTagActionsReads.end(); ++it) {
234                 if ((*it)->getEventPtrs() == event) {
235                         EventTagActionsReads.erase(it);
236                         LoggerD("event is removed. (" << EventTagActionsReads.size() << ")");
237                         break;
238                 }
239         }
240 }
241
242 void NFCTag::writeNdefManualAnswer(int result)
243 {
244         LoggerD("Enter");
245         if (m_EventTagActionWritePtr.Get() != NULL) {
246                 if (nfc_ndef_message_destroy(static_cast<nfc_ndef_message_h>(m_EventTagActionWritePtr->getNdefForWriting())) != NFC_ERROR_NONE)
247                         LoggerE("Can't destroy NdefMessage");
248
249                 if ((nfc_error_e)result == NFC_ERROR_NONE) {
250                         m_EventTagActionWritePtr->setResult(TRUE);
251                 } else {
252                         NFCUtil util;
253                         m_EventTagActionWritePtr->setResult(FALSE);
254                         m_EventTagActionWritePtr->setError(util.getNFCErrorString(result));
255                         m_EventTagActionWritePtr->setErrorMessage(util.getNFCErrorMessage(result));
256                 }
257                 EventRequestReceiver<EventTagActionWrite>::ManualAnswer(m_EventTagActionWritePtr);
258
259                 m_EventTagActionWritePtr.Reset();
260                 if (EventTagActionWrites.size() > 0) {
261                         EventTagActionWritePtr event = EventTagActionWrites.front();
262                         EventTagActionWrites.erase(EventTagActionWrites.begin());
263                         LoggerD("EventTagActionWrites is removed. (" << EventTagActionWrites.size() << ")");
264                         EventRequestReceiver<EventTagActionWrite>::PostRequest(event);
265                 }
266         }
267 }
268
269 void NFCTag::transceiveManualAnswer(int result , std::vector<unsigned char> &data)
270 {
271         LoggerD("Enter");
272         if (m_EventTagActionTransceivePtr.Get() != NULL) {
273                 if ((nfc_error_e)result == NFC_ERROR_NONE) {
274                         m_EventTagActionTransceivePtr->setResult(TRUE);
275                         m_EventTagActionTransceivePtr->setTransceiveBuffer(data);
276                 } else {
277                         NFCUtil util;
278                         m_EventTagActionTransceivePtr->setResult(FALSE);
279                         m_EventTagActionTransceivePtr->setError(util.getNFCErrorString(result));
280                         m_EventTagActionTransceivePtr->setErrorMessage(util.getNFCErrorMessage(result));
281                 }
282                 EventRequestReceiver<EventTagActionTransceive>::ManualAnswer(m_EventTagActionTransceivePtr);
283
284                 m_EventTagActionTransceivePtr.Reset();
285                 if (EventTagActionTransceives.size() > 0) {
286                         EventTagActionTransceivePtr event = EventTagActionTransceives.front();
287                         EventTagActionTransceives.erase(EventTagActionTransceives.begin());
288                         LoggerD("EventTagActionWrites is removed. (" << EventTagActionTransceives.size() << ")");
289                         EventRequestReceiver<EventTagActionTransceive>::PostRequest(event);
290                 }
291         }
292 }
293
294 void NFCTag::formatManualAnswer(int result)
295 {
296         LoggerD("Enter");
297         if (m_EventTagActionFormatPtr.Get() != NULL) {
298                 if ((nfc_error_e)result == NFC_ERROR_NONE) {
299                         m_EventTagActionFormatPtr->setResult(TRUE);
300                 } else {
301                         NFCUtil util;
302                         m_EventTagActionFormatPtr->setResult(FALSE);
303                         m_EventTagActionFormatPtr->setError(util.getNFCErrorString(result));
304                         m_EventTagActionFormatPtr->setErrorMessage(util.getNFCErrorMessage(result));
305                 }
306                 EventRequestReceiver<EventTagActionFormat>::ManualAnswer(m_EventTagActionFormatPtr);
307                 m_EventTagActionFormatPtr.Reset();
308         }
309 }
310
311 void NFCTag::OnRequestReceived(const EventTagActionReadPtr& event) {
312         LoggerD("Enter");
313         
314         try {
315                 event->switchToManualAnswer();
316
317                 TagReadDataPtr data( new EventNFCPtrs<EventTagActionRead>(event, this));
318                 EventTagActionsReads.push_back(data);
319                 int result = nfc_tag_read_ndef(handle, TagReadCallback, data.Get());
320
321                 NFCUtil util;
322                 std::string error = util.getNFCErrorString(result);
323                 if (error != "") {
324                         event->setResult(false);
325                         event->setError(error);
326                         event->setErrorMessage(util.getNFCErrorMessage(result));
327                         EventRequestReceiver<EventTagActionRead>::ManualAnswer(event);
328
329                         std::vector<TagReadDataPtr>::iterator it;
330                         for (it = EventTagActionsReads.begin(); it != EventTagActionsReads.end(); ++it) {
331                                 if ((*it)->getEventPtrs() == event) {
332                                         EventTagActionsReads.erase(it);
333                                         LoggerD("event is removed. (" << EventTagActionsReads.size() << ")");
334                                         break;
335                                 }
336                         }
337                 }
338         }
339         catch (const WrtDeviceApis::Commons::Exception& ex) {
340                 LoggerE("Exception: " << ex.GetMessage());
341                 event->setResult(false);
342         
343                 EventRequestReceiver<EventTagActionRead>::ManualAnswer(event);
344         }
345         
346 }
347
348 void NFCTag::OnRequestReceived(const EventTagActionWritePtr& event) {
349         try {
350                 event->switchToManualAnswer();
351
352                 m_EventTagActionWritePtr = event;
353
354                 int result = nfc_tag_write_ndef(handle, (nfc_ndef_message_h)event->getNdefForWriting(),TagWriteCallback, this);
355
356                 NFCUtil util;
357                 std::string error = util.getNFCErrorString(result);
358                 if (error != "") {
359                         writeNdefManualAnswer(result);
360                 }
361         }
362         catch (const WrtDeviceApis::Commons::Exception& ex) {
363                 LoggerE("Exception: " << ex.GetMessage());
364
365                  if (event != m_EventTagActionWritePtr)
366                         m_EventTagActionWritePtr = event;
367                 writeNdefManualAnswer(NFC_ERROR_OPERATION_FAILED);
368         }
369 }
370
371 void NFCTag::OnRequestReceived(const EventTagActionTransceivePtr& event) {
372         NFCUtil util;
373         try {
374                 event->switchToManualAnswer();
375                 
376                 m_EventTagActionTransceivePtr = event;
377
378                 unsigned char *buffer = util.toCharPtr(event->getTransceiveBuffer());
379                 int result = nfc_tag_transceive(handle, buffer, event->getTransceiveBufferSize(), TagTransceiveCallback, this);
380
381                 if (buffer)
382                         free(buffer);
383
384                 std::string error = util.getNFCErrorString(result);
385                 if (error != "") {
386                         std::vector<unsigned char> emptyData;
387                         transceiveManualAnswer(result, emptyData);
388                 }
389         }
390         catch (const WrtDeviceApis::Commons::Exception& ex) {
391                 LoggerE("Exception: " << ex.GetMessage());
392
393                 std::vector<unsigned char> emptyData;
394                 transceiveManualAnswer(NFC_ERROR_OPERATION_FAILED, emptyData);
395         }
396         
397 }
398
399 void NFCTag::OnRequestReceived(const EventTagActionFormatPtr& event) {
400         
401         try {
402                 event->switchToManualAnswer();
403
404                 if (m_EventTagActionFormatPtr.Get() != NULL) {
405                         event->setResult(false);
406                         event->setError(DeviceAPI::Common::JSTizenException::SERVICE_NOT_AVAILABLE);
407                         event->setErrorMessage("Progressing Identical Operation");
408                         EventRequestReceiver<EventTagActionFormat>::ManualAnswer(event);
409                         return;
410                 }
411                 m_EventTagActionFormatPtr = event;
412                 
413                 NFCUtil util;
414                 LoggerD("key size :" <<  event->getKeySize());
415
416                 unsigned char *key = util.toCharPtr(event->getKey());
417                 int result = nfc_tag_format_ndef(handle, key, event->getKeySize(), TagFormatCallback, this);
418
419                 if (key)
420                         free(key);
421
422                 std::string error = util.getNFCErrorString(result);
423                 if (error != "") {
424                         event->setResult(false);
425                         event->setError(error);
426                         event->setErrorMessage(util.getNFCErrorMessage(result));
427                         EventRequestReceiver<EventTagActionFormat>::ManualAnswer(event);
428                         m_EventTagActionFormatPtr.Reset();
429                 }
430         }
431         catch (const WrtDeviceApis::Commons::Exception& ex) {
432                 LoggerE("Exception: " << ex.GetMessage());
433                 event->setResult(false);
434                 
435                 EventRequestReceiver<EventTagActionFormat>::ManualAnswer(event);
436                 m_EventTagActionFormatPtr.Reset();
437         }
438         
439 }
440
441
442 }
443 }