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