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

WiFi location service with sample #708

Merged
merged 5 commits into from
Jan 11, 2025
Merged

WiFi location service with sample #708

merged 5 commits into from
Jan 11, 2025

Conversation

mniestroj
Copy link
Collaborator

No description provided.

@mniestroj mniestroj requested review from sam-golioth, szczys and hasheddan and removed request for sam-golioth December 11, 2024 19:14
Copy link

github-actions bot commented Dec 11, 2024

Visit the preview URL for this PR (updated for commit a0996d7):

https://golioth-firmware-sdk-doxygen-dev--pr708-location-wifi-mz17ai5t.web.app

(expires Fri, 17 Jan 2025 15:22:17 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: a9993e61697a3983f3479e468bcb0b616f9a0578

include/golioth/location/wifi_zephyr.h Outdated Show resolved Hide resolved
include/golioth/location/wifi.h Outdated Show resolved Hide resolved
@mniestroj mniestroj force-pushed the location-wifi branch 11 times, most recently from ff80383 to 623ec88 Compare December 16, 2024 18:33
Copy link

github-actions bot commented Dec 16, 2024

Code Coverage

Code Coverage

Package Line Rate Branch Rate Health
include.golioth 75% 50%
port.linux 62% 34%
port.utils 58% 46%
port.zephyr 58% 25%
src 69% 31%
Summary 67% (2719 / 4035) 31% (1126 / 3671)

Copy link

codecov bot commented Dec 16, 2024

Codecov Report

Attention: Patch coverage is 6.12245% with 92 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/location.c 0.00% 43 Missing ⚠️
src/location_wifi.c 0.00% 36 Missing ⚠️
src/coap_client_libcoap.c 30.00% 6 Missing and 1 partial ⚠️
src/coap_client.c 0.00% 3 Missing ⚠️
src/coap_client_zephyr.c 50.00% 2 Missing and 1 partial ⚠️
Files with missing lines Coverage Δ
src/coap_client.c 45.57% <0.00%> (-0.46%) ⬇️
src/coap_client_zephyr.c 57.28% <50.00%> (-0.25%) ⬇️
src/coap_client_libcoap.c 54.40% <30.00%> (-0.35%) ⬇️
src/location_wifi.c 0.00% <0.00%> (ø)
src/location.c 0.00% <0.00%> (ø)

... and 1 file with indirect coverage changes

@mniestroj mniestroj force-pushed the location-wifi branch 6 times, most recently from 83f680a to 1abbd41 Compare December 17, 2024 13:12
@@ -261,6 +261,34 @@ static enum golioth_status golioth_coap_client_set_internal(struct golioth_clien
return GOLIOTH_OK;
}

enum golioth_status golioth_coap_client_post(struct golioth_client *client,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have anywhere else that we use _post in the user API? I ask because this is a departure from the _set and _set_block API naming we currently have. I wonder if _set_payload or something along those lines would be a good fit?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... I was thinking about that myself and considered set_payload / set_with_response / set_with_rsp, etc.

  1. My first implementation was about extending set with payload (and payload_size) arguments. This seemed to be obvious choice for internals of our SDK and was the cleanest path forward, without introducing new API (like _post). This turned out to be very verbose for public API that SDK users consume. So... decided to leave those APIs without payload.
  2. Next approach was to implement either _set() equivalent with _set_with_rsp() to describe that payload is provided in that case. That however was very loosely related to our existing _set() APIs, like lightdb_*_set(). Then I was thinking about whether _set_*() is a good choice for API that sends and receives something. More natural is the _post() nomenclature, which is very well known in case of HTTP, CoAP and in general in the world of RESTful APIs.
  3. Decided to go with _post() API, since that maps very good to internal CoAP implementation without introducing new nomenclature. It does what POST method does technically... so it sends data and receives data. It is definitely more than set word describes.

So if we are about changing the (internal) APIs, my bet would be to use _post() in most places and just expose _set() for high-level APIs, like lightdb, where it makes sense. Even for stream service which just sends data now... I think it makes more sense to use golioth_stream__push() or golioth_stream__post() instead of golioth_stream__set().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also like using _post because it more closely matches our use of _get and _delete elsewhere. I don't love the idea of us now exposing a set_cb and a post_cb as part of the public API though. The post_cb looks very similar to the get_cb (identical?) and the set_cb is currently used for POST and DELETE operations. I wonder if moving to something more like "callback with response" and "callback without response" would make more sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good discussion! Here are my thoughts:

  • I like the idea of using _post() for the internal API. The use of set() here always felt a little odd here, since we are doing POST operations and the other APIs also use the CoAP REST operation names (GET, OBSERVE, DELETE, etc.). We can keep set() for the higher level APIs that don't return a payload like LightDB State and Stream. This change would be out of scope for this PR.
  • For this PR, I think adding the new API works fine.
  • I agree with Dan that we have a lot of overlap in the callbacks. I'm working on a change to proxy the callbacks through the upper half client as part of my hackday / holiday hours project. For that change, I'm using one catch-all callback between the lower and upper-half clients. We could do something similar for user callbacks (i.e. use one callback and set the payload to NULL if it is irrelevant for the operation). Or we could rename the callbacks as Dan suggested. Another idea is proxying all callbacks through the higher level services and then using service-specific callbacks. I think that will be easier for users, but it does add a lot of indirection to the callbacks (lower client => upper client => service => user code).

.content_type = content_type,
.callback_post = callback,
.arg = callback_arg,
.callback_is_post = true,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps not relevant to this PR, but this callback_is_post member makes me think of the is_observe member we have in some other params structs. Perhaps these could be unified in a type member that all params structs have with an enum that specifies is_post, is_observe, etc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I would 100% agree if we would have them in the same structure. Do you think it makes sense to introduce type now even if we have 2 types at most for each struct?

Even if we would switch to types, then I think that observe and post should be defined in separate enum, i.e. separate namespace. They are just different things, so I would prefer to not put them in single location to prevent confusion.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right about keeping namespaces separate. This is something to think about in future work but I don't think we should make any changes yet.

include/golioth/location.h Outdated Show resolved Hide resolved
@mniestroj mniestroj force-pushed the location-wifi branch 5 times, most recently from 3d255a2 to b95f216 Compare December 19, 2024 15:21
@mniestroj mniestroj requested a review from hasheddan December 19, 2024 15:31
Copy link
Contributor

@hasheddan hasheddan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work @mniestroj! Left a few comments below.

include/golioth/location.h Outdated Show resolved Hide resolved
include/golioth/location.h Outdated Show resolved Hide resolved
include/golioth/location.h Show resolved Hide resolved
include/golioth/location.h Outdated Show resolved Hide resolved
include/golioth/location/wifi.h Show resolved Hide resolved
@@ -261,6 +261,34 @@ static enum golioth_status golioth_coap_client_set_internal(struct golioth_clien
return GOLIOTH_OK;
}

enum golioth_status golioth_coap_client_post(struct golioth_client *client,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also like using _post because it more closely matches our use of _get and _delete elsewhere. I don't love the idea of us now exposing a set_cb and a post_cb as part of the public API though. The post_cb looks very similar to the get_cb (identical?) and the set_cb is currently used for POST and DELETE operations. I wonder if moving to something more like "callback with response" and "callback without response" would make more sense?

examples/zephyr/location/wifi/CMakeLists.txt Show resolved Hide resolved
@mniestroj mniestroj force-pushed the location-wifi branch 2 times, most recently from 7355624 to 8b77188 Compare January 2, 2025 15:00
Copy link
Contributor

@sam-golioth sam-golioth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @mniestroj! Can we add a twister test for the new sample? I'd like us to get into the habit of adding tests alongside new code rather than adding them retroactively.

include/golioth/location.h Outdated Show resolved Hide resolved
src/Kconfig Show resolved Hide resolved
include/golioth/location.h Outdated Show resolved Hide resolved
src/location_wifi.c Show resolved Hide resolved
examples/zephyr/location/wifi/CMakeLists.txt Show resolved Hide resolved
examples/zephyr/location/wifi/src/wifi_playback.c Outdated Show resolved Hide resolved
@@ -261,6 +261,34 @@ static enum golioth_status golioth_coap_client_set_internal(struct golioth_clien
return GOLIOTH_OK;
}

enum golioth_status golioth_coap_client_post(struct golioth_client *client,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good discussion! Here are my thoughts:

  • I like the idea of using _post() for the internal API. The use of set() here always felt a little odd here, since we are doing POST operations and the other APIs also use the CoAP REST operation names (GET, OBSERVE, DELETE, etc.). We can keep set() for the higher level APIs that don't return a payload like LightDB State and Stream. This change would be out of scope for this PR.
  • For this PR, I think adding the new API works fine.
  • I agree with Dan that we have a lot of overlap in the callbacks. I'm working on a change to proxy the callbacks through the upper half client as part of my hackday / holiday hours project. For that change, I'm using one catch-all callback between the lower and upper-half clients. We could do something similar for user callbacks (i.e. use one callback and set the payload to NULL if it is irrelevant for the operation). Or we could rename the callbacks as Dan suggested. Another idea is proxying all callbacks through the higher level services and then using service-specific callbacks. I think that will be easier for users, but it does add a lot of indirection to the callbacks (lower client => upper client => service => user code).

This allows to pass callback and parse returned payload at application
layer.

Signed-off-by: Marcin Niestroj <[email protected]>
@mniestroj mniestroj force-pushed the location-wifi branch 5 times, most recently from ccc2394 to 1f49b15 Compare January 9, 2025 13:26
@mniestroj mniestroj requested a review from sam-golioth January 9, 2025 19:09
Copy link
Contributor

@sam-golioth sam-golioth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good @mniestroj! Left a couple comments about using the location request struct while processing the response. Still missing a twister test for the sample as well.

src/location.c Outdated Show resolved Hide resolved
src/location.c Outdated Show resolved Hide resolved
Introduce support for Golioth WiFi location service.

Signed-off-by: Marcin Niestroj <[email protected]>
Add a sample with WiFi access points collected over the city trip.

Signed-off-by: Marcin Niestroj <[email protected]>
This driver is helpful for testing without access to hardware with WiFi.

Add also native_sim overlays with preconfigured wifi_playback driver.

Signed-off-by: Marcin Niestroj <[email protected]>
@mniestroj
Copy link
Collaborator Author

Still missing a twister test for the sample as well.

Working on that :) Which platforms do we want to support? I'm targeting native_sim for now, due to possiiblity to test with playback data. For real WiFi capable platforms we don't really have a reliable way of testing with accesspoint.

@sam-golioth
Copy link
Contributor

sam-golioth commented Jan 10, 2025

Still missing a twister test for the sample as well.

Working on that :) Which platforms do we want to support? I'm targeting native_sim for now, due to possiiblity to test with playback data. For real WiFi capable platforms we don't really have a reliable way of testing with accesspoint.

I'm good with just native_sim to start 👍

We might be able to test with other platforms later, since we don't actually care that the location data is accurate, just that we are able to use the APIs, and that the sample code compiles and runs as expected. Making sure the location data is accurate is for the cloud team to test 🙂

@mniestroj
Copy link
Collaborator Author

Twister sample test implemented in #725 (it requires dev environment for now due to Location backend service).

Copy link
Contributor

@sam-golioth sam-golioth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work @mniestroj!

@mniestroj mniestroj merged commit c2ac22d into main Jan 11, 2025
134 of 140 checks passed
@mniestroj mniestroj deleted the location-wifi branch January 11, 2025 06:11
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

Successfully merging this pull request may close these issues.

4 participants