Home | History | Annotate | Line # | Download | only in ServiceRegistration
      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 Apples 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