-
• #27
No Device Connected
1 Attachment
-
• #28
I have attached some (blurry!) pictures of the camera during this process.
Hmm... If only you had an expensive imaging device somewhere that you could use :)
What happens if you try to connect from the Android phone but enter the wrong PIN? Does it behave in exactly the same way that Espruino does?
If so it's possible that the PIN is getting corrupted somehow - it might give me a better idea where to look.
-
• #29
Ok, just some more thoughts:
- Maybe try setting
NRF.setSecurity({keyboard:1, mitm:1});
- You mention the PIN screen only shows when you try to write to a characteristic? How about removing the
startBonding
line and instead just trying to access the characteristic (but while listening for the passkeyRequest event)? It's possible that would be more successful at kicking off the bonding properly?
- Maybe try setting
-
• #30
Hmm... If only you had an expensive imaging device somewhere that you
could use :)Yes, all the gear, no idea ;)
Connecting in nRF and sending the wrong PIN results in the same behaviour, so there is a connection failed message on the camera which then is replaced by the no device connected screen as per the sequence when doing it from the Pixl.
This is an nRF session where I connect and put in the wrong PIN and then re-connect and put in the correct PIN
nRF Connect, 2019-02-04 Pocket Cinema Camera 4K A:1C2 (90:FD:9F:B8:CA:37) D 18:46:51.954 gatt.close() D 18:46:51.957 wait(200) V 18:46:52.158 Connecting to 90:FD:9F:B8:CA:37... D 18:46:52.158 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE) D 18:46:52.406 [Server callback] Connection state changed with status: 0 and new state: CONNECTED (2) I 18:46:52.406 [Server] Device with address 90:FD:9F:B8:CA:37 connected I 18:46:52.406 [Server] MTU changed to 64 D 18:46:52.453 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2) I 18:46:52.453 Connected to 90:FD:9F:B8:CA:37 D 18:46:52.457 wait(1600ms) D 18:46:52.484 [Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED V 18:46:54.072 Discovering services... D 18:46:54.072 gatt.discoverServices() D 18:46:54.087 [Callback] Services discovered with status: 0 I 18:46:54.087 Services discovered V 18:46:54.115 Generic Access (0x1800) - Device Name [R] (0x2A00) - Appearance [R] (0x2A01) Device Information (0x180A) - Manufacturer Name String [R] (0x2A29) - Model Number String [R] (0x2A24) Unknown Service (291d567a-6d75-11e6-8b77-86f30ca893d3) - Unknown Characteristic [W] (5dd3465f-1aee-4299-8493-d2eca2f8e1bb) - Unknown Characteristic [I] (b864e140-76a0-416a-bf30-5876504537d9) Client Characteristic Configuration (0x2902) - Unknown Characteristic [N] (6d8f2110-86f1-41bf-9afb-451d87e976c8) Client Characteristic Configuration (0x2902) - Unknown Characteristic [N R W] (7fe8691d-95dc-4fc5-8abd-ca74339b51b9) Client Characteristic Configuration (0x2902) - Unknown Characteristic [W] (ffac0c52-c9fb-41a0-b063-cc76282eb89c) - Unknown Characteristic [R] (8f1fd018-b508-456f-8f82-3d392bee2706) D 18:46:54.116 gatt.setCharacteristicNotification(b864e140-76a0-416a-bf30-5876504537d9, true) D 18:46:54.119 gatt.setCharacteristicNotification(6d8f2110-86f1-41bf-9afb-451d87e976c8, true) D 18:46:54.122 gatt.setCharacteristicNotification(7fe8691d-95dc-4fc5-8abd-ca74339b51b9, true) V 18:47:09.481 Writing request to characteristic 5dd3465f-1aee-4299-8493-d2eca2f8e1bb D 18:47:09.481 gatt.writeCharacteristic(5dd3465f-1aee-4299-8493-d2eca2f8e1bb, value=0xFF04000000010000) D 18:47:09.904 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_BONDING (11) D 18:47:09.920 [Broadcast] Action received: android.bluetooth.device.action.PAIRING_REQUEST, pairing variant: PAIRING_VARIANT_PIN (0) D 18:47:18.238 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_NONE (10) I 18:47:18.238 Bonding failed D 18:47:21.182 [Server callback] Connection state changed with status: 0 and new state: DISCONNECTED (0) I 18:47:21.182 [Server] Device disconnected D 18:47:21.196 [Callback] Connection state changed with status: 22 and new state: DISCONNECTED (0) E 18:47:21.197 Error 22 (0x16): GATT CONN TERMINATE LOCAL HOST I 18:47:21.197 Disconnected D 18:47:21.290 [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED D 18:47:48.789 gatt.close() D 18:47:48.791 wait(200) V 18:47:48.992 Connecting to 90:FD:9F:B8:CA:37... D 18:47:48.992 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE) D 18:47:49.292 [Server callback] Connection state changed with status: 0 and new state: CONNECTED (2) I 18:47:49.292 [Server] Device with address 90:FD:9F:B8:CA:37 connected I 18:47:49.292 [Server] MTU changed to 64 D 18:47:49.400 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2) D 18:47:49.400 [Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED I 18:47:49.400 Connected to 90:FD:9F:B8:CA:37 V 18:47:49.422 Discovering services... D 18:47:49.422 gatt.discoverServices() D 18:47:50.038 [Callback] Services discovered with status: 0 I 18:47:50.039 Services discovered V 18:47:50.062 Generic Access (0x1800) - Device Name [R] (0x2A00) - Appearance [R] (0x2A01) Device Information (0x180A) - Manufacturer Name String [R] (0x2A29) - Model Number String [R] (0x2A24) Unknown Service (291d567a-6d75-11e6-8b77-86f30ca893d3) - Unknown Characteristic [W] (5dd3465f-1aee-4299-8493-d2eca2f8e1bb) - Unknown Characteristic [I] (b864e140-76a0-416a-bf30-5876504537d9) Client Characteristic Configuration (0x2902) - Unknown Characteristic [N] (6d8f2110-86f1-41bf-9afb-451d87e976c8) Client Characteristic Configuration (0x2902) - Unknown Characteristic [N R W] (7fe8691d-95dc-4fc5-8abd-ca74339b51b9) Client Characteristic Configuration (0x2902) - Unknown Characteristic [W] (ffac0c52-c9fb-41a0-b063-cc76282eb89c) - Unknown Characteristic [R] (8f1fd018-b508-456f-8f82-3d392bee2706) D 18:47:50.062 gatt.setCharacteristicNotification(b864e140-76a0-416a-bf30-5876504537d9, true) D 18:47:50.065 gatt.setCharacteristicNotification(6d8f2110-86f1-41bf-9afb-451d87e976c8, true) D 18:47:50.068 gatt.setCharacteristicNotification(7fe8691d-95dc-4fc5-8abd-ca74339b51b9, true) V 18:48:01.291 Writing request to characteristic 5dd3465f-1aee-4299-8493-d2eca2f8e1bb D 18:48:01.291 gatt.writeCharacteristic(5dd3465f-1aee-4299-8493-d2eca2f8e1bb, value=0xFF04000000010000) D 18:48:01.778 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_BONDING (11) D 18:48:01.778 [Broadcast] Action received: android.bluetooth.device.action.PAIRING_REQUEST, pairing variant: PAIRING_VARIANT_PIN (0) D 18:48:12.993 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_BONDED (12) I 18:48:12.994 Device bonded I 18:48:13.021 Data written to 5dd3465f-1aee-4299-8493-d2eca2f8e1bb, value: (0x) FF-04-00-00-00-01-00-00 A 18:48:13.021 "(0x) FF-04-00-00-00-01-00-00" sent V 18:48:19.171 [Server] Cancelling server connection... D 18:48:19.171 server.cancelConnection(device) V 18:48:19.179 Disconnecting... D 18:48:19.179 gatt.disconnect() D 18:48:19.191 [Callback] Connection state changed with status: 0 and new state: DISCONNECTED (0) I 18:48:19.191 Disconnected D 18:48:20.229 [Server callback] Connection state changed with status: 0 and new state: DISCONNECTED (0) I 18:48:20.229 [Server] Device disconnected D 18:48:20.259 [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED
Changing the NRF.setSecurity doesn't change the behaviour and the PIN prompt will only be invoked on the camera and the passkeyRequest triggered if startBonding is included.
I changed the Write function so that it retains the startBonding but doesn't disconnect after writing to the characteristic. This leaves the PIN prompt up on the camera in the waiting state so gives me a chance to then pass the PIN to it but again it invokes the connection failure on the camera.
With the behaviour being identical by passing the wrong PIN when connected through nRF it does appear to point to the the problem being the PIN being mangled on its way from the Pixl.
-
• #31
Perfect - thanks! I just found the problem.
sendPasskey
wasn't sending the supplied key at all (I'd got the arguments to it wrong).If you try an automatic build from http://www.espruino.com/binaries/travis/master/ you should hopefully have a lot more success with it now!
Thanks for sticking with me on this and trying out the suggestions!
-
• #32
Thanks for sticking with me on this and trying out the suggestions!>
No, thanks to you for sorting it out!
Which it now is with regard to the PIN.
Using the startBonding(true) invokes the PIN prompt every time and startBonding() connects without once it has been done once so everything is working as it should there as well.
I'm away for a couple of days from this evening so can look at it more when I get back but my challenge now is to send commands while maintaining the connection.
When I'm connected to the camera, its stops advertising so functions with NRF.requestDevice can't find it and a composite function that bonds and then sends does connect but the camera isn't actioning the write to the characteristic that I'm sending.
Apologies for my ignorance over this but is there a way to stay connected and just use BluetoothRemoteGATTCharacteristic.writeValue(data) as a single command ?
-
• #33
Great! That sounds really promising!
Yes! Just delete:
gatt.disconnect();
writeValue
by itself shouldn't cause a disconnect, so you should be able to stay connected and just keep writing to it - you just have to have savedcharacteristic
to a variable that you can access once you've left that last part of the promise.If you can't see advertisements then it'll be because you're connected - so you should just be able to keep writing to the characteristic and you're sorted.
I guess it's possible that the camera wants you to have subscribed to indications on the other characteristic before it'll perform the command?
-
• #34
I had already removed the gatt.disconnect and wrote another function to write to it whilst it was still connected but couldn't get any joy in terms of the camera actioning the command.
I then thought to myself, "surely you haven't been stupid enough to be sending an invalid array to it have you?"
Turns out I had been exactly that stupid and been sending nine bytes instead of eight so we now - insert fanfare here - have a camera that bonds correctly and can be operated from the Pixl.
I won't have time now until the weekend to look at the notifications aspect but I'll be back to let you know how that worked out as soon as I've done so.
Many, many thanks for your help and patience with this.
-
• #35
That's fantastic news - thanks for letting me know!
Is this something you'd be willing to share the code for when you have it to a state you'd be happy with? As @user63214 brought this up reasonably recently you're obviously not the only person wanting to play around and do stuff with these cameras :)
-
• #36
No probelm, I'll pop up the basic connect/bond/PIN entry and single command code as a foundation and then people can use the Camera Control Protocol document that I linked to to build out the rest of it from there.
I'll sort it out over the weekend when I'm back at base.
-
• #37
OK, so here we go with a basic template for connecting and sending commands.
There is a bit of an issue regarding the bonding timing out when the flag isn't set to True to force it to pair. Basically, if you haven't sent the pin to it within about 7 seconds it times out which isn't long enough to set it through the terminal and send it.
As I want to have the Pixl auto-connect to the camera as soon as it is switched on and stay connected, it would be a bit of a pain to have to go through the PIN entry process every time its switched on.
Because the camera stores the bonding and it literally only needs to be sent the PIN once, I have not set it the flag to True but instead made a separate function with it being to True to initially set it. That way as soon as the Pixl powers on every time after the PIN has been set then it connects immediately and we are ready to send real commands to it.
The process for initial bonding only then is
1) Switch the Pixl on
2) Wait for the PIN entry screen on the camera to timeout
3) Press Button 4 on the Pixl which will start a new bonding process with no timeout
4) Enter the PIN value from the console with pin="xxxxxx"
5) Press Button 3 on the Pixl which will then send the PIN and complete the bonding.All subsequent restarts of the Pixl will connect the camera automatically with it being ready to receive commands.
I have included an example byte array for a command (it triggers the Auto Focus on the camera) and this is then sent using Button 1 on the Pixl.
The full camera control protocol for the camera can be downloaded here
var characteristicWrite; var characteristicRead; var dev; var gatt; var pin=""; var ServUUId="291d567a-6d75-11e6-8b77-86f30ca893d3"; var CharUUID="5dd3465f-1aee-4299-8493-d2eca2f8e1bb"; function Connect(){ // Insert own camera MAC address in id // NRF.requestDevice({ filters: [{ id: "90:fd:9f:b8:ca:37 public" }] }).then(function(device) { dev=device; NRF.setSecurity({keyboard:1, mitm:1}); console.log("Connecting"); device.on('passkeyRequest', function() { console.log("passkey requested"); }); return device.gatt.connect(); }).then(function(g) { gatt = g; console.log("Connected"); return gatt.startBonding(); //< If the camera has been previously bonded the PIN pop-up will not be invoked // }).then(function() { console.log("bonded", gatt.getSecurityStatus()); return gatt.getPrimaryService("291d567a-6d75-11e6-8b77-86f30ca893d3"); }).then(function(service) { return service.getCharacteristic("5dd3465f-1aee-4299-8493-d2eca2f8e1bb"); }).then(function(characteristic) { console.log("Writing To Characteristic"); characteristicWrite=characteristic; return characteristic.writeValue([0xFF, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00] ); }).then(function() { console.log("Done!"); }); } function Bond(){ // Insert own camera MAC address in id // NRF.requestDevice({ filters: [{ id: "90:fd:9f:b8:ca:37 public" }] }).then(function(device) { dev=device; NRF.setSecurity({keyboard:1, mitm:1}); console.log("Connecting"); device.on('passkeyRequest', function() { console.log("passkey requested"); }); return device.gatt.connect(); }).then(function(g) { gatt = g; console.log("Connected"); return gatt.startBonding(true);//< This will force the PIN pop-up to be invoked irrespective of previous bond// }).then(function() { console.log("bonded", gatt.getSecurityStatus()); return gatt.getPrimaryService("291d567a-6d75-11e6-8b77-86f30ca893d3"); }).then(function(service) { return service.getCharacteristic("5dd3465f-1aee-4299-8493-d2eca2f8e1bb"); }).then(function(characteristic) { console.log("Writing To Characteristic"); characteristicWrite=characteristic; return characteristic.writeValue([0xFF, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00] ); }).then(function() { console.log("Done!"); }); } function SendPin(){ //Enter required PIN in console using pin="xxxxxx"// dev.sendPasskey(pin); } function WriteValNoConnect(){ //Writes Auto-Focus command to the connected camera without re-connection// characteristicWrite.writeValue([0xFF, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00] ); } function onInit(){ //Automatically connects the camera and establishes Characteristic to be written to// // If camera has been bonded the PIN pop-up will not be invoked// Connect(); } setWatch(function() { console.log("WRITING AUTO FOCUS COMMAND TO CAMERA"); WriteValNoConnect(); }, BTN, {edge:"rising", debounce:50, repeat:true}); setWatch(function() { console.log("NO FUNCTION ASSIGNED"); }, BTN2, {edge:"rising", debounce:50, repeat:true}); setWatch(function() { console.log("SENDING PIN : "+pin); SendPin(); }, BTN3, {edge:"rising", debounce:50, repeat:true}); setWatch(function() { console.log("BONDING"); Bond(); }, BTN4, {edge:"rising", debounce:50, repeat:true});
-
• #38
Nice - thanks!
-
• #39
Done a quick mod job pressing a Puck into service as a Record Start/Stop control.
1 Attachment
-
• #40
Is there any Api documentation for NRF.setSecurity options (e.g. keyboard:1)? I want to use a Pixl as a peripheral (no keyboard attached) but force bonding and whitelisting. The central is an IOS app.
-
• #41
BTW, I've tried the NRF.setSecurity({passkey:"123456", mitm:1, display:1}); to no avail using 2v01.35 of the firmware.
-
• #42
The proper documentation for it is generated when I next do a release, so apart from http://www.espruino.com/Puck.js+Security you have to look at the source (which is used to generate the documentation).
For example setSecurity is here: https://github.com/espruino/Espruino/blob/master/libs/bluetooth/jswrap_bluetooth.c#L2493
Then you have the passkey event, passkeyRequest event and sendPasskey (just do a work search for them in quotes in the above file).
I'm not sure how you'd go about actually forcing bonding though - I believe you can do so from the iOS app though?
-
• #43
Sorry about the delay in replying and thanks for the pointer to GitHub. I'll work a bit more on it next week when hopefully I'll have a bluetooth dongle to sniff the packets with WireShark.
iOS takes the approach that it's up to the peripheral to decide if it wants to implement any security - there's no way to force it from that side.
Connection Failed
1 Attachment