Overview
The attached demo solution embeds a JNI, which wraps the below listed Microsoft Bluetooth functions / APIs to sense and set the Bluetooth radio power state:
--
As explained below, putting together such JNI was not overly complex.
1) First of all, I created the below Java class
BluetoothHelperJNI.java
class BluetoothHelperJNI
{
public static final int BTH_POWER_OFF = 0;
public static final int BTH_CONNECTABLE = 1;
public static final int BTH_DISCOVERABLE = 2;
public native int BthGetMode(int[] pdwMode);
public native int BthSetMode(int dwMode);
static
{
System.loadLibrary("BluetoothHelperJNI");
}
}
which I compiled as follows:
"C:\Program Files\Java\j2sdk1.4.2_19\bin\javac.exe" BluetoothHelperJNI.java
2) I then executed the below javah command to generate a C header file from the BluetoothHelperJNI class
"C:\Program Files\Java\j2sdk1.4.2_19\bin\javah" -jni -classpath "%CD%" BluetoothHelperJNI
The newly created C header file read as follows:
BluetoothHelperJNI.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class BluetoothHelperJNI */
#ifndef _Included_BluetoothHelperJNI
#define _Included_BluetoothHelperJNI
#ifdef __cplusplus
extern "C" {
#endif
#undef BluetoothHelperJNI_BTH_POWER_OFF
#define BluetoothHelperJNI_BTH_POWER_OFF 0L
#undef BluetoothHelperJNI_BTH_CONNECTABLE
#define BluetoothHelperJNI_BTH_CONNECTABLE 1L
#undef BluetoothHelperJNI_BTH_DISCOVERABLE
#define BluetoothHelperJNI_BTH_DISCOVERABLE 2L
/*
* Class: BluetoothHelperJNI
* Method: BthGetMode
* Signature: ([I)I
*/
JNIEXPORT jint JNICALL Java_BluetoothHelperJNI_BthGetMode
(JNIEnv *, jobject, jintArray);
/*
* Class: BluetoothHelperJNI
* Method: BthSetMode
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_BluetoothHelperJNI_BthSetMode
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
3) I then created the attached VS2008 C++ project to build the BluetoothHelperJNI.dll.
As you will read, this DLL exports two functions to wrap the above mentioned Microsoft Bluetooth functions / APIs to sense and set the Bluetooth radio power state.
BluetoothHelperJNI.cpp
#include <windows.h>
#include <bthutil.h>
#include <jni.h>
#include "..\BluetoothHelper.h" // this header file was generated by javah
#pragma comment(lib, "Bthutil.lib")
JNIEXPORT jint JNICALL Java_BluetoothHelperJNI_BthGetMode(JNIEnv *env, jobject obj, jintArray ptr)
{
jsize len = env->GetArrayLength(ptr);
if (len == 0)
return ERROR_BAD_ARGUMENTS;
DWORD dwMode = 0;
DWORD dwRet = BthGetMode(&dwMode);
if (dwRet == ERROR_SUCCESS)
{
jint *mode = (jint*)&dwMode;
env->SetIntArrayRegion(ptr, 0, 1, mode);
}
return dwRet;
}
JNIEXPORT jint JNICALL Java_BluetoothHelperJNI_BthSetMode(JNIEnv *env, jobject obj, jint dwMode)
{
return BthSetMode((DWORD)dwMode);
}
4) Next, I created the following Java program to conduct tests and verify the JNI does the trick
SenseSetBluetoothPowerState.java
class SenseSetBluetoothPowerState
{
public static void main(String[] args)
{
System.out.print("[+] main\n");
BluetoothHelperJNI bt = new BluetoothHelperJNI();
int[] iArray = new int[1];
iArray[0] = bt.BTH_POWER_OFF;
int dwRet = bt.BthGetMode(iArray);
if (dwRet != 0)
{
System.out.print("BthGetMode() failed with " + dwRet + "\n");
return;
}
System.out.print("Power mode currently set to " + iArray[0] + "\n");
int dwMode = bt.BTH_POWER_OFF;
if (iArray[0] == bt.BTH_POWER_OFF)
dwMode = bt.BTH_DISCOVERABLE;
dwRet = bt.BthSetMode(dwMode);
if (dwRet != 0)
{
System.out.print("BthSetMode(" + dwMode + ") failed with "
+ dwRet + "\n");
return;
}
System.out.print("BthSetMode(" + dwMode + ") returns " + dwRet + "\n");
System.out.print("[-] main\n");
}
}
which I compiled and archived (along with the BluetoothHelperJNI class) as follows:
"C:\Program Files\Java\j2sdk1.4.2_19\bin\javac.exe" -classpath "%CD%" SenseSetBluetoothPowerState.java
"C:\Program Files\Java\j2sdk1.4.2_19\bin\jar.exe" cmf SenseSetBluetoothPowerState.mf SenseSetBluetoothPowerState.jar *.class
5) Finally, I executed [1] this java test program against a Workabout Pro Windows Mobile 6.1 device [2] and got:
![]()
[1] See the Test BluetoothHelperJNI .cpp file embedded in the attachment for more details.
[2] The CrEme JVM v4.12 was previously installed on this device.
--
& Powering on the Bluetooth radio may take few seconds.
--
Ref: Case 218422