[IOT-1089] Change Android build system to accomodate both Android and Generic Java...
[contrib/iotivity.git] / java / jni / JniCaInterface.c
1 /*
2 * //******************************************************************
3 * //
4 * // Copyright 2015 Intel Corporation.
5 * //
6 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 * //
8 * // Licensed under the Apache License, Version 2.0 (the "License");
9 * // you may not use this file except in compliance with the License.
10 * // You may obtain a copy of the License at
11 * //
12 * //      http://www.apache.org/licenses/LICENSE-2.0
13 * //
14 * // Unless required by applicable law or agreed to in writing, software
15 * // distributed under the License is distributed on an "AS IS" BASIS,
16 * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * // See the License for the specific language governing permissions and
18 * // limitations under the License.
19 * //
20 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 */
22
23 #include <jni.h>
24 #include "logger.h"
25 #include <stdio.h>
26 #include "cainterface.h"
27 #include "JniCaInterface.h"
28 #include "cautilinterface.h"
29 #include "cacommon.h"
30
31 #define  LOG_TAG   "JNI_CA_INTERFACE"
32 #define  LOGI(...) OIC_LOG_V(OC_LOG_INFO, LOG_TAG, __VA_ARGS__)
33 #define  LOGE(...) OIC_LOG_V(OC_LOG_ERROR, LOG_TAG, __VA_ARGS__)
34
35 static jobject g_foundDeviceListenerObject = NULL;
36 static jobject g_listenerObject = NULL;
37 static JavaVM *g_jvm = NULL;
38
39 JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
40 {
41     LOGI("CaInterface_initialize");
42     g_jvm = jvm;
43     CANativeJNISetJavaVM(jvm);
44
45     return JNI_VERSION_1_6;
46 }
47
48 void JNI_OnUnload(JavaVM *jvm, void *reserved)
49 {
50     return;
51 }
52
53 #ifdef __ANDROID__
54 JNIEXPORT void JNICALL
55 Java_org_iotivity_ca_CaInterface_initialize
56 (JNIEnv *env, jclass clazz, jobject activity, jobject context)
57 {
58     LOGI("CaInterface_initialize");
59
60     CANativeSetActivity(env, activity);
61     CANativeJNISetContext(env, context);
62 }
63 #else
64 JNIEXPORT void JNICALL
65 Java_org_iotivity_ca_CaInterface_initialize
66 (JNIEnv *env, jclass clazz)
67 {
68     LOGI("CaInterface_initialize");
69 }
70 #endif
71
72 void CAManagerConnectionStateChangedCB(CATransportAdapter_t adapter,
73                                        const char *remote_address,
74                                        bool connected)
75 {
76     LOGI("Callback - CAManagerConnectionStateChangedCB : type(%d), address(%s), connected(%d)",
77          adapter, remote_address, connected);
78
79     if (!g_listenerObject)
80     {
81         LOGE("g_listener is NULL, cannot have callback");
82         return;
83     }
84
85     bool isAttached = false;
86     JNIEnv* env;
87     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
88     if (JNI_OK != res)
89     {
90         LOGI("AttachCurrentThread will be called for JNIEnv pointer");
91         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
92
93         if (JNI_OK != res)
94         {
95             LOGE("AttachCurrentThread has failed");
96             return;
97         }
98         isAttached = true;
99     }
100
101     jclass jni_cls_listener = (*env)->GetObjectClass(env, g_listenerObject);
102     if (!jni_cls_listener)
103     {
104         LOGE("could not get jni_cls_listener");
105         goto exit_error;
106     }
107
108     jmethodID jni_mid_listener = (*env)->GetMethodID(env, jni_cls_listener,
109                                                      "onConnectionStateChanged",
110                                                      "(Lorg/iotivity/base/OcConnectivityType;"
111                                                      "Ljava/lang/String;Z)V");
112     if (!jni_mid_listener)
113     {
114         LOGE("could not get Method ID");
115         goto exit_error;
116     }
117
118     jstring jni_address = (*env)->NewStringUTF(env, remote_address);
119     if (!jni_address)
120     {
121         LOGE("jni_address is null");
122         goto exit_error;
123     }
124
125     jclass jni_cls_enum = (*env)->FindClass(env, "org/iotivity/base/OcConnectivityType");
126     if (!jni_cls_enum)
127     {
128         LOGE("could not get jni_cls_enum");
129         goto exit_error;
130     }
131
132     jmethodID jni_mid_enum = (*env)->GetStaticMethodID(env, jni_cls_enum, "getInstance",
133                                                        "(I)Lorg/iotivity/base/OcConnectivityType;");
134     if (!jni_mid_enum)
135     {
136         LOGE("could not get Method ID (getInstance)");
137         goto exit_error;
138     }
139
140     jobject jni_adaptertype = (*env)->CallStaticObjectMethod(env, jni_cls_enum,
141                                                              jni_mid_enum, adapter);
142     (*env)->CallVoidMethod(env, g_listenerObject, jni_mid_listener,
143                            jni_adaptertype, jni_address,
144                            (jboolean)connected);
145
146 exit_error:
147     if (isAttached)
148     {
149         (*g_jvm)->DetachCurrentThread(g_jvm);
150     }
151
152     LOGI("OUT - CAManagerConnectionStateChangedCB");
153 }
154
155 void CAManagerAdapterStateChangedCB(CATransportAdapter_t adapter, bool enabled)
156 {
157     LOGI("Callback - CAManagerAdapterStateChangedCB : type(%d), enabled(%d)",
158          adapter, enabled);
159
160     if (!g_listenerObject)
161     {
162         LOGE("g_listener is NULL, cannot have callback");
163         return;
164     }
165
166     bool isAttached = false;
167     JNIEnv* env;
168     jint res = (*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6);
169     if (JNI_OK != res)
170     {
171         LOGI("AttachCurrentThread will be called for JNIEnv pointer");
172         res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
173
174         if (JNI_OK != res)
175         {
176             LOGE("AttachCurrentThread has failed");
177             return;
178         }
179         isAttached = true;
180     }
181
182     jclass jni_cls_listener = (*env)->GetObjectClass(env, g_listenerObject);
183     if (!jni_cls_listener)
184     {
185         LOGE("could not get jni_cls_listener");
186         goto exit_error;
187     }
188
189     jmethodID jni_mid_listener = (*env)->GetMethodID(env, jni_cls_listener,
190                                                      "onAdapterStateChanged",
191                                                      "(Lorg/iotivity/base/OcConnectivityType;Z)V");
192     if (!jni_mid_listener)
193     {
194         LOGE("could not get Method ID");
195         goto exit_error;
196     }
197
198     jclass jni_cls_enum = (*env)->FindClass(env, "org/iotivity/base/OcConnectivityType");
199     if (!jni_cls_enum)
200     {
201         LOGE("could not get jni_cls_enum");
202         goto exit_error;
203     }
204
205     jmethodID jni_mid_enum = (*env)->GetStaticMethodID(env, jni_cls_enum, "getInstance",
206                                                        "(I)Lorg/iotivity/base/OcConnectivityType;");
207     if (!jni_mid_enum)
208     {
209         LOGE("could not get Method ID (getInstance)");
210         goto exit_error;
211     }
212
213     jobject jni_adaptertype = (*env)->CallStaticObjectMethod(env, jni_cls_enum,
214                                                              jni_mid_enum, adapter);
215
216     (*env)->CallVoidMethod(env, g_listenerObject, jni_mid_listener,
217                            jni_adaptertype, (jboolean)enabled);
218
219 exit_error:
220     if (isAttached)
221     {
222         (*g_jvm)->DetachCurrentThread(g_jvm);
223     }
224     LOGI("OUT -  CAManagerAdapterStateChangedCB");
225 }
226
227 #ifdef __ANDROID__
228 JNIEXPORT void JNICALL
229 Java_org_iotivity_ca_CaInterface_caManagerInitialize(JNIEnv *env, jclass clazz,
230                                                      jobject context, jobject listener)
231 {
232     LOGI("CaManagere_initialize");
233
234     CAUtilClientInitialize(env, g_jvm, context);
235
236     g_listenerObject = (*env)->NewGlobalRef(env, listener);
237
238     CARegisterNetworkMonitorHandler(CAManagerAdapterStateChangedCB,
239                                     CAManagerConnectionStateChangedCB);
240 }
241 #else
242 JNIEXPORT void JNICALL
243 Java_org_iotivity_ca_CaInterface_caManagerInitialize(JNIEnv *env, jclass clazz,
244                                                      jobject listener)
245 {
246     LOGI("CaManagere_initialize");
247
248     g_listenerObject = (*env)->NewGlobalRef(env, listener);
249
250     CARegisterNetworkMonitorHandler(CAManagerAdapterStateChangedCB,
251                                     CAManagerConnectionStateChangedCB);
252 }
253 #endif
254
255 JNIEXPORT void JNICALL
256 Java_org_iotivity_ca_CaInterface_caManagerTerminate(JNIEnv *env, jclass clazz)
257 {
258     LOGI("CaManager_terminate");
259
260     CAUtilClientTerminate(env);
261
262     if (g_listenerObject)
263     {
264         (*env)->DeleteGlobalRef(env, g_listenerObject);
265         g_listenerObject = NULL;
266     }
267 }
268
269 JNIEXPORT void JNICALL
270 Java_org_iotivity_ca_CaInterface_caManagerSetAutoConnectionDeviceInfo(JNIEnv *env,
271                                                                       jclass clazz,
272                                                                       jstring jaddress)
273 {
274     LOGI("CaManager_setAutoConnectionDeviceInfo");
275
276     const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
277     if (!address)
278     {
279         LOGE("address is null");
280         return;
281     }
282
283     CASetAutoConnectionDeviceInfo(address);
284
285     (*env)->ReleaseStringUTFChars(env, jaddress, address);
286 }
287
288 JNIEXPORT void JNICALL
289 Java_org_iotivity_ca_CaInterface_caManagerUnsetAutoConnectionDeviceInfo(JNIEnv *env,
290                                                                         jclass clazz,
291                                                                         jstring jaddress)
292 {
293     LOGI("CaManager_unsetAutoConnectionDeviceInfo");
294
295     const char* address = (*env)->GetStringUTFChars(env, jaddress, NULL);
296     if (!address)
297     {
298         LOGE("address is null");
299         return;
300     }
301
302     CAUnsetAutoConnectionDeviceInfo(address);
303
304     (*env)->ReleaseStringUTFChars(env, jaddress, address);
305 }
306
307 #ifdef __ANDROID__
308 JNIEXPORT void JNICALL
309 Java_org_iotivity_ca_CaInterface_caBtPairingInitialize(JNIEnv *env, jclass clazz,
310                                                        jobject context, jobject listener)
311 {
312     LOGI("caBtPairingInitialize");
313     (void)clazz;
314
315     CAUtilClientInitialize(env, g_jvm, context);
316
317     g_foundDeviceListenerObject = (*env)->NewGlobalRef(env, listener);
318     CAUtilSetFoundDeviceListener(g_foundDeviceListenerObject);
319 }
320 #else
321 JNIEXPORT void JNICALL
322 Java_org_iotivity_ca_CaInterface_caBtPairingInitialize(JNIEnv *env, jclass clazz,
323                                                        jobject listener)
324 {
325     LOGI("caBtPairingInitialize");
326     (void)clazz;
327
328     CAUtilClientInitialize(env, g_jvm);
329
330     g_foundDeviceListenerObject = (*env)->NewGlobalRef(env, listener);
331     CAUtilSetFoundDeviceListener(g_foundDeviceListenerObject);
332 }
333 #endif
334
335 JNIEXPORT void JNICALL
336 Java_org_iotivity_ca_CaInterface_caBtPairingTerminate(JNIEnv *env, jclass clazz)
337 {
338     LOGI("caBtPairingTerminate");
339     (void)clazz;
340
341     if (g_foundDeviceListenerObject)
342     {
343         (*env)->DeleteGlobalRef(env, g_foundDeviceListenerObject);
344     }
345 }
346
347 JNIEXPORT void JNICALL
348 Java_org_iotivity_ca_CaInterface_caBtPairingStartScan(JNIEnv *env, jclass clazz)
349 {
350     LOGI("caBtPairingStartScan");
351     (void)clazz;
352     CAUtilStartScan(env);
353 }
354
355 JNIEXPORT void JNICALL
356 Java_org_iotivity_ca_CaInterface_caBtPairingStopScan(JNIEnv *env, jclass clazz)
357 {
358     LOGI("caBtPairingStopScan");
359     (void)clazz;
360     CAUtilStopScan(env);
361 }
362
363 JNIEXPORT void JNICALL
364 Java_org_iotivity_ca_CaInterface_caBtPairingCreateBond(JNIEnv *env, jclass clazz, jobject device)
365 {
366     LOGI("caBtPairingCreateBond");
367     (void)clazz;
368     CAUtilCreateBond(env, device);
369 }