blob: cd0c21f131c257f3344aa24a760db3bbb4c0f979 [file] [log] [blame]
Oliver Smith2bdcc8e2019-11-20 10:56:35 +01001/* Copyright 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
2 *
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include <osmocom/core/linuxlist.h>
22#include <osmocom/core/timer.h>
23#include <osmocom/core/sockaddr_str.h>
24#include <osmocom/mslookup/mslookup.h>
25
26struct osmo_mslookup_client;
27struct osmo_mslookup_result;
28
29typedef void (*osmo_mslookup_cb_t)(struct osmo_mslookup_client *client,
30 uint32_t request_handle,
31 const struct osmo_mslookup_query *query,
32 const struct osmo_mslookup_result *result);
33
34/*! This handling information is passed along with a lookup request.
35 * It tells the osmo_mslookup_client layer how to handle responses received from various mslookup methods (at the time
36 * of writing only mDNS exists as a method, but the intention is to easily allow adding other methods in the future).
37 * This query handling info is not seen by the individual method implementations, to clarify that it is the
38 * osmo_mslookup_client layer that takes care of these details. */
39struct osmo_mslookup_query_handling {
40 /*! Wait at least this long before returning any results.
41 *
42 * If nonzero, result_cb will be called as soon as this delay has elapsed, either with the so far youngest age
43 * result, or with a "not found yet" result. After this delay has elapsed, receiving results will continue
44 * until result_timeout_milliseconds has elapsed.
45 *
46 * If zero, responses are fed to the result_cb right from the start, every time a younger aged result than
47 * before comes in.
48 *
49 * If a result with age == 0 is received, min_wait_milliseconds is ignored, the result is returned immediately
50 * and listening for responses ends.
51 *
52 * Rationale: If a subscriber has recently moved between sites, multiple results will arrive, and the youngest
53 * age wins. It can make sense to wait a minimum time for responses before determining the winning result.
54 *
55 * However, if no result or no valid result has arrived within a short period, the subscriber may be at a site
56 * that is far away or that is currently experiencing high latency. It is thus a good safety net to still
57 * receive results for an extended period of time.
58 *
59 * For some services, it is possible to establish links to every received result, and whichever link succeeds
60 * will be used (for example for SIP calls: first to pick up the call gets connected, the others are dropped
61 * silently).
62 */
63 uint32_t min_wait_milliseconds;
64
65 /*! Total time in milliseconds to listen for lookup responses.
66 *
67 * When this timeout elapses, osmo_mslookup_client_request_cancel() is called implicitly; Manually invoking
68 * osmo_mslookup_client_request_cancel() after result_timeout_milliseconds has elapsed is not necessary, but is
69 * still safe to do anyway.
70 *
71 * If zero, min_wait_milliseconds is also used as result_timeout_milliseconds; if that is also zero, a default
72 * timeout value is used.
73 *
74 * If result_timeout_milliseconds <= min_wait_milliseconds, then min_wait_milliseconds is used as
75 * result_timeout_milliseconds, i.e. the timeout triggers as soon as min_wait_milliseconds hits.
76 *
77 * osmo_mslookup_client_request_cancel() can be called any time to end the request.
78 */
79 uint32_t result_timeout_milliseconds;
80
81 /*! Invoked every time a result with a younger age than the previous result has arrived.
82 * To stop receiving results before result_timeout_milliseconds has elapsed, call
83 * osmo_mslookup_client_request_cancel().
84 */
85 osmo_mslookup_cb_t result_cb;
86};
87
88uint32_t osmo_mslookup_client_request(struct osmo_mslookup_client *client,
89 const struct osmo_mslookup_query *query,
90 const struct osmo_mslookup_query_handling *handling);
91
92void osmo_mslookup_client_request_cancel(struct osmo_mslookup_client *client, uint32_t request_handle);
93
94struct osmo_mslookup_client *osmo_mslookup_client_new(void *ctx);
95bool osmo_mslookup_client_active(struct osmo_mslookup_client *client);
96void osmo_mslookup_client_free(struct osmo_mslookup_client *client);
97
98/*! Describe a specific mslookup client method implementation. This struct is only useful for a lookup method
99 * implementation to add itself to an osmo_mslookup_client, see for example osmo_mslookup_client_add_mdns(). */
100struct osmo_mslookup_client_method {
101 struct llist_head entry;
102
103 /*! Human readable name of this lookup method. */
104 const char *name;
105
106 /*! Private data for the lookup method implementation. */
107 void *priv;
108
109 /*! Backpointer to the client this method is added to. */
110 struct osmo_mslookup_client *client;
111
112 /*! Launch a lookup query. Called from osmo_mslookup_client_request().
113 * The implementation returns results by calling osmo_mslookup_client_rx_result(). */
114 void (*request)(struct osmo_mslookup_client_method *method,
115 const struct osmo_mslookup_query *query,
116 uint32_t request_handle);
117 /*! End a lookup query. Called from osmo_mslookup_client_request_cancel(). It is guaranteed to be called
118 * exactly once per above request() invocation. (The API user is required to invoke
119 * osmo_mslookup_client_request_cancel() exactly once per osmo_mslookup_client_request().) */
120 void (*request_cleanup)(struct osmo_mslookup_client_method *method,
121 uint32_t request_handle);
122
123 /*! The mslookup_client is removing this method, clean up all open requests, lists and allocations. */
124 void (*destruct)(struct osmo_mslookup_client_method *method);
125};
126
127void osmo_mslookup_client_method_add(struct osmo_mslookup_client *client,
128 struct osmo_mslookup_client_method *method);
129bool osmo_mslookup_client_method_del(struct osmo_mslookup_client *client,
130 struct osmo_mslookup_client_method *method);
131void osmo_mslookup_client_rx_result(struct osmo_mslookup_client *client, uint32_t request_handle,
132 const struct osmo_mslookup_result *result);