/*
*
* Copyright 2001-2011 Texas Instruments, Inc. - http://www.ti.com/
*
* 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.
*/
#include "android_runtime/AndroidRuntime.h"
#include "jni.h"
#include "JNIHelp.h"
#include "v4l2_JbtlLog.h"
#define LOG_TAG "JFmRxNative"
#include <cutils/properties.h>
using namespace android;
extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <asoundlib.h>
#include <linux/videodev.h>
#include <math.h>
#include <pthread.h>
#include <errno.h>
#include <string.h>
#include <poll.h>
#include "JFmRxNative.h"
/*Callback for FM commands*/
void nativeJFmRx_Callback(long context, int status,
int command, long value);
/*Callback for FM PS*/
void nativeJFmRx_PS_Callback(long context,int status, int freq,
int len,unsigned char * name,
int repertoire) ;
/*Callback for FM Radio Text*/
void nativeJFmRx_RadioText_Callback(int status, bool resetDisplay,
unsigned char * msg, int len, int startIndex,
int repertoire) ;
} //extern "C"
static JavaVM *g_jVM = NULL;
static jclass _sJClass;
typedef pthread_t THREAD_HANDLE;
THREAD_HANDLE p_threadHandle; /* Thread Handle for RDS data */
static bool isThreadCreated = false;
static int radio_fd;
//snd_ctl_t *fm_snd_ctrl;
long jContext;
volatile bool g_stopCommListener = false;
static int chanl_spacing=200000;
/* Complete parsing of the RDS data has not been implemented yet
Commented the FM RX RDS callbacks functionality start*/
#if 0
static jmethodID _sMethodId_nativeCb_fmRxRawRDS;
static jmethodID _sMethodId_nativeCb_fmRxPiCodeChanged;
static jmethodID _sMethodId_nativeCb_fmRxPtyCodeChanged;
static jmethodID _sMethodId_nativeCb_fmRxMonoStereoModeChanged;
static jmethodID _sMethodId_nativeCb_fmRxAudioPathChanged;
static jmethodID _sMethodId_nativeCb_fmRxAfSwitchFreqFailed;
static jmethodID _sMethodId_nativeCb_fmRxAfSwitchStart;
static jmethodID _sMethodId_nativeCb_fmRxAfSwitchComplete;
static jmethodID _sMethodId_nativeCb_fmRxAfListChanged;
static jmethodID _sMethodId_nativeCb_fmRxCompleteScanDone;
#endif
/*Commented the FM RX RDS callbacks functionality end*/
static jmethodID _sMethodId_nativeCb_fmRxPsChanged;
static jmethodID _sMethodId_nativeCb_fmRxRadioText;
static jmethodID _sMethodId_nativeCb_fmRxCmdEnable;
static jmethodID _sMethodId_nativeCb_fmRxCmdDisable;
static jmethodID _sMethodId_nativeCb_fmRxCmdEnableAudio;
static jmethodID _sMethodId_nativeCb_fmRxCmdChangeAudioTarget;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetBand;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetBand;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetMonoStereoMode;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetMonoStereoMode;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetMuteMode;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetMuteMode;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetRfDependentMuteMode;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetRfDependentMuteMode;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetRssiThreshhold;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetRssiThreshhold;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetDeemphasisFilter;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetDeemphasisFilter;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetVolume;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetVolume;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetChannelSpacing;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetChannelSpacing;
static jmethodID _sMethodId_nativeCb_fmRxCmdTune;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetTunedFrequency;
static jmethodID _sMethodId_nativeCb_fmRxCmdSeek;
static jmethodID _sMethodId_nativeCb_fmRxCmdStopSeek;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetRssi;
static jmethodID _sMethodId_nativeCb_fmRxCmdEnableRds;
static jmethodID _sMethodId_nativeCb_fmRxCmdDisableRds;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetRdsSystem;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetRdsSystem;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetRdsGroupMask;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetRdsGroupMask;
static jmethodID _sMethodId_nativeCb_fmRxCmdSetRdsAfSwitchMode;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetRdsAfSwitchMode;
static jmethodID _sMethodId_nativeCb_fmRxCmdDisableAudio;
static jmethodID _sMethodId_nativeCb_fmRxCmdDestroy;
static jmethodID _sMethodId_nativeCb_fmRxCmdChangeDigitalAudioConfiguration;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetFwVersion;
static jmethodID _sMethodId_nativeCb_fmRxCmdIsValidChannel;
static jmethodID _sMethodId_nativeCb_fmRxCmdGetCompleteScanProgress;
static jmethodID _sMethodId_nativeCb_fmRxCmdStopCompleteScan;
int rdsParseFunc_updateRepertoire(int byte1,int byte2)
{
int repertoire1,repertoire2;
int repertoire3,repertoire4;
int repertoire;
/*replace to nibble high/low*/
repertoire1 = (FMC_U8)(byte1&RDS_BIT_0_TO_BIT_3);
repertoire2 = (FMC_U8)((byte1&RDS_BIT_4_TO_BIT_7)>>4);
repertoire3 = (FMC_U8)(byte2&RDS_BIT_0_TO_BIT_3);
repertoire4 = (FMC_U8)((byte2&RDS_BIT_4_TO_BIT_7)>>4);
if((repertoire2==0)&&(repertoire1==15)&&(repertoire4==0)&&(repertoire3==15))
{
repertoire = FMC_RDS_REPERTOIRE_G0_CODE_TABLE;
}
else if((repertoire2==0)&&(repertoire1==14)&&(repertoire4==0)&&(repertoire3==14))
{
repertoire = FMC_RDS_REPERTOIRE_G1_CODE_TABLE;
}
else if ((repertoire2==1)&&(repertoire1==11)&&(repertoire4==6)&&(repertoire3==14))
{
repertoire = FMC_RDS_REPERTOIRE_G2_CODE_TABLE;
}
V4L2_JBTL_LOGD(" rdsParseFunc_updateRepertoire repertoire%d\n",repertoire);
return repertoire;
}
void rds_decode(int blkno, int byte1, int byte2)
{
static unsigned char rds_psn[9];
static unsigned char rds_txt[65];
static int rds_pty,ms_code;
static int group,spare,blkc_byte1,blkc_byte2;
int len;
bool resetDisplay =false;
int status = 0,startIndex=0,repertoire,freq;
switch (blkno) {
case 0: /* Block A */
V4L2_JBTL_LOGD("block A - id=%d\n",(byte1 << 8) | byte2);
break;
case 1: /* Block B */
V4L2_JBTL_LOGD("block B - group=%d%c tp=%d pty=%d spare=%d\n",
(byte1 >> 4) & 0x0f,
((byte1 >> 3) & 0x01) + 'A',
(byte1 >> 2) & 0x01,
((byte1 << 3) & 0x18) | ((byte2 >> 5) & 0x07),
byte2 & 0x1f);
group = (byte1 >> 3) & 0x1f;
spare = byte2 & 0x1f;
rds_pty = ((byte1 << 3) & 0x18) | ((byte2 >> 5) & 0x07);
ms_code = (byte2 >> 3)& 0x1;
break;
case 2: /* Block C */
V4L2_JBTL_LOGD("block C - 0x%02x 0x%02x\n",byte1,byte2);
blkc_byte1 = byte1;
blkc_byte2 = byte2;
break;
case 3 : /* Block D */
V4L2_JBTL_LOGD("block D - 0x%02x 0x%02x\n",byte1,byte2);
switch (group) {
case 0: /* Group 0A */
rds_psn[2*(spare & 0x03)+0] = byte1;
rds_psn[2*(spare & 0x03)+1] = byte2;
if ((spare & 0x03) == 0x03)
{
V4L2_JBTL_LOGD("PSN: %s, PTY: %d, MS: %s\n",rds_psn,
rds_pty,ms_code?"Music":"Speech");
len = strlen((const char *)rds_psn);
V4L2_JBTL_LOGD("PS len %d",len);
nativeJFmRx_PS_Callback(jContext,status,freq,len,rds_psn,repertoire);
}
break;
case 4: /* Group 2A */
repertoire = rdsParseFunc_updateRepertoire(byte1,byte2);
repertoire =0;
V4L2_JBTL_LOGD("Radio repertoire: %d\n",repertoire);
rds_txt[4*(spare & 0x0f)+0] = blkc_byte1;
rds_txt[4*(spare & 0x0f)+1] = blkc_byte2;
rds_txt[4*(spare & 0x0f)+2] = byte1;
rds_txt[4*(spare & 0x0f)+3] = byte2;
/* Display radio text once we get 16 characters */
if (spare > 16)
{
len =strlen((const char *)rds_txt);
V4L2_JBTL_LOGD("RDS len %d",len);
V4L2_JBTL_LOGD("Radio Text: %s\n",rds_txt);
nativeJFmRx_RadioText_Callback(status, resetDisplay,
rds_txt, len, startIndex,repertoire) ;
}
break;
}
V4L2_JBTL_LOGD("----------------------------------------\n");
break;
default:
V4L2_JBTL_LOGD("unknown block [%d]\n",blkno);
}
}
/**
* Function: entryFunctionForRdsThread
* Brief: Creates a thread for waiting on responses from RDS .
* Description:
*/
void *entryFunctionForRdsThread(void *data)
{
unsigned char buf[600];
int radio_fd;
int ret,index;
struct pollfd pfd;
radio_fd = (int)data;
V4L2_JBTL_LOGD(" entryFunctionForRdsThread: Entering.g_stopCommListener %d \n",g_stopCommListener);
while(!g_stopCommListener)
{
V4L2_JBTL_LOGD("RDS thread running..\n");
while(1){
memset(&pfd, 0, sizeof(pfd));
pfd.fd = radio_fd;
pfd.events = POLLIN;
ret = poll(&pfd, 1, 10);
if (ret == 0){
/* Break the poll after RDS data available */
break;
}
}
ret = read(radio_fd,buf,500);
if(ret < 0)
{ V4L2_JBTL_LOGD("NO RDS data to read..\n");
return NULL;
}
else if( ret > 0)
{
V4L2_JBTL_LOGD(" RDS data to read is available..\n");
for(index=0;index<ret;index+=3)
rds_decode(buf[index+2] & 0x7,buf[index+1],buf[index]);
}
}
V4L2_JBTL_LOGD("RDS thread exiting..\n");
return NULL;
}
int fm_read_tuner_capabilities(int radio_fd)
{
struct v4l2_capability cap;
int res;
res = ioctl(radio_fd,VIDIOC_QUERYCAP,&cap);
if(res < 0)
{
V4L2_JBTL_LOGD("Failed to read %s capabilities\n",DEFAULT_RADIO_DEVICE);
return FM_FAILED;
}
if((cap.capabilities & V4L2_CAP_RADIO) == 0)
{
V4L2_JBTL_LOGD("%s is not radio devcie",DEFAULT_RADIO_DEVICE);
return FM_FAILED;
}
V4L2_JBTL_LOGD("\n***%s Info ****\n",DEFAULT_RADIO_DEVICE);
V4L2_JBTL_LOGD("Driver : %s\n",cap.driver);
V4L2_JBTL_LOGD("Card : %s\n",cap.card);
V4L2_JBTL_LOGD("Bus : %s\n",cap.bus_info);
V4L2_JBTL_LOGD("Capabilities : 0x%x\n",cap.capabilities);
return FM_SUCCESS;
}
static int nativeJFmRx_Create(JNIEnv *env,jobject obj,jobject jContextValue)
{
int fmStatus ;
V4L2_JBTL_LOGD("Java_JFmRx_nativeJFmRx_Create(): Entered");
radio_fd = open(DEFAULT_RADIO_DEVICE, O_RDWR);
if(radio_fd < 0)
{
V4L2_JBTL_LOGD("Unable to open %s ..\n",DEFAULT_RADIO_DEVICE);
jniThrowIOException(env, errno);
return FM_FAILED;
}
fmStatus = fm_read_tuner_capabilities(radio_fd);
if(fmStatus< 0)
{
close(radio_fd);
return fmStatus;
}
V4L2_JBTL_LOGD("nativeJFmRx_create:Exiting Successfully");
return fmStatus;
}
static int nativeJFmRx_Destroy(JNIEnv *env, jobject obj,jlong jContextValue)
{
V4L2_JBTL_LOGD("nativeJFmRx_destroy(): Entered");
V4L2_JBTL_LOGD("nativeJFmRx_destroy(): Exit");
return FM_SUCCESS;
}
static int nativeJFmRx_Enable(JNIEnv *env, jobject obj, jlong jContextValue)
{
int status ;
struct v4l2_tuner vtun;
V4L2_JBTL_LOGD("nativeJFmRx_enable(): Entered");
jContext = jContextValue;
vtun.index = 0;
vtun.audmode = V4L2_TUNER_MODE_STEREO;
vtun.rxsubchans = V4L2_TUNER_SUB_RDS;
status = ioctl(radio_fd, VIDIOC_S_TUNER, &vtun);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to Enable FM\n");
return status;
}
V4L2_JBTL_LOGD("nativeJFmRx_enable: FM_RX_Enable() returned %d",(int)status);
nativeJFmRx_Callback(jContext,status,FM_RX_CMD_ENABLE,status);
V4L2_JBTL_LOGD("nativeJFmRx_enable(): Exit");
return status;
}
static int nativeJFmRx_Disable(JNIEnv *env, jobject obj, jlong jContextValue)
{
V4L2_JBTL_LOGD("nativeJFmRx_disable(): Entered");
// Terminate RDS thread
g_stopCommListener = true;
isThreadCreated = false;
close(radio_fd);
nativeJFmRx_Callback(jContext,0,FM_RX_CMD_DISABLE,0);
V4L2_JBTL_LOGD("nativeJFmRx_disable(): Exit");;
return FM_SUCCESS;
}
static int nativeJFmRx_SetBand(JNIEnv *env, jobject obj,jlong jContextValue, jint jFmBand)
{
int status=0;
static unsigned char last_band = FM_BAND_EUROPE_US;
char curr_band;
int fd, res;
switch(jFmBand) {
case 1:
curr_band = '1';
break;
case 0:
default:
curr_band = '0';
break;
}
V4L2_JBTL_LOGD("nativeJFmRx_setBand(): EnteredjFmBand %d",jFmBand);
V4L2_JBTL_LOGD("nativeJFmRx_setBand(): curr_band %d last_band %d",curr_band,last_band);
fd = open(FM_BAND_SYSFS_ENTRY, O_RDWR);
if (fd < 0) {
V4L2_JBTL_LOGD("Can't open %s", FM_BAND_SYSFS_ENTRY);
return FM_FAILED;
}
res = write(fd, &curr_band, sizeof(char));
if(res <= 0){
V4L2_JBTL_LOGD("Failed to set FM Band\n");
return FM_FAILED;
}
nativeJFmRx_Callback(jContext,status,FM_RX_CMD_SET_BAND,status);
V4L2_JBTL_LOGD("nativeJFmRx_setBand(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetBand(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status = 0;
unsigned char curr_band;
nativeJFmRx_Callback(jContext,status,FM_RX_CMD_GET_BAND,curr_band);
V4L2_JBTL_LOGD("nativeJFmRx_getBand(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_Tune(JNIEnv *env, jobject obj,jlong jContextValue,jint user_freq)
{
struct v4l2_frequency vf;
struct v4l2_tuner vt;
int status, div;
V4L2_JBTL_LOGD("nativeJFmRx_tune(): Entered");
vt.index = 0;
status = ioctl(radio_fd, VIDIOC_G_TUNER, &vt);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to get tuner capabilities\n");
return FM_FAILED;
}
vf.tuner = 0;
vf.frequency = rint(user_freq * 16 + 0.5);
div = (vt.capability & V4L2_TUNER_CAP_LOW) ? 1000 : 1;
if (div == 1)
vf.frequency /=1000;
status = ioctl(radio_fd, VIDIOC_S_FREQUENCY, &vf);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to tune to frequency %d\n",user_freq);
return FM_FAILED;
}
V4L2_JBTL_LOGD("Tuned to frequency %2.1f MHz\n",user_freq);
nativeJFmRx_Callback(jContext,status,FM_RX_CMD_TUNE,user_freq);
V4L2_JBTL_LOGD("nativeJFmRx_Tune(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetTunedFrequency(JNIEnv *env, jobject obj,jlong jContextValue)
{
struct v4l2_frequency vf;
int status;
V4L2_JBTL_LOGD("nativeJFmRx_getTunedFrequency(): Entered");
status = ioctl(radio_fd, VIDIOC_G_FREQUENCY,&vf);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to read current frequency\n");
return FM_FAILED;
}
V4L2_JBTL_LOGD("Tuned to frequency %2.1f MHz \n",(float)vf.frequency/1000);
nativeJFmRx_Callback(jContext,status,FM_RX_CMD_GET_TUNED_FREQUENCY,vf.frequency);
V4L2_JBTL_LOGD("nativeJFmRx_getTunedFrequency(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_SetMonoStereoMode(JNIEnv *env, jobject obj,jlong jContextValue,jint jFmMode)
{
struct v4l2_tuner vt;
int status;
V4L2_JBTL_LOGD("nativeJFmRx_SetMonoStereoMode(): Entered");
vt.index = 0;
vt.audmode = jFmMode;
status = ioctl(radio_fd, VIDIOC_S_TUNER, &vt);
if (status < 0){
V4L2_JBTL_LOGD("Failed to set stereo/mono mode\n");
return FM_FAILED;
}
V4L2_JBTL_LOGD("Set to %d Mode\n",jFmMode);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SET_MONO_STEREO_MODE,status);
V4L2_JBTL_LOGD("nativeJFmRx_SetMonoStereoMode(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetMonoStereoMode(JNIEnv *env, jobject obj,jlong jContextValue)
{
struct v4l2_tuner vt;
int status;
unsigned char mode;
V4L2_JBTL_LOGD("nativeJFmRx_GetMonoStereoMode(): Entered");
vt.index = 0;
status = ioctl(radio_fd, VIDIOC_G_TUNER, &vt);
if (status < 0){
V4L2_JBTL_LOGD("Failed to get stereo/mono mode\n");
return FM_FAILED;
}
mode = vt.audmode;
V4L2_JBTL_LOGD("%d mode\n",mode);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_MONO_STEREO_MODE,mode);
V4L2_JBTL_LOGD("nativeJFmRx_GetMonoStereoMode(): Exit");
return FM_PENDING ;
}
static int nativeJFmRx_SetMuteMode(JNIEnv *env, jobject obj,jlong jContextValue,jint jFmMuteMode)
{
struct v4l2_control vctrl;
int status;
V4L2_JBTL_LOGD("nativeJFmRx_setMuteMode(): Entered");
vctrl.id = V4L2_CID_AUDIO_MUTE;
vctrl.value = !jFmMuteMode; /* To Do:: Mapping in future for V4L2*/
status = ioctl(radio_fd,VIDIOC_S_CTRL,&vctrl);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to set mute mode\n");
return FM_FAILED;
}
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SET_MUTE_MODE,status);
V4L2_JBTL_LOGD("nativeJFmRx_setMuteMode(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetMuteMode(JNIEnv *env, jobject obj,jlong jContextValue)
{
struct v4l2_control vctrl;
int status;
V4L2_JBTL_LOGD("nativeJFmRx_getMuteMode(): Entered");
vctrl.id = V4L2_CID_AUDIO_MUTE;
status = ioctl(radio_fd,VIDIOC_G_CTRL,&vctrl);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to get mute mode\n");
return FM_FAILED;
}
V4L2_JBTL_LOGD("%d\n",vctrl.value);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_MUTE_MODE,vctrl.value);
V4L2_JBTL_LOGD("nativeJFmRx_getMuteMode(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_SetRssiThreshold(JNIEnv *env, jobject obj,jlong jContextValue,jint jFmRssi)
{
int status;
char rssi_lvl[10];
int fd, res;
V4L2_JBTL_LOGD("nativeJFmRx_setRssiThreshold(): Entered");
sprintf(rssi_lvl,"%d",jFmRssi);
V4L2_JBTL_LOGD("nativeJFmRx_setRssiThreshold(): val = %s", rssi_lvl);
;
fd = open(FM_RSSI_LVL_SYSFS_ENTRY, O_RDWR);
if (fd < 0) {
V4L2_JBTL_LOGD("Can't open %s", FM_RSSI_LVL_SYSFS_ENTRY);
return FM_FAILED;
}
res = write(fd, &rssi_lvl, sizeof(char));
if(res <= 0){
V4L2_JBTL_LOGD("Failed to set FM RSSI level\n");
return FM_FAILED;
}
V4L2_JBTL_LOGD("Setting rssi to %d\n",jFmRssi);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SET_RSSI_THRESHOLD,status);
V4L2_JBTL_LOGD("nativeJFmRx_setRssiThreshold(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetRssiThreshold(JNIEnv *env, jobject obj,jlong jContextValue)
{
short rssi_threshold;
int status;
V4L2_JBTL_LOGD("nativeJFmRx_getRssiThreshold(): Entered");
status = 0;
V4L2_JBTL_LOGD("RSSI threshold set to %d\n",rssi_threshold);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_RSSI_THRESHOLD,rssi_threshold);
V4L2_JBTL_LOGD("nativeJFmRx_getRssiThreshold(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetRssi(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status;
short curr_rssi_lvl;
V4L2_JBTL_LOGD("nativeJFmRx_getRssi(): Entered");
status = 0;
V4L2_JBTL_LOGD("RSSI level is %d\n",curr_rssi_lvl);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_RSSI,curr_rssi_lvl);
V4L2_JBTL_LOGD("nativeJFmRx_getRssi(): Exit");
return FM_PENDING;;
}
static int nativeJFmRx_SetVolume(JNIEnv *env, jobject obj,jlong jContextValue,jint jFmVolume)
{
struct v4l2_control vctrl;
int status;
V4L2_JBTL_LOGD("nativeJFmRx_SetVolume(): Entered");
vctrl.id = V4L2_CID_AUDIO_VOLUME;
vctrl.value = jFmVolume;
status = ioctl(radio_fd,VIDIOC_S_CTRL,&vctrl);
if(status < 0)
{
V4L2_JBTL_LOGD("nativeJFmRx_SetVolume():Failed to set volume\n");
return status;
}
V4L2_JBTL_LOGD("nativeJFmRx_SetVolume():Setting volume to %d \n",jFmVolume);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SET_VOLUME,status);
V4L2_JBTL_LOGD("nativeJFmRx_SetVolume(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetVolume(JNIEnv *env, jobject obj,jlong jContextValue)
{
struct v4l2_control vctrl;
int status;
V4L2_JBTL_LOGD("nativeJFmRx_getVolume(): Entered");
vctrl.id = V4L2_CID_AUDIO_VOLUME;
status = ioctl(radio_fd,VIDIOC_G_CTRL,&vctrl);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to get volume\n");
return status;
}
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_VOLUME,vctrl.value);
V4L2_JBTL_LOGD("nativeJFmRx_getVolume(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_SetChannelSpacing(JNIEnv *env, jobject obj,jlong jContextValue,jint jFmChannelSpacing)
{
int status = 0;
ALOGD("nativeJFmRx_SetChannelSpacing(): Entered");
chanl_spacing = jFmChannelSpacing * 50000;
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SET_CHANNEL_SPACING,status);
ALOGD("nativeJFmRx_SetChannelSpacing(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetChannelSpacing(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status =0;
ALOGD("nativeJFmRx_GetChannelSpacing(): Entered");
ALOGD("nativeJFmRx_GetChannelSpacing(): Exit");
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_CHANNEL_SPACING,status);
return FM_PENDING;
}
static jint nativeJFmRx_SetDeEmphasisFilter(JNIEnv *env, jobject obj,jlong jContextValue,jint jFmEmphasisFilter)
{
int status;
V4L2_JBTL_LOGD("nativeJFmRx_SetDeEmphasisFilter(): Entered");
V4L2_JBTL_LOGD("1. nativeJFmRx_EnableRDS\n");
status = 0;
V4L2_JBTL_LOGD("Set to De-emphasis %d mode\n",jFmEmphasisFilter);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SET_DEEMPHASIS_FILTER,status);
V4L2_JBTL_LOGD("nativeJFmRx_SetDeEmphasisFilter(): Exit");
V4L2_JBTL_LOGD("2. nativeJFmRx_EnableRDS\n");
return FM_PENDING;
}
static int nativeJFmRx_GetDeEmphasisFilter(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status;
unsigned char mode;
V4L2_JBTL_LOGD("nativeJFmRx_GetDeEmphasisFilter(): Entered");
V4L2_JBTL_LOGD("1. nativeJFmRx_EnableRDS\n");
mode = 0;
V4L2_JBTL_LOGD("De-emphasis filter %d\n",mode);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_DEEMPHASIS_FILTER,mode);
V4L2_JBTL_LOGD("nativeJFmRx_GetDeEmphasisFilter(): Exit");
V4L2_JBTL_LOGD("2. nativeJFmRx_EnableRDS\n");
return FM_PENDING;
}
static int nativeJFmRx_Seek(JNIEnv *env, jobject obj,jlong jContextValue,jint jdirection)
{
struct ti_v4l2_hw_freq_seek frq_seek;
struct v4l2_frequency vf;
struct v4l2_tuner vt;
int status, div;
V4L2_JBTL_LOGD("nativeJFmRx_Seek(): Entered");
V4L2_JBTL_LOGD("Seeking %s.. and channel spacing is %d\n",jdirection?"up":"down", chanl_spacing);
frq_seek.seek_upward = jdirection;
frq_seek.type = (v4l2_tuner_type)1;
frq_seek.spacing = chanl_spacing;
frq_seek.wrap_around = 0;
errno = 0;
status = ioctl(radio_fd,VIDIOC_S_HW_FREQ_SEEK,&frq_seek);
if(errno == EAGAIN)
{
V4L2_JBTL_LOGD("Band limit reached\n");
}
else if(status <0)
{
V4L2_JBTL_LOGD("Seek operation failed\n");
return status;
}
V4L2_JBTL_LOGD("nativeJFmRx_tune(): Entered");
vt.index = 0;
status = ioctl(radio_fd, VIDIOC_G_TUNER, &vt);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to get tuner capabilities\n");
return FM_FAILED;
}
div = (vt.capability & V4L2_TUNER_CAP_LOW) ? 1000 : 1;
status = ioctl(radio_fd, VIDIOC_G_FREQUENCY,&vf);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to read current frequency\n");
return status;
}
V4L2_JBTL_LOGD("Tuned to frequency %3.2f MHz \n",vf.frequency / (16.0 * div));
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SEEK,vf.frequency * 1000 / (16 * div));
V4L2_JBTL_LOGD("nativeJFmRx_Seek(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_StopSeek(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status =0;
V4L2_JBTL_LOGD("nativeJFmRx_StopSeek(): Entered");
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_STOP_SEEK,status);
V4L2_JBTL_LOGD("nativeJFmRx_StopSeek(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_EnableRDS(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status;
unsigned char rds_mode = FM_RDS_ENABLE;
struct v4l2_tuner vt;
V4L2_JBTL_LOGD("nativeJFmRx_enableRDS(): Entered");
V4L2_JBTL_LOGD("1. nativeJFmRx_EnableRDS\n");
vt.index = 0;
status = ioctl(radio_fd, VIDIOC_G_TUNER, &vt);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to get tuner attributes\n");
return status;
}
V4L2_JBTL_LOGD("2. nativeJFmRx_EnableRDS\n");
if ((vt.rxsubchans & V4L2_TUNER_SUB_RDS) != 1)
vt.rxsubchans |= V4L2_TUNER_SUB_RDS;
status = ioctl(radio_fd, VIDIOC_S_TUNER, &vt);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to set RDS on/off status\n");
return status;
}
V4L2_JBTL_LOGD("3. nativeJFmRx_EnableRDS\n");
if(isThreadCreated == false)
{
V4L2_JBTL_LOGD(" nativeJFmRx_EnableRDS: creating thread !!! \n");
g_stopCommListener = false;
/* Create rds receive thread once */
status = pthread_create(&p_threadHandle, /* Thread Handle. */
NULL, /* Default Atributes. */
entryFunctionForRdsThread, /* Entry Function. */
(void *)radio_fd); /* Parameters. */
if (status < 0)
{
V4L2_JBTL_LOGD(" nativeJFmRx_EnableRDS: Thread Creation FAILED !!! \n");
return FM_ERR_THREAD_CREATION_FAILED;
}
isThreadCreated = true;
}
else
V4L2_JBTL_LOGD("RDS thread already created\n");
V4L2_JBTL_LOGD("4. nativeJFmRx_EnableRDS\n");
V4L2_JBTL_LOGD("RDS %d\n",rds_mode);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_ENABLE_RDS,status);
V4L2_JBTL_LOGD("nativeJFmRx_enableRDS(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_DisableRDS(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status;
unsigned char rds_mode = FM_RDS_DISABLE;
struct v4l2_tuner vt;
V4L2_JBTL_LOGD("1. nativeJFmRx_DisableRDS\n");
vt.index = 0;
status = ioctl(radio_fd, VIDIOC_G_TUNER, &vt);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to get tuner attributes\n");
return status;
}
if(vt.rxsubchans & V4L2_TUNER_SUB_RDS)
vt.rxsubchans &= ~V4L2_TUNER_SUB_RDS;
V4L2_JBTL_LOGD("2. nativeJFmRx_DisableRDS and vt.rxsubchans = %d\n", vt.rxsubchans);
status = ioctl(radio_fd, VIDIOC_S_TUNER, &vt);
if(status < 0)
{
V4L2_JBTL_LOGD("Failed to set RDS on/off status\n");
return status;
}
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_DISABLE_RDS,status);
V4L2_JBTL_LOGD("nativeJFmRx_DisableRDS(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_EnableAudioRouting(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status = 0 ;
V4L2_JBTL_LOGD("nativeJFmRx_enableAudioRouting(): Entered");
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_ENABLE_AUDIO,status);
V4L2_JBTL_LOGD("nativeJFmRx_enableAudioRouting(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_DisableAudioRouting(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status = 0 ;
V4L2_JBTL_LOGD("nativeJFmRx_disableAudioRouting(): Entered");
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_ENABLE_AUDIO,status);
V4L2_JBTL_LOGD("nativeJFmRx_disableAudioRouting(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_SetRdsAfSwitchMode(JNIEnv *env, jobject obj,jlong jContextValue,jint jRdsAfSwitchMode)
{
int status;
char af_switch;
int fd, res;
V4L2_JBTL_LOGD("nativeJFmRx_setRdsAfSwitchMode(): Entered");
switch(jRdsAfSwitchMode) {
case 1:
af_switch = '1';
break;
case 0:
default:
af_switch = '0';
break;
}
fd = open(FM_RDS_AF_SYSFS_ENTRY, O_RDWR);
if (fd < 0) {
V4L2_JBTL_LOGD("Can't open %s", FM_RDS_AF_SYSFS_ENTRY);
return FM_FAILED;
}
res = write(fd, &af_switch, sizeof(char));
if(res <= 0){
V4L2_JBTL_LOGD("Failed to set FM AF Switch\n");
return FM_FAILED;
}
V4L2_JBTL_LOGD("AF Switch %d ",jRdsAfSwitchMode);
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SET_RDS_AF_SWITCH_MODE,status);
V4L2_JBTL_LOGD("nativeJFmRx_setRdsAfSwitchMode(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetRdsAfSwitchMode(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status;
unsigned char af_mode;
V4L2_JBTL_LOGD("nativeJFmRx_getRdsAfSwitchMode(): Entered");
status = 0;
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_RDS_AF_SWITCH_MODE,af_mode);
V4L2_JBTL_LOGD("nativeJFmRx_getRdsAfSwitchMode(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_ChangeAudioTarget (JNIEnv *env, jobject obj,jlong jContextValue, jint jFmRxAudioTargetMask, jint digitalConfig)
{
V4L2_JBTL_LOGD("nativeJFmRx_ChangeAudioTarget(): Entered");
//nativeJFmRx_Callback(jContext,status, FM_RX_CMD_CHANGE_AUDIO_TARGET,status);
V4L2_JBTL_LOGD("nativeJFmRx_ChangeAudioTarget(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_ChangeDigitalTargetConfiguration(JNIEnv *env, jobject obj,jlong jContextValue,jint digitalConfig)
{
V4L2_JBTL_LOGD("nativeJFmRx_ChangeDigitalTargetConfiguration(): Entered");
//nativeJFmRx_Callback(jContext,status, FM_RX_CMD_CHANGE_DIGITAL_AUDIO_CONFIGURATION,status);
V4L2_JBTL_LOGD("nativeJFmRx_ChangeDigitalTargetConfiguration(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_SetRfDependentMuteMode(JNIEnv *env, jobject obj,jlong jContextValue, jint rf_mute)
{
int status;
V4L2_JBTL_LOGD("nativeJFmRx_SetRfDependentMuteMode(): Entered");
status = 0;
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SET_RF_DEPENDENT_MUTE_MODE,status);
V4L2_JBTL_LOGD("nativeJFmRx_SetRfDependentMuteMode(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetRfDependentMute(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status;
unsigned char rf_mute;
V4L2_JBTL_LOGD(" nativeJFmRx_GetRfDependentMute(): Entered");
status = 0;
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_RF_DEPENDENT_MUTE_MODE,rf_mute);
V4L2_JBTL_LOGD(" nativeJFmRx_GetRfDependentMute(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_SetRdsSystem(JNIEnv *env, jobject obj,jlong jContextValue, jint rdsSystem)
{
int status;
V4L2_JBTL_LOGD(" nativeJFmRx_SetRdsSystem(): Entered");
V4L2_JBTL_LOGD("entered to ELSE\n");
status = 0;
V4L2_JBTL_LOGD("Set to %d\n",rdsSystem);
nativeJFmRx_Callback(jContext,status,FM_RX_CMD_SET_RDS_SYSTEM,status);
V4L2_JBTL_LOGD(" nativeJFmRx_SetRdsSystem(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetRdsSystem(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status;
unsigned char mode;
V4L2_JBTL_LOGD("nativeJFmRx_GetRdsSystem(): Entered");
status = 0;
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_RDS_SYSTEM,mode);
V4L2_JBTL_LOGD(" nativeJFmRx_GetRdsSystem(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_SetRdsGroupMask(JNIEnv *env, jobject obj,jlong jContextValue, jlong groupMask)
{
int status =0;
V4L2_JBTL_LOGD("nativeJFmRx_SetRdsGroupMask(): Entered");
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_SET_RDS_GROUP_MASK,status);
V4L2_JBTL_LOGD(" nativeJFmRx_SetRdsGroupMask(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetRdsGroupMask(JNIEnv *env, jobject obj,jlong jContextValue)
{
int status =0;
V4L2_JBTL_LOGD("nativeJFmRx_GetRdsGroupMask(): Entered");
nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_RDS_GROUP_MASK,status);
V4L2_JBTL_LOGD(" nativeJFmRx_GetRdsGroupMask(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_CompleteScan(JNIEnv *env, jobject obj, jlong jContextValue)
{
int status =0;
ALOGD("nativeJFmRx_CompleteScan(): Entered");
//nativeJFmRx_Callback(jContext,status, FM_RX_CMD_COMPLETE_SCAN,status);
ALOGD("nativeJFmRx_CompleteScan(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetCompleteScanProgress(JNIEnv *env, jobject obj, jlong jContextValue)
{
int status =0;
ALOGD("nativeJFmRx_GetCompleteScanProgress(): Entered");
//nativeJFmRx_Callback(jContext,status, FM_RX_CMD_COMPLETE_SCAN_PROGRESS,status);
ALOGD("nativeJFmRx_GetCompleteScanProgress(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_StopCompleteScan(JNIEnv *env, jobject obj, jlong jContextValue)
{
ALOGD("nativeJFmRx_StopCompleteScan(): Entered");
//nativeJFmRx_Callback(jContext,status, FM_RX_CMD_STOP_COMPLETE_SCAN,status);
ALOGD("nativeJFmRx_StopCompleteScan(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_IsValidChannel(JNIEnv *env, jobject obj, jlong jContextValue)
{
ALOGD("nativeJFmRx_IsValidChannel(): Entered");
//nativeJFmRx_Callback(jContext,status, FM_RX_CMD_IS_CHANNEL_VALID ,status);
ALOGD("nativeJFmRx_IsValidChannel(): Exit");
return FM_PENDING;
}
static int nativeJFmRx_GetFwVersion(JNIEnv *env, jobject obj, jlong jContextValue)
{
ALOGD("nativeJFmRx_GetFwVersion(): Entered");
//nativeJFmRx_Callback(jContext,status, FM_RX_CMD_GET_FW_VERSION,status);
ALOGD("nativeJFmRx_GetFwVersion(): Exit");
return FM_PENDING;
}
//################################################################################
// SIGNALS
//###############################################################################
extern "C"
{
void nativeJFmRx_RadioText_Callback(int status, bool resetDisplay,
unsigned char * msg, int len, int startIndex,
int repertoire)
{
ALOGE("nativeJFmRx_RadioText_Callback: Entering");
ALOGE("nativeJFmRx_RadioText_Callback: msg %s",msg);
JNIEnv* env = NULL;
bool attachedThread = false;
int jRet ;
jbyteArray jRadioTxtMsg = NULL;
/* check whether the current thread is attached to a virtual machine instance,
if no only then try to attach to the current thread. */
jRet = g_jVM->GetEnv((void **)&env,JNI_VERSION_1_4);
if(jRet < 0)
{
ALOGE("failed to get JNI env,assuming native thread");
jRet = g_jVM->AttachCurrentThread((&env), NULL);
if(jRet != JNI_OK)
{
ALOGE("failed to atatch to current thread %d",jRet);
return ;
}
attachedThread = true;
}
if(env == NULL) {
ALOGI("%s: Entered, env is null", __func__);
} else {
ALOGD("%s: jEnv %p", __func__, (void *)env);
}
V4L2_JBTL_LOGD("nativeJFmRx_Callback():EVENT --------------->FM_RX_EVENT_RADIO_TEXT");
jRadioTxtMsg = env->NewByteArray(len);
if (jRadioTxtMsg == NULL) {
ALOGE("%s: Failed converting elements", __func__);
goto CLEANUP;
}
env->SetByteArrayRegion(jRadioTxtMsg,
0,
len,
(jbyte*)msg);
if (env->ExceptionOccurred()) {
ALOGE("%s: Calling nativeCb_fmRxRadioText failed",
__func__);
goto CLEANUP;
}
env->CallStaticVoidMethod(_sJClass,
_sMethodId_nativeCb_fmRxRadioText,(jlong)jContext,
(jint)status,
(jboolean)resetDisplay,
jRadioTxtMsg,
(jint)len,
(jint)startIndex,
(jint)repertoire);
if (env->ExceptionOccurred()) {
ALOGE("nativeJFmRx_RadioText_Callback: ExceptionOccurred");
goto CLEANUP;
}
if(jRadioTxtMsg!= NULL)
env->DeleteLocalRef(jRadioTxtMsg);
if(attachedThread == true)
g_jVM->DetachCurrentThread();
return ;
CLEANUP:
ALOGE("nativeJFmRx_RadioText_Callback: Exiting due to failure");
if(jRadioTxtMsg!= NULL)
env->DeleteLocalRef(jRadioTxtMsg);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
if(attachedThread == true)
g_jVM->DetachCurrentThread();
return ;
}
void nativeJFmRx_PS_Callback(long context,int status, int freq,
int len,unsigned char * name,
int repertoire)
{
ALOGE("nativeJFmRx_PS_Callback: Exiting due to failure");
JNIEnv* env = NULL;
bool attachedThread = false;
int jRet ;
jbyteArray jNameString = NULL;
int frequency =0;
/* check whether the current thread is attached to a virtual machine instance,
if no only then try to attach to the current thread. */
jRet = g_jVM->GetEnv((void **)&env,JNI_VERSION_1_4);
if(jRet < 0)
{
ALOGE("failed to get JNI env,assuming native thread");
jRet = g_jVM->AttachCurrentThread((&env), NULL);
if(jRet != JNI_OK)
{
ALOGE("failed to atatch to current thread %d",jRet);
return ;
}
attachedThread = true;
}
if(env == NULL) {
ALOGI("%s: Entered, env is null", __func__);
} else {
ALOGD("%s: jEnv %p", __func__, (void *)env);
}
V4L2_JBTL_LOGD("nativeJFmRx_PS_Callback():EVENT --------------->FM_RX_EVENT_PS_CHANGED len %d",len);
jNameString = env->NewByteArray(len);
if (jNameString == NULL)
{
V4L2_JBTL_LOGD("nativeJFmRx_PS_Callback: Failed converting elements");
goto CLEANUP;
}
env->SetByteArrayRegion(jNameString,0,len,(jbyte*)name);
if (env->ExceptionOccurred()) {
V4L2_JBTL_LOGD("nativeJFmRx_PS_Callback: Calling Java nativeCb_fmRxRadioText failed");
goto CLEANUP;
}
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxPsChanged,(jlong)context,
(jint)status,
(jint)frequency,
jNameString,
(jint)repertoire);
if (env->ExceptionOccurred()) {
ALOGE("nativeJFmRx_PS_Callback: ExceptionOccurred");
goto CLEANUP;
}
if(jNameString!= NULL)
env->DeleteLocalRef(jNameString);
if(attachedThread == true)
g_jVM->DetachCurrentThread();
return ;
CLEANUP:
ALOGE("nativeJFmRx_PS_Callback: Exiting due to failure");
if(jNameString!= NULL)
env->DeleteLocalRef(jNameString);
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
if(attachedThread == true)
g_jVM->DetachCurrentThread();
return ;
}
void nativeJFmRx_Callback(long context, int status,
int command, long value)
{
V4L2_JBTL_LOGI("nativeJFmRx_Callback: Entered, ");
JNIEnv* env = NULL;
bool attachedThread = false;
int jRet ;
/* check whether the current thread is attached to a virtual machine instance,
if no only then try to attach to the current thread. */
jRet = g_jVM->GetEnv((void **)&env,JNI_VERSION_1_4);
if(jRet < 0)
{
V4L2_JBTL_LOGI("failed to get JNI env,assuming native thread");
jRet = g_jVM->AttachCurrentThread((&env), NULL);
if(jRet != JNI_OK)
{
V4L2_JBTL_LOGI("failed to atatch to current thread %d",jRet);
return ;
}
attachedThread = true;
}
if(env == NULL)
{
V4L2_JBTL_LOGD("nativeJFmRx_Callback: Entered, env is null");
}
switch (command)
{
case FM_RX_CMD_ENABLE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdEnable,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_DISABLE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdDisable,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_BAND:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetBand,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_BAND:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetBand,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_MONO_STEREO_MODE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetMonoStereoMode,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_MONO_STEREO_MODE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetMonoStereoMode,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_MUTE_MODE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetMuteMode,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_MUTE_MODE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetMuteMode,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_RF_DEPENDENT_MUTE_MODE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetRfDependentMuteMode,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_RF_DEPENDENT_MUTE_MODE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetRfDependentMuteMode,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_RSSI_THRESHOLD:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetRssiThreshhold,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_RSSI_THRESHOLD:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetRssiThreshhold,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_DEEMPHASIS_FILTER:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetDeemphasisFilter,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_DEEMPHASIS_FILTER:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetDeemphasisFilter,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_VOLUME:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetVolume,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_VOLUME:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetVolume,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_TUNE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdTune,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_TUNED_FREQUENCY:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetTunedFrequency,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SEEK:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSeek,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_STOP_SEEK:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdStopSeek,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_RSSI:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetRssi,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_ENABLE_RDS:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdEnableRds,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_DISABLE_RDS:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdDisableRds,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_RDS_SYSTEM:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetRdsSystem,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_RDS_SYSTEM:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetRdsSystem,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_RDS_GROUP_MASK:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetRdsGroupMask,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_RDS_GROUP_MASK:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetRdsGroupMask,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_RDS_AF_SWITCH_MODE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetRdsAfSwitchMode,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_RDS_AF_SWITCH_MODE:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetRdsAfSwitchMode,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_ENABLE_AUDIO:
V4L2_JBTL_LOGD("nativeJFmRx_Callback: at FM_RX_CMD_ENABLE_AUDIO step 1");
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdEnableAudio,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
V4L2_JBTL_LOGD("nativeJFmRx_Callback: at FM_RX_CMD_ENABLE_AUDIO step 2");
break;
case FM_RX_CMD_DISABLE_AUDIO:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdDisableAudio, (jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_CHANGE_AUDIO_TARGET:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdChangeAudioTarget,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_CHANGE_DIGITAL_AUDIO_CONFIGURATION:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdChangeDigitalAudioConfiguration,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_SET_CHANNEL_SPACING:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdSetChannelSpacing,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_CHANNEL_SPACING:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetChannelSpacing,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_GET_FW_VERSION:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetFwVersion,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_IS_CHANNEL_VALID:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdIsValidChannel,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_COMPLETE_SCAN_PROGRESS:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdGetCompleteScanProgress,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
case FM_RX_CMD_STOP_COMPLETE_SCAN:
env->CallStaticVoidMethod(_sJClass,_sMethodId_nativeCb_fmRxCmdStopCompleteScan,(jlong)context,
(jint)status,
(jint)command,
(jlong)value);
break;
default:
V4L2_JBTL_LOGD("nativeJFmRx_Callback:FM_RX_EVENT_CMD_DONE,unhendeld event");
break;
}
if (env->ExceptionOccurred()) {
V4L2_JBTL_LOGD("nativeJFmRx_Callback: ExceptionOccurred");
goto EXCEPTION;
}
V4L2_JBTL_LOGD("nativeJFmRx_Callback: Exiting, Calling DetachCurrentThread at the END");
if(attachedThread == true)
g_jVM->DetachCurrentThread();
return;
EXCEPTION:
/*Delete Jni Local refrencece */
V4L2_JBTL_LOGD("nativeJFmRx_Callback: Exiting due to failure");
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
if(attachedThread == true)
g_jVM->DetachCurrentThread();
return;
}
} //extern c
/**********************************************************************
* Callback registration
***********************************************************************/
#define VERIFY_METHOD_ID(methodId) \
if (!_VerifyMethodId(methodId, #methodId)) { \
V4L2_JBTL_LOGD("Error obtaining method id for %s", #methodId); \
return; \
}
static bool _VerifyMethodId(jmethodID methodId, const char *name)
{
bool result = true;
if (methodId == NULL)
{
V4L2_JBTL_LOGD("_VerifyMethodId: Failed getting method id of %s", name);
result = false;
}
return result;
}
void nativeJFmRx_ClassInitNative(JNIEnv* env, jclass clazz){
V4L2_JBTL_LOGD("nativeJFmRx_ClassInitNative: Entered");
if (NULL == env)
{
V4L2_JBTL_LOGD("nativeJFmRx_ClassInitNative: NULL == env");
}
env->GetJavaVM(&g_jVM);
/* Save class information in global reference in order to prevent class unloading */
_sJClass = (jclass)env->NewGlobalRef(clazz);
V4L2_JBTL_LOGI("nativeJFmRx_ClassInitNative: Obtaining method IDs");
_sMethodId_nativeCb_fmRxRadioText = env->GetStaticMethodID(clazz,
"nativeCb_fmRxRadioText",
"(JIZ[BIII)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxRadioText);
_sMethodId_nativeCb_fmRxPsChanged = env->GetStaticMethodID(clazz,
"nativeCb_fmRxPsChanged",
"(JII[BI)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxPsChanged);
/* Complete parsing of the RDS data has not been implemented yet
Commented the FM RX RDS callbacks functionality start*/
#if 0
_sMethodId_nativeCb_fmRxRawRDS = env->GetStaticMethodID(clazz,
"nativeCb_fmRxRawRDS",
"(JII[B)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxRawRDS);
_sMethodId_nativeCb_fmRxPiCodeChanged = env->GetStaticMethodID(clazz,
"nativeCb_fmRxPiCodeChanged",
"(JII)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxPiCodeChanged);
_sMethodId_nativeCb_fmRxPtyCodeChanged = env->GetStaticMethodID(clazz,
"nativeCb_fmRxPtyCodeChanged",
"(JII)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxPtyCodeChanged);
_sMethodId_nativeCb_fmRxMonoStereoModeChanged = env->GetStaticMethodID(clazz,
"nativeCb_fmRxMonoStereoModeChanged",
"(JII)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxMonoStereoModeChanged);
_sMethodId_nativeCb_fmRxAudioPathChanged = env->GetStaticMethodID(clazz,
"nativeCb_fmRxAudioPathChanged",
"(JI)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxAudioPathChanged);
_sMethodId_nativeCb_fmRxAfSwitchFreqFailed = env->GetStaticMethodID(clazz,
"nativeCb_fmRxAfSwitchFreqFailed",
"(JIIII)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxAfSwitchFreqFailed);
_sMethodId_nativeCb_fmRxAfSwitchStart = env->GetStaticMethodID(clazz,
"nativeCb_fmRxAfSwitchStart",
"(JIIII)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxAfSwitchStart);
_sMethodId_nativeCb_fmRxAfSwitchComplete = env->GetStaticMethodID(clazz,
"nativeCb_fmRxAfSwitchComplete",
"(JIIII)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxAfSwitchComplete);
_sMethodId_nativeCb_fmRxAfListChanged = env->GetStaticMethodID(clazz,
"nativeCb_fmRxAfListChanged",
"(JII[BI)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxAfListChanged);
#endif
/*Commented the FM RX RDS callbacks functionality end*/
_sMethodId_nativeCb_fmRxCmdEnable = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdEnable",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdEnable);
_sMethodId_nativeCb_fmRxCmdDisable = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdDisable",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdDisable);
_sMethodId_nativeCb_fmRxCmdEnableAudio = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdEnableAudio",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdEnableAudio);
_sMethodId_nativeCb_fmRxCmdChangeAudioTarget = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdChangeAudioTarget",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdChangeAudioTarget);
_sMethodId_nativeCb_fmRxCmdSetBand = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetBand",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetBand);
_sMethodId_nativeCb_fmRxCmdGetBand = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetBand",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetBand);
_sMethodId_nativeCb_fmRxCmdSetMonoStereoMode = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetMonoStereoMode",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetMonoStereoMode);
_sMethodId_nativeCb_fmRxCmdGetMonoStereoMode = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetMonoStereoMode",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetMonoStereoMode);
_sMethodId_nativeCb_fmRxCmdGetMuteMode = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetMuteMode",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetMuteMode);
_sMethodId_nativeCb_fmRxCmdSetMuteMode = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetMuteMode",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetMuteMode);
_sMethodId_nativeCb_fmRxCmdSetRfDependentMuteMode = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetRfDependentMuteMode",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetRfDependentMuteMode);
_sMethodId_nativeCb_fmRxCmdGetRfDependentMuteMode = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetRfDependentMuteMode",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetRfDependentMuteMode);
_sMethodId_nativeCb_fmRxCmdSetRssiThreshhold = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetRssiThreshhold",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetRssiThreshhold);
_sMethodId_nativeCb_fmRxCmdGetRssiThreshhold = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetRssiThreshhold",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetRssiThreshhold);
_sMethodId_nativeCb_fmRxCmdSetDeemphasisFilter = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetDeemphasisFilter",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetDeemphasisFilter);
_sMethodId_nativeCb_fmRxCmdGetDeemphasisFilter = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetDeemphasisFilter",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetDeemphasisFilter);
_sMethodId_nativeCb_fmRxCmdSetVolume = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetVolume",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetVolume);
_sMethodId_nativeCb_fmRxCmdGetVolume = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetVolume",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetVolume);
_sMethodId_nativeCb_fmRxCmdSetChannelSpacing = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetChannelSpacing",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetChannelSpacing);
_sMethodId_nativeCb_fmRxCmdGetChannelSpacing = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetChannelSpacing",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetChannelSpacing);
_sMethodId_nativeCb_fmRxCmdTune = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdTune",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdTune);
_sMethodId_nativeCb_fmRxCmdGetTunedFrequency = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetTunedFrequency",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetTunedFrequency);
_sMethodId_nativeCb_fmRxCmdSeek = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSeek",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSeek);
_sMethodId_nativeCb_fmRxCmdStopSeek = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdStopSeek",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdStopSeek);
_sMethodId_nativeCb_fmRxCmdGetRssi = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetRssi",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetRssi);
_sMethodId_nativeCb_fmRxCmdEnableRds = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdEnableRds",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdEnableRds);
_sMethodId_nativeCb_fmRxCmdDisableRds = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdDisableRds",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdDisableRds);
_sMethodId_nativeCb_fmRxCmdGetRdsSystem = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetRdsSystem",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetRdsSystem);
_sMethodId_nativeCb_fmRxCmdSetRdsSystem = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetRdsSystem",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetRdsSystem);
_sMethodId_nativeCb_fmRxCmdSetRdsGroupMask = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetRdsGroupMask",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetRdsGroupMask);
_sMethodId_nativeCb_fmRxCmdGetRdsGroupMask = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetRdsGroupMask",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetRdsGroupMask);
_sMethodId_nativeCb_fmRxCmdSetRdsAfSwitchMode = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdSetRdsAfSwitchMode",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdSetRdsAfSwitchMode);
_sMethodId_nativeCb_fmRxCmdGetRdsAfSwitchMode = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetRdsAfSwitchMode",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetRdsAfSwitchMode);
_sMethodId_nativeCb_fmRxCmdDisableAudio = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdDisableAudio",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdDisableAudio);
_sMethodId_nativeCb_fmRxCmdDestroy = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdDestroy",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdDestroy);
_sMethodId_nativeCb_fmRxCmdChangeDigitalAudioConfiguration= env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdChangeDigitalAudioConfiguration",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdChangeDigitalAudioConfiguration);
/* Complete scan in V4l2 FM driver is not implemented yet
Commented the FM RX Completescan functionality start*/
/*_sMethodId_nativeCb_fmRxCompleteScanDone = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCompleteScanDone",
"(JII[I)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCompleteScanDone);*/
/*Commented the FM RX Completescan functionality end*/
_sMethodId_nativeCb_fmRxCmdGetFwVersion = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetFwVersion",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetFwVersion);
_sMethodId_nativeCb_fmRxCmdIsValidChannel = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdIsValidChannel",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdIsValidChannel);
_sMethodId_nativeCb_fmRxCmdGetCompleteScanProgress = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdGetCompleteScanProgress",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdGetCompleteScanProgress);
_sMethodId_nativeCb_fmRxCmdStopCompleteScan = env->GetStaticMethodID(clazz,
"nativeCb_fmRxCmdStopCompleteScan",
"(JIIJ)V");
VERIFY_METHOD_ID(_sMethodId_nativeCb_fmRxCmdStopCompleteScan);
V4L2_JBTL_LOGD("nativeJFmRx_ClassInitNative:Exiting");
}
static JNINativeMethod JFmRxNative_sMethods[] = {
/* name, signature, funcPtr */
{"nativeJFmRx_ClassInitNative", "()V", (void*)nativeJFmRx_ClassInitNative},
{"nativeJFmRx_Create", "(Lcom/ti/jfm/core/JFmContext;)I", (void*)nativeJFmRx_Create},
{"nativeJFmRx_Destroy", "(J)I", (void*)nativeJFmRx_Destroy},
{"nativeJFmRx_Enable", "(J)I", (void*)nativeJFmRx_Enable},
{"nativeJFmRx_Disable", "(J)I", (void*)nativeJFmRx_Disable},
{"nativeJFmRx_SetBand","(JI)I", (void*)nativeJFmRx_SetBand},
{"nativeJFmRx_GetBand","(J)I", (void*)nativeJFmRx_GetBand},
{"nativeJFmRx_Tune","(JI)I", (void*)nativeJFmRx_Tune},
{"nativeJFmRx_GetTunedFrequency","(J)I", (void*)nativeJFmRx_GetTunedFrequency},
{"nativeJFmRx_SetMonoStereoMode","(JI)I", (void*)nativeJFmRx_SetMonoStereoMode},
{"nativeJFmRx_GetMonoStereoMode","(J)I", (void*)nativeJFmRx_GetMonoStereoMode},
{"nativeJFmRx_SetMuteMode","(JI)I", (void*)nativeJFmRx_SetMuteMode},
{"nativeJFmRx_GetMuteMode","(J)I", (void*)nativeJFmRx_GetMuteMode},
{"nativeJFmRx_SetRssiThreshold","(JI)I", (void*)nativeJFmRx_SetRssiThreshold},
{"nativeJFmRx_GetRssiThreshold","(J)I", (void*)nativeJFmRx_GetRssiThreshold},
{"nativeJFmRx_GetRssi","(J)I", (void*)nativeJFmRx_GetRssi},
{"nativeJFmRx_SetVolume","(JI)I", (void*)nativeJFmRx_SetVolume},
{"nativeJFmRx_GetVolume","(J)I", (void*)nativeJFmRx_GetVolume},
{"nativeJFmRx_SetChannelSpacing","(JI)I", (void*)nativeJFmRx_SetChannelSpacing},
{"nativeJFmRx_GetChannelSpacing","(J)I", (void*)nativeJFmRx_GetChannelSpacing},
{"nativeJFmRx_SetDeEmphasisFilter","(JI)I", (void*)nativeJFmRx_SetDeEmphasisFilter},
{"nativeJFmRx_GetDeEmphasisFilter","(J)I", (void*)nativeJFmRx_GetDeEmphasisFilter},
{"nativeJFmRx_Seek","(JI)I", (void*)nativeJFmRx_Seek},
{"nativeJFmRx_StopSeek","(J)I", (void*)nativeJFmRx_StopSeek},
{"nativeJFmRx_EnableRDS","(J)I", (void*)nativeJFmRx_EnableRDS},
{"nativeJFmRx_DisableRDS","(J)I", (void*)nativeJFmRx_DisableRDS},
{"nativeJFmRx_EnableAudioRouting","(J)I", (void*)nativeJFmRx_EnableAudioRouting},
{"nativeJFmRx_DisableAudioRouting","(J)I", (void*)nativeJFmRx_DisableAudioRouting},
{"nativeJFmRx_SetRdsAfSwitchMode","(JI)I", (void*)nativeJFmRx_SetRdsAfSwitchMode},
{"nativeJFmRx_GetRdsAfSwitchMode","(J)I", (void*)nativeJFmRx_GetRdsAfSwitchMode},
{"nativeJFmRx_ChangeAudioTarget","(JII)I",(void*)nativeJFmRx_ChangeAudioTarget},
{"nativeJFmRx_ChangeDigitalTargetConfiguration","(JI)I",(void*)nativeJFmRx_ChangeDigitalTargetConfiguration},
{"nativeJFmRx_SetRfDependentMuteMode","(JI)I",(void*)nativeJFmRx_SetRfDependentMuteMode},
{"nativeJFmRx_GetRfDependentMute","(J)I",(void*)nativeJFmRx_GetRfDependentMute},
{"nativeJFmRx_SetRdsSystem","(JI)I",(void*)nativeJFmRx_SetRdsSystem},
{"nativeJFmRx_GetRdsSystem","(J)I",(void*)nativeJFmRx_GetRdsSystem},
{"nativeJFmRx_SetRdsGroupMask","(JJ)I",(void*)nativeJFmRx_SetRdsGroupMask},
{"nativeJFmRx_GetRdsGroupMask","(J)I",(void*)nativeJFmRx_GetRdsGroupMask},
{"nativeJFmRx_CompleteScan","(J)I",(void*)nativeJFmRx_CompleteScan},
{"nativeJFmRx_IsValidChannel","(J)I",(void*)nativeJFmRx_IsValidChannel},
{"nativeJFmRx_GetFwVersion","(J)I",(void*)nativeJFmRx_GetFwVersion},
{"nativeJFmRx_GetCompleteScanProgress","(J)I",(void*)nativeJFmRx_GetCompleteScanProgress},
{"nativeJFmRx_StopCompleteScan","(J)I",(void*)nativeJFmRx_StopCompleteScan},
};
/**********************************/
/*
* Register several native methods for one class.
*/
static int registerNatives(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = env->FindClass(className);
if (clazz == NULL) {
V4L2_JBTL_LOGD("Can not find class %s\n", className);
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
V4L2_JBTL_LOGD("Can not RegisterNatives\n");
return JNI_FALSE;
}
return JNI_TRUE;
}
/*Commented the FM TX functionality start*/
extern JNINativeMethod JFmTxNative_sMethods[];
extern int getTxNativeSize();
/*Commented the FM TX functionality end*/
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;
V4L2_JBTL_LOGD("OnLoad");
if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
goto bail;
}
if (!registerNatives(env,
"com/ti/jfm/core/JFmRx",
JFmRxNative_sMethods,
NELEM(JFmRxNative_sMethods))) {
goto bail;
}
if (!registerNatives(env,
"com/ti/jfm/core/JFmTx",
JFmTxNative_sMethods,
getTxNativeSize())) {
goto bail;
}
env->GetJavaVM(&g_jVM);
/* success -- return valid version number */
result = JNI_VERSION_1_4;
bail:
return result;
}