/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once
#undef LOG_TAG
#define LOG_TAG "BrcmNfcJni"
#include <jni.h>
#include <pthread.h>
#include <sys/queue.h>
#include <semaphore.h>


/* Discovery modes -- keep in sync with NFCManager.DISCOVERY_MODE_* */
#define DISCOVERY_MODE_TAG_READER         0
#define DISCOVERY_MODE_NFCIP1             1
#define DISCOVERY_MODE_CARD_EMULATION     2
#define DISCOVERY_MODE_TABLE_SIZE         3

#define DISCOVERY_MODE_DISABLED           0
#define DISCOVERY_MODE_ENABLED            1

#define MODE_P2P_TARGET                   0
#define MODE_P2P_INITIATOR                1


/* Properties values */
#define PROPERTY_LLCP_LTO                 0
#define PROPERTY_LLCP_MIU                 1
#define PROPERTY_LLCP_WKS                 2
#define PROPERTY_LLCP_OPT                 3
#define PROPERTY_NFC_DISCOVERY_A          4
#define PROPERTY_NFC_DISCOVERY_B          5
#define PROPERTY_NFC_DISCOVERY_F          6
#define PROPERTY_NFC_DISCOVERY_15693      7
#define PROPERTY_NFC_DISCOVERY_NCFIP      8


/* Error codes */
#define ERROR_BUFFER_TOO_SMALL            -12
#define ERROR_INSUFFICIENT_RESOURCES      -9


/* Pre-defined tag type values. These must match the values in
 * Ndef.java in the framework.
 */
#define NDEF_UNKNOWN_TYPE                -1
#define NDEF_TYPE1_TAG                   1
#define NDEF_TYPE2_TAG                   2
#define NDEF_TYPE3_TAG                   3
#define NDEF_TYPE4_TAG                   4
#define NDEF_MIFARE_CLASSIC_TAG          101


/* Pre-defined card read/write state values. These must match the values in
 * Ndef.java in the framework.
 */
#define NDEF_MODE_READ_ONLY              1
#define NDEF_MODE_READ_WRITE             2
#define NDEF_MODE_UNKNOWN                3


/* Name strings for target types. These *must* match the values in TagTechnology.java */
#define TARGET_TYPE_UNKNOWN               -1
#define TARGET_TYPE_ISO14443_3A           1
#define TARGET_TYPE_ISO14443_3B           2
#define TARGET_TYPE_ISO14443_4            3
#define TARGET_TYPE_FELICA                4
#define TARGET_TYPE_ISO15693              5
#define TARGET_TYPE_NDEF                  6
#define TARGET_TYPE_NDEF_FORMATABLE       7
#define TARGET_TYPE_MIFARE_CLASSIC        8
#define TARGET_TYPE_MIFARE_UL             9
#define TARGET_TYPE_KOVIO_BARCODE         10


//define a few NXP error codes that NFC service expects;
//see external/libnfc-nxp/src/phLibNfcStatus.h;
//see external/libnfc-nxp/inc/phNfcStatus.h
#define NFCSTATUS_SUCCESS (0x0000)
#define NFCSTATUS_FAILED (0x00FF)

struct nfc_jni_native_data
{
   /* Thread handle */
   pthread_t thread;
   int running;

   /* Our VM */
   JavaVM *vm;
   int env_version;

   /* Reference to the NFCManager instance */
   jobject manager;

   /* Cached objects */
   jobject cached_NfcTag;
   jobject cached_P2pDevice;

   /* Secure Element selected */
   int seId;

   /* LLCP params */
   int lto;
   int miu;
   int wks;
   int opt;

   int tech_mask;
   int discovery_duration;

   /* Tag detected */
   jobject tag;

   int tHandle;
   int tProtocols[16];
   int handles[16];
};


class ScopedAttach
{
public:
    ScopedAttach(JavaVM* vm, JNIEnv** env) : vm_(vm)
    {
        vm_->AttachCurrentThread(env, NULL);
    }

    ~ScopedAttach()
    {
        vm_->DetachCurrentThread();
    }

private:
        JavaVM* vm_;
};


extern "C"
{
    jint JNI_OnLoad(JavaVM *jvm, void *reserved);
}


namespace android
{
    int nfc_jni_cache_object (JNIEnv *e, const char *clsname, jobject *cached_obj);
    int nfc_jni_cache_object_local (JNIEnv *e, const char *className, jobject *cachedObj);
    int nfc_jni_get_nfc_socket_handle (JNIEnv *e, jobject o);
    struct nfc_jni_native_data* nfc_jni_get_nat (JNIEnv *e, jobject o);
    int register_com_android_nfc_NativeNfcManager (JNIEnv *e);
    int register_com_android_nfc_NativeNfcTag (JNIEnv *e);
    int register_com_android_nfc_NativeP2pDevice (JNIEnv *e);
    int register_com_android_nfc_NativeLlcpConnectionlessSocket (JNIEnv *e);
    int register_com_android_nfc_NativeLlcpServiceSocket (JNIEnv *e);
    int register_com_android_nfc_NativeLlcpSocket (JNIEnv *e);
} // namespace android
