xref: /netbsd-src/external/apache2/mDNSResponder/dist/ServiceRegistration/omr-watcher.h (revision 4439cfd0acf9c7dc90625e5cd83b2317a9ab8967)
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