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 
30 extern "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 
133 struct 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 
176 typedef 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 
194 typedef 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 
207 typedef 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 
226 namespace android {
227 
228 extern JavaVM *vm;
229 
230 JNIEnv *nfc_get_env();
231 
232 bool nfc_cb_data_init(nfc_jni_callback_data* pCallbackData, void* pContext);
233 void nfc_cb_data_deinit(nfc_jni_callback_data* pCallbackData);
234 void nfc_cb_data_releaseAll();
235 
236 const char* nfc_jni_get_status_name(NFCSTATUS status);
237 int nfc_jni_cache_object(JNIEnv *e, const char *clsname,
238    jobject *cached_obj);
239 struct nfc_jni_native_data* nfc_jni_get_nat(JNIEnv *e, jobject o);
240 struct nfc_jni_native_data* nfc_jni_get_nat_ext(JNIEnv *e);
241 nfc_jni_native_monitor_t* nfc_jni_init_monitor(void);
242 nfc_jni_native_monitor_t* nfc_jni_get_monitor(void);
243 
244 int get_technology_type(phNfc_eRemDevType_t type, uint8_t sak);
245 void 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 */
251 phLibNfc_Handle nfc_jni_get_p2p_device_handle(JNIEnv *e, jobject o);
252 jshort nfc_jni_get_p2p_device_mode(JNIEnv *e, jobject o);
253 
254 /* TAG */
255 jint nfc_jni_get_connected_technology(JNIEnv *e, jobject o);
256 jint nfc_jni_get_connected_technology_libnfc_type(JNIEnv *e, jobject o);
257 phLibNfc_Handle nfc_jni_get_connected_handle(JNIEnv *e, jobject o);
258 jintArray nfc_jni_get_nfc_tag_type(JNIEnv *e, jobject o);
259 
260 /* LLCP */
261 phLibNfc_Handle nfc_jni_get_nfc_socket_handle(JNIEnv *e, jobject o);
262 
263 int register_com_android_nfc_NativeNfcManager(JNIEnv *e);
264 int register_com_android_nfc_NativeNfcTag(JNIEnv *e);
265 int register_com_android_nfc_NativeP2pDevice(JNIEnv *e);
266 int register_com_android_nfc_NativeLlcpConnectionlessSocket(JNIEnv *e);
267 int register_com_android_nfc_NativeLlcpServiceSocket(JNIEnv *e);
268 int register_com_android_nfc_NativeLlcpSocket(JNIEnv *e);
269 
270 } // namespace android
271 
272 #endif
273