1/*
2 * Copyright (C) 2010 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#ifndef __COM_ANDROID_NFC_JNI_H__
18#define __COM_ANDROID_NFC_JNI_H__
19
20#define LOG_TAG "NFC JNI"
21
22#include <JNIHelp.h>
23#include <jni.h>
24
25#include <pthread.h>
26#include <sys/queue.h>
27
28extern "C" {
29#include <phNfcStatus.h>
30#include <phNfcTypes.h>
31#include <phNfcIoctlCode.h>
32#include <phLibNfc.h>
33#include <phDal4Nfc_messageQueueLib.h>
34#include <phFriNfc_NdefMap.h>
35#include <cutils/log.h>
36#include <com_android_nfc_list.h>
37#include <semaphore.h>
38
39}
40#include <cutils/properties.h> // for property_get
41
42
43/* Discovery modes -- keep in sync with NFCManager.DISCOVERY_MODE_* */
44#define DISCOVERY_MODE_TAG_READER         0
45#define DISCOVERY_MODE_NFCIP1             1
46#define DISCOVERY_MODE_CARD_EMULATION     2
47
48#define DISCOVERY_MODE_TABLE_SIZE         3
49
50#define DISCOVERY_MODE_DISABLED           0
51#define DISCOVERY_MODE_ENABLED            1
52
53#define MODE_P2P_TARGET                   0
54#define MODE_P2P_INITIATOR                1
55
56/* Properties values */
57#define PROPERTY_LLCP_LTO                 0
58#define PROPERTY_LLCP_MIU                 1
59#define PROPERTY_LLCP_WKS                 2
60#define PROPERTY_LLCP_OPT                 3
61#define PROPERTY_NFC_DISCOVERY_A          4
62#define PROPERTY_NFC_DISCOVERY_B          5
63#define PROPERTY_NFC_DISCOVERY_F          6
64#define PROPERTY_NFC_DISCOVERY_15693      7
65#define PROPERTY_NFC_DISCOVERY_NCFIP      8
66
67/* Error codes */
68#define ERROR_BUFFER_TOO_SMALL            -12
69#define ERROR_INSUFFICIENT_RESOURCES      -9
70
71/* Pre-defined card read/write state values. These must match the values in
72 * Ndef.java in the framework.
73 */
74
75#define NDEF_UNKNOWN_TYPE                -1
76#define NDEF_TYPE1_TAG                   1
77#define NDEF_TYPE2_TAG                   2
78#define NDEF_TYPE3_TAG                   3
79#define NDEF_TYPE4_TAG                   4
80#define NDEF_MIFARE_CLASSIC_TAG          101
81#define NDEF_ICODE_SLI_TAG               102
82
83/* Pre-defined tag type values. These must match the values in
84 * Ndef.java in the framework.
85 */
86
87#define NDEF_MODE_READ_ONLY              1
88#define NDEF_MODE_READ_WRITE             2
89#define NDEF_MODE_UNKNOWN                3
90
91
92/* Name strings for target types. These *must* match the values in TagTechnology.java */
93#define TARGET_TYPE_UNKNOWN               -1
94#define TARGET_TYPE_ISO14443_3A           1
95#define TARGET_TYPE_ISO14443_3B           2
96#define TARGET_TYPE_ISO14443_4            3
97#define TARGET_TYPE_FELICA                4
98#define TARGET_TYPE_ISO15693              5
99#define TARGET_TYPE_NDEF                  6
100#define TARGET_TYPE_NDEF_FORMATABLE       7
101#define TARGET_TYPE_MIFARE_CLASSIC        8
102#define TARGET_TYPE_MIFARE_UL             9
103
104#define SMX_SECURE_ELEMENT_ID   11259375
105
106/* Maximum byte length of an AID. */
107#define AID_MAXLEN                        16
108
109/* Utility macros for logging */
110#define GET_LEVEL(status) ((status)==NFCSTATUS_SUCCESS)?ANDROID_LOG_DEBUG:ANDROID_LOG_WARN
111
112#if 0
113  #define LOG_CALLBACK(funcName, status)  LOG_PRI(GET_LEVEL(status), LOG_TAG, "Callback: %s() - status=0x%04x[%s]", funcName, status, nfc_jni_get_status_name(status));
114  #define TRACE(...) LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)
115#else
116  #define LOG_CALLBACK(...)
117  #define TRACE(...)
118#endif
119
120struct nfc_jni_native_data
121{
122   /* Thread handle */
123   pthread_t thread;
124   int running;
125
126   /* Our VM */
127   JavaVM *vm;
128   int env_version;
129
130   /* Reference to the NFCManager instance */
131   jobject manager;
132
133   /* Cached objects */
134   jobject cached_NfcTag;
135   jobject cached_P2pDevice;
136
137   /* Target discovery configuration */
138   int discovery_modes_state[DISCOVERY_MODE_TABLE_SIZE];
139   phLibNfc_sADD_Cfg_t discovery_cfg;
140   phLibNfc_Registry_Info_t registry_info;
141
142   /* Secure Element selected */
143   int seId;
144
145   /* LLCP params */
146   int lto;
147   int miu;
148   int wks;
149   int opt;
150
151   /* Tag detected */
152   jobject tag;
153
154   /* Lib Status */
155   NFCSTATUS status;
156
157};
158
159typedef struct nfc_jni_native_monitor
160{
161   /* Mutex protecting native library against reentrance */
162   pthread_mutex_t reentrance_mutex;
163
164   /* Mutex protecting native library against concurrency */
165   pthread_mutex_t concurrency_mutex;
166
167   /* List used to track pending semaphores waiting for callback */
168   struct listHead sem_list;
169
170   /* List used to track incoming socket requests (and associated sync variables) */
171   LIST_HEAD(, nfc_jni_listen_data) incoming_socket_head;
172   pthread_mutex_t incoming_socket_mutex;
173   pthread_cond_t  incoming_socket_cond;
174
175} nfc_jni_native_monitor_t;
176
177typedef struct nfc_jni_callback_data
178{
179   /* Semaphore used to wait for callback */
180   sem_t sem;
181
182   /* Used to store the status sent by the callback */
183   NFCSTATUS status;
184
185   /* Used to provide a local context to the callback */
186   void* pContext;
187
188} nfc_jni_callback_data_t;
189
190typedef struct nfc_jni_listen_data
191{
192   /* LLCP server socket receiving the connection request */
193   phLibNfc_Handle pServerSocket;
194
195   /* LLCP socket created from the connection request */
196   phLibNfc_Handle pIncomingSocket;
197
198   /* List entries */
199   LIST_ENTRY(nfc_jni_listen_data) entries;
200
201} nfc_jni_listen_data_t;
202
203/* TODO: treat errors and add traces */
204#define REENTRANCE_LOCK()        pthread_mutex_lock(&nfc_jni_get_monitor()->reentrance_mutex)
205#define REENTRANCE_UNLOCK()      pthread_mutex_unlock(&nfc_jni_get_monitor()->reentrance_mutex)
206#define CONCURRENCY_LOCK()       pthread_mutex_lock(&nfc_jni_get_monitor()->concurrency_mutex)
207#define CONCURRENCY_UNLOCK()     pthread_mutex_unlock(&nfc_jni_get_monitor()->concurrency_mutex)
208
209namespace android {
210
211extern JavaVM *vm;
212
213JNIEnv *nfc_get_env();
214
215bool nfc_cb_data_init(nfc_jni_callback_data* pCallbackData, void* pContext);
216void nfc_cb_data_deinit(nfc_jni_callback_data* pCallbackData);
217void nfc_cb_data_releaseAll();
218
219const char* nfc_jni_get_status_name(NFCSTATUS status);
220int nfc_jni_cache_object(JNIEnv *e, const char *clsname,
221   jobject *cached_obj);
222struct nfc_jni_native_data* nfc_jni_get_nat(JNIEnv *e, jobject o);
223struct nfc_jni_native_data* nfc_jni_get_nat_ext(JNIEnv *e);
224nfc_jni_native_monitor_t* nfc_jni_init_monitor(void);
225nfc_jni_native_monitor_t* nfc_jni_get_monitor(void);
226
227int get_technology_type(phNfc_eRemDevType_t type, uint8_t sak);
228void nfc_jni_get_technology_tree(JNIEnv* e, phLibNfc_RemoteDevList_t* devList,
229                        uint8_t count, jintArray* techList, jintArray* handleList,
230                        jintArray* typeList);
231
232/* P2P */
233phLibNfc_Handle nfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o);
234jshort nfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o);
235
236/* TAG */
237jint nfc_jni_get_connected_technology(JNIEnv *e, jobject o);
238jint nfc_jni_get_connected_technology_libnfc_type(JNIEnv *e, jobject o);
239phLibNfc_Handle nfc_jni_get_connected_handle(JNIEnv *e, jobject o);
240jintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o);
241
242/* LLCP */
243phLibNfc_Handle nfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o);
244
245int register_com_android_nfc_NativeNfcManager(JNIEnv *e);
246int register_com_android_nfc_NativeNfcTag(JNIEnv *e);
247int register_com_android_nfc_NativeP2pDevice(JNIEnv *e);
248int register_com_android_nfc_NativeLlcpConnectionlessSocket(JNIEnv *e);
249int register_com_android_nfc_NativeLlcpServiceSocket(JNIEnv *e);
250int register_com_android_nfc_NativeLlcpSocket(JNIEnv *e);
251int register_com_android_nfc_NativeNfcSecureElement(JNIEnv *e);
252
253} // namespace android
254
255#endif
256