blob: d5ff299e984a9007881a4ff483b8d00566ffbda7 [file] [log] [blame] [edit]
/* omr-watcher.h
*
* Copyright (c) 2023-2024 Apple Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This code adds border router support to 3rd party HomeKit Routers as part of Apple’s commitment to the CHIP project.
*
* This file contains the interface for the omr_watcher_t object, which tracks off-mesh-routable prefixes on the
* Thread network.
*/
#ifndef __OMR_WATCHER_H__
#define __OMR_WATCHER_H__ 1
typedef struct omr_watcher omr_watcher_t;
typedef struct omr_watcher_callback omr_watcher_callback_t;
typedef enum {
omr_watcher_event_prefix_withdrawn,
omr_watcher_event_prefix_flags_changed,
omr_watcher_event_prefix_added,
omr_watcher_event_prefix_update_finished
} omr_watcher_event_type_t;
typedef enum {
omr_prefix_priority_invalid,
omr_prefix_priority_low,
omr_prefix_priority_medium,
omr_prefix_priority_high,
} omr_prefix_priority_t;
struct omr_prefix {
int ref_count;
omr_prefix_t *NULLABLE next;
struct in6_addr prefix;
int prefix_length;
int metric;
int rloc;
int flags;
omr_prefix_priority_t priority;
bool user, ncp, stable, onmesh, slaac, dhcp, preferred;
bool previous_user, previous_ncp, previous_stable;
bool added, removed, ignore;
thread_service_publication_state_t publication_state;
};
typedef void (*omr_watcher_event_callback_t)(route_state_t *NONNULL route_state, void *NULLABLE context, omr_watcher_event_type_t event_type,
omr_prefix_t *NULLABLE prefixes, omr_prefix_t *NULLABLE prefix);
typedef void (*omr_watcher_context_release_callback_t)(route_state_t *NONNULL route_state, void *NULLABLE context);
// Release/retain functions for omr_watcher_t:
RELEASE_RETAIN_DECLS(omr_watcher);
#define omr_watcher_retain(watcher) omr_watcher_retain_(watcher, __FILE__, __LINE__)
#define omr_watcher_release(watcher) omr_watcher_release_(watcher, __FILE__, __LINE__)
RELEASE_RETAIN_DECLS(omr_prefix);
#define omr_prefix_retain(prefix) omr_prefix_retain_(prefix, __FILE__, __LINE__)
#define omr_prefix_release(prefix) omr_prefix_release_(prefix, __FILE__, __LINE__)
// omr_prefix_create
//
// Allocate an omr_prefix_t and initialize it with the specified settings.
omr_prefix_t *NULLABLE omr_prefix_create(struct in6_addr *NONNULL prefix, int prefix_length, int metric, int flags,
int rloc, bool stable, bool ncp);
// omr_prefix_flags_generate
//
// Given various common parameters, generate a flags word in the format expected by OpenThread for prefixes.
int omr_prefix_flags_generate(bool on_mesh, bool preferred, bool slaac, omr_prefix_priority_t priority);
// omr_prefix_priority_to_bits
//
// Given an omr_priority_t, return the bits that represent it in the prefix flag word.
//
int omr_prefix_priority_to_bits(omr_prefix_priority_t priority);
// omr_prefix_priority_to_int
//
// Given an omr_priority_t, return the human-readable integer that represents it. Invalid priority is
// returned as -1 (low).
//
int omr_prefix_priority_to_int(omr_prefix_priority_t priority);
// omr_watcher_callback_add
//
// Adds a callback on the omr_watcher object.
//
// watcher: the omr_watcher_t to which to add the callback
#define omr_watcher_callback_add(omw, callback, context_release, context) \
omr_watcher_callback_add_(omw, callback, context_release, context, __FILE__, __LINE__)
omr_watcher_callback_t *NULLABLE
omr_watcher_callback_add_(omr_watcher_t *NONNULL omw, omr_watcher_event_callback_t NONNULL callback,
omr_watcher_context_release_callback_t NULLABLE context_release,
void *NULLABLE context, const char *NONNULL file, int line);
// omr_watcher_callback_cancel
//
// Cancel a callback that was returned by omr_watcher_add_callback().
//
// watcher: the watcher that returned the callback object.
// callback: the callback to free
//
// The object passed in callback should not be retained by the caller after calling omr_watcher_callback_cancel().
void omr_watcher_callback_cancel(omr_watcher_t *NONNULL omw, omr_watcher_callback_t *NONNULL callback);
// omr_watcher_create
//
// Creates and starts an omr_watcher_t object. The object starts an ongoing query with wpantund/threadradiod to watch the Thread:OnMeshPrefixes
// property. Changes are reported to callbacks, which can be registered with
//
// route_state: pointer to a route state object to reference in callbacks, must be non-NULL.
//
// returns value: NULL on failure, or a pointer to an omr_watcher_t object.
#define omr_watcher_create(route_state, disconnect_callback) \
omr_watcher_create_(route_state, disconnect_callback, __FILE__, __LINE__)
omr_watcher_t *NULLABLE
omr_watcher_create_(route_state_t *NONNULL route_state, void (*NULLABLE disconnect_callback)(void *NONNULL),
const char *NONNULL file, int line);
// omr_watcher_start
//
// Starts the omr watcher object. Prior to calling omr_start, no events will be delivered; after calling omr_start, events may be delivered.
//
// watcher: pointer to an omr_watcher_t object to start.
bool omr_watcher_start(omr_watcher_t *NONNULL watcher);
// omr_watcher_cancel
//
// Cancels the omr watcher object. No callbacks can occur after omr_watcher_cancel has been called.
//
// watcher: pointer to an omr_watcher_t object to cancel.
void omr_watcher_cancel(omr_watcher_t *NONNULL watcher);
// omr_watcher_prefix_present
//
// Returns true if there is a prefix in the watcher's prefix list that has the specified priority.
//
// watcher: watcher we use for the search
// ignore_prefix: the prefix we are currently publishing, and hence should ignore
// ignore_prefix_len: length of the prefix we should ignore
bool omr_watcher_prefix_present(omr_watcher_t *NONNULL watcher, omr_prefix_priority_t priority,
struct in6_addr *NONNULL ignore_prefix, int ignore_prefix_len);
// omr_watcher_prefix_exists
//
// Returns true if the specified prefix is in the watcher's current prefix list.
//
// watcher: watcher we use for the search
// address: address on prefix to search for
// prefix_len: length of prefix (host bits in address are ignored)
bool omr_watcher_prefix_exists(omr_watcher_t *NONNULL watcher,
const struct in6_addr *NONNULL address, int prefix_len);
// omr_watcher_prefix_present
//
// Returns true if there is a prefix in the provided list that has the specified priority.
//
// prefixes: pointer to an omr_prefix_t object to check
// preference: low, medium or high
bool
omr_watcher_prefix_wins(omr_watcher_t *NONNULL watcher, omr_prefix_priority_t priority,
struct in6_addr *NONNULL ignore_prefix, int ignore_prefix_length);
// omr_watcher_prefixes_get
//
// Returns the list of prefixes the omr_watcher has most recently seen, or NULL if none.
//
omr_prefix_t *NULLABLE
omr_watcher_prefixes_get(omr_watcher_t *NONNULL watcher);
// omr_watcher_add_prefix
//
// Adds the specified prefix at the specified priority. Returns true if prefix was added, false otherwise.
//
bool
omr_watcher_prefix_add(omr_watcher_t *NONNULL watcher, const void *NONNULL data, int prefix_length, omr_prefix_priority_t priority);
// omr_watcher_prefixes
//
// Deletes the specified prefix. Returns true of it was deleted, false otherwise.
//
bool
omr_watcher_prefix_remove(omr_watcher_t *NONNULL watcher, const void *NONNULL data, int prefix_length);
// omw_watcher_non_ula_prefix_present
//
// Returns true if there is an on-mesh prefix in the thread network data that is not a ULA prefix (implicitly a global prefix)
//
bool omr_watcher_non_ula_prefix_present(omr_watcher_t *NONNULL watcher);
#define omr_watcher_prefix_is_non_ula_prefix(omr_prefix) ((((uint8_t *)&(omr_prefix)->prefix)[0] & 0xfc) != 0xfc)
#endif // _OMR_WATCHER_H__
// Local Variables:
// mode: C
// tab-width: 4
// c-file-style: "bsd"
// c-basic-offset: 4
// fill-column: 120
// indent-tabs-mode: nil
// End: