Home | History | Annotate | Download | only in jni
      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