b7d95b2064e9a1dd0e83ad3258b4be34be942e5a
[framework/web/wrt-plugins-tizen.git] / src / NFC / NFCDefaultAdapter.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 <dpl/log/log.h>
19 #include <dpl/scoped_ptr.h>
20 #include <dpl/singleton_impl.h>
21 #include <Commons/Exception.h>
22 #include <JSTizenException.h>
23 #include <nfc.h>
24 #include "NFCDefaultAdapter.h"
25 #include "NFCUtil.h"
26
27
28 using namespace DPL;
29 IMPLEMENT_SINGLETON(DeviceAPI::NFC::NFCDefaultAdapter)
30
31 namespace DeviceAPI {
32 namespace NFC {
33
34 namespace
35 {
36         static void TagDetectedCallback(nfc_discovered_type_e type, nfc_tag_h tag, void *data) {
37                 LogDebug("Callback TagDetectedCallback.");
38
39                 if (data) {
40                         if (NFC_DISCOVERED_TYPE_ATTACHED == type) {
41                                 (static_cast<NFCDefaultAdapter*>(data))->NFCTagHasDetected((void *)tag);
42                         } else {
43                                 (static_cast<NFCDefaultAdapter*>(data))->NFCTagHasDetected(NULL);
44                         }
45                 } else {
46                         LogError("Callback private data is NULL.");
47                 }
48
49         }
50
51         static void TargetDetectedCallback(nfc_discovered_type_e type, nfc_p2p_target_h target, void *data) {
52                 LogDebug("Callback TargetDetectedCallback.");
53
54                 if (data) {
55                         if (NFC_DISCOVERED_TYPE_ATTACHED == type) {
56                                 (static_cast<NFCDefaultAdapter*>(data))->NFCTargetHasDetected((void *)target);
57                         } else {
58                                 (static_cast<NFCDefaultAdapter*>(data))->NFCTargetHasDetected(NULL);
59                         }
60                 } else {
61                         LogError("Callback private data is NULL.");
62                 }
63
64         }
65         static void NFCInitializeCompletedCallback(nfc_error_e result, void *user_data) {
66                 LogDebug("Callback NFCInitializeCompletedCallback. result : " << (int)result);
67                 if (user_data && (result == NFC_ERROR_NONE))
68                         (static_cast<NFCDefaultAdapter*>(user_data))->getCurrentNFC();
69         }
70         static void NFCSetActivationCompletedCallback(nfc_error_e error, void *user_data) {
71                 LogDebug("Callback NFCSetActivationCompletedCallback.");
72                 NFCDefaultAdapterSingleton::Instance().setPoweredManualAnswer(error);
73         }
74         static void NFCSetCardEmulationCompletedCallback(nfc_error_e error, void *user_data) {
75                 LogDebug("Callback NFCSetActivationCompletedCallback.");
76                 NFCDefaultAdapterSingleton::Instance().setCardEmulationManualAnswer(error, user_data);
77         }
78         static void NFCSetSEEventCallback(nfc_se_event_e event, void *user_data) {
79                 LogDebug("Callback NFCSetSEEventCallback.");
80                 if (event == NFC_SE_EVENT_SE_TYPE_CHANGED)
81                         NFCDefaultAdapterSingleton::Instance().seChanged();
82         }
83 }//private namespace
84
85 NFCDefaultAdapter::NFCDefaultAdapter()
86         :m_initialized(false) {
87         LogDebug("NFC Enter");
88
89         m_NFCTagListeners.clear();
90         m_NFCTargetListeners.clear();
91         m_NFCChangedSETypes.clear();
92         m_poweredAdapter = NULL;
93         m_seType = NFC_SE_INVALID;
94 }
95
96 NFCDefaultAdapter::~NFCDefaultAdapter() {
97         LogDebug("Enter");
98         deinitialze();
99 }
100
101 bool NFCDefaultAdapter::isSupported() {
102         return nfc_manager_is_supported();
103 }
104
105 void NFCDefaultAdapter::deinitialze() {
106         LogDebug("Enter");
107         int result = -1;
108
109         m_NFCTagListeners.clear();
110         m_NFCTargetListeners.clear();
111         m_poweredAdapter = NULL;
112
113         nfc_manager_unset_tag_discovered_cb();
114         nfc_manager_unset_p2p_target_discovered_cb();
115
116         if(m_initialized == true)
117         {
118                 result = nfc_manager_deinitialize ();
119                 if (result !=NFC_ERROR_NONE) {
120                         LogInfo("failed to deinitialize nfc");
121                 }
122         }
123         m_initialized = false;
124
125         LogDebug("destroy nfc");
126 }
127
128 int NFCDefaultAdapter::setTagListener(NFCAdapter * adapter) {
129         LogDebug(" NFCDefaultAdapter::setTagListener Entered");
130         int result = -1;
131
132         m_NFCTagListeners.push_back(adapter);
133
134         if (!m_initialized) {
135                 if (initialize() != NFC_ERROR_NONE) {
136                         m_NFCTagListeners.clear();
137                         ThrowMsg(PlatformException, "Could not initialize NFC.");
138                 }
139         } else {
140                 nfc_tag_h currentTag;
141                 if (nfc_manager_get_connected_tag(&currentTag) == NFC_ERROR_NONE)
142                         adapter->NFCTagHasDetected((void *)currentTag);
143         }
144
145         if (m_NFCTagListeners.size() > 1)
146                 return 0;
147
148         result = nfc_manager_set_tag_discovered_cb (TagDetectedCallback, this);
149
150         NFCUtil util;
151         if (result != NFC_ERROR_NONE) {
152                 m_NFCTagListeners.pop_back();
153                 util.throwNFCException(result, "failed to set callback of nfc_manager_set_tag_discovered_cb");
154         }
155
156         LogInfo("NFCDefaultAdapter::setTagListener : result << " << result);
157         return result;
158 }
159
160 int NFCDefaultAdapter::setPeerListener(NFCAdapter *adapter) {
161         LogDebug(" NFCDefaultAdapter::setPeerListener Entered");
162         int result = -1;
163
164         m_NFCTargetListeners.push_back(adapter);
165
166         if (!m_initialized) {
167                 if (initialize() != NFC_ERROR_NONE) {
168                         m_NFCTargetListeners.clear();
169                         ThrowMsg(PlatformException, "Could not initialize NFC.");
170                 }
171         } else {
172                 nfc_p2p_target_h currentTarget;
173                 if (nfc_manager_get_connected_target(&currentTarget) == NFC_ERROR_NONE)
174                         adapter->NFCTargetHasDetected((void *)currentTarget);
175         }
176
177         if (m_NFCTargetListeners.size() > 1)
178                 return 0;
179
180         result = nfc_manager_set_p2p_target_discovered_cb (TargetDetectedCallback, this);
181
182         NFCUtil Util;
183         if (result != NFC_ERROR_NONE) {
184                 m_NFCTargetListeners.pop_back();
185                 Util.throwNFCException(result, "failed to set callback of nfc_manager_set_p2p_target_discovered_cb");
186         }
187
188         LogInfo("NFCDefaultAdapter::setPeerListener : result << " << result);
189         return result;
190 }
191
192 void NFCDefaultAdapter::unsetTagListener(NFCAdapter * adapter) {
193         LogDebug(" NFCDefaultAdapter::unsetTagListener Entered");
194
195         if (!m_initialized) {
196                 if (initialize() != NFC_ERROR_NONE) {
197                         ThrowMsg(PlatformException, "Could not initialize NFC.");
198                 }
199         }
200
201         std::vector<NFCAdapter *>::iterator it;
202         for (it = m_NFCTagListeners.begin(); it != m_NFCTagListeners.end(); ++it) {
203                 if (*it == adapter) {
204                         m_NFCTagListeners.erase(it);
205                         LogDebug("emitter is removed. (" << m_NFCTagListeners.size() << ")");
206                         break;
207                 }
208         }
209
210         if (m_NFCTagListeners.empty())
211                 nfc_manager_unset_tag_discovered_cb ();
212 }
213
214 void NFCDefaultAdapter::unsetPeerListener(NFCAdapter * adapter) {
215         LogDebug(" NFCDefaultAdapter::unsetPeerListener Entered");
216
217         if (!m_initialized) {
218                 if (initialize() != NFC_ERROR_NONE) {
219                         ThrowMsg(PlatformException, "Could not initialize NFC.");
220                 }
221         }
222
223         std::vector<NFCAdapter *>::iterator it;
224         for (it = m_NFCTargetListeners.begin(); it != m_NFCTargetListeners.end(); ++it) {
225                 if (*it == adapter) {
226                         m_NFCTargetListeners.erase(it);
227                         LogDebug("emitter is removed. (" << m_NFCTargetListeners.size() << ")");
228                         break;
229                 }
230         }
231
232         if (m_NFCTargetListeners.empty())
233                 nfc_manager_unset_p2p_target_discovered_cb();
234
235 }
236
237 void NFCDefaultAdapter::NFCTagHasDetected(void *props)
238 {
239         LogDebug("NFCDefaultAdapter::NFCTagHasDetected Enter type");
240
241         std::vector<NFCAdapter *>::iterator it;
242         for (it = m_NFCTagListeners.begin(); it != m_NFCTagListeners.end(); ++it) {
243                 (*it)->NFCTagHasDetected(props);
244         }
245 }
246
247 void NFCDefaultAdapter::NFCTargetHasDetected(void *props)
248 {
249         std::vector<NFCAdapter *>::iterator it;
250         for (it = m_NFCTargetListeners.begin(); it != m_NFCTargetListeners.end(); ++it) {
251                 (*it)->NFCTargetHasDetected(props);
252         }
253 }
254
255 void NFCDefaultAdapter::getCurrentNFC() {
256         LogDebug("Enter");
257
258         if (!m_initialized) {
259                 LogError("No Initialized");
260                 return;
261         }
262
263         if (!m_NFCTagListeners.empty()) {
264                 nfc_tag_h currentTag;
265                 if (nfc_manager_get_connected_tag(&currentTag) == NFC_ERROR_NONE) {
266                         NFCTagHasDetected((void *)currentTag);
267                         return;
268                 }
269         }
270
271         if (!m_NFCTargetListeners.empty()) {
272                 nfc_p2p_target_h currentTarget;
273                 if (nfc_manager_get_connected_target(&currentTarget) == NFC_ERROR_NONE) {
274                         NFCTargetHasDetected((void *)currentTarget);
275                 }
276         }
277 }
278
279 int NFCDefaultAdapter::initialize() {
280         LogDebug("NFCDefaultAdapter::initialize Entered");
281         int result = -1;
282         //nfc_manager_deinitialize();
283         result = nfc_manager_initialize(NFCInitializeCompletedCallback, this);
284         if (result != NFC_ERROR_NONE) {
285                 LogError("Could not initialize NFC.");
286                 m_initialized = false;
287         } else {
288                 m_initialized = true;
289                 nfc_manager_set_tag_filter(NFC_TAG_FILTER_ALL_ENABLE);
290         }
291         return result;
292 }
293
294 void *NFCDefaultAdapter::getCachedMessage() {
295         LogDebug("Entered");
296         nfc_ndef_message_h messageHandle = NULL;
297         int result = nfc_manager_get_cached_message(&messageHandle);
298         if ((result == NFC_ERROR_INVALID_NDEF_MESSAGE) || (result == NFC_ERROR_NO_NDEF_MESSAGE)) {
299                 if (messageHandle)
300                         nfc_ndef_message_destroy(messageHandle);
301
302                 return NULL;
303         }
304
305         NFCUtil util;
306         if (result != NFC_ERROR_NONE) {
307                 if (messageHandle)
308                         nfc_ndef_message_destroy(messageHandle);
309
310                 util.throwNFCException(result, "Can't get cached message");
311         }
312         return (void *)(messageHandle);
313 }
314
315 bool NFCDefaultAdapter::getPowerState() {
316         return nfc_manager_is_activated();
317 }
318
319 void NFCDefaultAdapter::setPowered(const bool state, NFCAdapter * poweredAdapter) {
320         LogDebug("Enter");
321         try {
322                 if (m_poweredAdapter != NULL) {
323                         ThrowMsg(PlatformException, "Progressing Identical Operation");
324                         return;
325                 } else if (getPowerState() == state) {
326                         poweredAdapter->setPoweredManualAnswer(NFC_ERROR_NONE);
327                         return;
328                 }
329
330                 int result = NFC_ERROR_NONE;
331                 if (!m_initialized)
332                         result = initialize();
333
334                 if (result == NFC_ERROR_NONE) {
335                         m_poweredAdapter = poweredAdapter;
336                         result = nfc_manager_set_activation(state, NFCSetActivationCompletedCallback, NULL);
337                 }
338
339                 if (result != NFC_ERROR_NONE) {
340                         poweredAdapter->setPoweredManualAnswer(result);
341                         m_poweredAdapter = NULL;
342                 }
343         } catch (const WrtDeviceApis::Commons::Exception& ex) {
344                 LogError("Exception: " << ex.GetMessage());
345                 poweredAdapter->setPoweredManualAnswer(NFC_ERROR_OPERATION_FAILED);
346                 m_poweredAdapter = NULL;
347         }
348 }
349
350 void NFCDefaultAdapter::setPoweredManualAnswer(int error) {
351         if (m_poweredAdapter != NULL) {
352                 m_poweredAdapter->setPoweredManualAnswer(error);
353                 m_poweredAdapter = NULL;
354         }
355 }
356
357 EventNFCSEType NFCDefaultAdapter::getSEType() {
358         LogDebug("Enter");
359         nfc_se_type_e type = NFC_SE_TYPE_DISABLE;
360         if (nfc_manager_get_card_emulation_se_type(&type) == NFC_ERROR_NONE) {
361                 NFCUtil util;
362                 if (util.convertTonfcSEType(type) != NFC_SE_INVALID)
363                         return util.convertTonfcSEType(type);
364         }
365         ThrowMsg(PlatformException, "Wrong SE Type or operation to get SE Type is failed");
366 }
367
368 void NFCDefaultAdapter::setCardEmulation(const EventNFCSEType seType, NFCAdapter * adapter) {
369         LogDebug("Enter");
370         try {
371                 if (getSEType() == seType) {
372                         adapter->setCardEmulationManualAnswer(NFC_ERROR_NONE);
373                         seChanged();
374                         return;
375                 }
376
377                 nfc_se_type_e nfcSeType = NFC_SE_TYPE_DISABLE;
378                 if (seType == NFC_SE_NONE)
379                         nfcSeType = NFC_SE_TYPE_DISABLE;
380                 else if (seType == NFC_SE_ESE)
381                         nfcSeType = NFC_SE_TYPE_ESE;
382                 else if (seType == NFC_SE_UICC)
383                         nfcSeType = NFC_SE_TYPE_UICC;
384                 else
385                         ThrowMsg(PlatformException, "Wrong SE TYPE");
386
387                 int result = NFC_ERROR_NONE;
388                 if (!m_initialized)
389                         result = initialize();
390
391                 if (result == NFC_ERROR_NONE) {
392                         result = nfc_manager_set_card_emulation_se_type(nfcSeType, NFCSetCardEmulationCompletedCallback, (void *)adapter);
393                 }
394
395                 if (result != NFC_ERROR_NONE)
396                         adapter->setCardEmulationManualAnswer(result);
397         } catch (const WrtDeviceApis::Commons::Exception& ex) {
398                 LogError("Exception: " << ex.GetMessage());
399                 adapter->setCardEmulationManualAnswer(NFC_ERROR_OPERATION_FAILED);
400         }
401 }
402
403 void NFCDefaultAdapter::setCardEmulationManualAnswer(int error, void *adapter) {
404         if (adapter != NULL) {
405                 ((NFCAdapter *)adapter)->setCardEmulationManualAnswer(error);
406                 if (error == NFC_ERROR_NONE)
407                         seChanged();
408         }
409 }
410
411 void NFCDefaultAdapter::setCardEmulationChangeListener(NFCAdapter *adapter) {
412         LogDebug("Entered");
413         int result = -1;
414
415         m_NFCChangedSETypes.push_back(adapter);
416
417         if (!m_initialized) {
418                 if (initialize() != NFC_ERROR_NONE) {
419                         m_NFCChangedSETypes.clear();
420                         ThrowMsg(PlatformException, "Could not initialize NFC.");
421                 }
422         }
423         if (m_NFCChangedSETypes.size() > 1)
424                 return;
425
426         m_seType = getSEType();
427         result = nfc_manager_set_se_event_cb(NFCSetSEEventCallback, this);
428
429         NFCUtil util;
430         if (result != NFC_ERROR_NONE) {
431                 m_NFCTargetListeners.pop_back();
432                 util.throwNFCException(result, "failed to set callback of nfc_manager_set_p2p_target_discovered_cb");
433         }
434
435         LogInfo("NFCDefaultAdapter::setPeerListener : result << " << result);
436 }
437
438 void NFCDefaultAdapter::unsetCardEmulationChangeListener(NFCAdapter * adapter) {
439         LogDebug("Entered");
440
441         if (!m_initialized) {
442                 if (initialize() != NFC_ERROR_NONE) {
443                         ThrowMsg(PlatformException, "Could not initialize NFC.");
444                 }
445         }
446
447         std::vector<NFCAdapter *>::iterator it;
448         for (it = m_NFCChangedSETypes.begin(); it != m_NFCChangedSETypes.end(); ++it) {
449                 if (*it == adapter) {
450                         m_NFCChangedSETypes.erase(it);
451                         LogDebug("emitter is removed. (" << m_NFCChangedSETypes.size() << ")");
452                         break;
453                 }
454         }
455
456         if (m_NFCChangedSETypes.empty()) {
457                 nfc_manager_unset_se_event_cb();
458                 m_seType = NFC_SE_INVALID;
459         }
460 }
461
462 void NFCDefaultAdapter::seChanged() {
463         if (m_seType != NFC_SE_INVALID) {
464                 if (m_seType != getSEType()) {
465                         m_seType = getSEType();
466                         std::vector<NFCAdapter *>::iterator it;
467                         for (it = m_NFCChangedSETypes.begin(); it != m_NFCChangedSETypes.end(); ++it) {
468                                 (*it)->seChanged(m_seType);
469                         }
470                 }
471         }
472 }
473
474 }
475 }