diff options
author | Satish kumar sugasi <ssugas@codeaurora.org> | 2012-12-08 20:51:55 -0800 |
---|---|---|
committer | Satish kumar sugasi <ssugas@codeaurora.org> | 2012-12-08 20:51:55 -0800 |
commit | 8dbae1cbcd8ee795e2d30f5ac26996d5c235d38b (patch) | |
tree | 64258b09cbadd7ce47b7d1f3d71880a43764b914 /src/common/JAntNative.cpp | |
parent | 709b0e9416802fff4b45611f17bf878a64af07d6 (diff) | |
parent | 274e0ddfa092938c5839643af6abed3e6e7ef773 (diff) | |
download | android_external_ant-wireless_ant_native-8dbae1cbcd8ee795e2d30f5ac26996d5c235d38b.tar.gz android_external_ant-wireless_ant_native-8dbae1cbcd8ee795e2d30f5ac26996d5c235d38b.tar.bz2 android_external_ant-wireless_ant_native-8dbae1cbcd8ee795e2d30f5ac26996d5c235d38b.zip |
Merge remote-tracking branch 'remotes/origin/caf/github/master'
Diffstat (limited to 'src/common/JAntNative.cpp')
-rw-r--r-- | src/common/JAntNative.cpp | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/src/common/JAntNative.cpp b/src/common/JAntNative.cpp new file mode 100644 index 0000000..2e3beb0 --- /dev/null +++ b/src/common/JAntNative.cpp @@ -0,0 +1,366 @@ +/* + * ANT Stack + * + * Copyright 2009 Dynastream Innovations + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/*******************************************************************************\ +* +* FILE NAME: JAntNative.cpp +* +* BRIEF: +* This file provides the implementation of the native interface functions for ANT +* +* +\*******************************************************************************/ + +#include "android_runtime/AndroidRuntime.h" +#include "jni.h" +#include "nativehelper/JNIHelp.h" + +static JNIEnv *g_jEnv = NULL; +static JavaVM *g_jVM = NULL; +static jclass g_sJClazz; +static jmethodID g_sMethodId_nativeCb_AntRxMessage; +static jmethodID g_sMethodId_nativeCb_AntStateChange; + +extern "C" +{ + #include "ant_native.h" + #include "ant_log.h" + #undef LOG_TAG + #define LOG_TAG "JAntNative" + + void nativeJAnt_RxCallback(ANT_U8 ucLen, ANT_U8* pucData); + void nativeJAnt_StateCallback(ANTRadioEnabledStatus uiNewState); +} + +static jint nativeJAnt_Create(JNIEnv *env, jobject obj) +{ + ANTStatus antStatus = ANT_STATUS_FAILED; + (void)env; //unused warning + (void)obj; //unused warning + + ANT_FUNC_START(); + + antStatus = ant_init(); + if (antStatus) + { + ANT_DEBUG_D("failed to init ANT stack"); + goto CLEANUP; + } + + antStatus = set_ant_rx_callback(nativeJAnt_RxCallback); + if (antStatus) + { + ANT_DEBUG_D("failed to set ANT rx callback"); + goto CLEANUP; + } + + antStatus = set_ant_state_callback(nativeJAnt_StateCallback); + if (antStatus) + { + ANT_DEBUG_D("failed to set ANT state callback"); + goto CLEANUP; + } + +CLEANUP: + ANT_FUNC_END(); + return antStatus; +} + +static jint nativeJAnt_Destroy(JNIEnv *env, jobject obj) +{ + (void)env; //unused warning + (void)obj; //unused warning + ANTStatus status; + ANT_FUNC_START(); + + ANT_DEBUG_D("nativeJAnt_Destroy(): calling ant_deinit"); + status = ant_deinit(); + if (status) + { + ANT_DEBUG_D("failed to deinit ANT stack returned %d",(int)status); + return status; + } + else + { + ANT_DEBUG_D("deinit ANT stack Success"); + } + + ANT_FUNC_END(); + return status; +} + +static jint nativeJAnt_Enable(JNIEnv *env, jobject obj) +{ + (void)env; //unused warning + (void)obj; //unused warning + ANT_FUNC_START(); + + ANTStatus status = ant_enable_radio(); + + ANT_FUNC_END(); + return status; +} + +static jint nativeJAnt_Disable(JNIEnv *env, jobject obj) +{ + (void)env; //unused warning + (void)obj; //unused warning + ANT_FUNC_START(); + + ANTStatus status = ant_disable_radio(); + + ANT_FUNC_END(); + return status; +} + +static jint nativeJAnt_GetRadioEnabledStatus(JNIEnv *env, jobject obj) +{ + (void)env; //unused warning + (void)obj; //unused warning + ANT_FUNC_START(); + + jint status = ant_radio_enabled_status(); + + ANT_FUNC_END(); + return status; +} + +static jint nativeJAnt_TxMessage(JNIEnv *env, jobject obj, jbyteArray msg) +{ + (void)obj; //unused warning + ANT_FUNC_START(); + + if (msg == NULL) + { + if (jniThrowException(env, "java/lang/NullPointerException", NULL)) + { + ANT_ERROR("Unable to throw NullPointerException"); + } + return -1; + } + + jbyte* msgBytes = env->GetByteArrayElements(msg, NULL); + jint msgLength = env->GetArrayLength(msg); + + ANTStatus status = ant_tx_message((ANT_U8) msgLength, (ANT_U8 *)msgBytes); + ANT_DEBUG_D("nativeJAnt_TxMessage: ant_tx_message() returned %d", (int)status); + + env->ReleaseByteArrayElements(msg, msgBytes, JNI_ABORT); + + ANT_FUNC_END(); + return status; +} + +static jint nativeJAnt_HardReset(JNIEnv *env, jobject obj) +{ + (void)env; //unused warning + (void)obj; //unused warning + ANT_FUNC_START(); + + ANTStatus status = ant_radio_hard_reset(); + + ANT_FUNC_END(); + return status; +} + +extern "C" +{ + + /********************************************************************** + * Callback registration + ***********************************************************************/ + void nativeJAnt_RxCallback(ANT_U8 ucLen, ANT_U8* pucData) + { + JNIEnv* env = NULL; + jbyteArray jAntRxMsg = NULL; + ANT_FUNC_START(); + + ANT_DEBUG_D( "got message %d bytes", ucLen); + + g_jVM->AttachCurrentThread((&env), NULL); + + if (env == NULL) + { + ANT_DEBUG_D("nativeJAnt_RxCallback: Entered, env is null"); + return; // log error? cleanup? + } + else + { + ANT_DEBUG_D("nativeJAnt_RxCallback: jEnv %p", env); + } + + jAntRxMsg = env->NewByteArray(ucLen); + + if (jAntRxMsg == NULL) + { + ANT_ERROR("nativeJAnt_RxCallback: Failed creating java byte[]"); + goto CLEANUP; + } + + env->SetByteArrayRegion(jAntRxMsg,0,ucLen,(jbyte*)pucData); + + if (env->ExceptionOccurred()) + { + ANT_ERROR("nativeJAnt_RxCallback: ExceptionOccurred during byte[] copy"); + goto CLEANUP; + } + ANT_DEBUG_V("nativeJAnt_RxCallback: Calling java rx callback"); + env->CallStaticVoidMethod(g_sJClazz, g_sMethodId_nativeCb_AntRxMessage, jAntRxMsg); + ANT_DEBUG_V("nativeJAnt_RxCallback: Called java rx callback"); + + if (env->ExceptionOccurred()) + { + ANT_ERROR("nativeJAnt_RxCallback: Calling Java nativeCb_AntRxMessage failed"); + goto CLEANUP; + } + + //Delete the local references + if (jAntRxMsg != NULL) + { + env->DeleteLocalRef(jAntRxMsg); + } + + ANT_DEBUG_D("nativeJAnt_RxCallback: Exiting, Calling DetachCurrentThread at the END"); + + g_jVM->DetachCurrentThread(); + + ANT_FUNC_END(); + return; + + CLEANUP: + ANT_ERROR("nativeJAnt_RxCallback: Exiting due to failure"); + if (jAntRxMsg != NULL) + { + env->DeleteLocalRef(jAntRxMsg); + } + + if (env->ExceptionOccurred()) + { + env->ExceptionDescribe(); + env->ExceptionClear(); + } + + g_jVM->DetachCurrentThread(); + + return; + } + + void nativeJAnt_StateCallback(ANTRadioEnabledStatus uiNewState) + { + JNIEnv* env = NULL; + jint jNewState = uiNewState; + ANT_BOOL iShouldDetach = ANT_FALSE; + ANT_FUNC_START(); + + g_jVM->GetEnv((void**) &env, JNI_VERSION_1_4); + if (env == NULL) + { + ANT_DEBUG_D("nativeJAnt_StateCallback: called from rx thread, attaching to VM"); + g_jVM->AttachCurrentThread((&env), NULL); + if (env == NULL) + { + ANT_DEBUG_E("nativeJAnt_StateCallback: failed to attach rx thread to VM"); + return; + } + iShouldDetach = ANT_TRUE; + } + else + { + ANT_DEBUG_D("nativeJAnt_StateCallback: called from java enable/disable" + ", already attached, don't detach"); + } + + ANT_DEBUG_V("nativeJAnt_StateCallback: Calling java state callback"); + env->CallStaticVoidMethod(g_sJClazz, g_sMethodId_nativeCb_AntStateChange, jNewState); + ANT_DEBUG_V("nativeJAnt_StateCallback: Called java state callback"); + + if (env->ExceptionOccurred()) + { + ANT_ERROR("nativeJAnt_StateCallback: Calling Java nativeCb_AntStateChange failed"); + env->ExceptionDescribe(); + env->ExceptionClear(); + } + + if (iShouldDetach) + { + ANT_DEBUG_D("nativeJAnt_StateCallback: env was attached, detaching"); + g_jVM->DetachCurrentThread(); + } + + ANT_FUNC_END(); + return; + } +} + +static JNINativeMethod g_sMethods[] = +{ + /* name, signature, funcPtr */ + {"nativeJAnt_Create", "()I", (void*)nativeJAnt_Create}, + {"nativeJAnt_Destroy", "()I", (void*)nativeJAnt_Destroy}, + {"nativeJAnt_Enable", "()I", (void*)nativeJAnt_Enable}, + {"nativeJAnt_Disable", "()I", (void*)nativeJAnt_Disable}, + {"nativeJAnt_GetRadioEnabledStatus", "()I", (void*)nativeJAnt_GetRadioEnabledStatus}, + {"nativeJAnt_TxMessage","([B)I", (void*)nativeJAnt_TxMessage}, + {"nativeJAnt_HardReset", "()I", (void *)nativeJAnt_HardReset} +}; + +jint JNI_OnLoad(JavaVM* vm, void* reserved) { + ANT_FUNC_START(); + (void)reserved; //unused warning + + g_jVM = vm; + if (g_jVM->GetEnv((void**) &g_jEnv, JNI_VERSION_1_4) != JNI_OK) { + ANT_ERROR("GetEnv failed"); + return -1; + } + if (NULL == g_jEnv) { + ANT_ERROR("env is null"); + return -1; + } + + g_sJClazz = g_jEnv->FindClass("com/dsi/ant/core/JAntJava"); + if (NULL == g_sJClazz) { + ANT_ERROR("could not find class \"com/dsi/ant/core/JAntJava\""); + return -1; + } + + /* Save class information in global reference to prevent class unloading */ + g_sJClazz = (jclass)g_jEnv->NewGlobalRef(g_sJClazz); + + if (g_jEnv->RegisterNatives(g_sJClazz, g_sMethods, NELEM(g_sMethods)) != JNI_OK) { + ANT_ERROR("failed to register methods"); + return -1; + } + + g_sMethodId_nativeCb_AntRxMessage = g_jEnv->GetStaticMethodID(g_sJClazz, + "nativeCb_AntRxMessage", "([B)V"); + if (NULL == g_sMethodId_nativeCb_AntRxMessage) { + ANT_ERROR("VerifyMethodId: Failed getting method id of \"void nativeCb_AntRxMessage(byte[])\""); + return -1; + } + + g_sMethodId_nativeCb_AntStateChange = g_jEnv->GetStaticMethodID(g_sJClazz, + "nativeCb_AntStateChange", "(I)V"); + if (NULL == g_sMethodId_nativeCb_AntStateChange) { + ANT_ERROR("VerifyMethodId: Failed getting method id of \"void nativeCb_AntStateChange(int)\""); + return -1; + } + + ANT_FUNC_END(); + return JNI_VERSION_1_4; +} + |