1 /* omr-watcher.h 2 * 3 * Copyright (c) 2023-2024 Apple Inc. All rights reserved. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * This code adds border router support to 3rd party HomeKit Routers as part of Apple’s commitment to the CHIP project. 18 * 19 * This file contains the interface for the omr_watcher_t object, which tracks off-mesh-routable prefixes on the 20 * Thread network. 21 */ 22 23 #ifndef __OMR_WATCHER_H__ 24 #define __OMR_WATCHER_H__ 1 25 26 typedef struct omr_watcher omr_watcher_t; 27 typedef struct omr_watcher_callback omr_watcher_callback_t; 28 typedef enum { 29 omr_watcher_event_prefix_withdrawn, 30 omr_watcher_event_prefix_flags_changed, 31 omr_watcher_event_prefix_added, 32 omr_watcher_event_prefix_update_finished 33 } omr_watcher_event_type_t; 34 35 typedef enum { 36 omr_prefix_priority_invalid, 37 omr_prefix_priority_low, 38 omr_prefix_priority_medium, 39 omr_prefix_priority_high, 40 } omr_prefix_priority_t; 41 42 struct omr_prefix { 43 int ref_count; 44 omr_prefix_t *NULLABLE next; 45 struct in6_addr prefix; 46 int prefix_length; 47 int metric; 48 int rloc; 49 int flags; 50 omr_prefix_priority_t priority; 51 bool user, ncp, stable, onmesh, slaac, dhcp, preferred; 52 bool previous_user, previous_ncp, previous_stable; 53 bool added, removed, ignore; 54 thread_service_publication_state_t publication_state; 55 }; 56 57 typedef void (*omr_watcher_event_callback_t)(route_state_t *NONNULL route_state, void *NULLABLE context, omr_watcher_event_type_t event_type, 58 omr_prefix_t *NULLABLE prefixes, omr_prefix_t *NULLABLE prefix); 59 typedef void (*omr_watcher_context_release_callback_t)(route_state_t *NONNULL route_state, void *NULLABLE context); 60 61 // Release/retain functions for omr_watcher_t: 62 RELEASE_RETAIN_DECLS(omr_watcher); 63 #define omr_watcher_retain(watcher) omr_watcher_retain_(watcher, __FILE__, __LINE__) 64 #define omr_watcher_release(watcher) omr_watcher_release_(watcher, __FILE__, __LINE__) 65 RELEASE_RETAIN_DECLS(omr_prefix); 66 #define omr_prefix_retain(prefix) omr_prefix_retain_(prefix, __FILE__, __LINE__) 67 #define omr_prefix_release(prefix) omr_prefix_release_(prefix, __FILE__, __LINE__) 68 69 // omr_prefix_create 70 // 71 // Allocate an omr_prefix_t and initialize it with the specified settings. 72 73 omr_prefix_t *NULLABLE omr_prefix_create(struct in6_addr *NONNULL prefix, int prefix_length, int metric, int flags, 74 int rloc, bool stable, bool ncp); 75 76 // omr_prefix_flags_generate 77 // 78 // Given various common parameters, generate a flags word in the format expected by OpenThread for prefixes. 79 80 int omr_prefix_flags_generate(bool on_mesh, bool preferred, bool slaac, omr_prefix_priority_t priority); 81 82 // omr_prefix_priority_to_bits 83 // 84 // Given an omr_priority_t, return the bits that represent it in the prefix flag word. 85 // 86 int omr_prefix_priority_to_bits(omr_prefix_priority_t priority); 87 88 // omr_prefix_priority_to_int 89 // 90 // Given an omr_priority_t, return the human-readable integer that represents it. Invalid priority is 91 // returned as -1 (low). 92 // 93 int omr_prefix_priority_to_int(omr_prefix_priority_t priority); 94 95 // omr_watcher_callback_add 96 // 97 // Adds a callback on the omr_watcher object. 98 // 99 // watcher: the omr_watcher_t to which to add the callback 100 101 #define omr_watcher_callback_add(omw, callback, context_release, context) \ 102 omr_watcher_callback_add_(omw, callback, context_release, context, __FILE__, __LINE__) 103 omr_watcher_callback_t *NULLABLE 104 omr_watcher_callback_add_(omr_watcher_t *NONNULL omw, omr_watcher_event_callback_t NONNULL callback, 105 omr_watcher_context_release_callback_t NULLABLE context_release, 106 void *NULLABLE context, const char *NONNULL file, int line); 107 108 // omr_watcher_callback_cancel 109 // 110 // Cancel a callback that was returned by omr_watcher_add_callback(). 111 // 112 // watcher: the watcher that returned the callback object. 113 // callback: the callback to free 114 // 115 // The object passed in callback should not be retained by the caller after calling omr_watcher_callback_cancel(). 116 117 void omr_watcher_callback_cancel(omr_watcher_t *NONNULL omw, omr_watcher_callback_t *NONNULL callback); 118 119 // omr_watcher_create 120 // 121 // Creates and starts an omr_watcher_t object. The object starts an ongoing query with wpantund/threadradiod to watch the Thread:OnMeshPrefixes 122 // property. Changes are reported to callbacks, which can be registered with 123 // 124 // route_state: pointer to a route state object to reference in callbacks, must be non-NULL. 125 // 126 // returns value: NULL on failure, or a pointer to an omr_watcher_t object. 127 128 #define omr_watcher_create(route_state, disconnect_callback) \ 129 omr_watcher_create_(route_state, disconnect_callback, __FILE__, __LINE__) 130 omr_watcher_t *NULLABLE 131 omr_watcher_create_(route_state_t *NONNULL route_state, void (*NULLABLE disconnect_callback)(void *NONNULL), 132 const char *NONNULL file, int line); 133 134 // omr_watcher_start 135 // 136 // Starts the omr watcher object. Prior to calling omr_start, no events will be delivered; after calling omr_start, events may be delivered. 137 // 138 // watcher: pointer to an omr_watcher_t object to start. 139 bool omr_watcher_start(omr_watcher_t *NONNULL watcher); 140 141 142 // omr_watcher_cancel 143 // 144 // Cancels the omr watcher object. No callbacks can occur after omr_watcher_cancel has been called. 145 // 146 // watcher: pointer to an omr_watcher_t object to cancel. 147 void omr_watcher_cancel(omr_watcher_t *NONNULL watcher); 148 149 // omr_watcher_prefix_present 150 // 151 // Returns true if there is a prefix in the watcher's prefix list that has the specified priority. 152 // 153 // watcher: watcher we use for the search 154 // ignore_prefix: the prefix we are currently publishing, and hence should ignore 155 // ignore_prefix_len: length of the prefix we should ignore 156 157 bool omr_watcher_prefix_present(omr_watcher_t *NONNULL watcher, omr_prefix_priority_t priority, 158 struct in6_addr *NONNULL ignore_prefix, int ignore_prefix_len); 159 160 // omr_watcher_prefix_exists 161 // 162 // Returns true if the specified prefix is in the watcher's current prefix list. 163 // 164 // watcher: watcher we use for the search 165 // address: address on prefix to search for 166 // prefix_len: length of prefix (host bits in address are ignored) 167 168 bool omr_watcher_prefix_exists(omr_watcher_t *NONNULL watcher, 169 const struct in6_addr *NONNULL address, int prefix_len); 170 171 // omr_watcher_prefix_present 172 // 173 // Returns true if there is a prefix in the provided list that has the specified priority. 174 // 175 // prefixes: pointer to an omr_prefix_t object to check 176 // preference: low, medium or high 177 178 bool 179 omr_watcher_prefix_wins(omr_watcher_t *NONNULL watcher, omr_prefix_priority_t priority, 180 struct in6_addr *NONNULL ignore_prefix, int ignore_prefix_length); 181 182 // omr_watcher_prefixes_get 183 // 184 // Returns the list of prefixes the omr_watcher has most recently seen, or NULL if none. 185 // 186 187 omr_prefix_t *NULLABLE 188 omr_watcher_prefixes_get(omr_watcher_t *NONNULL watcher); 189 190 // omr_watcher_add_prefix 191 // 192 // Adds the specified prefix at the specified priority. Returns true if prefix was added, false otherwise. 193 // 194 195 bool 196 omr_watcher_prefix_add(omr_watcher_t *NONNULL watcher, const void *NONNULL data, int prefix_length, omr_prefix_priority_t priority); 197 198 // omr_watcher_prefixes 199 // 200 // Deletes the specified prefix. Returns true of it was deleted, false otherwise. 201 // 202 203 bool 204 omr_watcher_prefix_remove(omr_watcher_t *NONNULL watcher, const void *NONNULL data, int prefix_length); 205 206 // omw_watcher_non_ula_prefix_present 207 // 208 // Returns true if there is an on-mesh prefix in the thread network data that is not a ULA prefix (implicitly a global prefix) 209 // 210 211 bool omr_watcher_non_ula_prefix_present(omr_watcher_t *NONNULL watcher); 212 213 214 #define omr_watcher_prefix_is_non_ula_prefix(omr_prefix) ((((uint8_t *)&(omr_prefix)->prefix)[0] & 0xfc) != 0xfc) 215 216 #endif // _OMR_WATCHER_H__ 217 218 // Local Variables: 219 // mode: C 220 // tab-width: 4 221 // c-file-style: "bsd" 222 // c-basic-offset: 4 223 // fill-column: 120 224 // indent-tabs-mode: nil 225 // End: 226