randdusing / cordova-plugin-bluetoothle

Bluetooth Low Energy Phonegap Plugin
803 stars 356 forks source link

scanResult raw bytes #69

Closed diverJohn closed 9 years ago

diverJohn commented 9 years ago

Rand,

First of all thanks for the BTLE plugin...

I would like access to the scanResult raw data. Our device returns the serial number with the scanResult, see capture below, so the user can select which device to connect to.

Looking at the object returned it looks like the bytes are stored in obj.advertisement so I tried to print the returned data but get "undefined".

How do I read the rest of the data in scanResult?

Thanks,

Remote console log...

"BT: Scan advertisment: undefined"

code...

function startScanSuccess(obj)  {
  if (obj.status == "scanResult")
  {
     console.log("BT: Scan match: " + obj.name );
     console.log("BT: Scan advertisment: " + obj.advertisement);

     bluetoothle.stopScan(stopScanSuccess, stopScanError);
     clearScanTimeout();

     window.localStorage.setItem(addressKey, obj.address);
    ConnectBluetoothDevice(obj.address);
 }

Bluetooth capture showing scan result:

image

randdusing commented 9 years ago

Is this on Android or iOS, or both? I need to review some older issues, but I'm pretty sure iOS blocks the advertisement data.

diverJohn commented 9 years ago

Currently I am on Android using Phonegap build. I can get connected but I would still like to get the rest of the scan results. Looking at your plugin code it looks like you fill the returned object with an "advertisement" member containing the bytes of the scan result.

randdusing commented 9 years ago

Yah, advertisement data should be included on Android. Can you add console.log(JSON.stringify(obj)) to the scanResult code to see what's being returned?

randdusing commented 9 years ago

Actually I think this is just an issue with PhoneGap Build using an older version that didn't have advertisement. I've submitted newer versions for review, but haven't heard anything back yet...

diverJohn commented 9 years ago

I will give the console.log(JSON.stringify(obj)) a try tomorrow when I get my BLE hardware back.
I am currently including the plugin as follows:

<gap:plugin name="com.randdusing.bluetoothle" version="1.0.0" />

Should I remove the version to pull in the latest?

randdusing commented 9 years ago

Version 1.0.1 and 1.0.2 haven't been approved yet, so I don't think you can use them.

diverJohn commented 9 years ago

The raw scan results data does not seem to be available with this version. Do you know when this functionality will be available? I can work around for now... Below are the results...(By the way, I am using jsconsole to debug. It provides console output to the PC.)

Code:

    console.log("BT: Scan match: " + obj.name + " string: " + JSON.stringify(obj) );

jsconsole debug output:

remote console.log
"BT: Scan match: Cel-Fi string:     {\"status\":\"scanResult\",\"address\":\"7C:66:9D:78:58:4F\",\"rssi\":-49,\"name\":\"Cel-Fi\"}"
randdusing commented 9 years ago

I'm not sure, PhoneGap Build has been really slow to review.

randdusing commented 9 years ago

Latest version has been approved. Not sure why the other version was ignored.

diverJohn commented 9 years ago

So I should use 1.0.2 with Phonegap Build?

randdusing commented 9 years ago

Yep, 1.0.2 should work

diverJohn commented 9 years ago

Great... I will give 1.0.2 a spin...

Are you still traveling?

randdusing commented 9 years ago

Still traveling for the foreseeable future with an iPhone 5S and Nexus 7. Just need to find a cheap Windows phone along the way.

diverJohn commented 9 years ago

Are you in Korea?

randdusing commented 9 years ago

Yep in Seoul for a few months

diverJohn commented 9 years ago

I have spent a lot of time in Korea, mostly in Seoul, Suwon and Gumi.

Phonegap Build issues the following warning when I try to use 1.0.2, even though it completes the build. Do I need to change anything other than my config.xml file?

"This app has a plugin dependency conflict (com.randdusing.bluetoothle). Check the plugins tab."

I also changed my "write" arguments from 1.0.0 version to the latest which caused the service not found issue which makes me think that Phonegap build used plugin 1.0.0 when I specified 1.0.2.

// Version 1.0.0 of the plugin
//    var paramsObj = {"value":u64, "serviceAssignedNumber":bridgeServiceUuid, "characteristicAssignedNumber":bridgeRxCharacteristicUuid};

// 1.0.2 of the plugin 
var paramsObj = {"value":u64, "serviceUuid":bridgeServiceUuid, "characteristicUuid":bridgeRxCharacteristicUuid};

bluetoothle.write(writeSuccess, writeError, paramsObj);

I need version 1.0.2 so that I can use the fix for issue 30, "Subscription issue after write" which is what I have a problem with using version 1.0.0.

randdusing commented 9 years ago

It's a fun place with great food.

Maybe try fulling removing the plugin, adding it back and seeing if that warning goes away

diverJohn commented 9 years ago

Remember I am using Phonegap build so how do I remove?

This is what I tried... I deleted the line from my config.xml file, built it, surprised it built successfully. I added 1.0.2 back in to my config.xml file and built it again with the same warning.

randdusing commented 9 years ago

Oh yah duh, I used PhoneGap build for a very short period of time.

When it builds, does the Bluetooth code work?

diverJohn commented 9 years ago

My mistake. I had a second addition of the plugin later on in my config.xml file so now the build works without the warning.

However, the initialization returns an "Unexpected initialize status: enabled" instead of the obj.status of "initialized". I have reset both devices, my bluetooth device and my phone but it still returns "enabled". Is this something new with 1.0.2?

randdusing commented 9 years ago

Yah, I improved the handling of enabling / disabling Bluetooth. Basically just called initialize once and the initializeCallback will return status=>enabled if on or error=>enable if off. The callback will continually be used if the user turns Bluetooth on and off.

status=>initialized is no longer user. error=>initialize can still occur if you try to call something before calling initialize.

diverJohn commented 9 years ago

Thanks...so the initialize logic in your example should be changed to the following, i..e just change "initialized" to "enabled"?

bluetoothle.initialize(initializeSuccess, initializeError); function initializeSuccess(obj) { if (obj.status == "enabled") { var address = window.localStorage.getItem(addressKey); if (address == null) { console.log("Bluetooth initialized successfully, starting scan for heart rate devices."); var paramsObj = {"serviceUuids":[heartRateServiceUuid]}; bluetoothle.startScan(startScanSuccess, startScanError, paramsObj); } else { connectDevice(address); } } else { console.log("Unexpected initialize status: " + obj.status); } }

function initializeError(obj) { console.log("Initialize error: " + obj.error + " - " + obj.message); }

randdusing commented 9 years ago

Oops, fixed that

diverJohn commented 9 years ago

Using 1.0.2 I am able to see the raw data using obj.advertisement with scan result. Thanks for the help...

Code:

function startScanSuccess(obj)
{
  if (obj.status == "scanResult")
  {
    console.log("BT: Scan match: " + obj.name + " string: " + JSON.stringify(obj) );
    var bytes = bluetoothle.encodedStringToBytes(obj.advertisement);

Log:

"BT: Scan match: Cel-Fi string: {\"advertisement\":\"AgEGAwI0Zwz/AAECESIzRFVmJSkHCUNlbC1GaQMCNGcM/wARIjNEVWZ3iCUpAAAAAAAAAAAAAAAAAAAAAAA=\",\"rssi\":-59,\"status\":\"scanResult\",\"address\":\"7C:66:9D:78:58:4F\",\"name\":\"Cel-Fi\"}"
yubozhao commented 9 years ago

@diverJohn a Quick question about the raw data. How did you turn the bytes data into more useful information like a string or an object?

The project I am working on advertising the data instead of going through connect ble device and discovering it. However, the bytes I decoded has random characters like "ó ÿ׺þ|", any idea to solve this?

    var bytes = bluetoothle.encodedStringToBytes(object.advertisement);
    var results = new Uint8Array(62);
    var str = '';

    for (var i = 1; i < 62; i++) {
       results[i] = bytes[i];
    }

    for (var j = 0; j < results.length; j++) {
        str +=  String.fromCharCode(results[j]);
    }

    console.log(str)  //   "óÿ׺þ|  ÿ¼j)®Ö)"
diverJohn commented 9 years ago

Bozhao,

Below is how I convert so that I can view it...

var u8ScanResults = new Uint8Array(62);

if (obj.status == "scanResult") { PrintLog(10, "BT: Scan match: " + obj.name + " string: " + JSON.stringify(obj) ); var bytes = bluetoothle.encodedStringToBytes(obj.advertisement);

// Save the Scan Results data...
if( bytes.length != 0 )
{
    for( var i = 1; i < 62; i++ )
    {
        u8ScanResults[i] = bytes[i];
    }
}

var outText = u8ScanResults[0].toString(16);    // Convert to hex output...
for( i = 1; i < u8ScanResults.length; i++ )
{
    outText = outText + " " + u8ScanResults[i].toString(16);
}
PrintLog(10,  "Msg Advert_Scan: " + outText );

}

yubozhao commented 9 years ago

@diverJohn Thank you, I will try it out and let you know how it goes