evothings / cordova-ble Goto Github PK
View Code? Open in Web Editor NEWBluetooth Low Energy plugin for Cordova
Home Page: http://www.evothings.com/
License: Apache License 2.0
Bluetooth Low Energy plugin for Cordova
Home Page: http://www.evothings.com/
License: Apache License 2.0
Problem:
Notifications for TI SensorTag buttons do not work on Android.
Test app:
https://github.com/divineprog/evo-demos/tree/master/Demos2014/TISensorTag
How to reproduce:
The test app runs OK on an iPhone 4S.
The app from TI detects the button presses on Nexus 5.
Possibly, there is a bug in the Android BLE plugin.
Also tested to comment out all sensors except the keypress, but no notifications are sent.
Investigate the requirements for creating a Cordova iOS BLE plugin. Create additional tasks along the way.
I'm running into an issue with unsigned vs signed bytes. I'm sending data over BLE by passing an unsigned int array, but when the code runs on Android it converts it to a signed int. When that happens, the data that I'm trying to send never actually gets sent because the values get changed. Has anyone else experienced this?
If, on the same device, a two calls to rssi() are made before the first call completes, the second one will overwrite the callback context, leaving the first one hanging.
Establish a queue to fix this problem.
Hello,
I am doing a project where we are connecting to our custom device and trying to communicate over BLE. We have done succesful round of implementation and test using your plugin with Android. Now I have to test same with ios. I am new to ios. I build and installed same application for ios. I can scan and connect using this plugin. But rest is not working. Not even giving error. Dont understand what is going wrong:
if(zDeviceID != null){
console.log('Got some device id '+zDeviceID);
evothings.ble.connect(zDeviceID,connectSuccess,failure);
}
var connectSuccess = function(e){
console.log("Connect Success");
zenDeviceHandle = e.deviceHandle;
evothings.ble.services(zenDeviceHandle,onServiceReadSuccess,failure);
}
var onServiceReadSuccess = function(services)
{
console.log("Read service done");
console.log("Services "+JSON.stringify(services));
var serviceHandle;
for (var i = 0; i < services.length; i++)
{
var service = services[i];
console.log('BLE service: ');
serviceHandle = service.handle;
console.log(' ' + service.handle);
console.log(' ' + service.uuid);
console.log(' ' + service.serviceType);
}
evothings.ble.characteristics(1,serviceHandle,onCharReadSuccess,failure);
}
After this evothings.ble.services call nothing happens. Where as when I run same on android i get list of services and interanlly get the list of charachteristics.
MAC version : version 10.8.5
xcodebuild -version : 5.1
cordova -version : 4.2.0
Ios version 7.0.1
Can some one please help me?
Regards,
Shraddha
Write a tutorial that explains how to use the JavaScript BLE API.
Should this be a Markdown document in the repository or a page on the Wiki?
On an Android platform, disabling a notification returns into the win callback after it completes.
This doesn't happen on iOS.
It looks like the close function is not implemented in BLE.java.
I've got a cordova-ble app on an Android (S4) device, and during startup I quite common get the following (see trace below). I think it might be because I commonly do a reset (evothings.ble.reset();) because the whole BLE-stack on Android feels unstable. It seems then that sometimes bluetooth is turned off and not back on, and I think that's the reason why I get the below trace. Is there a way to check whether BLE is on from within Javascript, and possibly turn it on?
D/BluetoothAdapter(18863): stopLeScan()
D/BluetoothAdapter(18863): startLeScan(): null
E/BluetoothAdapter(18863):
E/BluetoothAdapter(18863): android.os.DeadObjectException
E/BluetoothAdapter(18863): at android.os.BinderProxy.transact(Native Method
)
E/BluetoothAdapter(18863): at android.bluetooth.IBluetoothGatt$Stub$Proxy.r
egisterClient(IBluetoothGatt.java:813)
E/BluetoothAdapter(18863): at android.bluetooth.BluetoothAdapter.startLeSca
n(BluetoothAdapter.java:1680)
E/BluetoothAdapter(18863): at android.bluetooth.BluetoothAdapter.startLeSca
n(BluetoothAdapter.java:1641)
E/BluetoothAdapter(18863): at com.evothings.BLE.startScan(BLE.java:108)
E/BluetoothAdapter(18863): at com.evothings.BLE.execute(BLE.java:41)
E/BluetoothAdapter(18863): at org.apache.cordova.CordovaPlugin.execute(Cord
ovaPlugin.java:84)
E/BluetoothAdapter(18863): at org.apache.cordova.CordovaPlugin.execute(Cord
ovaPlugin.java:65)
E/BluetoothAdapter(18863): at org.apache.cordova.PluginManager.execHelper(P
luginManager.java:242)
E/BluetoothAdapter(18863): at org.apache.cordova.PluginManager.exec(PluginM
anager.java:227)
E/BluetoothAdapter(18863): at org.apache.cordova.ExposedJsApi.exec(ExposedJ
sApi.java:53)
E/BluetoothAdapter(18863): at com.android.org.chromium.base.SystemMessageHa
ndler.nativeDoRunLoopOnce(Native Method)
E/BluetoothAdapter(18863): at com.android.org.chromium.base.SystemMessageHa
ndler.handleMessage(SystemMessageHandler.java:27)
E/BluetoothAdapter(18863): at android.os.Handler.dispatchMessage(Handler.ja
va:102)
E/BluetoothAdapter(18863): at android.os.Looper.loop(Looper.java:157)
E/BluetoothAdapter(18863): at android.os.HandlerThread.run(HandlerThread.ja
va:61)
W/BluetoothAdapter(20010): getBluetoothService() called with no BluetoothManager
Callback
W/BluetoothAdapter(20010): getBluetoothService() called with no BluetoothManager
Callback
W/BluetoothAdapter(20010): getBluetoothService() called with no BluetoothManager
Callback
I maybe over-eagerly reset the BLE stack on the Android device, and sometimes it doesn't start up properly. This means that I start the scanning without there being a valid BLE device. But I don't seem to get a proper feedback that BLE isn't running.
Should the error callback of easyble.startScan be called when the above happens? I can't see that happening. I'm using slightly old code, so I apologize if this has been updated since I updated.
Build problem reported on Twitter by @nrocy
https://twitter.com/nrocy/status/449169997089497088
Log: http://norc.homeip.net/~nroc/x/DEZT5.png
Folder structure used:
code
cordova-ble
micketest
Cloned repo evothings/cordova-ble from GitHub into the folder structure as shown above.
Created Cordova project and build with the following commands (on OS X):
cordova create micketest com.kindborg.micketest MickeTest
cd MickeTest
cordova platform add android
cordova plugin add ../cordova-ble/
cordova build
This built a project with the plugin installed (did not recreate the problem).
@nrocy Can you fill in with more detail?
Call the error callback if enableNotification is called twice without disableNotification in between.
This needs to be done on both Android and iOS.
See #18.
The scanRecord parsing which appears in the easyble.js code would be so much more useful if it was added to the native Android code layer by default.
advertisementData and scanRecord data could then be accessed in a common way, perhaps even replacing the existing structures.
This would remove the need to (slowly) parse the data in JavaScript and make the API more consistent across iOS and Android devices.
The JavaScript API has changed, and the Android plugin needs updating.
Summary of changes:
There is a test program in file tests/test.html that can be used to verify that the plugins work consistently on Android and iOS.
Hi !
You noticed that the application stop when it reload so it's impossible to get the rssi in real time ?
thanks
The test program in test.html could be extended with tests for notifications.
One approach is that when a characteristic that supports notifications is found, notifications are enabled and kept running for something like 10 updates (or more), then disabled.
How about testing write operations? This would need devices for testing that can be written to. A basic test could be to write a value then read the value and check that yet are equal.
Why does it require Cordova < 4.0.0?
It tried it on Cordova 5.0.0 on Android and it works great !
Review the commits made in other forks:
https://github.com/evothings/cordova-ble/network
Merge commits that contain useful updates.
Hey,
similar to the evothings examples, I have a very simple project.
My problem is that in most cases connect() is not returning, although sometimes it does return (rarely) but it takes at least 5 min.
All I want do at this point is connecting and reading the services. Consuming the services with a laptop worked so far.
Phone: Galaxy S4 Mini with CyanogenMod 11-20140315-nightly, Android 4.4.2
Peripheral: Raspberry PI with Bluetooth-Dongle
Any help or pointers for pointers would be highly appreciated.
(I hope you're not blaming CyanogenMod ;-) )
Code:
$scope.stopBleScan();
console.log('connect(' + address + ')', new Date());
ble.connect(address, function (r) {
console.log('connect ' + r.deviceHandle + ' state ' + r.state, new Date());
if (r.state == 2) {
console.log('connected, requesting services...');
$scope.getServices(r.deviceHandle);
}
}, function (errorCode) {
console.log('connect error: ' + errorCode);
});
This plugin looks great so far!
Is their any available example of how to register to recieve notifications or indications? I see the notes in the jsdoc comments for enableNotification about having to "write a special value to a separate configuration characteristic". I'm guessing that something like writing the BluetoothGattDescriptor.ENABLE_INDICATION_VALUE on android, But I'm not sure how to pull that off on the Javascript side.
Problem
Should be possible to use the plugin for the type of limited background scanning iOS provides.
Solution
Research settings needed for this and add them to the cordova-xml file.
Some links related to iOS background processing (mostly iBeacon related however):
Related Evothings Forum thread:
After building the plugin with cordova-cli I got errors about the plugin not being found or the file name not matching the class name. There might be problems when using other versions of the Java compiler, cordova-cli and/or Android SDK build tools. Try building with a few different versions of these.
Results this far:
I am working with the plugin on android and ios.
On ios the scan is not working in the background although all plist values are set so
I am using the connect function that works correctly in the background.
I have a solution that tries to connect to a near by estimate beacon every 30 seconds during a time span of 30 minutes to 2 hours, mostly runs in the background. for some reason on some iphone devices after a while, can happen during a phone call when app is in the background, maybe due to cpu usage, the connect function fails to connect. I tried to connect and disconnect 10 times every 10 or 30 seconds but I get no response and also if the app returns to the foreground it still cant scan (that works in the foreground), only if I restart the app connection can be established. any idea why? and how can I overcome this issue? Would this happen if I would convert to the estimote plugin?
are there different functions that I can use like advertise or notify that may be more reliable? apparently the app works correctly in the background because it tries to connect multiple times and stops the app and sends a notification that more than 10 times the ble device was not connectable.
this is correct data
{ranged: [{ uuid: "74278BDA-B645-4520-8F0C-720EAF059935", major: 10, minor: 10, rssi: -60, power: -59 }]}
and your lib cordova-ble on iphone5s 7.01 got this data
{"scanRecord":"","rssi":-46,"name":"HMSensor","address":"097B6444-8691-5631-20DB-E56886D373CD"}
The identifier property is not available in iOS 8:
This property is used by the plugin as the address of a peripheral. See file EVOBLE.m, this line:
@"address" : [peripheral.identifier UUIDString],
Strangely this method retrievePeripheralsWithIdentifiers in CBCentralManager is not marked as unavailable, but how are you supposed to retrieve peripherals by identifier when the identifier is not known? Here is how this method is used ib EVOBLE.m:
// Get the pheripheral object for the given address.
NSUUID* uuid = [[NSUUID UUID] initWithUUIDString: address];
NSArray* pheriperals = [self.central
retrievePeripheralsWithIdentifiers: @[uuid]];
Problem/feature request:
"I think that the startScan method should fail immediately when executed if the BLE is disabled on the phone. As for now it seems like it just thinks that it is actually scanning."
Some possible solutions:
There could also be functions for checking if Blutooth is on/off, and turn Bluetooth on/off.
Would be good to have shorter lines and comments in the Android implementation.
I'd like to use the cordova-ble module with ionic using ngCordova
What is the procedure to make the module ngCordova compatible ?
Currently any underlying errors in the native stacks are exposed directly in JavaScript.
This means that string errors are seen on iOS and integer errors on android.
This doesn't encapsulate/abstract the platforms entirely which means developers cannot have a single code base when error handling.
Perhaps android ints can be converted into the iOS strings, or both be hidden behind an evothings-specific error code list.
I´ve written a short BLE app and I am trying to run this on an iPad. It runs on the Android, but the same app gives me an exception when I do ´cordova run iOS´. I am not an experienced iOS-developer, so I´m struggling to see what could be wrong. The iPad is running 7.1.1. Here is the exception log. Is there an example app that runs on iPad?
(lldb) script fruitstrap_connect_url="connect://127.0.0.1:12345"
(lldb) command script import "/tmp/fruitstrap_.py"
(lldb) command script add -f fruitstrap_.connect_command connect
(lldb) command script add -s asynchronous -f fruitstrap_.run_command run
(lldb) connect
(lldb) run
2014-05-02 23:20:23.099 BLE[144:60b] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIApplication 0x15e41f00> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key view.'
*** First throw call stack:
(0x30600fd3 0x3b1a1ccf 0x30600ce9 0x30f44f23 0x30f56b55 0x3057113b 0x3318bec3 0x3318d727 0x33093c0f 0x32e8649d 0x32e22709 0x32e21871 0x32e85cc9 0x3545baed 0x3545b6d7 0x305cbab7 0x305cba53 0x305ca227 0x30534f0f 0x30534cf3 0x32e84ef1 0x32e8016d 0x326ab 0x3b6aeab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
Process 144 stopped
__pthread_kill + 8, queue = 'com.apple.main-thread', stop reason = signal SIGABRT frame #0: 0x3b7641f0 libsystem_kernel.dylib
__pthread_kill + 8please mention it in the docs to avoid confusion of why things like connect are not working in iOS.
I'm trying to find the closest beacons, and I've ran into an issue where one device is being found more than the others. In the following:
evothings.ble.startScan(function(device) {
if (device.rssi <= 0) callbackFun(device, null)
device.address
tends to not change. Has this issue been discovered before, and how did you get around it? If it hasn't been seen before, what are some ways that I might get around it?
Thank you.
Add license headers to files ble.js and BLE.java.
Perform general testing of the plugin on Android by e.g. using EvoThings Client and the EvoThings example apps. Keep note of hardware and OS versions as well as which features were tested (e.g. which example app was used).
After polling the RSSI value for a BLE device using the evothings.ble.rssi function, any following attempts to poll the RSSI for the device fail with the following error message: "Previous call to rssi() not yet completed!"
It appears the mRssiContext is not being reset to null after the callbackContext (which is assigned to mRssiContext) completes.
I'm getting the following error when I run readAllServiceData on iOS:
Error in Success callbackId: BLE1950252338 : ReferenceError: Can't find variable: service
ReferenceError: Can't find variable: service, cordova.js, Line: 1114
Suggest renaming the function close to disconnect for symmetry with function connect.
Is this the way it works? In the comments it says that it calls the callback when a new device is detected. When I run startScan, it keeps returning the same device until I call stopScan.
Hi, I opened the cordova project in xcode: Command+O, then select my_project/platforms/ios as the project root
I can emulate the app by selecting Product -> Run from the file menu. After verifying the app is running in the emulator, I attempted to build the project (Product -> Build), but I received an error:
/Users/mario/MyProject/platforms/ios/MyProject/Plugins/com.evothings.ble/EVOBLE.m:1295:22: Incompatible pointer types sending 'NSObject *' to parameter of type 'NSDictionary *'
Suggestions on how to get around this?
When running the example "TI SensorTag Demo" or "TI SensorTag Sensors" on Android, scanning does not find the SensorTag if it recently got disconnected.
How to reproduce:
Tested on Nexus 7 (2013). Tested working as expected on iOS.
Another way to reproduce:
In example "TI SensorTag Demo" I have seen that scanning works but connecting fails using a procedure similar to the above (activating SensorTag before pressing START button in the app, or pressing STOP then START after successful run.)
Could this issue possibly be related to the following forum thread, which also reports problems scanning for the SensorTag?
We should document how the API functions can be called, in particular how many calls can be made in parallel to different functions.
Here is an outline of how many simultaneous calls can be made to the API functions:
startScan/stopCall - one call per program
connect/close - one call per device
rssi - many calls per device
services - one call calls per device
characteristics - one call call per service
descriptors - one call per characteristic
readCharacteristics - one call per characteristic
readDescriptors - one call per descriptor
writeCharacteristic - one call per characteristic
writeDescriptor - - one call per descriptor
enableNotification - one call per characteristic
disableNotification - one call per characteristic
I've used this plugin with great success. I recently bought a lightblue bean (Arduino with ble) and worked great with this plugin. The only problem that I am facing is that there is no background service and thus when the app goes in the background it does not wake up when there is a change in a characteristic . I would be nice is someone could implement background mode in ios (and android) for bluetooth.
When I call readCharacteristic()
on a peripheral implementing PASSKEY security, Android often doesn't ask for passkey.
So readCharacterstic
failed but neither success nor error callback are called.
However, using logcat, I can see that the API returns GATT_INSUFFICIENT_AUTHENTICATION (status = 5)
D/BluetoothGatt(23821): onCharacteristicRead() - Device=FD:8B:BA:4B:1D:27 UUID=f3851521-5942-b2cb-ae40-271cd0dd17e5 Status=0
I found out that mentioned properties of characteristics and descriptors have different names in objects returned by Android and iOS plugin's implementation.
Discovered using readAllServiceData function.
If you subscribe to notifications from a characteristic in iOS and subsequently read that characteristic, notifications are no longer raised.
I can see from the objc code that this is due to read code stomping the existing notify callback handler.
This page should list our plugin (when you serach for "bluetooth" we are not listed):
http://plugreg.com/search?q=bluetooth
And what about listing the plugin on this page:
"Publishing Plugins
Once you develop your plugin, you may want to publish and share it with the community. You can publish your plugin to the cordova registry (based on npmjs) or to any other npmjs-based registry. Other developers can install it automatically using either plugman or the Cordova CLI. (For details on each development path, see Using Plugman to Manage Plugins and The Command-Line Interface.)
To publish a plugin you need to use the plugman tool and go through the following steps:
$ plugman adduser # that is if you don't have an account yet
$ plugman publish /path/to/your/plugin"
https://forums.estimote.com/t/reading-more-than-one-uuid/1067
The callback to evothings.ble.startScan, function deviceFound(device)
, is reading different addresses, i.e. device.address
is different depending on the phone. Has anyone ever ran into this?
e.g.
iphone5c reads E2B0A070...
iphone5s reads B9401000...
iphone6 reads C7EEF8AC...
and the android reads something that looks like a MAC address: `5F:C7:E2:FF:0A..."
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.