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

Add Battery status as payload? #24

Open
epe opened this issue Feb 19, 2025 · 15 comments
Open

Add Battery status as payload? #24

epe opened this issue Feb 19, 2025 · 15 comments

Comments

@epe
Copy link

epe commented Feb 19, 2025

Hi!
Thanks for your great work. would it be possible to publish the battery level as a payload.
IIRC for Find my Devices you can not only see the location, but also its battery level.

If i have a Powerbank, add an ESP32 that measures its capacity, can I add this value 0-100% somehow to this code to publish that ?

@gsrbr
Copy link

gsrbr commented Feb 20, 2025

Hello @epe ,
I don't know if Google FMDN supports a custom payload, but by the Google FMDN docs it supports a simple battery status ussing the Hashed flags inside the adv_data_raw , Google FMDN Hashed flags docs.
Supported battery status:

  • Battery level indication unsupported
  • Normal battery level
  • Low battery level
  • Critically low battery level

Actually this repo has a simple and generic implementation of the "Firmware for custom ESP32-based trackers" so I think add it to the repo will be a little bit strange and will add complexity to the code.

I don't have how to test it now but i think you can add it just filling the Hashed flags inside the adv_data_raw

uint8_t adv_raw_data[31] = {
0x02, // Length
0x01, // Flags data type value
0x06, // Flags data
0x19, // Length
0x16, // Service data data type value
0xAA, // 16-bit service UUID
0xFE, // 16-bit service UUID
0x41, // FMDN frame type with unwanted tracking protection mode indication
// 20-byte ephemeral identifier (inserted below)
// Hashed flags (implicitly initialized to 0)
};

For add info on Hashed flags you can see this example

// 20-byte ephemeral identifier
uint8_t eid_bytes[20];
hex_string_to_bytes(eid_string, eid_bytes, 20);
memcpy(&adv_raw_data[8], eid_bytes, 20);

Remenber to respect the hashed flags field patern.

I hope it help :)

@epe epe changed the title Add payload? Add Battery status as payload? Feb 20, 2025
@epe
Copy link
Author

epe commented Feb 20, 2025

Oh, wow thanks for the insight. Even a "feedback" of 4 states could probably even be helpful in some applications!

Further up in the document there is another chapter about battery notification: https://developers.google.com/nearby/fast-pair/specifications/extensions/batterynotification?hl=de
Does this also apply for our usecase here or is that only feasible in another context?

@leonboe1
Copy link
Owner

Just a note: Reading out the battery status is only possible when the tracker is nearby, it is not sent with network reports.

@geissdoerfer
Copy link
Contributor

Oh, wow thanks for the insight. Even a "feedback" of 4 states could probably even be helpful in some applications!

Further up in the document there is another chapter about battery notification: https://developers.google.com/nearby/fast-pair/specifications/extensions/batterynotification?hl=de Does this also apply for our usecase here or is that only feasible in another context?

No this service is part of fast pair and basically a sibling to the FMDN functionality implemented in this repository.

@sivar2311
Copy link

Sorry for this dumb question but how to calculate the hashed flags on the ESP32 ?
The docs says "To produce the final value of this byte, it is xor-ed with the least significant byte of SHA256(r)."
Is "SHA256(r)" the last byte of the EID ?
Or does the ESP32 have to have the secret key to perform this calculation?

@leonboe1
Copy link
Owner

Yes, the EIK is needed for this, as well as key rotation. Both are not implemented, therefore you cannot implement the battery status as proposed by Google, but you could implement a custom, more simpler battery status advertisement.

@sivar2311
Copy link

sivar2311 commented Feb 22, 2025

Could the EIK also exposed by main.py so this can be used on the ESP32 side?
Are you available for a chat like on discord or something?

I'm working on an Arduino based library (https://github.com/sivar2311/FMD-Arduino).
It would be great if the battery level as well as the unwanted tracking mode can be set.
But this would require to expose the EIK instead the EID to the library. The EID can be calculated by the library itself.

@leonboe1
Copy link
Owner

Yes, the EIK could be exposed, but you would still need to implement the key rotation. I'm currently quite busy, and cannot work on this.

@epe
Copy link
Author

epe commented Feb 24, 2025

I'm not so much into the technical Details. What is EIK/EID? It would be great if we could get this going .. there is plenty of usecases to send sensor data through this new kind of network :-)

@leonboe1
Copy link
Owner

leonboe1 commented Feb 24, 2025

As mentioned above, the battery status is not sent over the network. Therefore, repurposing this to send sensor data is not possible.

@mrx23dot
Copy link

mrx23dot commented Mar 5, 2025

More info here
https://github.com/mrx23dot/GoogleFindMyTools/blob/75d60fa3c7e807e89e2e686366be1da7805e0cba/ESP32Firmware/main/main.c#L66

not sure about bit order in 'Hashed flags' bit7..0 or bit0..7

@sivar2311
Copy link

@mrx23dot Check the Google FMDN Hashed flags docs.

The problem is you have to hash the flag byte.
For this you have to use the EIK not the EID... (if i understand this correctly)

@epe
Copy link
Author

epe commented Mar 5, 2025

EID? EIK?
If there is only 4 possible states, would it be possible to prepare the necessary crypto stuff and put it on the microcontroller, and that will just use one of for different values?

@mrx23dot
Copy link

mrx23dot commented Mar 5, 2025

Yes you are right

To produce the final value of this byte, it is xor-ed with the least significant byte of SHA256(r).

Note that r should be aligned to the curve's size. Add zeros as most significant bits if its representation is shorter than 160 or 256 bits, or the most significant bits should be truncated if its representation is larger than 160 or 256 bits.

If the beacon doesn't support battery level indication, and isn't in unwanted tracking protection mode, it's allowed to omit this byte entirely from the advertisement.

it mislead me is that this byte is constant zero in this repo.

So in order to use these fields some extra math is needed. i.e. to use battery indicator, and enable 'unwanted tracking protection mode'

The engineering way is to precalculate the hashed values during key generation for each of 3 battery states, instead of having SHA256 on MCU.
Or to use the hash part 'r' is needed, which is related to the rotating MAC scheme?

What does Status:1 Status:3 mean in main.py reports?

@leonboe1
Copy link
Owner

leonboe1 commented Mar 6, 2025

I'm still unsure what you are trying to achieve with the battery status. Encrypting the battery status like Google does it provides no additional value, since it is not sent over the network. It's just for local communication, meaning it would be much, much simpler to just not encrypt it if you want to read out the Battery status of the ESP.

Regarding the meaning of the status:
Status 1 = Own Report
Status 2 = Report from a "At All Areas" contributor
Status 3 = Report from a "High Traffic only" contributor

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

6 participants