Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to connect to MOVE #25

Open
beanian opened this issue Feb 8, 2018 · 114 comments
Open

Unable to connect to MOVE #25

beanian opened this issue Feb 8, 2018 · 114 comments

Comments

@beanian
Copy link

beanian commented Feb 8, 2018

When I execute hcitool lescan I can see the MOVE2 which i'm assuming is my MOVE device. (I have noticed it is not CSRMESH like others have seen)
image

Executing the cli results in the following error:
image

Any ideas?

@Swiftnesses
Copy link

I guess this is because you're using the new firmware? Bluetooth standard. Has anyone has success accessing the blinds with this new firmware?

@beanian
Copy link
Author

beanian commented Feb 10, 2018

That could be it. I wasn't aware there was a difference in bluetongue protocols depending on firmware. Have you a source of or more information on this?
I have only took delivery of the unit this week.

@nkaminski
Copy link
Owner

I do not have a MOVE unit, however I am aware of some previous issues related to MOVE connectivity that were thought to be a result of the MOVE unit enforcing a random source address. Can you try temporarily replacing addrType=btle.ADDR_TYPE_PUBLIC with addrType=btle.ADDR_TYPE_RANDOM on line 13 of csrmesh/gatt.py and see if it resolves this?

@beanian
Copy link
Author

beanian commented Feb 16, 2018

Thanks for your help, I tried that and i'm getting this message now

[+] Connecting to device C1:43:18:00:00:01
[+] Writing 0x81fb8d008041e17a696a1b80e0c3f446afe3ff to BTLE handle 0x21
[-] A communication error has occured: Error from Bluetooth stack (comerr)
[+] BTLE disconnected
[+] Communication complete
[-] Operation failed

@klimbot
Copy link

klimbot commented Feb 27, 2018

I've just updated one of my old MOVE devices that used to work using this library and it is no longer working. It appears the firmware update breaks compatibility with this library somehow.

@nkaminski
Copy link
Owner

nkaminski commented Feb 27, 2018 via email

@beanian
Copy link
Author

beanian commented Mar 2, 2018

@nkaminski I have attached my snoop log. I followed the following procedure

  1. Enabled snoop log
  2. connected to MOVE device
  3. Issued a blind up command
  4. issued a blind down command

My move mac address is c1:43:18:00:00:01
Hopefully this makes sense to you
btsnoop_hci.log

@nkaminski
Copy link
Owner

nkaminski commented Mar 2, 2018 via email

@beanian
Copy link
Author

beanian commented Mar 2, 2018

@nkaminski the network key is 8888.
Yeah I was looking at it in wireshark to see if I could make sense of it but I'm not familiar enough with bluetooth protocols to understand what is going on!

@beanian
Copy link
Author

beanian commented Mar 12, 2018

@nkaminski Did you get a chance to look at this?

@nkaminski
Copy link
Owner

nkaminski commented Mar 12, 2018 via email

@nkaminski
Copy link
Owner

OK so this still looks like CSRMesh traffic, which is good. Possibly the format of the payload is what has changed. Going to revise my decryption tool slightly to make it easier for all (including myself) to analyze and see what has changed.

@lisaele
Copy link

lisaele commented Apr 26, 2018

Any progress on this? I'm having the same issue since updating the firmware and it would be much appreciated if you could find a solution. :)

@nkaminski
Copy link
Owner

I should be able to look into this more this weekend.

@Swiftnesses
Copy link

@nkaminski any luck?

@nkaminski
Copy link
Owner

nkaminski commented May 12, 2018 via email

@Swiftnesses
Copy link

@nkaminski Just fired up the RP I used to test this some time ago... Trying to remember the commands :)

Have the commands changed with your new exp. branch release?

@Swiftnesses
Copy link

@nkaminski

Seem to be hitting an error upon install:

https://pastebin.com/CYeXwkwF

@Swiftnesses
Copy link

Seems I needed to run: sudo apt-get install libglib2.0-dev

@Swiftnesses
Copy link

Tried issuing this command:

sudo ./bin/csrmesh-cli move --pin 263056 --dest EE:16:B0:00:00:04 --position 120

I get:

[+] Connecting to device EE:16:B0:00:00:04
[-] A connection error has occured: Failed to connect to peripheral EE:16:B0:00:00:04, addr type: public
[-] Connection to mesh failed
[-] Operation failed

@nkaminski
Copy link
Owner

nkaminski commented May 14, 2018 via email

@Swiftnesses
Copy link

@nkaminski I can just make the changes to the file on my pi, right? No need to rebuild etc?

@nkaminski
Copy link
Owner

nkaminski commented May 14, 2018 via email

@nkaminski
Copy link
Owner

nkaminski commented May 14, 2018 via email

@Swiftnesses
Copy link

Same error as before, with the exception that the error message now states 'random'

@Swiftnesses
Copy link

The new app generates 6 digit pins, I'll override it however and re-add some devices to test!

@Swiftnesses
Copy link

@nkaminski created a new 'place' with a 4 digit pin and re-added the devices. Tried with the both experimental versions (with and without random). Sadly, no luck :(

@Swiftnesses
Copy link

@beanian I'm not great with debugging (no wireshark), can you perhaps help us too?

@Swiftnesses
Copy link

My dreams of integrating these into my home automation schedule are slipping away, perhaps it's time to look for an alternative 😢

@lisaele
Copy link

lisaele commented May 15, 2018

Did you kill the app on your phone before sending the commands?

@Swiftnesses
Copy link

@andrasj I'd love to somehow implement the confirmation event into my Node JS script, is this returned via CSRmesh, or do I need to use something else? Did you turn anything else up with regards responses, it's obvious the app has little / no issues and seems to work pretty well tbh!

@nkaminski do the responses above make sense to you?

@kmidt
Copy link

kmidt commented Mar 20, 2019

Hey Guys. Any Solution ? When not Move is dead in my House in FHEM :)

@wasbaun
Copy link

wasbaun commented May 9, 2019

Hey, Iam new to Github und following this project quite a while. I have two Move Units and had it up and running with csrmesh und raspberrypi. Today I received a Mail from OmniaBlinds, that they are not selling them anymore and that I can buy a newer better blind motor from them.... The teptron website is under construction now. Now I want to contribute to this project, because from now on, we are on our own and I dont want to throw the units to the trash. Invested to much money.
As I said, I the move units worrk with raspberrypi and openhab. I use one of the experimental branches oh this project that worked for me. But I have the problem, that the units forget their start and stop position. So I think the only solution would be a firmware hack or use one of the uart commands to change positions.

@nkaminski
Copy link
Owner

This issue has been idle for quite some time; is there still interest in advancing this given that the move units are no longer readily available?

@lisaele
Copy link

lisaele commented Jan 28, 2020

Yes, I'm still interested.
My move worked great in Home assistant before I upgraded to the new firmware. Been searching google to see if there is a way to flash the old firmware back on the Move but no luck.
Any progress on this would be much appreciated!

@andrasj
Copy link

andrasj commented Jan 31, 2020

Short answer: yes
Longer answer: I think the real problem is not clearly defined, there are conflicting reports that csrmesh is/isn't working with old/new firmware of the devices. It seems some people keep trying stuff on their own. I cannot spend time on this project at the moment, so I'm passively following this thread for now.

To be honest, I'm afraid that one day, the official app will no longer work (on newer phones), but it is still needed for initializing the meshnetwork and pin (at least afaik). For this reason, I already hoped someone knew a way to replace the firmware of the device. I think most of us only need a BLE/IO-gateway and could do automations from another system. With a 'simple' open source FW (if possible at all on csr-chips), it would be much easier to develop/integrate the product.
I'm willing to open up or provide one of my devices for reverse engineering to someone that can help with this.
IIRC the proprietary csr-mesh stuff is all done in the csr-SDK and doesn't need special hardware, which could mean the controller/BT-module could be reused without the mesh-stuff.

@nkaminski
Copy link
Owner

Open source replacement firmware is an interesting thought.

However as I don't have a move unit myself and therefore don't know anything about the hardware platform used, I would be dependent on someone with one to take a few internal photos and provide visible part numbers or similar hardware identifiers. That should give us an idea of how easy or difficult it would be to develop and flash a replacement firmware.

That being said, it sounds like the current major issues interfacing with the proprietary V2 firmware are the fact that the MAC address changes after every boot and that the provisioning process requires the now-unsupported app. Agree?

@andrasj
Copy link

andrasj commented Feb 1, 2020

about interfacing with v2, the changing MAC is an issue, but since the network still advertises itself as 'MOVE', it is possible to implement a workaround.
My main problems were:
-unreliable communication (sometimes multiple retransmits are needed before the device starts moving)
-lack of documentation of the protocol to set speed or read data.

about the hardware: some documents can be found on https://fccid.io/2AICLM1508 , the original crowdfunding campaign mentioned CSR1010 , in the user manual the technical section says:
Primary MCU chip: CSR1010
Secondary MCU chip: Atmel ATtiny48
These pictures are not really clear, but it's a start.

@andrasj
Copy link

andrasj commented Feb 6, 2020

Meanwhile I opened up one of my devices, see attached for pictures with more detailed components.
The motor seems to be standard DC, for positioning there is a half plastic disc attached to shaft. I guess the optical sensor is on the motor/IO pcb. Maybe I'm gonna try to control it with an ESP, so there is direct wifi-access. (but I'll stop hijacking this thread, people who are interested or are willing to help can contact me)
MOVE_Battery-IO-Board
MOVE_ControllerBoard

@nkaminski
Copy link
Owner

nkaminski commented Feb 7, 2020

@andrasj If you have access to a multimeter: when assembled and powered with batteries or USB, what voltage level do you see between the leftmost and 4th from left as well as leftmost and 5th from left pin (in orientation of photo) in the pin header that is partially visible at the top right of the main board?

From your photo, I can see that the pin count as well as location of the ground pin on that header is consistent with the FTDI style serial pinout.

If this is indeed a serial header, it is very possible that this port may still be active even though USB serial has been disabled.

@andrasj
Copy link

andrasj commented Feb 7, 2020

the 2 outer pins seem to be connected, they had exactly 0V, between the left and the middle 4 pins it was kind of floating between 20-30mV. When measuring while powering up, I could see a short peak of higher voltage (or it might be an artifact of my simple multimeter). If it's a serial, I guess I should be able to measure 0 Ohm between the pins and the Rx/Tx pins from one of the controllers?

@nkaminski
Copy link
Owner

nkaminski commented Feb 7, 2020

Correct regarding the fact that you should see zero ohms resistance between the serial pins on the header and the respective microcontroller pins.

However, my suggestion to measure voltage was based off of the fact that an enabled but idle TTL serial port will drive it's Tx line high. Therefore it looks like this either isn't a serial port or isn't active.

@andrasj
Copy link

andrasj commented Feb 8, 2020

I looked for the open contacts, it seems they are debug/programming headers for the controllers.
The ones in the corner next to the USB-connector are debug lines for the CSR-chip:
1 -> CSR pin GND
2 -> CSR pin 18: DEBUG_CLK : debug SPI CLK selected by SPI_PIO#
3 -> CSR pin 19: DEBUG_CS# : debug SPI chip select (CS#) selected by SPI_PIO#
4 -> CSR pin 20: DEBUG_MOSI : debug SPI MISO selected by SPI_PIO#
5 -> CSR pin 22: DEBUG_MISO : debug SPI MISO selected by SPI_PIO#
6 -> CSR pin 26: SPI_PIO# : Selects SPI debug on PIO[8:5]

The ones around the atmel are the debugging lines for the ATTiny, and according to the datasheet they can be used for serial programming the chip.
1 -> AT pin 25: PC6 (RESET/PCINT14)
2 -> AT pin 15: PB5 (SCK/PCINT5)
3 -> AT pin 13: PB3 (PCINT3/MOSI)
4 -> AT pin 14: PB4 (PCINT4/MISO)
5 -> AT pin 4: GND
6 -> AT pin 3: VCC

@nkaminski
Copy link
Owner

nkaminski commented Feb 8, 2020 via email

@andrasj
Copy link

andrasj commented Feb 8, 2020

Thanks for the quick feedback, I'm not familiar with atmel (little experience with PCI & ESP), but it looks like I could use/flash a spare ESP (which is 3.3V) to use as an avrisp. There is even some hope for flashing the CSR-chip: https://github.com/lorf/csr-spi-ftdi

Based on looking at the pcb-traces & datasheets I'm currently asuming:
-CSR & Atmel are communicating over I2C (or SPI? pins are overloaded on CSR)
-datapins of the usb-connector for power are connected to UART RX/TX of CSR-chip
-CSR-chip is handling BLE/battery/(solar/)temperature monitoring/automation rules
-ATTiny is controlling the motor/encoder
(I'll try to verify some of these assumptions with the multimeter)

There are several things which could be done:
-sniff between atmel & csr (maybe some correlations with datapackets sent over BLE which could help debugging/reverse engineering the protocol)
-forget about the csr & put another comms-module in front of the atmel (if that protocol is understandable)
-same as above but with custom FW in atmel (which will require further analysis of the electronics for motor control)
-custom FW on csr (but need to get the SDK and experience of programming BLE)

Only the first idea could help people who don't want to open up their device (and maybe the last if we could find a way to upload the FW over serial/usb). And since the shell of the device is glued together it won't be easy to open up all devices to get close to the hardware to modify or reflash.

Sometimes I'm thinking it's easier to rebuild it from scratch, but at least this way I learn new stuff and I am having fun :-)

@Maatss
Copy link

Maatss commented Feb 14, 2020

Two years later..
This might speed things up!

MoveDeviceConstants
byte ALLOC_SUN_AUTOMATION = Byte.MAX_VALUE;
byte ALLOC_TEMP_AUTOMATION = -65;
byte ALLOC_TIME_AUTOMATION = 63;
byte AUTOMATION_TYPE_SUN = 1;
byte AUTOMATION_TYPE_TEMP = 2;
byte AUTOMATION_TYPE_TIME = 0;
byte CALIBRATE_CLOCKWIZE = 35;
byte CALIBRATE_COUNTER_CLOCKWIZE = 36;
byte FULLY_CLOSED = -1;
byte FULLY_OPEN = 0;
int MOVE_1_APPEARANCE = 4192;
int MOVE_2_APPEARANCE = 4352;
byte MOVE_AUT_GET_AUTOMATION_LIST = 80;
byte MOVE_AUT_GET_MOVE_TIME = 82;
byte MOVE_AUT_GET_SENSOR_AUTOMATION = 88;
byte MOVE_AUT_GET_TIME_AUTOMATION = 86;
byte MOVE_AUT_REMOVE_AUTOMATION = 89;
byte MOVE_AUT_SET_MOVE_TIME = 81;
byte MOVE_AUT_SET_SENSOR_AUTOMATION = 87;
byte MOVE_AUT_SET_TIME_AUTOMATION = 85;
byte MOVE_CMD_CALIBRATE_CLOSE = 114;
byte MOVE_CMD_CALIBRATE_OPEN = 112;
byte MOVE_CMD_ECHO_REQUEST = -32;
byte MOVE_CMD_ECHO_RESPONSE = -31;
byte MOVE_CMD_GET_DEVICE_NAME = 66;
byte MOVE_CMD_GET_DEVICE_STATUS = 64;
byte MOVE_CMD_GET_STATUS = 22;
byte MOVE_CMD_GOTO_GROUP_PRESET = 68;
byte MOVE_CMD_MOVE_POSITION_ON_TIME = 70;
byte MOVE_CMD_MOVE_REBOOT = 41;
byte MOVE_CMD_MOVE_TO_POSITION = 34;
byte MOVE_CMD_SET_DEVICE_NAME = 65;
byte MOVE_CMD_SET_GROUP_PRESET_POS = 67;
byte MOVE_CMD_SET_MESH_WAKE = 69;
byte MOVE_CMD_STOP_TURNING = 33;
byte MOVE_DEVICE_NAME_MAX_LEN = 20;
byte MOVE_GET_STATUS_RSP = -106;
int MOVE_HORIZONTAL = 1;
int MOVE_HORIZONTAL_TILT = 2;
byte MOVE_SET_POS_ACK = -94;
byte MOVE_STATUS_INVALID_ID = 1;
byte MOVE_STATUS_NOT_TIMESYNCED = 3;
byte MOVE_STATUS_NO_MEM = 2;
byte MOVE_STATUS_OK = 0;
byte MOVE_STATUS_REQ_INCOMPLETE = 4;
int MOVE_VERTICAL_CENTRE = 4;
int MOVE_VERTICAL_LEFT = 6;
int MOVE_VERTICAL_RIGHT = 7;
int MOVE_VERTICAL_SPLIT = 5;
int MOVE_VERTICAL_TILT = 3;

Wake up procedure
Runnable wakeBurst = new Runnable() {
public void run() {
if (mBurstCount <= 32) {
ByteBuffer buffer = getFrameBuffer(6);
buffer.put(MoveDeviceConstants.MOVE_CMD_SET_MESH_WAKE);
buffer.put((byte) 100);
buffer.putShort(180);
buffer.put((byte) 4);
buffer.put((byte) -1);
sendMeshFrame(0, buffer, false);
mBurstCount++;
mWakeBurstHandler.postDelayed(wakeBurst, 357);
return;
}
stopWakeBurst();
}
};

Note
Should be noted that I have not verified this apart from recognizing a couple commands, such as:
byte MOVE_CMD_MOVE_TO_POSITION = 34;

@Swiftnesses
Copy link

Amazing work, I still have 10 of these in use (using a pi as a custom API interface), mesh never worked, so I directly talk with each unit using MAC (which kills me as it changes upon reboot!).

Following progress here, great work!

@andrasj
Copy link

andrasj commented Feb 15, 2020

I once tried to use command MOVE_CMD_GET_DEVICE_NAME, without success, but I based it on the orignal/official doc released, which used 18 instead of 66. So the old doc is definitely different from the values above. (probably the old doc is obsolete).
@Maatss : where did you find this? decompiled from the android app? Is it possible to get the complete sources? This would help to see how de app identifies the devices & the provisioning.

@Maatss
Copy link

Maatss commented Feb 15, 2020

ApkStudio to decompile the android app and then Android Studio to easily navigate the project. Though much of the code will be nonsense, i.e random class, method and variable names, much can be deducted by context. Fortunately, many classes are found almost completely intact.

@andrasj
Copy link

andrasj commented Feb 22, 2020

@Maatss thanks for the info about apk-decompiling, it was (and will be) very useful.

Meanwhile I've tried to create an application which gets as close as possible (on the bluetooth-level) as the official MOVE-app. I have some progress and data to share. It looks like now I'm able to get data back from the device (so able to detect packet loss or unresponsive device).
The first simple scenario is:

  1. Connect to mesh (1 device, pin 4242)
  2. Move the MOVE to one end
  3. Move the MOVE to the other end

With the help of the java-code and decryption routines, I could analyze what is (or should) happen to control the device. Here is what's happening at BT-level:

  1. Connect & perform some Gatt service/characteristic discovery (later on only characteristic with handle 0x1e and 0x21 are used)
  2. enable notifications for both handles (Description-WriteValueWITHResponse)
  3. request device status: 1 write-without-response to 0x21
  4. device sends value by means of notification (large packet, notification on both handles, which should contain battery/temperature/position/...)
  5. app starts sending a bunch 'wake mesh' commands. (always same command, but re-encrypted with new sequenceNumber, so different bytes 'in the air')
  6. moveToPositionOldMove: 2 write-without-response, first bytes to 0x1e, remaining to 0x21
  7. device sends notification on handle 0x21 (meanwhile the app tries to resend a new encrypted version of the same command)
  8. (repeat previous 2 steps)

Currently, I'm able to:

  • 'moveToPositionWithSpeed' (which is different from the csrmesh-command that doesn't include speed). So writing large payloads (> 20bytes) seem to work reliable.
  • receive some response-notification as a confirmation of the command

Attached you can find 2 captures of my test scenario, one captured from a phone with the offical app, and one from my testApp on PC
moveFromPhone1.zip
moveFromPc1.zip

Next steps:
-Try multiple devices on the same mesh.
-Try to decrypt and understand the notification-values. (I'll try to get some information from the decompiled apk, but the csrmesh-part seems to be obfuscated)
-Find out why the device is sending me notifications as a response to the WakeMesh packets (it's a minor issue, but this isn't the case with the official app)

@nkaminski : do you have any idea how the data comming from the device could be decrypted? how did you manage to make it work for data sent to the device?

Response on 'GetStatus' in 2 ATT-messages:
88:c5:96:01:80:9e:c4:ae:7c:69:47:68:59:37:87:0b:b4:ac:be:a9 and 9c:b1:d7:12:35:32
Response on 'MoveToPosition' in 1 ATT-message:
89:c5:96:01:80:01:c3:83:d9:f3:90:67:71:bc:58:bb:39:65:32

current info on responses:
-All notifications seem to end on 0x32
-first data-byte in the response on GetStatus should be -106 or 0x96 , so maybe these are not encrypted (need to check if other data bytes make sense)

Edit: sorry for the long post, but I think it might be worth as a summary of workings with data-captures

@andrasj
Copy link

andrasj commented Feb 22, 2020

Follow up: After digging through the obfuscated code, I managed to find the decryption routine for responses/notifications.
Currently i managed to decode what they call 'block responses'. Now I'm able to fetch the current position (among others), even when the position was changed with the hardware-buttons.
Still missing is processing 'stream responses' (needed to fetch device name and automations).

@andrasj
Copy link

andrasj commented Feb 24, 2020

This evening I performed some tests with multiple devices. Seems to work (but not that reliable).

  • I powered 2 devices, by just changing the objectId, I could control both devices (both could be controlled from a connection to a single mac - doesn't matter which one)
  • I noticed that sometimes the devices are not responding to commands, but I think it's not really a mesh issue. When I ran my testapp to simultaneously (1 second apart) move both devices, sometimes the first devices did'nt respond, sometimes the second wouldn't move. All while devices were physically untouched and always communicating with the same MAC.
  • I think to get reliable sends, we need to wait for the commands to be acknowledged, and resend if needed. I assume that's how the teptron-app manages it to get reliable communication (assumption based on BT-traffic capture). (Need to change my implementation to automatically correlate request/notifications to confirm this).
  • I've also put both devices on a powerbank, and put them in the middle/other side of the house. I could control both through the MAC of the middle device (RSSI -70). (after some minutes the farmost device also showed up on a scan, but with an RSSI of -92).
  • Strange observation: my first device reports with a random MAC and alias 'MOVE', my second device uses a fixed public MAC with alias 'CSRmesh', the was the same after switching it from usb-plug to powerbank. (To be investigated, maybe something to do with the provisioning on the mesh, and only the first device gets a random address?)

@nkaminski
Copy link
Owner

@andrasj Excellent work on reversing the decryption flow for the responses! Is it similar to the device -> mesh crypto schema?

Regarding correlation of requests and responses, does the acknowledgement response to a command include the sequence number of the original command? Possibly csrmesh takes cues from similar standardized protocols like TCP in this regard; that would make packet loss easily detectable.

Regarding RE of the official app, another worthwhile tool (at least in my opinion when reversing the outgoing message crypto) was IGLogger (https://github.com/intrepidusgroup/IGLogger).

Instrumenting calls to the Java crypto APIs in the offical app made it pretty straightforward to identify the crypto functions involved and the inputs to such, providing a really nice starting point in the heavily obfuscated code.

@andrasj
Copy link

andrasj commented Feb 25, 2020

It is very similar, only the data which is given to the ciper is slightly different:
image

  • bArr : received notification data
  • bArr2 : bytes from MeshPinKey (same as for write-to-mesh traffic)
  • z : unused
  • aj.a().f() : this is a byte[8] structure, something which is called "NetworkIv", and probably provided by the device itself (It seems to be something provided by the remote device during the provisioning on the network, but probably only for other encryption schemes, because it seems to work with 8 bytes of 0x00)

Main difference: from the received notification data only 3 bytes of the sequence number and 2 other bytes which seems to be the id of the sending device.

Thanks for the tooling-hints (since my last serious java-exepriences are from times at university some decades ago, i'm not that familiar with the ecosystem any more). To find the routine, I assumed it would be similar to sending-encryption, so I started by searching for some string-literals (like the winning 'ECB'), and started exploring the sources around these matches.

@andrasj
Copy link

andrasj commented Mar 1, 2020

I've spent some time again with the moves, and here is some additional protocol description:

  • The last byte of the encrypted mesh-packets was set to '0xff'. I'm pretty sure this is some kind of TTL which is decremented on retransmission. I have 2 reasons to believe it. First reason: while bulk-parsing BLE-traffic from the original app, I encountered notification/repsonse-data with a previously 'moveToPosition' command inside, after looking closer, I saw the raw packet bytes (sequenceNr & encrytped data) were exactly the same as a few packets earlier in the capture file, but it was 'Write command' instead of 'Gatt Notification', and the last byte was 0xFE (in notification) instead of 0xFF (in original sent command). Second reason: I see the same behavior on regular responses on other commands. I have 2 devices on the same mesh, all notifications from deviceId 2 end with 0x32, all notifications from deviceId 1 end with 0x31. (mesh connection went through device2).
  • The 'magic' byte '0x73' which seems to be present in all commands/responses has probably some meaning and is some kind of 'GATT-only'-indication. I've encountered packets (command and response) where this byte was 0x70, 0x71 or 0x72. (on special commands with automations and 'set device speed' from the app). Worth mentioning is that around these commands, there is some other BLE-traffic on the L2CAP-layer but with custom CID's. And in the original app, I've found some traces these 0x70-0x72 could be related to 'DATASTREAM', 'STREAM RX' and 'STREAM FLUSH'. This needs some deeper investigation before being able to actually use them, but this is a start in the good direction I guess.
  • Also worth mentioning is that the offical app uses Gatt-'Write without response' instead of 'write with response' (the latter is currently used in this csrmesh implementation)

Currently, I think we have enough information to reliably create/use the MOVE-devices for daily use (not provisioning/calibrating). So I think I'm going to try to get latest bluez working on my NAS, and design some mount to put the device directly on the rail of my blinds.
My tests were done from c# code (initially on windows with the UWP-BT-api), later on I continued with mainly the same code but on linux with bluez through DBUS. So my repo is kind of a mess with usefull (partially compiling) information, so I don't have some kind of pull-request ready. But if someone wants to contribute or have a look, let me know.

@stexie
Copy link

stexie commented Mar 27, 2020

@andrasj: that's wonderful news. Looks like the final pieces are finally found?
Following this thread for a long time its fantastic to find out someone got a new breakthrough in this quest.
Looking forward to a usable version. I too have a nas and am voluteering to test any code you want to be tested. Let me know if i can be of some use.

@m00nlait
Copy link

I've spent some time again with the moves, and here is some additional protocol description:

  • The last byte of the encrypted mesh-packets was set to '0xff'. I'm pretty sure this is some kind of TTL which is decremented on retransmission. I have 2 reasons to believe it. First reason: while bulk-parsing BLE-traffic from the original app, I encountered notification/repsonse-data with a previously 'moveToPosition' command inside, after looking closer, I saw the raw packet bytes (sequenceNr & encrytped data) were exactly the same as a few packets earlier in the capture file, but it was 'Write command' instead of 'Gatt Notification', and the last byte was 0xFE (in notification) instead of 0xFF (in original sent command). Second reason: I see the same behavior on regular responses on other commands. I have 2 devices on the same mesh, all notifications from deviceId 2 end with 0x32, all notifications from deviceId 1 end with 0x31. (mesh connection went through device2).
  • The 'magic' byte '0x73' which seems to be present in all commands/responses has probably some meaning and is some kind of 'GATT-only'-indication. I've encountered packets (command and response) where this byte was 0x70, 0x71 or 0x72. (on special commands with automations and 'set device speed' from the app). Worth mentioning is that around these commands, there is some other BLE-traffic on the L2CAP-layer but with custom CID's. And in the original app, I've found some traces these 0x70-0x72 could be related to 'DATASTREAM', 'STREAM RX' and 'STREAM FLUSH'. This needs some deeper investigation before being able to actually use them, but this is a start in the good direction I guess.
  • Also worth mentioning is that the offical app uses Gatt-'Write without response' instead of 'write with response' (the latter is currently used in this csrmesh implementation)

Currently, I think we have enough information to reliably create/use the MOVE-devices for daily use (not provisioning/calibrating). So I think I'm going to try to get latest bluez working on my NAS, and design some mount to put the device directly on the rail of my blinds.
My tests were done from c# code (initially on windows with the UWP-BT-api), later on I continued with mainly the same code but on linux with bluez through DBUS. So my repo is kind of a mess with usefull (partially compiling) information, so I don't have some kind of pull-request ready. But if someone wants to contribute or have a look, let me know.

Hi andrasj,
at first thank you for the great job and updates. How is your progess on the project going on? I´am quite interested following this thread since 2 years with the goal to integrate my single move to the openhab network on my raspberry. Since you mentioned you have a bluez based version which can send commands to the move in will solve my solution and "move the move". Can you give me a look in your linux based code. Many thanks.

@andrasj
Copy link

andrasj commented Jun 1, 2020

I'm hopping around on personal projects, this one's been ignored since my last update...
Anyway, I used a private repo on gitlab, which I just made public for anyone's interest.
There are a couple of network pins,mac and ip's in there, but there are all from 'test'-environment. so shouldn't be a problem.
Also keep in mind this code was produced in an organic way. (read: it's kind of a mess)
I started with good intentions, but moving from windows to linux, start subscribing notifications, attempting various batch packet analysis, the code got quite messy.
Anyway, if you're interested in the bluez/move magic, you could start in the 'testBleLinux'-project which is the entrypoint application with linux-implementations, bluez stuff is in the class CsrmeshNetworkDBus, some cross-platform stuff is in 'movectlLib'
https://gitlab.com/andrasj/movectl
Enjoy your journey, hope you'll be contributing new info/sources if they are of value.
In case of questions, don't hesitate to drop me a msg.

@Swiftnesses
Copy link

Hello @andrasj,

I was meant to check-in months ago, but it slipped my mind... 2020 huh :)

I'm still using the script from here to address each Move blind directly (via ID) - as I cannot figure out how to issue a mesh wake first. I seems you've really improved the implementation of commands (speed etc) and are also getting data back, i.e. battery? How can we add these commands to the script here?

Many thanks in advance, oh and Happy Christmas to you (and the others following!).

@andrasj
Copy link

andrasj commented Dec 30, 2020

Thanks for triggering on this project, but my devices are still in the drawer... and they were meant to be installed years ago :-) .
I didn't update the python script, because I think the current script is just 'fire and forget', it sends some data and exits. To get it working reliably, there is additional logic needed, to watch for response-notifications, an possibly resends. This means the script isn't that 'simple' any more. It probably will break the functionality to control the other type of device (it was a light bulb I guess), and I'm not that experienced with python. That's mainly why I didn't update this script, but contributed the knowledge for the community to decide how to 'move' on. (At least till I'ld like to use them)

Summary of what I think are required changes compared to the current script-logic:

  • subscribe for notifications to receive 'acknowledgments' (and decrypt them to be able to correlate and get values)
  • use WriteCommand instead of WriteValue to put data on the network
  • resend if acknowledgment takes too long
  • optional: send the wake-sequence for better succes rate
  • optional: discover devices to avoid the mac-changing issues (if suffering from this)

I won't have time to work on this in the coming weeks, but I'll try to answer questions, if any...
I think it is better to fork or start over again, because the 2 supported device types are really diverging from each other.
Feel free to spin up something, I'm sure others are still interested, and maybe I'll do some pull requests in a couple of years ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests