1/*
2 * Copyright 2008, 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#define LOG_TAG "wifi"
18
19#include "jni.h"
20#include <ScopedUtfChars.h>
21#include <utils/misc.h>
22#include <android_runtime/AndroidRuntime.h>
23#include <utils/Log.h>
24#include <utils/String16.h>
25
26#include "wifi.h"
27#include "wifi_hal.h"
28#include "jni_helper.h"
29
30namespace android {
31
32/* JNI Helpers for wifi_hal implementation */
33
34void throwException( JNIEnv *env, const char *message, int line )
35{
36    ALOGE("error at line %d: %s", line, message);
37
38    const char *className = "java/lang/Exception";
39
40    jclass exClass = (env)->FindClass(className );
41    if ( exClass == NULL ) {
42        ALOGE("Could not find exception class to throw error");
43        ALOGE("error at line %d: %s", line, message);
44        return;
45    }
46
47    (env)->ThrowNew(exClass, message);
48}
49
50jboolean getBoolField(JNIEnv *env, jobject obj, const char *name)
51{
52    jclass cls = (env)->GetObjectClass(obj);
53    jfieldID field = (env)->GetFieldID(cls, name, "Z");
54    if (field == 0) {
55        THROW(env, "Error in accessing field");
56        return 0;
57    }
58
59    jboolean value = (env)->GetBooleanField(obj, field);
60    env->DeleteLocalRef(cls);
61    return value;
62}
63
64jint getIntField(JNIEnv *env, jobject obj, const char *name)
65{
66    jclass cls = (env)->GetObjectClass(obj);
67    jfieldID field = (env)->GetFieldID(cls, name, "I");
68    if (field == 0) {
69        THROW(env, "Error in accessing field");
70        return 0;
71    }
72
73    jint value = (env)->GetIntField(obj, field);
74    env->DeleteLocalRef(cls);
75    return value;
76}
77
78jlong getLongField(JNIEnv *env, jobject obj, const char *name)
79{
80    jclass cls = (env)->GetObjectClass(obj);
81    jfieldID field = (env)->GetFieldID(cls, name, "J");
82    if (field == 0) {
83        THROW(env, "Error in accessing field");
84        return 0;
85    }
86
87    jlong value = (env)->GetLongField(obj, field);
88    env->DeleteLocalRef(cls);
89    return value;
90}
91
92jlong getStaticLongField(JNIEnv *env, jobject obj, const char *name)
93{
94    jclass cls = (env)->GetObjectClass(obj);
95    jlong result = getStaticLongField(env, cls, name);
96    env->DeleteLocalRef(cls);
97    return result;
98}
99
100jlong getStaticLongField(JNIEnv *env, jclass cls, const char *name)
101{
102    jfieldID field = (env)->GetStaticFieldID(cls, name, "J");
103    if (field == 0) {
104        THROW(env, "Error in accessing field");
105        return 0;
106    }
107    ALOGE("getStaticLongField %s %p", name, cls);
108
109    return (env)->GetStaticLongField(cls, field);
110}
111
112jobject getObjectField(JNIEnv *env, jobject obj, const char *name, const char *type)
113{
114    jclass cls = (env)->GetObjectClass(obj);
115    jfieldID field = (env)->GetFieldID(cls, name, type);
116    if (field == 0) {
117        THROW(env, "Error in accessing field");
118        return 0;
119    }
120
121    jobject value = (env)->GetObjectField(obj, field);
122    env->DeleteLocalRef(cls);
123    return value;
124}
125
126jlong getLongArrayField(JNIEnv *env, jobject obj, const char *name, int index)
127{
128    jclass cls = (env)->GetObjectClass(obj);
129    jfieldID field = (env)->GetFieldID(cls, name, "[J");
130    if (field == 0) {
131        THROW(env, "Error in accessing field definition");
132        return 0;
133    }
134
135    jlongArray array = (jlongArray)(env)->GetObjectField(obj, field);
136    if (array == NULL) {
137        THROW(env, "Error in accessing array");
138        return 0;
139    }
140
141    jlong *elem = (env)->GetLongArrayElements(array, 0);
142    if (elem == NULL) {
143        THROW(env, "Error in accessing index element");
144        return 0;
145    }
146
147    jlong value = elem[index];
148    (env)->ReleaseLongArrayElements(array, elem, 0);
149
150    env->DeleteLocalRef(array);
151    env->DeleteLocalRef(cls);
152
153    return value;
154}
155
156jlong getStaticLongArrayField(JNIEnv *env, jobject obj, const char *name, int index)
157{
158    jclass cls = (env)->GetObjectClass(obj);
159    jlong result = getStaticLongArrayField(env, cls, name, index);
160    env->DeleteLocalRef(cls);
161    return result;
162}
163
164jlong getStaticLongArrayField(JNIEnv *env, jclass cls, const char *name, int index)
165{
166    jfieldID field = (env)->GetStaticFieldID(cls, name, "[J");
167    if (field == 0) {
168        THROW(env, "Error in accessing field definition");
169        return 0;
170    }
171
172    jlongArray array = (jlongArray)(env)->GetStaticObjectField(cls, field);
173    jlong *elem = (env)->GetLongArrayElements(array, 0);
174    if (elem == NULL) {
175        THROW(env, "Error in accessing index element");
176        return 0;
177    }
178
179    jlong value = elem[index];
180    (env)->ReleaseLongArrayElements(array, elem, 0);
181
182    env->DeleteLocalRef(array);
183    return value;
184}
185
186jobject getObjectArrayField(JNIEnv *env, jobject obj, const char *name, const char *type, int index)
187{
188    jclass cls = (env)->GetObjectClass(obj);
189    jfieldID field = (env)->GetFieldID(cls, name, type);
190    if (field == 0) {
191        THROW(env, "Error in accessing field definition");
192        return 0;
193    }
194
195    jobjectArray array = (jobjectArray)(env)->GetObjectField(obj, field);
196    jobject elem = (env)->GetObjectArrayElement(array, index);
197    if (elem == NULL) {
198        THROW(env, "Error in accessing index element");
199        return 0;
200    }
201
202    env->DeleteLocalRef(array);
203    env->DeleteLocalRef(cls);
204    return elem;
205}
206
207void setIntField(JNIEnv *env, jobject obj, const char *name, jint value)
208{
209    jclass cls = (env)->GetObjectClass(obj);
210    if (cls == NULL) {
211        THROW(env, "Error in accessing class");
212        return;
213    }
214
215    jfieldID field = (env)->GetFieldID(cls, name, "I");
216    if (field == NULL) {
217        THROW(env, "Error in accessing field");
218        return;
219    }
220
221    (env)->SetIntField(obj, field, value);
222    env->DeleteLocalRef(cls);
223}
224
225void setLongField(JNIEnv *env, jobject obj, const char *name, jlong value)
226{
227    jclass cls = (env)->GetObjectClass(obj);
228    if (cls == NULL) {
229        THROW(env, "Error in accessing class");
230        return;
231    }
232
233    jfieldID field = (env)->GetFieldID(cls, name, "J");
234    if (field == NULL) {
235        THROW(env, "Error in accessing field");
236        return;
237    }
238
239    (env)->SetLongField(obj, field, value);
240    env->DeleteLocalRef(cls);
241}
242
243void setStaticLongField(JNIEnv *env, jobject obj, const char *name, jlong value)
244{
245    jclass cls = (env)->GetObjectClass(obj);
246    if (cls == NULL) {
247        THROW(env, "Error in accessing class");
248        return;
249    }
250
251    setStaticLongField(env, cls, name, value);
252    env->DeleteLocalRef(cls);
253}
254
255void setStaticLongField(JNIEnv *env, jclass cls, const char *name, jlong value)
256{
257    jfieldID field = (env)->GetStaticFieldID(cls, name, "J");
258    if (field == NULL) {
259        THROW(env, "Error in accessing field");
260        return;
261    }
262
263    (env)->SetStaticLongField(cls, field, value);
264}
265
266void setLongArrayField(JNIEnv *env, jobject obj, const char *name, jlongArray value)
267{
268    jclass cls = (env)->GetObjectClass(obj);
269    if (cls == NULL) {
270        THROW(env, "Error in accessing field");
271        return;
272    } else {
273        ALOGD("cls = %p", cls);
274    }
275
276    jfieldID field = (env)->GetFieldID(cls, name, "[J");
277    if (field == NULL) {
278        THROW(env, "Error in accessing field");
279        return;
280    }
281
282    (env)->SetObjectField(obj, field, value);
283    ALOGD("array field set");
284
285    env->DeleteLocalRef(cls);
286}
287
288void setStaticLongArrayField(JNIEnv *env, jobject obj, const char *name, jlongArray value)
289{
290    jclass cls = (env)->GetObjectClass(obj);
291    if (cls == NULL) {
292        THROW(env, "Error in accessing field");
293        return;
294    } else {
295        ALOGD("cls = %p", cls);
296    }
297
298    setStaticLongArrayField(env, cls, name, value);
299    env->DeleteLocalRef(cls);
300}
301
302void setStaticLongArrayField(JNIEnv *env, jclass cls, const char *name, jlongArray value)
303{
304    jfieldID field = (env)->GetStaticFieldID(cls, name, "[J");
305    if (field == NULL) {
306        THROW(env, "Error in accessing field");
307        return;
308    }
309
310    (env)->SetStaticObjectField(cls, field, value);
311    ALOGD("array field set");
312}
313
314void setLongArrayElement(JNIEnv *env, jobject obj, const char *name, int index, jlong value)
315{
316    jclass cls = (env)->GetObjectClass(obj);
317    if (cls == NULL) {
318        THROW(env, "Error in accessing field");
319        return;
320    } else {
321        ALOGD("cls = %p", cls);
322    }
323
324    jfieldID field = (env)->GetFieldID(cls, name, "[J");
325    if (field == NULL) {
326        THROW(env, "Error in accessing field");
327        return;
328    } else {
329        ALOGD("field = %p", field);
330    }
331
332    jlongArray array = (jlongArray)(env)->GetObjectField(obj, field);
333    if (array == NULL) {
334        THROW(env, "Error in accessing array");
335        return;
336    } else {
337        ALOGD("array = %p", array);
338    }
339
340    jlong *elem = (env)->GetLongArrayElements(array, NULL);
341    if (elem == NULL) {
342        THROW(env, "Error in accessing index element");
343        return;
344    }
345
346    elem[index] = value;
347    env->ReleaseLongArrayElements(array, elem, 0);
348    env->DeleteLocalRef(array);
349    env->DeleteLocalRef(cls);
350}
351
352void setObjectField(JNIEnv *env, jobject obj, const char *name, const char *type, jobject value)
353{
354    jclass cls = (env)->GetObjectClass(obj);
355    if (cls == NULL) {
356        THROW(env, "Error in accessing class");
357        return;
358    }
359
360    jfieldID field = (env)->GetFieldID(cls, name, type);
361    if (field == NULL) {
362        THROW(env, "Error in accessing field");
363        return;
364    }
365
366    (env)->SetObjectField(obj, field, value);
367    env->DeleteLocalRef(cls);
368}
369
370void setStringField(JNIEnv *env, jobject obj, const char *name, const char *value)
371{
372    jstring str = env->NewStringUTF(value);
373
374    if (str == NULL) {
375        THROW(env, "Error in accessing class");
376        return;
377    }
378
379    setObjectField(env, obj, name, "Ljava/lang/String;", str);
380    env->DeleteLocalRef(str);
381}
382
383void reportEvent(JNIEnv *env, jclass cls, const char *method, const char *signature, ...)
384{
385    va_list params;
386    va_start(params, signature);
387
388    jmethodID methodID = env->GetStaticMethodID(cls, method, signature);
389    if (method == NULL) {
390        ALOGE("Error in getting method ID");
391        return;
392    }
393
394    env->CallStaticVoidMethodV(cls, methodID, params);
395    va_end(params);
396}
397
398jobject createObject(JNIEnv *env, const char *className)
399{
400    jclass cls = env->FindClass(className);
401    if (cls == NULL) {
402        ALOGE("Error in finding class");
403        return NULL;
404    }
405
406    jmethodID constructor = env->GetMethodID(cls, "<init>", "()V");
407    if (constructor == NULL) {
408        ALOGE("Error in constructor ID");
409        return NULL;
410    }
411    jobject obj = env->NewObject(cls, constructor);
412    if (constructor == NULL) {
413        ALOGE("Could not create new object of %s", className);
414        return NULL;
415    }
416
417    env->DeleteLocalRef(cls);
418    return obj;
419}
420
421}; // namespace android
422
423
424