title: Get weight data from bluetooth le scale by disassemble manucaftures library
body: <p>a friend has a body scale with Bluetooth Le. To save his weight measurements he has to open the Manufactures App on his phone. So we try to use his raspberry pi for the Job. We find out, that the scale sends the data over advertisments. The scale is never connectable, and you can use different phones at the same time to receive the data. During the measurement the app(s) shows the same values as the display of the scale does. You know, if you stand on the scale the value will go up and down until the measurement is finished. This 'going up and down' is also visible on the phone, or phones if you use more than one at the same time. So i think it is a fact, that the data is transmitted over BLe advertisments. They can only be in the manufacturer data, what for example looks like this:</p>
  <pre><code>starts always with:
  0f ff ac a0 db 58 e2 53 91 a0
  
  and then:
  
  88,30kg
  20 c9 f8 42 0d b0
  20 c9 f8 78 0d a6
  
  88,35kg
  20 c9 f9 b4 0d a3
  20 c9 f9 88 0d b7
  
  88,40kg
  20 c9 f9 e6 0d b5
  20 c9 f9 e6 0d b5
  
  2,15kg
  a0 c8 ab 40 0d a0
  
  0,00kg
  a0 c8 a0 a0 0d b5
  </code></pre>
  <p>But no matter how i have tried, i can't calculate this data to the given weight. I tried it in big endian, little endian, other untis like pound, ounces or even stone. I can not find a formula to calculate the data to every known weight. Interesting is, that zero is &quot;a0 c8 a0 a0 0d b5&quot;. The first byte is 20 during the measurement, after finishing it, the scale sends many advertisment-packages with a0 in the first byte. I think this will say &quot;final value&quot;. The fifth byte is always 0d, no matter what. The second byte changes from c8 to c9 on higher weights. I think at 50 or 60 kg.
  Because i can't find the solution for this i tried something else. I decompiled the android app an look for the part, where the advertisment-package is parsed. Unfortunately the app loads a native library to do this. Looks like the Manufacture really wanna keep it`s secret. I tried to use their library for my one purpose. But it looks like i need a Header-File to use the library in my own Java-Application. So my last chance is to disassemble the Library, what i have done. I used objdump. I know from the Java-Code, the function that i need is</p>
  <pre><code>private native List&lt;Map&lt;String, Object&gt;&gt; decode(byte[] bArr, int i, int i2, Object obj);
  </code></pre>
  <p>I can find this function/subroutine in the dump file.. but i can not understand how to work with it. I watched a video tutorial series for assembler, what was really interesting, but it doesn't really help me with this. I assumed you can somehow see where the data comes in (parameters for decode), how they be processed and returned (saved to memory for example). I also found a &quot;BleBroadcastScaleProtocol16decodeWeightData&quot;-Function but have still the same problem. My questions is now: Is there a real chance, that this can be done this way? The dump file has 10MB of text. Do someone know how to do this, or have done something like this before? I'm working for months on this and ever step forward brings me two steps back.</p>
  <p>I put the dump file on my Cloud drive, maybe someone will have a look.</p>
  <p><a href="https://drive.google.com/file/d/1KGwhYcQZBsUKWEeagwr1qx7BnjP233q4/view?usp=sharing" rel="nofollow noreferrer">Dump File</a></p>
  <p>Edit:
  I use my Raspberry Pi to send advertisements to the Manufactures App. I use the example-advertisement script from bluez.
  If i send adverts with the Service-ID FFB0 and &quot;aca0&quot; on the first two bytes of the manufacturer data the app recognize the pi as an &quot;Insmart&quot; scale.
  I'm also able to send weight data to the app. If i send &quot;(ac a0 db 58 e2 53 91 a0)
  a0 c8 a0 a0 0d b5&quot; the app show 0.
  I played around and find out the last four bits are a checksum, calculated by adding all hex-values together and take the last four bits of the summary.
  The weight data must be somewhere in the 2. to 4. bit (c8 - second a0). I wrote a script to take 16 bits from an offset and print out the hex value. As input data i use c8a0a0 (=0). With an offset of 1 (take 16 bits, starting from bit 2) it prints out &quot;0x9141&quot;.
  In a second script i can input a hex value and it will merge it with the default value of &quot;c8a0a0&quot;. So i can enter 9142 and put it together to data i can send as manufacuter data. 9142 is c8a120, what does nothing but 9143 is c8a1a0. This value is 0,25kg. When i increase the first value (9143) by 2 it will add 0,25kg in the app. Sometimes it adds 0,3kg. This works to 917f / c8bfa0 / 7,95kg. If i go to 9181 / c8c0a0 it jumps to 24,55kg. The i can continue in 0,25kg steps to 9195 / c8caa0 / 27,15kg. On 9197 / c8cba0 it changes unit and shows 4:4.4st:lb.
  If i count up by 1 the app crashs most of the time with the other values (9144, 9146, 9148...)
  Does anyone recognize a pattern in it?
  I'm also starting to try different offsets, but it doesn't look very promising.</p>
  <p>Edit2:
  4:4.4st:lb is equal to 27.397kg. Next step is 4:5.0st:lb what is 27,67kg. So it is linear at this point. But the range 8 - 24kg is missing</p>
  <p><a href="https://pastebin.com/MQY8Q8RM" rel="nofollow noreferrer">Here are the scripts that i use</a></p>