1 /* 2 * Copyright (C) 2012 The Android Open Source Project 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 /***************************************************************************** 18 ** 19 ** Description: Implement operations that provide compatibility with NXP 20 ** PN544 controller. Specifically facilitate peer-to-peer 21 ** operations with PN544 controller. 22 ** 23 *****************************************************************************/ 24 #include "Pn544Interop.h" 25 #include "IntervalTimer.h" 26 #include "Mutex.h" 27 #include "NfcTag.h" 28 29 #include <android-base/stringprintf.h> 30 #include <base/logging.h> 31 32 using android::base::StringPrintf; 33 34 extern bool nfc_debug_enabled; 35 36 namespace android { 37 extern void startStopPolling(bool isStartPolling); 38 } 39 40 /***************************************************************************** 41 ** 42 ** private variables and functions 43 ** 44 *****************************************************************************/ 45 46 static const int gIntervalTime = 47 1000; // millisecond between the check to restore polling 48 static IntervalTimer gTimer; 49 static Mutex gMutex; 50 static void pn544InteropStartPolling( 51 union sigval); // callback function for interval timer 52 static bool gIsBusy = false; // is timer busy? 53 static bool gAbortNow = false; // stop timer during next callback 54 55 /******************************************************************************* 56 ** 57 ** Function: pn544InteropStopPolling 58 ** 59 ** Description: Stop polling to let NXP PN544 controller poll. 60 ** PN544 should activate in P2P mode. 61 ** 62 ** Returns: None 63 ** 64 *******************************************************************************/ 65 void pn544InteropStopPolling() { 66 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); 67 gMutex.lock(); 68 gTimer.kill(); 69 android::startStopPolling(false); 70 gIsBusy = true; 71 gAbortNow = false; 72 gTimer.set(gIntervalTime, 73 pn544InteropStartPolling); // after some time, start polling again 74 gMutex.unlock(); 75 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); 76 } 77 78 /******************************************************************************* 79 ** 80 ** Function: pn544InteropStartPolling 81 ** 82 ** Description: Start polling when activation state is idle. 83 ** sigval: Unused. 84 ** 85 ** Returns: None 86 ** 87 *******************************************************************************/ 88 void pn544InteropStartPolling(union sigval) { 89 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", __func__); 90 gMutex.lock(); 91 NfcTag::ActivationState state = NfcTag::getInstance().getActivationState(); 92 93 if (gAbortNow) { 94 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: abort now", __func__); 95 gIsBusy = false; 96 goto TheEnd; 97 } 98 99 if (state == NfcTag::Idle) { 100 DLOG_IF(INFO, nfc_debug_enabled) 101 << StringPrintf("%s: start polling", __func__); 102 android::startStopPolling(true); 103 gIsBusy = false; 104 } else { 105 DLOG_IF(INFO, nfc_debug_enabled) 106 << StringPrintf("%s: try again later", __func__); 107 gTimer.set( 108 gIntervalTime, 109 pn544InteropStartPolling); // after some time, start polling again 110 } 111 112 TheEnd: 113 gMutex.unlock(); 114 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: exit", __func__); 115 } 116 117 /******************************************************************************* 118 ** 119 ** Function: pn544InteropIsBusy 120 ** 121 ** Description: Is the code performing operations? 122 ** 123 ** Returns: True if the code is busy. 124 ** 125 *******************************************************************************/ 126 bool pn544InteropIsBusy() { 127 bool isBusy = false; 128 gMutex.lock(); 129 isBusy = gIsBusy; 130 gMutex.unlock(); 131 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: %u", __func__, isBusy); 132 return isBusy; 133 } 134 135 /******************************************************************************* 136 ** 137 ** Function: pn544InteropAbortNow 138 ** 139 ** Description: Request to abort all operations. 140 ** 141 ** Returns: None. 142 ** 143 *******************************************************************************/ 144 void pn544InteropAbortNow() { 145 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", __func__); 146 gMutex.lock(); 147 gAbortNow = true; 148 gMutex.unlock(); 149 } 150