Ken Van Hoeylandt 6e437d3288
Location services, kernel Device improvements, de-incubate devices, and more (#691)
**New Features**
  * Added location services with GPS and network-based positioning, approximate or precise accuracy, and live status updates.
  * Added a Location Settings app to view status, control location access and accuracy, and manage GPS devices.
  * Added location choices during device setup and a location toggle in the system menu.
  * Added support for thread stacks in external memory when available, with fallback to existing memory options.

**Improvements**
  * Wi-Fi and Bluetooth enabled states are saved when changed and applied at startup; separate “Enable on boot” switches are no longer shown in their management screens.
  * GPS setup can stop promptly when interrupted.
  * Improved device removal handling during startup and while references are outstanding.
  * Updated several device listings to no longer be marked as incubating.
2026-10-13 23:13:30 +02:00

121 lines
4.2 KiB
C

// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <tactility/concurrent/task_event_group.h>
#include <tactility/error.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Location service. Location providers (e.g. GPS) report fixes to the service.
* The most recent fix of a regular provider is used while it's less than 2 minutes old.
* Otherwise, the most recent fix of a fallback provider (e.g. IP geolocation) is used, if there is one.
* Providers only run while there is at least one subscription.
*/
#define LOCATION_PROVIDER_ID_MAX_LENGTH 15
/** Horizontal accuracy in meters of a fix with LOCATION_PRECISION_APPROXIMATE */
#define LOCATION_APPROXIMATE_ACCURACY_METERS 3000.0f
enum LocationPrecision {
/** Providers only report fixes with a horizontal accuracy of LOCATION_APPROXIMATE_ACCURACY_METERS or worse */
LOCATION_PRECISION_APPROXIMATE,
/** Providers report fixes as accurate as they can */
LOCATION_PRECISION_PRECISE,
};
/**
* A location fix. Values the provider doesn't know are NAN for floating point fields and 0 for the others.
* Accuracies are the radius of 68% confidence, in the unit of the value they belong to.
*/
struct Location {
/** Degrees in WGS84, positive is north */
double latitude;
/** Degrees in WGS84, positive is east */
double longitude;
/** Meters */
float horizontal_accuracy;
/** Meters above mean sea level */
float altitude;
/** Meters above the WGS84 ellipsoid */
float ellipsoidal_altitude;
/** Meters */
float vertical_accuracy;
/** Speed over ground in meters per second */
float speed;
/** Meters per second */
float speed_accuracy;
/** Direction of travel in degrees clockwise from true north, in range [0, 360) */
float course;
/** Degrees */
float course_accuracy;
/** Number of satellites used for the fix */
uint8_t satellites;
/** Time of the fix according to the provider, in milliseconds since the Unix epoch */
int64_t time_ms;
/** Milliseconds since boot when the service received the fix */
uint64_t uptime_ms;
/** Id of the provider that reported the fix */
char provider[LOCATION_PROVIDER_ID_MAX_LENGTH + 1];
};
/**
* Allow or disallow the use of location services. The service only runs while allowed. The choice is persisted.
* Location services are disallowed by default.
*/
error_t location_set_enabled(bool enabled);
bool location_is_enabled(void);
/** Set the precision that providers should report. The choice is persisted. */
error_t location_set_precision(enum LocationPrecision precision);
enum LocationPrecision location_get_precision(void);
/**
* Get the current fix. Without subscriptions, this is the last known fix.
* @param[out] location the fix
* @retval ERROR_NOT_FOUND when no fix was reported since the service started, or location services are disabled
*/
error_t location_get(struct Location* location);
/**
* Caller-owned subscription: the service signals @a bit on the event group whenever a new current fix is reported.
* Read the fix with location_get().
* @warning Fields other than `bit` are for internal use only.
*/
struct LocationSubscription {
uint32_t bit;
struct {
struct TaskEventGroup* event_group;
struct LocationSubscription* next;
} internal;
};
/**
* Subscribing starts the providers when location services are enabled. They stop when the last subscription is removed.
* Providers start and stop in the background: subscribing and unsubscribing don't wait for them.
* @param[in,out] sub subscription to register, must stay alive until unsubscribed
* @param[in] event_group caller-owned group to wait on, must outlive @a sub
* @retval ERROR_RESOURCE @a event_group has no free bits left
* @retval ERROR_INVALID_STATE @a sub is already registered
*/
error_t location_subscribe(struct LocationSubscription* sub, struct TaskEventGroup* event_group);
/** @retval ERROR_NOT_FOUND when @a sub is not registered */
error_t location_unsubscribe(struct LocationSubscription* sub);
/** @return true when location services are enabled and there is at least one subscription */
bool location_is_in_use(void);
#ifdef __cplusplus
}
#endif