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;
}
ANTStatus ant_deinit(void)
{
    int mutexResult;
    ANTStatus result_status = ANT_STATUS_FAILED;
    ANT_FUNC_START();

    mutexResult = pthread_mutex_destroy(&txLock);
    if (mutexResult)
    {
        ANT_ERROR("Tx Lock mutex destroy failed: %s", strerror(mutexResult));
    }
    else
    {
        mutexResult = pthread_mutex_destroy(&enableLock);
        if (mutexResult)
        {
            ANT_ERROR("Enable Lock mutex destroy failed: %s", strerror(mutexResult));
        }
        else
        {
            result_status = ANT_STATUS_SUCCESS;
        }
    }

    ANT_FUNC_END();
    return result_status;
}
int ant_disable(void)
{
   int iRet = -1;
   ant_channel_type eChannel;
   ANT_FUNC_START();

   stRxThreadInfo.ucRunThread = 0;

   if (stRxThreadInfo.stRxThread != 0) {
      ANT_DEBUG_I("Sending shutdown signal to rx thread.");
      if(write(stRxThreadInfo.iRxShutdownEventFd, &EVENT_FD_PLUS_ONE, sizeof(EVENT_FD_PLUS_ONE)) < 0)
      {
         ANT_ERROR("failed to signal rx thread with eventfd. Reason: %s", strerror(errno));
         goto out;
      }
      ANT_DEBUG_I("Waiting for rx thread to finish.");
      if (pthread_join(stRxThreadInfo.stRxThread, NULL) < 0) {
         ANT_ERROR("failed to join rx thread: %s", strerror(errno));
         goto out;
      }
   } else {
      ANT_DEBUG_D("rx thread is not running");
   }

   for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) {
      ant_disable_channel(&stRxThreadInfo.astChannels[eChannel]);
   }

   iRet = 0;

out:
   stRxThreadInfo.stRxThread = 0;
   ANT_FUNC_END();
   return iRet;
}
ANTStatus ant_init(void)
{
   ANTStatus status = ANT_STATUS_FAILED;
   ANT_FUNC_START();

   stRxThreadInfo.stRxThread = 0;
   stRxThreadInfo.ucRunThread = 0;
   stRxThreadInfo.ucChipResetting = 0;
   stRxThreadInfo.pstEnabledStatusLock = &stEnabledStatusLock;
   g_fnStateCallback = 0;

#ifdef ANT_DEVICE_NAME // Single transport path
   ant_channel_init(&stRxThreadInfo.astChannels[SINGLE_CHANNEL], ANT_DEVICE_NAME);
#else // Separate data/command paths
   ant_channel_init(&stRxThreadInfo.astChannels[COMMAND_CHANNEL], ANT_COMMANDS_DEVICE_NAME);
   ant_channel_init(&stRxThreadInfo.astChannels[DATA_CHANNEL], ANT_DATA_DEVICE_NAME);
#endif // Separate data/command paths

   // Make the eventfd. Want it non blocking so that we can easily reset it by reading.
   stRxThreadInfo.iRxShutdownEventFd = eventfd(0, EFD_NONBLOCK);

   // Check for error case
   if(stRxThreadInfo.iRxShutdownEventFd == -1)
   {
      ANT_ERROR("ANT init failed. Could not create event fd. Reason: %s", strerror(errno));
   } else {
      status = ANT_STATUS_SUCCESS;
   }

   ANT_FUNC_END();
   return status;
}
////////////////////////////////////////////////////////////////////
//  get_and_set_radio_status
//
//  Returns if the chip/transport is disabled/enabled/unknown This function WILL
//  overwrite what it thinks the state is with what the BlueZ core (kernel)
//  thinks it is. It will overwrite enabling or disabling states, and might
//  change internal state from enabled, disabled, or unknown to any of these
//  three on errors.
//
//  Parameters:
//      -
//
//  Returns:
//      The current radio status (ANTRadioEnabledStatus)
//
////////////////////////////////////////////////////////////////////
ANTRadioEnabledStatus get_and_set_radio_status(void)
{
    ANT_FUNC_START();
#if USE_EXTERNAL_POWER_LIBRARY
    ANTRadioEnabledStatus orig_status = radio_status;
    switch (ant_is_enabled())
    {
    case 0:
        radio_status = RADIO_STATUS_DISABLED;
        break;
    case 1:
        radio_status = RADIO_STATUS_ENABLED;
        break;
    default:
        ANT_ERROR("getting chip state returned an error");
        radio_status = RADIO_STATUS_UNKNOWN;
        break;
    }
    if (orig_status != radio_status)
    {
        ANT_DEBUG_I("radio_status (%d -> %d)", orig_status, radio_status);

        if (RxParams.pfStateCallback)
            RxParams.pfStateCallback(radio_status);
    }
#endif
    ANT_FUNC_END();
    return radio_status;
}
ANTStatus ant_init(void)
{
    int mutexResult;
    ANTStatus status = ANT_STATUS_FAILED;
    ANT_FUNC_START();

    mutexResult = pthread_mutex_init(&txLock, NULL); //use default attr
    if (mutexResult)
    {
        ANT_ERROR("Tx Lock mutex initialization failed: %s", strerror(mutexResult));
    }
    else
    {
        mutexResult = pthread_mutex_init(&enableLock, NULL);
        if (mutexResult)
        {
            ANT_ERROR("Enable Lock mutex init failed %s", strerror(mutexResult));
        }
        else
        {
            status = ANT_STATUS_SUCCESS;
        }
    }

    ANT_FUNC_END();
    return status;
}
////////////////////////////////////////////////////////////////////
//  setFlowControl
//
//  Sets the flow control "flag" to the value provided and signals the transmit
//  thread to check the value.
//
//  Parameters:
//      pstChnlInfo   the details of the channel being updated
//      ucFlowSetting the value to use
//
//  Returns:
//      Success:
//          0
//      Failure:
//          -1
////////////////////////////////////////////////////////////////////
int setFlowControl(ant_channel_info_t *pstChnlInfo, ANT_U8 ucFlowSetting)
{
   int iRet = -1;
   int iMutexResult;
   ANT_FUNC_START();

   ANT_DEBUG_V("getting stFlowControlLock in %s", __FUNCTION__);
   iMutexResult = pthread_mutex_lock(pstChnlInfo->pstFlowControlLock);
   if (iMutexResult) {
      ANT_ERROR("failed to lock flow control mutex during response: %s", strerror(iMutexResult));
   } else {
      ANT_DEBUG_V("got stFlowControlLock in %s", __FUNCTION__);

      pstChnlInfo->ucFlowControlResp = ucFlowSetting;

      ANT_DEBUG_V("releasing stFlowControlLock in %s", __FUNCTION__);
      pthread_mutex_unlock(pstChnlInfo->pstFlowControlLock);
      ANT_DEBUG_V("released stFlowControlLock in %s", __FUNCTION__);

      pthread_cond_signal(pstChnlInfo->pstFlowControlCond);

      iRet = 0;
   }

   ANT_FUNC_END();
   return iRet;
}
ANTStatus ant_radio_hard_reset(void)
{
    ANTStatus result_status = ANT_STATUS_NOT_SUPPORTED;
    ANT_FUNC_START();
    ANT_FUNC_END();
    return result_status;
}
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;
}
ANTStatus ant_disable_radio(void)
{
   int iLockResult;
   ANTStatus ret = ANT_STATUS_FAILED;
   ANT_FUNC_START();

   ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
   iLockResult = pthread_mutex_lock(&stEnabledStatusLock);
   if(iLockResult) {
      ANT_ERROR("disable failed to get state lock: %s", strerror(iLockResult));
      goto out;
   }
   ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);

   if (g_fnStateCallback) {
      g_fnStateCallback(RADIO_STATUS_DISABLING);
   }

   ant_disable();

   if (g_fnStateCallback) {
      g_fnStateCallback(ant_radio_enabled_status());
   }

   ret = ANT_STATUS_SUCCESS;

   ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
   pthread_mutex_unlock(&stEnabledStatusLock);
   ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);

out:
   ANT_FUNC_END();
   return ret;
}
ANTStatus set_ant_state_callback(ANTNativeANTStateCb state_callback_func)
{
   ANTStatus status = ANT_STATUS_SUCCESS;
   ANT_FUNC_START();

   g_fnStateCallback = state_callback_func;

   ANT_FUNC_END();
   return status;
}
ANTStatus set_ant_rx_callback(ANTNativeANTEventCb rx_callback_func)
{
    ANTStatus status = ANT_STATUS_SUCCESS;
    ANT_FUNC_START();

    RxParams.pfRxCallback = rx_callback_func;

    ANT_FUNC_END();
    return status;
}
Example #13
0
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;
}
Example #14
0
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;
}
Example #15
0
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;
}
ANTRadioEnabledStatus ant_radio_enabled_status(void)
{
    ANT_FUNC_START();

    if ((RADIO_STATUS_ENABLING != radio_status) &&
            (RADIO_STATUS_DISABLING != radio_status))
    {
        get_and_set_radio_status();
    }

    ANT_FUNC_END();
    return radio_status;
}
void doReset(ant_rx_thread_info_t *stRxThreadInfo)
{
   int iMutexLockResult;

   ANT_FUNC_START();
   /* Chip was reset or other error, only way to recover is to
    * close and open ANT chardev */
   stRxThreadInfo->ucChipResetting = 1;

   if (g_fnStateCallback) {
      g_fnStateCallback(RADIO_STATUS_RESETTING);
   }

   stRxThreadInfo->ucRunThread = 0;

   ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
   iMutexLockResult = pthread_mutex_lock(stRxThreadInfo->pstEnabledStatusLock);
   if (iMutexLockResult < 0) {
      ANT_ERROR("chip was reset, getting state mutex failed: %s",
            strerror(iMutexLockResult));
      stRxThreadInfo->stRxThread = 0;
      stRxThreadInfo->ucChipResetting = 0;
   } else {
      ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);

      stRxThreadInfo->stRxThread = 0; /* spoof our handle as closed so we don't
                                       * try to join ourselves in disable */

      ant_disable();

      int enableResult = ant_enable();

      stRxThreadInfo->ucChipResetting = 0;
      if (enableResult) { /* failed */
         if (g_fnStateCallback) {
            g_fnStateCallback(RADIO_STATUS_DISABLED);
         }
      } else { /* success */
         if (g_fnStateCallback) {
            g_fnStateCallback(RADIO_STATUS_RESET);
         }
      }

      ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
      pthread_mutex_unlock(stRxThreadInfo->pstEnabledStatusLock);
      ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
   }


   ANT_FUNC_END();
}
ANTStatus ant_radio_hard_reset(void)
{
   ANTStatus result_status = ANT_STATUS_NOT_SUPPORTED;
   ANT_FUNC_START();

#ifdef ANT_IOCTL_RESET
   ant_channel_type eChannel;
   int iLockResult;

   result_status = ANT_STATUS_FAILED;

   ANT_DEBUG_V("getting stEnabledStatusLock in %s", __FUNCTION__);
   iLockResult = pthread_mutex_lock(&stEnabledStatusLock);
   if(iLockResult) {
      ANT_ERROR("enable failed to get state lock: %s", strerror(iLockResult));
      goto out;
   }
   ANT_DEBUG_V("got stEnabledStatusLock in %s", __FUNCTION__);

   stRxThreadInfo.ucChipResetting = 1;
   if (g_fnStateCallback)
      g_fnStateCallback(RADIO_STATUS_RESETTING);

#ifdef ANT_IOCTL_RESET_PARAMETER
   ioctl(stRxThreadInfo.astChannels[0].iFd, ANT_IOCTL_RESET, ANT_IOCTL_RESET_PARAMETER);
#else
   ioctl(stRxThreadInfo.astChannels[0].iFd, ANT_IOCTL_RESET);
#endif  // ANT_IOCTL_RESET_PARAMETER

   ant_disable();

   if (ant_enable()) { /* failed */
      if (g_fnStateCallback)
         g_fnStateCallback(RADIO_STATUS_DISABLED);
   } else { /* success */
      if (g_fnStateCallback)
         g_fnStateCallback(RADIO_STATUS_RESET);
      result_status = ANT_STATUS_SUCCESS;
   }
   stRxThreadInfo.ucChipResetting = 0;

   ANT_DEBUG_V("releasing stEnabledStatusLock in %s", __FUNCTION__);
   pthread_mutex_unlock(&stEnabledStatusLock);
   ANT_DEBUG_V("released stEnabledStatusLock in %s", __FUNCTION__);
out:
#endif // ANT_IOCTL_RESET

   ANT_FUNC_END();
   return result_status;
}
ANTStatus ant_deinit(void)
{
   ANTStatus result_status = ANT_STATUS_FAILED;
   ANT_FUNC_START();

   if(close(stRxThreadInfo.iRxShutdownEventFd) < 0)
   {
      ANT_ERROR("Could not close eventfd in deinit. Reason: %s", strerror(errno));
   } else {
      result_status = ANT_STATUS_SUCCESS;
   }

   ANT_FUNC_END();
   return result_status;
}
ANTStatus set_ant_rx_callback(ANTNativeANTEventCb rx_callback_func)
{
   ANTStatus status = ANT_STATUS_SUCCESS;
   ANT_FUNC_START();

#ifdef ANT_DEVICE_NAME // Single transport path
   stRxThreadInfo.astChannels[SINGLE_CHANNEL].fnRxCallback = rx_callback_func;
#else // Separate data/command paths
   stRxThreadInfo.astChannels[COMMAND_CHANNEL].fnRxCallback = rx_callback_func;
   stRxThreadInfo.astChannels[DATA_CHANNEL].fnRxCallback = rx_callback_func;
#endif // Separate data/command paths

   ANT_FUNC_END();
   return status;
}
int ant_enable(void)
{
   int iRet = -1;
   ant_channel_type eChannel;
   ANT_FUNC_START();

   // Reset the shutdown signal.
   uint64_t counter;
   ssize_t result = read(stRxThreadInfo.iRxShutdownEventFd, &counter, sizeof(counter));
   // EAGAIN result indicates that the counter was already 0 in non-blocking mode.
   if(result < 0 && errno != EAGAIN)
   {
      ANT_ERROR("Could not clear shutdown signal in enable. Reason: %s", strerror(errno));
      goto out;
   }

   stRxThreadInfo.ucRunThread = 1;

   for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) {
      if (ant_enable_channel(&stRxThreadInfo.astChannels[eChannel]) < 0) {
         ANT_ERROR("failed to enable channel %s: %s",
                         stRxThreadInfo.astChannels[eChannel].pcDevicePath,
                         strerror(errno));
         goto out;
      }
   }

   if (stRxThreadInfo.stRxThread == 0) {
      if (pthread_create(&stRxThreadInfo.stRxThread, NULL, fnRxThread, &stRxThreadInfo) < 0) {
         ANT_ERROR("failed to start rx thread: %s", strerror(errno));
         goto out;
      }
   } else {
      ANT_DEBUG_D("rx thread is already running");
   }

   if (!stRxThreadInfo.ucRunThread) {
      ANT_ERROR("rx thread crashed during init");
      goto out;
   }

   iRet = 0;

out:
   ANT_FUNC_END();
   return iRet;
}
Example #22
0
   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;
   }
Example #23
0
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;
}
ANTStatus ant_tx_message_flowcontrol_none(ant_channel_type eTxPath, ANT_U8 ucMessageLength, ANT_U8 *pucTxMessage)
{
   int iResult;
   ANTStatus status = ANT_STATUS_FAILED;\
   ANT_FUNC_START();

   iResult = write(stRxThreadInfo.astChannels[eTxPath].iFd, pucTxMessage, ucMessageLength);
   if (iResult < 0) {
      ANT_ERROR("failed to write message to device: %s", strerror(errno));
   }  else if (iResult != ucMessageLength) {
      ANT_ERROR("bytes written and message size don't match up");
   } else {
      status = ANT_STATUS_SUCCESS;
   }

   ANT_FUNC_END();
   return status;
}
ANTRadioEnabledStatus ant_radio_enabled_status(void)
{
   ant_channel_type eChannel;
   int iOpenFiles = 0;
   int iOpenThread;
   ANTRadioEnabledStatus uiRet = RADIO_STATUS_UNKNOWN;
   ANT_FUNC_START();

   if (stRxThreadInfo.ucChipResetting) {
      uiRet = RADIO_STATUS_RESETTING;
      goto out;
   }

   for (eChannel = 0; eChannel < NUM_ANT_CHANNELS; eChannel++) {
      if (stRxThreadInfo.astChannels[eChannel].iFd != -1) {
         iOpenFiles++;
      }
   }

   iOpenThread = (stRxThreadInfo.stRxThread) ? 1 : 0;

   if (!stRxThreadInfo.ucRunThread) {
      if (iOpenFiles || iOpenThread) {
         uiRet = RADIO_STATUS_DISABLING;
      } else {
         uiRet = RADIO_STATUS_DISABLED;
      }
   } else {
      if ((iOpenFiles == NUM_ANT_CHANNELS) && iOpenThread) {
         uiRet = RADIO_STATUS_ENABLED;
      } else if (!iOpenFiles && iOpenThread) {
         uiRet = RADIO_STATUS_UNKNOWN;
      } else {
         uiRet = RADIO_STATUS_ENABLING;
      }
   }

out:
   ANT_DEBUG_D("get radio enabled status returned %d", uiRet);

   ANT_FUNC_END();
   return uiRet;
}
static void ant_disable_channel(ant_channel_info_t *pstChnlInfo)
{
   ANT_FUNC_START();
   if (!pstChnlInfo) {
      ANT_ERROR("null channel info passed to channel disable function");
      goto out;
   }
   if (pstChnlInfo->iFd != -1) {
      // Use the new init_transport function instead of open() to get our fd.
      if (init_transport_bdroid(0) < 0) {
         ANT_ERROR("failed to close channel %s(%#x): %s", pstChnlInfo->pcDevicePath, pstChnlInfo->iFd, strerror(errno));
      }

      pstChnlInfo->iFd = -1; //TODO can this overwrite a still valid fd?
   } else {
      ANT_DEBUG_D("%s file is already closed", pstChnlInfo->pcDevicePath);
   }

out:
   ANT_FUNC_END();
}
Example #27
0
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 void ant_channel_init(ant_channel_info_t *pstChnlInfo, const char *pcCharDevName)
{
   ANT_FUNC_START();

   // TODO Don't need to store, only accessed when trying to open:
   // Is however useful for logs.
   pstChnlInfo->pcDevicePath = pcCharDevName;

   // This is the only piece of info that needs to be stored per channel
   pstChnlInfo->iFd = -1;

   // TODO Only 1 of these (not per-channel) is actually ever used:
   pstChnlInfo->fnRxCallback = NULL;
   pstChnlInfo->ucFlowControlResp = ANT_FLOW_GO;
#ifdef ANT_FLOW_RESEND
   pstChnlInfo->ucResendMessageLength = 0;
   pstChnlInfo->pucResendMessage = NULL;
#endif // ANT_FLOW_RESEND
   // TODO Only used when Flow Control message received, so must only be Command path Rx thread
   pstChnlInfo->pstFlowControlCond = &stFlowControlCond;
   pstChnlInfo->pstFlowControlLock = &stFlowControlLock;

   ANT_FUNC_END();
}
static int ant_enable_channel(ant_channel_info_t *pstChnlInfo)
{
   int iRet = -1;
   ANT_FUNC_START();
   if (!pstChnlInfo) {
      ANT_ERROR("null channel info passed to channel enable function");
      errno = EINVAL;
      goto out;
   }
   if (pstChnlInfo->iFd == -1) {
      // Use the init_transport function to release our fd instead of close()
      pstChnlInfo->iFd = init_transport_bdroid(1);
      if (pstChnlInfo->iFd < 0) {
         ANT_ERROR("failed to open dev %s: %s", pstChnlInfo->pcDevicePath, strerror(errno));
         goto out;
      }
   } else {
      ANT_DEBUG_D("%s is already enabled", pstChnlInfo->pcDevicePath);
   }
   iRet = 0;
out:
   ANT_FUNC_END();
   return iRet;
}
Example #30
0
/*
 * This thread opens a Bluez HCI socket and waits for ANT messages.
 */
void *ANTHCIRxThread(void *pvHCIDevice)
{
   int ret = ANT_STATUS_SUCCESS;
   int rxSocket;
   int len;
   unsigned char buf[HCI_MAX_EVENT_SIZE];
   int result;
   struct hci_filter eventVendorFilter;
   ANT_FUNC_START();

   (void)pvHCIDevice; //unused waring

   ANT_DEBUG_D("Entering ANTHCIRxThread");

   rxSocket = create_hci_sock();
   if (rxSocket < 0)
   {
      ANT_DEBUG_E("can't open HCI socket in rx thread: %s", strerror(errno));

      ret = ANT_STATUS_FAILED;
      goto out;
   }

   eventVendorFilter.type_mask = TYPE_MASK_EVENT_PACKET;
   eventVendorFilter.event_mask[0] = 0;
   eventVendorFilter.event_mask[1] = EVENT_MASK_1_EVENT_VENDOR;
   eventVendorFilter.opcode = htobs(ANT_EVENT_VENDOR_CODE);

   if (setsockopt(rxSocket, SOL_HCI, HCI_FILTER, &eventVendorFilter, sizeof(eventVendorFilter)) < 0)
   {
      ANT_ERROR("failed to set socket options: %s", strerror(errno));

      ret = ANT_STATUS_FAILED;
      goto close;
   }

   /* continue running as long as not terminated */
   while (get_and_set_radio_status() == RADIO_STATUS_ENABLED)
   {
      struct pollfd p;
      int n;

      p.fd = rxSocket;
      p.events = POLLIN;

      ANT_DEBUG_V("    RX: Polling HCI for data...");

      /* poll socket, wait for ANT messages */
      while ((n = poll(&p, 1, 2500)) == -1)
      {
         if (errno == EAGAIN || errno == EINTR)
            continue;

         ANT_ERROR("failed to poll socket: %s", strerror(errno));

         ret = ANT_STATUS_FAILED;
         goto close;
      }

      /* we timeout once in a while */
      /* this let's us the chance to check if we were terminated */
      if (0 == n)
      {
         ANT_DEBUG_V("    RX: Timeout");
         continue;
      }

      ANT_DEBUG_D("New HCI data available, reading...");

      /* read newly arrived data */
      /* TBD: rethink assumption about single arrival */
      while ((len = read(rxSocket, buf, sizeof(buf))) < 0)
      {
         if (errno == EAGAIN || errno == EINTR)
            continue;

         ANT_ERROR("failed to read socket: %s", strerror(errno));

         ret = ANT_STATUS_FAILED;
         goto close;
      }

      hci_event_packet_t *event_packet = (hci_event_packet_t *)buf;
      int hci_payload_len = validate_hci_event_packet(event_packet, len);
      if (hci_payload_len == -1)
      {
         // part of the message is incorrect, ignore it. validate_event_packet will log error
         continue;
      }

      ANT_SERIAL(event_packet->hci_payload, hci_payload_len, 'R');

      if(RxParams.pfRxCallback != NULL)
      {
         RxParams.pfRxCallback(hci_payload_len, event_packet->hci_payload);
      }
      else
      {
         ANT_ERROR("Can't send rx message - no callback registered");
      }
   }

close:
   result = pthread_mutex_trylock(&enableLock);
   ANT_DEBUG_D("rx thread close: trylock enableLock returned %d", result);

   if (result == 0)
   {
      ANT_DEBUG_W("rx thread socket has unexpectedly crashed");
#if USE_EXTERNAL_POWER_LIBRARY
      if (RxParams.pfStateCallback)
         RxParams.pfStateCallback(RADIO_STATUS_DISABLING);
      ant_disable();
      get_and_set_radio_status();
#else
      radio_status = RADIO_STATUS_DISABLED;
#endif
      RxParams.thread = 0;
      pthread_mutex_unlock(&enableLock);
   }
   else if (result == EBUSY)
   {
      ANT_DEBUG_V("rx thread socket was closed");
   }
   else
   {
      ANT_ERROR("rx thread close: trylock failed: %s", strerror(result));
   }

   if (-1 == close(rxSocket))
   {
      ANT_ERROR("failed to close hci device (socket handle=%#x): %s", rxSocket, strerror(errno));
   }
   else
   {
      ANT_DEBUG_D("closed hci device (socket handle=%#x)", rxSocket);
   }

out:
   ANT_FUNC_END();

   pthread_exit((void *)ret);

#if defined(ANDROID)
   return 0;
#endif
}