nkaminski / csrmesh

Reverse engineered bridge implementation of the CSRMesh BTLE protocol
GNU Lesser General Public License v3.0
70 stars 20 forks source link

Connectivity to HomeBrite A19 Household bulb does not work #4

Closed truedat101 closed 8 years ago

truedat101 commented 8 years ago

I've got an A19 Household bulb, which is definitely running the CSRMesh stack (maybe 1.3?)

Steps:

Some platform details: Linux 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

I've attached the BLE Gatt information I gathered from an android app:

screenshot_20160703-174734

screenshot_20160703-174730

screenshot_20160703-174721

truedat101 commented 8 years ago

I have to create an account to get into the firmware stuff

truedat101 commented 8 years ago

Confirmed bulb is 0.16 FW

truedat101 commented 8 years ago

Also, my USB dongle may be a factor. Using a CSR 1101 based dongle, which you'd think would be working :p . I believe it supports BLE 4.0.

nkaminski commented 8 years ago

There is not an obvious reset confirmation, other than the fact that the bulb is completely unconfigured and you have to explicitly reassign it to the network. Before calling this a BT hardware issue, can you capture an on and off broadcast using the Android hci snoop logging so that we can ensure that the packets being provided to gattool by my implementation are byte-identical to what your app is sending?

truedat101 commented 8 years ago

I'll try that. I have to figure out how to do that capture from Marshmellow (android 6.0) since they removed the menu checkbox. My other droid's were not operational with the CSRMesh network.

nkaminski commented 8 years ago

And you need to be fairly accurate with the timings for a reset.

truedat101 commented 8 years ago

Seems there is a way from the app to "reset" state of bulbs and app from within the app if you are logged in.

truedat101 commented 8 years ago

Yes, the same goes for the Zigbee Bulbs. The Cree that I have is a super difficult one.

nkaminski commented 8 years ago

If it was a BT hardware issue, I would not think you would get the write confirmation too. This may be a case where one of the values that appeared to be constant is instead specific to the bulb. Getting a packet capture would be interesting and prove/disprove this theory.

truedat101 commented 8 years ago

I may have to switch back to using a 4.x or 5.x android, as I think my Phone's OEM didn't opt to allow the BLE HCI capture (it's an option they can choose to expose or not). So I'll assume that I should be able to get the capture going. I'll report back hopefully by 2pm PST. I have three phones that might work, though two were not working yesterday.

nkaminski commented 8 years ago

OK cool, since the Android app can join the mesh (kind of) and control a bulb initially setup using iOS, a scenario that I have just reproduced myself, we can safely rule out a difference in the pin derivation algorithm. This is either a BT hardware issue or a flaw in my protocol where one of the 3 constants is not actually constant but unique to a particular bulb.

truedat101 commented 8 years ago

I have a question, where do the handles 0x0011 and 0x0014 come from? What do they represent? I couldn't find any reference to these handles in the anlysis that I posted using my Bluetooth Finder tool.

truedat101 commented 8 years ago

What Bluetooth dongle do you use? Or what chipset does it have?

nkaminski commented 8 years ago

My Acer C720 uses a QC/Atheros AR9462 and my Raspberry Pi 3 uses the BCM2837's built in bluetooth. Characteristics can be referenced by either a 16 bit handle or a 128 bit UUID. The handle I am referencing is the 16 bit characteristic identifier.

truedat101 commented 8 years ago

I examined the details of the services exposed in my Android BLE scanner, but I didn't see any 0x0011 or 0x0014 , unless I overlooked it, associated with a characteristic.

truedat101 commented 8 years ago

I finally managed to get a bulb associated with a Nexus5 with droid 5.0.x. I'll grab the logs.

truedat101 commented 8 years ago

Posted the btsnoop_hci.log here: https://1drv.ms/u/s!AuIL2jCvMCqRgYdRfORA_LakEjIB4w

If you need me to re-run this a bit more cleanly, I can. However, I had much difficulty getting the app to ever join a mesh and see any devices.

nkaminski commented 8 years ago

Will look at it in a few hours.

Sent from my iPad

On Jul 4, 2016, at 4:54 PM, David J. Kordsmeier notifications@github.com wrote:

Posted the btsnoop_hci.log here: https://1drv.ms/u/s!AuIL2jCvMCqRgYdRfORA_LakEjIB4w

If you need me to re-run this a bit more cleanly, I can. However, I had much difficulty getting the app to ever join a mesh and see any devices.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

nkaminski commented 8 years ago

What was the network pin for the network that these packets were sent to?

On July 4, 2016 4:54:26 PM CDT, "David J. Kordsmeier" notifications@github.com wrote:

Posted the btsnoop_hci.log here: https://1drv.ms/u/s!AuIL2jCvMCqRgYdRfORA_LakEjIB4w

If you need me to re-run this a bit more cleanly, I can. However, I had much difficulty getting the app to ever join a mesh and see any devices.


You are receiving this because you commented. Reply to this email directly or view it on GitHub: https://github.com/nkaminski/csrmesh/issues/4#issuecomment-230357844

Sent from my Android device with K-9 Mail.

truedat101 commented 8 years ago

I believe it was 2222

nkaminski commented 8 years ago

Assuming the second to last command before the end of the capture is a breadcast "off" command (please confirm), it looks like a protocol level bug where a value that was always zero in my case is actually not.

Decrypted payloads: My "broadcast off": 00007311000000000000 Yours from the packet cap:00007311018000000000

Going to cleanup my decryption function and add that to the repo since that will ease debugging greatly. Will investigate more extensively tomorrow too since it is getting late.

nkaminski commented 8 years ago

Last command in capture looks the same (confirm that this is a "broadcast on"):

My implementation: 000073110000e4ffffff Yours from pcap:000073110180e4ffffff

And just for ref. what is currently known about the structure is: <2 pad bytes><2 byte opcode><2 pad bytes?><1 byte white_level><1 byte red_level><1 byte green_level><1 byte blue_level>

nkaminski commented 8 years ago

Created a branch called test that sends packets that exactly match yours, try testing with that and see if that resolves your issue. My bulb responds as expected to both 000073110000xxxxxxxx and 000073110180xxxxxxxx packets.

truedat101 commented 8 years ago

If it helps, I can re-run this with my session with a fixed set of steps:

truedat101 commented 8 years ago

Log uploaded here: https://1drv.ms/u/s!AuIL2jCvMCqRgYdTvjiHpy429VoCmA

truedat101 commented 8 years ago

Let me know if there is anything else I can provide to help here.

nkaminski commented 8 years ago

OK, will look into it more tomorrow. In the mean time, test my modified version in branch "test" and let me know if that works for you or not.

Sent from my iPad

On Jul 6, 2016, at 3:03 PM, David J. Kordsmeier notifications@github.com wrote:

Let me know if there is anything else I can provide to help here.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

truedat101 commented 8 years ago

The test branch has just one change, correct: 8b246ed ?

I've patched in those changes, but no effect.

nkaminski commented 8 years ago

Interesting, going to finish my packet decrypt function after work and school since it looks like there are more packets in your case than mine. Judging by the length, you have a packet other than an RTC set or lightlevel. Just want to confirm that both the bulb and app have been reset / had their data cleared and that there are not any other bulbs other than this one that have been configured by the Android app since it was installed or reset?

truedat101 commented 8 years ago

I did exactly these steps.

reset
pair (2222)
signal off
signal on
set level 50%

The reset was through the app. I'm not 100% but it's possible the set level step doesn't ramp down but sends a series of levels. It really depends on how smooth I was turning the level down.

I haven't gone and checked the file sizes, but was wondering if the snoop file is concatenated or truncated each time you enable HCI snooping.

nkaminski commented 8 years ago

Have not lost sight of this, just very busy with work and school and should be able to spend some time on this shortly.

truedat101 commented 8 years ago

Ok, great, would love to get this working. Let me know how I can help.

nkaminski commented 8 years ago

Wrote a decryption and network key cracking routine to make it easier to examine large groups of packets to see what is different in your case to hopefully be able to explain this issue. However I had some difficulty making sense of the 2nd packet capture log. After further investigation, I discovered the cause of the issue was the key you used the 2nd time appears to be 1111 instead of 2222? Can you confirm?

import csrmesh from binascii import hexlify, unhexlify d = unhexlify("d609d30080e84d2654293783e60fa182d3f06d0e7cb388ff") result = csrmesh.network_key_bruteforce(d) print(result[0]) 1111 csrmesh.print_decrypted_packet(result[1]) seq: 13830614 magic: 80 decpayload: 00007311018000000000 encpayload: e84d2654293783e60fa1 eof: ff hmac_packet: 82d3f06d0e7cb388 hmac_computed: 82d3f06d0e7cb388

truedat101 commented 8 years ago

I'll reconfirm. This was a while back, so I'll see what pin works.

truedat101 commented 8 years ago

Will have a look this week. Been tied up as well with some stuff.

nkaminski commented 8 years ago

Recently acquired a 2nd bulb and can confirm that issues DO occur if any bulb is "aware" of any other bulbs on its same network (i.e. with the same PIN) regardless of if they are powered or not. In such case, all commands sent to any of the bulbs on the mesh effect only the first bulb that was ever setup on such network. If the first bulb that was assigned to the network is unavailable or powered off, the command appears to send successfully but nothing happens. Hard resetting both bulbs via power cycling (resetting via the app does NOT work!) and setting each one up with a separate network PIN allows them to work as intended. I would like to look into this more myself and determine how to specify a destination other than the first device in packets.

truedat101 commented 8 years ago

Hmmm, this may explain my current problems, in addition to possibly having used the wrong pin. A reset via the app maintained the old pin then.

nkaminski commented 8 years ago

This looks like it has been resolved for the most part. Feel free to reopen this issue if you still have trouble.

truedat101 commented 7 years ago

I'll re-test this next week. Working on some CES demo stuff, so would like to utilize this possibly since I need an alternative platform to Zigbee.