Merge branch 'upstream' into tizen
[platform/upstream/iotivity.git] / resource / csdk / connectivity / util / src / btpairing / android / cabtpairing.c
1 /* ****************************************************************
2  *
3  * Copyright 2016 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************/
20
21 #include "cabtpairinginterface.h"
22 #include "cabtpairing.h"
23 #include "cacommon.h"
24 #include "logger.h"
25 #include <jni.h>
26
27 #define  TAG   "OIC_CA_BT_PAIRING"
28
29 /**
30  * pointer to store JavaVM
31  */
32 static JavaVM *g_jvm = NULL;
33
34 /**
35  * pointer to store context for android callback interface
36  */
37 static jobject g_context = NULL;
38 static jobject g_listener = NULL;
39
40 static const char CLASSPATH_CONTEXT[] = "android/content/Context";
41 static const char METHODID_CONTEXTNONPARAM[] = "()Landroid/content/Context;";
42 static const char CLASSPATH_BT_PAIRING_INTERFACE[] = "org/iotivity/ca/CaBtPairingInterface";
43 static const char CLASSPATH_BT_ADAPTER[] = "android/bluetooth/BluetoothAdapter";
44 static const char METHODID_OBJECTNONPARAM[] = "()Landroid/bluetooth/BluetoothAdapter;";
45 static const char CLASSPATH_BT_DEVICE[] = "android/bluetooth/BluetoothDevice";
46
47 static void CABTPaitingCreateJNIInterfaceObject(jobject context)
48 {
49     JNIEnv* env;
50     OIC_LOG(INFO, TAG, "OICEDRCreateJNIInterfaceObject");
51
52     if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
53     {
54         OIC_LOG(ERROR, TAG, "Could not get JNIEnv pointer");
55         return;
56     }
57
58     //getApplicationContext
59     jclass contextClass = (*env)->FindClass(env, CLASSPATH_CONTEXT);
60     if (!contextClass)
61     {
62         OIC_LOG(ERROR, TAG, "Could not get context object class");
63         return;
64     }
65
66     jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
67                                                                 "getApplicationContext",
68                                                                 METHODID_CONTEXTNONPARAM);
69     if (!getApplicationContextMethod)
70     {
71         OIC_LOG(ERROR, TAG, "Could not get getApplicationContext method");
72         return;
73     }
74
75     //Create EDRJniInterface instance
76     jclass EDRJniInterface = (*env)->FindClass(env, CLASSPATH_BT_PAIRING_INTERFACE);
77     if (!EDRJniInterface)
78     {
79         OIC_LOG(ERROR, TAG, "Could not get CaEdrInterface class");
80         return;
81     }
82
83     jmethodID EDRInterfaceConstructorMethod = (*env)->GetMethodID(env, EDRJniInterface, "<init>",
84                                                                   "(Landroid/content/Context;)V");
85     if (!EDRInterfaceConstructorMethod)
86     {
87         OIC_LOG(ERROR, TAG, "Could not get CaEdrInterface constructor method");
88         return;
89     }
90
91     (*env)->NewObject(env, EDRJniInterface, EDRInterfaceConstructorMethod, context);
92     OIC_LOG(INFO, TAG, "New Object has been created successfully");
93 }
94
95 CAResult_t CABTPairingInitialize(JNIEnv *env, JavaVM *jvm, jobject context)
96 {
97     OIC_LOG(INFO, TAG, "CABTPairingInitialize");
98
99     if (!context)
100     {
101         OIC_LOG(ERROR, TAG, "context is null");
102         return CA_STATUS_FAILED;
103     }
104
105     g_jvm = jvm;
106     g_context = (*env)->NewGlobalRef(env, context);
107
108     if (g_context)
109     {
110         /* create java interface instance*/
111         CABTPaitingCreateJNIInterfaceObject(g_context);
112     }
113     return CA_STATUS_OK;
114 }
115
116 void CABTPairingSetFoundDeviceListener(jobject listener)
117 {
118     g_listener = listener;
119 }
120
121 CAResult_t CABTPairingStartScan(JNIEnv *env)
122 {
123     OIC_LOG(INFO, TAG, "CABTPairingStartScan");
124     if (!env)
125     {
126         OIC_LOG(ERROR, TAG, "parameter is null");
127         return CA_STATUS_FAILED;
128     }
129
130     CABTPairingStopScan(env);
131
132     // get default bt adapter class
133     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
134     if (!jni_cid_BTAdapter)
135     {
136         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
137         return CA_STATUS_FAILED;
138     }
139
140     // get remote bt adapter method ID
141     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
142                                                                     "getDefaultAdapter",
143                                                                     METHODID_OBJECTNONPARAM);
144     if (!jni_mid_getDefaultAdapter)
145     {
146         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
147         return CA_STATUS_FAILED;
148     }
149
150     // get startDiscovery() method ID
151     jmethodID jni_mid_startDiscovery = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startDiscovery",
152                                                            "()Z");
153     if (!jni_mid_startDiscovery)
154     {
155         OIC_LOG(ERROR, TAG, "jni_mid_startDiscovery is null");
156         return CA_STATUS_FAILED;
157     }
158
159     // get bluetooth adapter object
160     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
161                                                                jni_mid_getDefaultAdapter);
162     if (!jni_obj_BTAdapter)
163     {
164         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
165         return CA_STATUS_FAILED;
166     }
167
168     // call startDiscovery() method
169     jboolean jni_obj_startDiscovery = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
170                                                                 jni_mid_startDiscovery);
171     if (!jni_obj_startDiscovery)
172     {
173         OIC_LOG(ERROR, TAG, "startDiscovery has failed");
174         return CA_STATUS_FAILED;
175     }
176     else
177     {
178         OIC_LOG(INFO, TAG, "startDiscovery has started");
179         return CA_STATUS_OK;
180     }
181 }
182
183 CAResult_t CABTPairingStopScan(JNIEnv *env)
184 {
185     OIC_LOG(INFO, TAG, "CABTPairingStopScan");
186     if (!env)
187     {
188         OIC_LOG(ERROR, TAG, "parameter is null");
189         return CA_STATUS_FAILED;
190     }
191
192     // get default bt adapter class
193     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
194     if (!jni_cid_BTAdapter)
195     {
196         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
197         return CA_STATUS_FAILED;
198     }
199
200     // get remote bt adapter method ID
201     jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
202                                                                     "getDefaultAdapter",
203                                                                     METHODID_OBJECTNONPARAM);
204     if (!jni_mid_getDefaultAdapter)
205     {
206         OIC_LOG(ERROR, TAG, "jni_mid_getDefaultAdapter is null");
207         return CA_STATUS_FAILED;
208     }
209
210     // get cancelDiscovery() method ID
211     jmethodID jni_mid_cancelDiscovery = (*env)->GetMethodID(env, jni_cid_BTAdapter, "cancelDiscovery",
212                                                            "()Z");
213     if (!jni_mid_cancelDiscovery)
214     {
215         OIC_LOG(ERROR, TAG, "jni_mid_cancelDiscovery is null");
216         return CA_STATUS_FAILED;
217     }
218
219     // gat bt adapter object
220     jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
221                                                                jni_mid_getDefaultAdapter);
222     if (!jni_obj_BTAdapter)
223     {
224         OIC_LOG(ERROR, TAG, "jni_obj_BTAdapter is null");
225         return CA_STATUS_FAILED;
226     }
227
228     // call cancelDiscovery() method
229     jboolean jni_obj_cancelDiscovery = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter,
230                                                                  jni_mid_cancelDiscovery);
231     if (!jni_obj_cancelDiscovery)
232     {
233         OIC_LOG(ERROR, TAG, "cancelDiscovery has failed");
234         return CA_STATUS_FAILED;
235     }
236     else
237     {
238         OIC_LOG(INFO, TAG, "cancelDiscovery has started");
239         return CA_STATUS_OK;
240     }
241 }
242
243 CAResult_t CABTPairingCreateBond(JNIEnv *env, jobject device)
244 {
245     OIC_LOG(INFO, TAG, "CABTPairingCreateBond");
246     if (!env || !device)
247     {
248         OIC_LOG(ERROR, TAG, "parameter is null");
249         return CA_STATUS_FAILED;
250     }
251
252     // get default bt adapter class
253     jclass jni_cid_BTDevice = (*env)->FindClass(env, CLASSPATH_BT_DEVICE);
254     if (!jni_cid_BTDevice)
255     {
256         OIC_LOG(ERROR, TAG, "jni_cid_BTDevice is null");
257         return CA_STATUS_FAILED;
258     }
259
260     // get createBond() method ID
261     jmethodID jni_mid_createBond = (*env)->GetMethodID(env, jni_cid_BTDevice, "createBond",
262                                                        "()Z");
263     if (!jni_mid_createBond)
264     {
265         OIC_LOG(ERROR, TAG, "jni_mid_createBond is null");
266         return CA_STATUS_FAILED;
267     }
268
269     // call createBond() method
270     jboolean jni_obj_createBond = (*env)->CallBooleanMethod(env, device, jni_mid_createBond);
271     if (!jni_obj_createBond)
272     {
273         OIC_LOG(ERROR, TAG, "createBond has failed");
274         return CA_STATUS_FAILED;
275     }
276     else
277     {
278         OIC_LOG(INFO, TAG, "createBond has started");
279         return CA_STATUS_OK;
280     }
281 }
282
283 JNIEXPORT void JNICALL
284 Java_org_iotivity_ca_CaBtPairingInterface_oicEdrStateChangedCallback(JNIEnv *env, jobject obj,
285                                                                      jint status)
286 {
287     OIC_LOG(INFO, TAG, "oicEdrStateChangedCallback");
288     if (!env || !obj)
289     {
290         OIC_LOG(ERROR, TAG, "parameter is null");
291         return;
292     }
293
294     // STATE_ON:12, STATE_OFF:10
295     jclass jni_cid_BTAdapter = (*env)->FindClass(env, CLASSPATH_BT_ADAPTER);
296     if (!jni_cid_BTAdapter)
297     {
298         OIC_LOG(ERROR, TAG, "jni_cid_BTAdapter is null");
299         return;
300     }
301
302     jfieldID id_state_on = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
303     if (!id_state_on)
304     {
305         OIC_LOG(ERROR, TAG, "id_state_on is null");
306         return;
307     }
308
309     jfieldID id_state_off = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_OFF", "I");
310     if (!id_state_off)
311     {
312         OIC_LOG(ERROR, TAG, "id_state_off is null");
313         return;
314     }
315
316     jint state_on = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, id_state_on);
317     jint state_off = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, id_state_off);
318
319     if (state_on == status)
320     {
321         OIC_LOG(INFO, TAG, "oicEdrStateChangedCallback : state_on");
322     }
323     else if (state_off == status)
324     {
325         OIC_LOG(INFO, TAG, "oicEdrStateChangedCaloicEdrFoundDeviceCallbacklback : state_off");
326     }
327 }
328
329 JNIEXPORT void JNICALL
330 Java_org_iotivity_ca_CaBtPairingInterface_oicEdrBondStateChangedCallback(JNIEnv *env, jobject obj,
331                                                                          jstring addr)
332 {
333     OIC_LOG(INFO, TAG, "oicEdrBondStateChangedCallback");
334     (void)env;
335     (void)obj;
336     (void)addr;
337 }
338
339 JNIEXPORT void JNICALL
340 Java_org_iotivity_ca_CaBtPairingInterface_oicEdrFoundDeviceCallback(JNIEnv *env, jobject obj,
341                                                                     jobject device)
342 {
343     if (!env || !obj || !device)
344     {
345         return;
346     }
347
348     if (!g_listener)
349     {
350         return;
351     }
352
353     jclass jni_cls_listener = (*env)->GetObjectClass(env, g_listener);
354     if (!jni_cls_listener)
355     {
356         OIC_LOG(ERROR, TAG, "could not get jni_cls_listener");
357         return;
358     }
359
360     jmethodID jni_mid_listener = (*env)->GetMethodID(env, jni_cls_listener, "onBtDeviceFound",
361                                         "(Landroid/bluetooth/BluetoothDevice;)V");
362     if (!jni_mid_listener)
363     {
364         OIC_LOG(ERROR, TAG, "could not get Method ID");
365         return;
366     }
367
368     (*env)->CallVoidMethod(env, g_listener, jni_mid_listener, device);
369 }
370