ponewheel / android-ponewheel

pOneWheel Android app
MIT License
71 stars 25 forks source link

No stats after firmware update #86

Closed jj05y closed 4 years ago

jj05y commented 5 years ago

Hey, I just cloned the repo and while the app connects fine, there's no stats available. It may be the firmware update. Can you repro?

kariudo commented 5 years ago

I have been pulling my hair out for days trying to read GATT from the damn onewheel, and was thrown off into thinking it wasn't the firmware update but was on my end when it was able to read once. Then it occurred to me I should check ponewheels issues to see if this was happening to anyone else... so thank you for restoring my sanity. It clearly worked once for me because I had just disconnected from the official app before attempting to read the characteristics. Anyway, I got to the same dead end after capturing the hci dump, and realized they must be doing some "secure" handshake first (as you all seem to have discovered). Decompiling Java and untangling that is out of my wheelhouse though, so I guess I will just wait for you guys to find the secret sauce there; however, my initial guess would have been they were salting their signature with a time stamp as an easy way to sort of sign their traffic.

To the point, I have another dump log if anyone wants it, or wants another set of eyes or to test something with bluez/gatttool/python etc.

0xH3xWheel commented 5 years ago

Looks like many of you have already pulled the app apart. Looking at the firmware side of things, I can verify a few of your findings. The new firmware adds code to compute an md5 hash. Also I can verify that the binary string "D9255F0F23354E19BA739CCDC4" is hard-coded in the firmware. I'm not sure where or how those the last three bytes ("A91765") are calculated yet.

0xH3xWheel commented 5 years ago

This code is called from the USART3_IRQHandler

ROM:0800A334 MOVS R1, #0xD9 ; Builds binary string "D9255F0F23354E19BA739CCDC4" ROM:0800A336 STRB.W R1, [SP,#0x30+var_20] ROM:0800A33A MOVS R0, #0xA9 ROM:0800A33C MOVS R1, #0x25 ROM:0800A33E STRB.W R1, [SP,#0x30+var_1F] ROM:0800A342 STRB.W R0, [SP,#0x30+var_13] ROM:0800A346 MOVS R1, #0x5F ROM:0800A348 STRB.W R1, [SP,#0x30+var_1E] ROM:0800A34C MOVS R0, #0x17 ROM:0800A34E MOVS R1, #0xF ROM:0800A350 STRB.W R1, [SP,#0x30+var_1D] ROM:0800A354 STRB.W R0, [SP,#0x30+var_12] ROM:0800A358 MOVS R1, #0x23 ROM:0800A35A STRB.W R1, [SP,#0x30+var_1C] ROM:0800A35E MOVS R0, #0x65 ROM:0800A360 MOVS R1, #0x35 ROM:0800A362 STRB.W R1, [SP,#0x30+var_1B] ROM:0800A366 STRB.W R0, [SP,#0x30+var_11] ROM:0800A36A MOVS R1, #0x4E ROM:0800A36C STRB.W R1, [SP,#0x30+var_1A] ROM:0800A370 MOVS R1, #0x19 ROM:0800A372 STRB.W R1, [SP,#0x30+var_19] ROM:0800A376 MOVS R1, #0xBA ROM:0800A378 STRB.W R1, [SP,#0x30+var_18] ROM:0800A37C MOVS R1, #0x73 ROM:0800A37E STRB.W R1, [SP,#0x30+var_17] ROM:0800A382 MOVS R1, #0x9C ROM:0800A384 STRB.W R1, [SP,#0x30+var_16] ROM:0800A388 MOVS R1, #0xCD ROM:0800A38A STRB.W R1, [SP,#0x30+var_15] ROM:0800A38E MOVS R1, #0xC4 ROM:0800A390 STRB.W R1, [SP,#0x30+var_14] BL sub_800D228

beeradmoore commented 5 years ago

Where outputArray is our pre-computed data just before we send it back to the board. So taking any of those sample outputs above and only copying the first 19 bytes, run it through this and the 20th byte is what we expect it to be.

byte[] checkByte = new byte[1];
checkByte[0] = 0;
int j = outputArray.Count;
int i = 0;
while (i < j)
{
    checkByte[0] = ((byte)(outputArray[i] ^ checkByte[0]));
    i += 1;
}
outputArray.AddRange(checkByte);

Goes into byte validation: 43:52:58:d8:82:11:d1:26:96:5f:9f:aa:72:fc:de:92:f3:25:3d Comes out of byte validation: 43:52:58:d8:82:11:d1:26:96:5f:9f:aa:72:fc:de:92:f3:25:3d:20

What is also interesting is this works for any of our given input byte arrays directly from the board. So they are also doing this validation before they send it off the board to the phone.

beeradmoore commented 5 years ago

It is done <3

I thought I knew the flow but it just wouldn't work. Turns out I was md5ing the wrong array -_-

Here is my Xamarin.Android code. It won't copy/paste to java but it'll be 98% of the way to working. I sent this to the board and confirm it unlocks the rest of the details.

// The 20 bytes the board sends.
var input = StringToByteArrayFastest("43:52:58:ff:fe:cb:12:dd:3f:b7:b7:b7:57:57:57:57:57:6c:6b:94");

// Im using a List so I don't have to deal with indexes as I'm only appending to this
var outputArray = new List<byte>();
outputArray.AddRange(StringToByteArrayFastest("43:52:58"));

// Take almost all of the bytes from the input array. This is almost the same as the last part as
// we are ignoring the first 3 and the last bytes.
var arrayToMD5_part1 = Java.Util.Arrays.CopyOfRange(input, 3, 19);

// This string appears to be static
var arrayToMD5_part2 = StringToByteArrayFastest("D9255F0F23354E19BA739CCDC4A91765");

// New byte array we are going to MD5 hash. Part of the input string, part of this static string.
var arrayToMD5 = new byte[arrayToMD5_part1.Length + arrayToMD5_part2.Length];
arrayToMD5_part1.CopyTo(arrayToMD5, 0);
arrayToMD5_part2.CopyTo(arrayToMD5, arrayToMD5_part1.Length);

// Start prepping the MD5 hash
MessageDigest localMessageDigest = MessageDigest.GetInstance("MD5");
DigestInputStream digestInputStream = new DigestInputStream(new System.IO.MemoryStream(arrayToMD5), localMessageDigest);

// This is actually the byte that represents a space character. ¯\_(ツ)_/¯ 
byte[] arrayOfByte = new byte[] { 101 };
while (digestInputStream.Read(arrayOfByte) != -1) { }
digestInputStream.Close();
var md5Hash = localMessageDigest.Digest();

// Add it to the 3 bytes we already have.
outputArray.AddRange(md5Hash);

// Validate the check byte.
byte checkByte = 0;
int j = outputArray.Count;
int i = 0;
while (i < j)
{
    checkByte = ((byte)(outputArray[i] ^ checkByte));
    i += 1;
}
outputArray.Add(checkByte);

The helper method I found on StackOverflow. StringToByteArrayFastest is just a method which converts these hex arrays to a byte array. For me it was important to make them capital and remove any : or -

public static byte[] StringToByteArrayFastest(string hex)
{
    hex = hex.Replace(":", "");
    hex = hex.Replace("-", "");
    hex = hex.ToUpper();

    if (hex.Length % 2 == 1)
        throw new Exception("The binary key cannot have an odd number of digits");

    byte[] arr = new byte[hex.Length >> 1];

    for (int i = 0; i < hex.Length >> 1; ++i)
    {
        arr[i] = (byte)((GetHexVal(hex[i << 1]) << 4) + (GetHexVal(hex[(i << 1) + 1])));
    }

    return arr;
}

public static int GetHexVal(char hex)
{
    int val = (int)hex;
    //For uppercase A-F letters:
    return val - (val < 58 ? 48 : 55);
    //For lowercase a-f letters:
    //return val - (val < 58 ? 48 : 87);
    //Or the two combined, but a bit slower:
    //return val - (val < 58 ? 48 : (val < 97 ? 55 : 87));
}

Awesome job to everyone involved! @jj05y thanks for kicking off the topic and throwing in all your input, @COM8 for the decompilation help. But super thanks to @kwatkins, without the inputs and outputs of that now useless password method none of this would have been possible.

kwatkins commented 5 years ago

@beeradmoore @#$@#$ YOU ROCK!!!! I was dropping in to share the stack to the MD5 that contains the pointer to the code we were heading for... but you solved it already :) Great job all!!!

kariudo commented 5 years ago

@beeradmoore well done! My requests are now working in my python app thanks to your bit above.

jj05y commented 5 years ago

This is amazing! Will update here with anything created from,

Thank you!

My next question is why!? The firmware handshake is fair to establish the correct protocol but the rest is bonkers!

If it's security through obscurity, fair enough, but this thread is clear that the security lasted less than a week. What's the point? If there's other reasons I'd love to know.

kariudo commented 5 years ago

As my thanks, and to help anyone else trying to sort this out I made a quick implementation in python: https://github.com/kariudo/onewheel-bluetooth

@jj05y it is definitely security through obscurity, but it certainly seems like it was a bad implementation. They should just provide the user a means of securing the board and used a more typical authentication scheme. I feel like it was a half hearted attempt to just close a bug in their tracker.

COM8 commented 5 years ago

@kariudo Totally agree with you. I would love to see some kind of pairing for the app. For example if you hold down the power button for more than x seconds the board enters pairing mode. Or use the first 4 to 6 numbers from the boards serial number as a pin. Or if the power button is just a simple on/off button you could enable pairing to an app for the first minute or so an than disable it. Or if you turn on the borad while it's flipped over it enables paring mode and then remembers the device. Or...

jj05y commented 5 years ago

I guess given there's the potential for firmware updates over the air you could actually build a one wheel bricking app, that when connected will do exactly that :/

Some personal security is defo needed.

beeradmoore commented 5 years ago

I wonder if devices that can pair vs devices that are just a BLE interface need to go through different security, regulations and approval for various countries. All that said, the new features in the gemini are amazing and FM has done a good job with that update!

jj05y commented 5 years ago

Hey Kwatkins! I just merged your fix and can confirm that the handshake works and it starts communicating, for ~30 seconds. I remember seeing in the 1st party app something along the lines of: if (!commsActive) {handshake()}

I'm going to start working on my own app today and will update on the above...

I've one question about the sendKeyChallengeForGemini() method. You retrieve the firmware version, explicitly reset it from a magic value, and write the value. Why do you explicitly reset the value? Have you found the value read from the board to be inconsistent?

image

Commenting out the line as above works just fine for me,

COM8 commented 5 years ago

UWP-Onewheel supports now the Gemini firmware. My implementation can be found here: OnewheelUnlockHelper

I've refined the unlock process a little bit:

  1. Request the firmware revision fom the board
  2. If does not match the Gemini firmware revision - Done
  3. Subscribe to the serial read characteristic
  4. Send firmware revision to the Onewheel
  5. Wait for the challenge to arrive
  6. Send response based on the algorithm from @beeradmoore
  7. Unsubscribe from the serial read characteristic - not needed any more
  8. Start an unlockTimer for every 15 seconds - has to be less than 24 seconds
  9. Done

The unlockTimer:

  1. Send the firmware revision to the board
  2. Done

If the board does not receive the firmware revision after the initial unlock for mor than 24 seconds it will lock up again.

Edit1: Gemini firmware revision means:

beeradmoore commented 5 years ago

I did my C# implementation over the weekend. I'm glad that reading ' ' for the MD5 buffer was just to get it to process. I was worried what the pure C# version would do as my above code was within Xamarin.Android so it was still using some of the Java classes.

kwatkins commented 5 years ago

@jj05y ahh good catch, no reason to modify firmware value before sending - thanksgiving turkey sloppiness on my part. Just catching up and see we need to add a timertask or something of that sort, if your working on it great! Feel free to branch/checkin and we can git pull'it into master.

mherfurt commented 5 years ago

Hi there, it is really great to watch the enthusiasm in this thread! I am the developer of OneWheelWear and of course I also ran into the issues discussed here. Recently, I found some time to look into the "secret handshake" thing with the new firmware. Using @kariudo 's python implementation to see an actual implementation, I ran into a situation, where I only would get sensible data, when I connected shortly after the official OneWheel app. At all other times running the readdata.py script, zero-values were returned. Do you experience the same behaviour? The process in the script looks exactly as the one described in this thread.

Cheers, Martin

COM8 commented 5 years ago

After the initial unlock of the board send by onewheel-bluetooth you have about 24 seconds to request values from the board before it locks up again. To get around this you have to send the Gemini firmware to the board before the 24 seconds are over to extend the window to an other 24 seconds. Make sure you only subscribe to characteristics after the board is unlocked. Else you will successfully subscribe but never get values back.

mherfurt commented 5 years ago

Thanks for clarifying this! The values requested by the python script itself are bogus. I assume these are requested within the correct time-frame. I assume that the unlocking mechanism - as implemented by onewheel-bluetooth - does not work in my case ... for some reason. I am curious if this is only the case with my setup...

COM8 commented 5 years ago

@mherfurt The handshake fails for me under the following circumstances: a) Some amount off wrong/unfinished handshakes have been send to the bord -> board locks up and won't react on anything any more via bluetooth

b) Sending a handshake request while an other app (e.g. official app) has been closed but the board is still connected via Bluetooth to the other phone

To solve all of these issues I just turn off the board, wait 2-5 seconds and turn it back on.

Also make sure you disable bluetooth of the device running the official app because the app runs in the background and might try to reconnect - locking you out.

kwatkins commented 5 years ago

@jj05y can you pick up and test this, wanted to get this in from https://github.com/ponewheel/android-ponewheel/tree/issue_86 but out for a few weeks (had a little v1 future OW'er baby, taking up all my time!)

if you can complete it + test i'll merge + build + drop it on google play for all to use, anticipate the "dig the app, but can you fix it for gemini" comments and feedback already

@COM8 @ebabel @audkar you may be working on this too

jj05y commented 5 years ago

Sure! Can have a look over the holidays :)

ghost commented 5 years ago

For anyone trying to access the new custom shaping, it seems they crammed it all into what was Unknown Characteristic 2. It updates like 5-6 times a second, and cycles through 3 values. You parse it as an unsigned integer with offset 0 and a signed integer with offset 1. the first unsigned integer cycles through 0, 1, and 2, and this indicates which custom shaping "attribute" it represents. 0 is stance, 1 is carvability, and 2 is aggressiveness.(Which isn't the order they're in in the app for some reason.) The second signed integer is the actual value. From my testing, stance goes from -20 to 60, carvability goes from -100 to 100, and aggressiveness goes from -80 to 127, If you set them in the official app. I don't know what happens if you set these values outside of those ranges, someone more brave than I will have to find that out.

To set values, you write them to the same characteristic. It doesn't seem like the timing matters at all. To do it, you create a byte array of size two. The first element is either 0,1,or 2, indicating the custom ridemode attribute you want, and the second element is the value. You then write the whole array.

The characteristic that used to represent the last error mode seems to be cycling through a lot of values in a similar manner, I might take a stab at that one as well.

hammer-is commented 5 years ago

Just joined the family as a bought a used OW+. I was curious about individual cell (health) voltage and as it was updated to Gemini I build the app from https://github.com/ponewheel/android-ponewheel/tree/issue_86 and it seems to work just fine and keeps the connection for 24+ seconds. I've only tested it inside with OW+ not activated/floating. @kwatkins @jj05y are there any known issues left you need help fixing before merging to master? I'd like to help develop and/or test if possible.

coolkingcole commented 5 years ago

@muellergit Did you extract the firmware? Do you have the file or can you tell me how you did it?

muellergit commented 5 years ago

No, sorry I haven't. It has been claimed to be done prior to Andromeda but FM got wind and sent a cease and desist order.

On Mon, Jan 7, 2019, 2:43 PM coolkingcole <notifications@github.com wrote:

@muellergit https://github.com/muellergit Did you extract the firmware? Do you have the file or can you tell me how you did it?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ponewheel/android-ponewheel/issues/86#issuecomment-452075125, or mute the thread https://github.com/notifications/unsubscribe-auth/APHfOWYXvfJwviI1lmKYJ8gBqx8d4h48ks5vA7FugaJpZM4YnXma .

coolkingcole commented 5 years ago

@Nanoux I have been trying to change the custom shaping, but I have been having problems. First, I still have to do the jerry rigged way of connecting with my phone first to unlock the board. I've tried messing with timeouts and such to no avail. I can for example write 003C to "OnewheelCharacteristicUNKNOWN2"(0x009d) and can read it back as being written, but stance doesn't seem to change. I have similar issues when trying to change the lights. When I change the mode"0x0045=02 is manual mode for lights" the lights turn off, but then I can not get the lights to turn back on in any fashion. I might be missing something obvious. Does anyone have insight into this?

ghost commented 5 years ago

@Nanoux I have been trying to change the custom shaping, but I have been having problems. First, I still have to do the jerry rigged way of connecting with my phone first to unlock the board. I've tried messing with timeouts and such to no avail. I can for example write 003C to "OnewheelCharacteristicUNKNOWN2"(0x009d) and can read it back as being written, but stance doesn't seem to change. I have similar issues when trying to change the lights. When I change the mode"0x0045=02 is manual mode for lights" the lights turn off, but then I can not get the lights to turn back on in any fashion. I might be missing something obvious. Does anyone have insight into this?

Honestly, messing around with trying to read and write stuff to the board without properly connecting is completely unknown territory, I would get that sorted first. Whats your problem with that?

coolkingcole commented 5 years ago

@Nanoux I have been trying to change the custom shaping, but I have been having problems. First, I still have to do the jerry rigged way of connecting with my phone first to unlock the board. I've tried messing with timeouts and such to no avail. I can for example write 003C to "OnewheelCharacteristicUNKNOWN2"(0x009d) and can read it back as being written, but stance doesn't seem to change. I have similar issues when trying to change the lights. When I change the mode"0x0045=02 is manual mode for lights" the lights turn off, but then I can not get the lights to turn back on in any fashion. I might be missing something obvious. Does anyone have insight into this?

Honestly, messing around with trying to read and write stuff to the board without properly connecting is completely unknown territory, I would get that sorted first. Whats your problem with that?

I finally was able to get to somewhere with less rf interference, and I reinstalled pygatt. The unlocking works, I can write the Light mode, but still I can't get the front or back light characteristic to stick.

device.char_write(UUIDs.LightingMode,bytearray.fromhex("00 02"),True) # Man Mode
device.char_write(UUIDs.LightsFront,bytearray.fromhex("00 75"),True) #Front red
device.char_write(UUIDs.LightsBack,bytearray.fromhex("75 00"),True) #Back white
ghost commented 5 years ago

@coolkingcole Its not impossible that they removed the individual front and back light characteristics with the Gemini firmware, I've only tried writing the lighting mode. What happens if you try to read them?

coolkingcole commented 5 years ago

@Nanoux I can read them, they stay at '\x00\x00'. The tool (https://github.com/evilsocket/bleah) reports the light characteristics as writable, but I'm not positive that the tool is 100% accurate.

ghost commented 5 years ago

@coolkingcole The front and back characteristics may still exist but just not do anything. They did change a few things, like the characterisitc that was previously for status errors now does something completely different, I think its for sending diagnostics, but I'm not sure. Since they removed the names for all the characteristics, its really hard to tell, but if everything except those two are working its not unreasonable to think they are just empty now.

COM8 commented 5 years ago

I'm still able to write to all light related characteristics:

They also respond and update to the new values. Reading the light mode works for me but front and back lighting I still have to test.

device.char_write(UUIDs.LightsFront,bytearray.fromhex("00 75"),True) #Front red The error with the line above is, that you try to set it to 0x75 but the max value is 75 in decimal (0x4B hex).

kwatkins commented 5 years ago

@hammer-is - I finally got around to merging that branch with gemini support, thanks for validating it works. Any more tests/issues let me know. Also tagged/apk/etc at https://github.com/ponewheel/android-ponewheel/releases/tag/gemini_support

ghost commented 5 years ago

Hey, I am/was the developer of the Onewave app on android, which used to live on the Play Store.

When Gemini dropped, a few people here speculated the new connection system was designed to lockout 3rd party apps. As far as I can tell, my app was the only 3rd party app on android that worked with Gemini. Today I got a DMCA takedown notice for it. It only had about 270 users between both versions, so obscurity doesn't seem to be any protection. I have no idea if I can do anything except warn you guys.

I wish @kwatkins , @beeradmoore , @mherfurt , and @COM8 the best of luck. If ya'll have any questions feel free to ask. I'll keep ya'll updated if anything happens.

beeradmoore commented 5 years ago

That’s depressing.

Was there any particar mention as to what the DMCA was regarding? Logo copyright, name, etc?

mherfurt commented 5 years ago

I agree. This makes me sad!

Any manufacturer should be happy (and feel flattered) when a community of people is building other products around their product.

It would indeed be interesting what FM objected with your product, when they sent you this DMCA notice!

ghost commented 5 years ago

The stated reason was this, verbatim:

"To be functional, the allegedly infringing software app is circumventing the Future Motion technological measures to gain access to the Future Motion copyrighted software/firmware without authorization, and to integrate the allegedly infringing software with the Future Motion works in a manner that could create rider safety hazards."

Everything in the app was either open source or created by me, nothing is infringing on copyright. They are just using DMCA to take it down.

EDIT: Can confirm, this also makes me quite sad.

EDIT2: All links to the store page are dead, but I found a super old screenshot of the storepage on my phone. The only thing that ever changed about it were the included screenshots. I was planning on taking a better header image soon but I guess that doesn't matter now. Anyway, it looks copyright free to me. https://photos.app.goo.gl/sApqRDTeYtnE1hDf9

EDIT3: It should be noted the notice was sent out by Kolitch Romano LLP on behalf of Future Motion, they didn't do it themselves. A quick google search shows its a pretty new firm. It might be possible Future Motion brought them on and then they just went after everything they could find. Thats the only thing I can think of, the official app itself was once unofficial until they bought it, so they were ok with these apps existing in the past. However, when the thing first came out I made a forum post about it, only for it to get deleted. I thought it was a rule I missed about self promotion or something but maybe it had to do with this, I don't know. It makes me scared to reach out to FM about it though.

beeradmoore commented 5 years ago

Was doing some googling and found this post on the topic. Mainly

According to Google, over 50% of DMCA takedown notices are illegitimate, targeted at the competitors of the sender in an attempt to sabotage their business.

Based on your third edit the accepted answer seems very relevant.

Be proactive and contact the company who runs the service you are using, and ask them if they are ok with your app being available on the app store, and with the way it uses their services. This approach has benefits: If you ignore the email from this competing company, they might inform the service owners of your app, which might lead them to ask you to take it down. If you approach them directly they might take a more lenient view as it shows you are willing to comply with their terms and not sneak something by them (even if that's what you've been doing so far).

Although if you contact FM about it they may look at it as you're (/we're all) against the ropes and its easy for them to say "yeah take down your app, thanks".

TBH I am surprised that FM itself has done this over apps. They all seem pretty chill, California vibes, etc. I understand that firmware modification takedowns with DMCA, sure, makes sense. It can be dangerous, you can damage the board, other people, etc. But having an app that just reads (and rarely writes) data from the a board that doesn't require modification I see in no way would cause it to be "a manner that could create rider safety hazards.".

We mainly want new features they don't have. If they open-sourced their app I'd be fairly happy to contribute to it and add new features and updates.

I wonder if it's worth a post in the OneWheel Legal Freedoms Facebook group?

muellergit commented 5 years ago

I'm glad I already downloaded Onewave.

So you didn't need to add a handshake protocol to stay connected with Gemini? That would make their DMCA takedown request even more of a stretch.

On Fri, Feb 1, 2019, 4:35 PM beeradmoore <notifications@github.com wrote:

Was doing some googling and found this https://softwareengineering.stackexchange.com/questions/142238/do-i-have-to-remove-my-app-from-app-store-copyright-infringement post on the topic. Mainly

According to Google, over 50% of DMCA takedown notices are illegitimate, targeted at the competitors of the sender in an attempt to sabotage their business.

Based on your third edit the accepted answer seems very relevant.

Be proactive and contact the company who runs the service you are using, and ask them if they are ok with your app being available on the app store, and with the way it uses their services. This approach has benefits: If you ignore the email from this competing company, they might inform the service owners of your app, which might lead them to ask you to take it down. If you approach them directly they might take a more lenient view as it shows you are willing to comply with their terms and not sneak something by them (even if that's what you've been doing so far).

Although if you contact FM about it they may look at it as you're (/we're all) against the ropes and its easy for them to say "yeah take down your app, thanks".

TBH I am surprised that FM itself has done this over apps. They all seem pretty chill, California vibes, etc. I understand that firmware modification takedowns with DMCA, sure, makes sense. It can be dangerous, you can damage the board, other people, etc. But having an app that just reads (and rarely writes) data from the a board that doesn't require modification I see in no way would cause it to be "a manner that could create rider safety hazards.".

We mainly want new features they don't have. If they open-sourced their app I'd be fairly happy to contribute to it and add new features and updates.

I wonder if it's worth a post in the OneWheel Legal Freedoms https://www.facebook.com/groups/270423860123092/ Facebook group?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ponewheel/android-ponewheel/issues/86#issuecomment-459914794, or mute the thread https://github.com/notifications/unsubscribe-auth/APHfOTB_oUC-2ZksPRHFy6JFYiNI09E4ks5vJN1IgaJpZM4YnXma .

ghost commented 5 years ago

@muellergit I totally had to add a handshake, its impossible to connect otherwise, the thing was broken for like 2 months. I'm glad you like it though.

@beeradmoore I'll give it a shot, I don't really have anything to lose at this point. Is there a way to contact them outside of the customer support system? That doesn't seem like it would end well.

Also, I've never heard about it before, but that facebook page seems to be fighting cities to legalize electric boards, not fighting against FM itself. I don't know how much of a help that would be.

muellergit commented 5 years ago

Ok, well I think FM added that handshake just so that third party apps would also have to use the handshake key to connect. Before the connection was open. So now FM has a little legal cover to attempt to prevent that key use to connect.

However it probably would not be upheld in court since there was a recent judgement in California that upholds the owner's right to repair, and access firmware to maintain the use of their property.

On Fri, Feb 1, 2019, 6:25 PM Nanoux <notifications@github.com wrote:

@muellergit https://github.com/muellergit I totally had to add a handshake, its impossible to connect otherwise, the thing was broken for like 2 months. I'm glad you like it though.

@beeradmoore https://github.com/beeradmoore I'll give it a shot, I don't really have anything to lose at this point. Is there a way to contact them outside of the customer support system? That doesn't seem like it would end well.

Also, I've never heard about it before, but that facebook page seems to be fighting cities to legalize electric boards, not fighting against FM itself. I don't know how much of a help that would be.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ponewheel/android-ponewheel/issues/86#issuecomment-459926971, or mute the thread https://github.com/notifications/unsubscribe-auth/APHfOTm2XO1HPXbQzrQYp3pVfH_mg_Ooks5vJPcagaJpZM4YnXma .

beeradmoore commented 5 years ago

@Nanoux I don't know of any other way to contact them other than customer support sorry. And yeah, this whole things hinges on how the customer support manager decides to handle it, and if they want to even inform someone from higher up on the chain. From what I can see them talking about in the group is about being sure riders are legal to ride in their state/country and to help get relevant material on that incase the police decide to tell them to stop. Only reason I mention it is because it seems some people have legal knowledge and they may be able to provide some "this isn't legal advice but..." legal advice.

beeradmoore commented 5 years ago

@muellergit that does make sense (although I don't want to wear a tinfoil hat and speculate) considering this thread is evidence that people did infect break open their own android app to see how it ticks. Does give them a little legal cover AFAIK.

I messaged @mherfurt on Facebook but I'll ping him here too. From what I understand OneWheelWear got the Gemini update patched in and released? Can you let us know if you get any form of DMCA message.

Im wondering if I should just hack together the bear minimum of my OWCE app to be a viable App Store product and release it to see if I also get a takedown or if Onewave was unlucky.

muellergit commented 5 years ago

I am guilty of letting the Onewheel Owners Group know about using Onewave to view cell voltages.

Ponewheel I thought was about to release a Gemini compatible version. Is that held up?

On Fri, Feb 1, 2019, 6:50 PM beeradmoore <notifications@github.com wrote:

@muellergit https://github.com/muellergit that does make sense (although I don't want to wear a tinfoil hat and speculate) considering this thread is evidence that people did infect break open their own android app to see how it ticks. Does give them a little legal cover AFAIK.

I messaged @mherfurt https://github.com/mherfurt on Facebook but I'll ping him here too. From what I understand OneWheelWear got the Gemini update patched in and released? Can you let us know if you get any form of DMCA message.

Im wondering if I should just hack together the bear minimum of my OWCE app to be a viable App Store product and release it to see if I also get a takedown or if Onewave was unlucky.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ponewheel/android-ponewheel/issues/86#issuecomment-459928663, or mute the thread https://github.com/notifications/unsubscribe-auth/APHfOfLP4h51aU2oL6yn1RJkJkcCgEaaks5vJPzdgaJpZM4YnXma .

ghost commented 5 years ago

I thought of it more as a security through obscurity measure, there's nothing illegal about reverse engineering software, as long as you don't distribute it. You also can't copyright a string of characters and a hash algorithm.

I appreciate spreading the word @muellergit but I think thats what set them off.

If you did that @beeradmoore it would probably fly under the radar for a few months until someone noticed it, I don't think they are doing active scans for it. I havent heard form the OneWheelWear guys, but I can't find their app on the App store. I thought they pulled it until they got Gemini working but they probably got struck too now that I think about it.

@kwatkins made a branch of ponewheel that works with gemini, I don't know what the plans for releasing it were though, especially now.

hammer-is commented 5 years ago

@muellergit @Nanoux The pOnewheel release with Gemini support was added to the Play store on the 14th of January 2019.

mherfurt commented 5 years ago

@beerandmore I did not receive a message on facebook - which BTW I do not use a lot, anymore. I did not receive a DMCA notice so far. This could relate to the fact that I am based in Europe. A quick research brought me to this discussion: https://www.lowendtalk.com/discussion/18615/dmca-does-it-apply-outside-of-the-usa

The "works in a manner that could create rider safety hazards" part in the notice could really backfire on Future Motion. At the moment, any entity within the range of an OneWheel board could send stuff there. The implemented handshake does only protect by obscurity. If it was possible to interfere with boards in a way that was dangerous to riders, it would be Future Motion's (legal) obligation to prevent this by implementing a way that only allows certain Bluetooth peers to talk to the respective board... BLE pairing would be just one way of doing this...

I will inform you about anything coming my way from Future Motion in this issue thread.

ghost commented 5 years ago

I feel like I'm going crazy right now, but the play store page for ponewheel says it was last updated April 8th 2018 and after downloading it just now it wouldn't connect. Is there a beta channel or a new store page I'm missing?

Thanks for the update @mherfurt

Sorry for any duplicate alerts, accidently posted from my school GitHub account.

hammer-is commented 5 years ago

@Nanoux See screenshot from my OnePlus about the 14th January release: image As far as I know both the April 8th release and the current release targets API21 (Android 5.0+) so I don't undestand why you can't see latest release. Btw. I've not joined the "beta" option.

UPDATE; Something is odd. Play Store in a PC browser shows current version is 3.3 - on my mobile it shows 3.4! However they both show 14th January as last update. And the "WHAT'S NEW" shows "Finally added Gemini firmware support!" both on PC and mobile.